From edcabb80b788c0bf91b7edbaf4c79deb8b7b8553 Mon Sep 17 00:00:00 2001
From: Salvatore Campagna
<93581129+salvatore-campagna@users.noreply.github.com>
Date: Sat, 12 Oct 2024 18:14:15 +0200
Subject: [PATCH 01/77] Introduce `index.mapping.source.mode` setting to
override `_source.mode` (#114433)
* featur : introduce index.mapping.source.mode setting
Introduce a new `index.mapper.source.mode` setting which will be used
to override the mapping level `_source.mode`. For now the mapping
level setting will stay and be deprecated later with another PR.
The setting takes precedence always precedence. When not defined
the index mode is used and can be overridden by the _source.mode
mapping level definition.
---
.../common/settings/IndexScopedSettings.java | 2 +
.../elasticsearch/index/IndexSettings.java | 7 +
.../index/mapper/SourceFieldMapper.java | 114 ++-
.../TransportResumeFollowActionTests.java | 2 +
.../test/40_source_mode_setting.yml | 847 ++++++++++++++++++
5 files changed, 950 insertions(+), 22 deletions(-)
create mode 100644 x-pack/plugin/logsdb/src/yamlRestTest/resources/rest-api-spec/test/40_source_mode_setting.yml
diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
index ad3d7d7f1c2ec..884ce38fba391 100644
--- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
+++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
@@ -35,6 +35,7 @@
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
+import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.similarity.SimilarityService;
import org.elasticsearch.index.store.FsDirectoryFactory;
import org.elasticsearch.index.store.Store;
@@ -186,6 +187,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
FieldMapper.SYNTHETIC_SOURCE_KEEP_INDEX_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING,
+ SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING,
// validate that built-in similarities don't get redefined
Setting.groupSetting("index.similarity.", (s) -> {
diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java
index e82f9eff7d5e0..f3f8ce4b8e7e4 100644
--- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java
+++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java
@@ -28,6 +28,7 @@
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
import org.elasticsearch.index.mapper.Mapper;
+import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.ingest.IngestService;
import org.elasticsearch.node.Node;
@@ -820,6 +821,7 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
private volatile long mappingDimensionFieldsLimit;
private volatile boolean skipIgnoredSourceWrite;
private volatile boolean skipIgnoredSourceRead;
+ private final SourceFieldMapper.Mode indexMappingSourceMode;
/**
* The maximum number of refresh listeners allows on this shard.
@@ -980,6 +982,7 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
es87TSDBCodecEnabled = scopedSettings.get(TIME_SERIES_ES87TSDB_CODEC_ENABLED_SETTING);
skipIgnoredSourceWrite = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING);
skipIgnoredSourceRead = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
+ indexMappingSourceMode = scopedSettings.get(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING);
scopedSettings.addSettingsUpdateConsumer(
MergePolicyConfig.INDEX_COMPOUND_FORMAT_SETTING,
@@ -1659,6 +1662,10 @@ private void setSkipIgnoredSourceRead(boolean value) {
this.skipIgnoredSourceRead = value;
}
+ public SourceFieldMapper.Mode getIndexMappingSourceMode() {
+ return indexMappingSourceMode;
+ }
+
/**
* The bounds for {@code @timestamp} on this index or
* {@code null} if there are no bounds.
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java
index 0f4549c679d42..f9b9de97715ed 100644
--- a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java
+++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java
@@ -18,11 +18,13 @@
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.CollectionUtils;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.IndexMode;
+import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.IndexVersions;
import org.elasticsearch.index.query.QueryShardException;
import org.elasticsearch.index.query.SearchExecutionContext;
@@ -62,8 +64,16 @@ public class SourceFieldMapper extends MetadataFieldMapper {
public static final String LOSSY_PARAMETERS_ALLOWED_SETTING_NAME = "index.lossy.source-mapping-parameters";
+ public static final Setting INDEX_MAPPER_SOURCE_MODE_SETTING = Setting.enumSetting(SourceFieldMapper.Mode.class, settings -> {
+ final IndexMode indexMode = IndexSettings.MODE.get(settings);
+ return switch (indexMode) {
+ case IndexMode.LOGSDB, IndexMode.TIME_SERIES -> Mode.SYNTHETIC.name();
+ default -> Mode.STORED.name();
+ };
+ }, "index.mapping.source.mode", value -> {}, Setting.Property.Final, Setting.Property.IndexScope);
+
/** The source mode */
- private enum Mode {
+ public enum Mode {
DISABLED,
STORED,
SYNTHETIC
@@ -96,6 +106,15 @@ private enum Mode {
true
);
+ private static final SourceFieldMapper TSDB_DEFAULT_STORED = new SourceFieldMapper(
+ Mode.STORED,
+ Explicit.IMPLICIT_TRUE,
+ Strings.EMPTY_ARRAY,
+ Strings.EMPTY_ARRAY,
+ IndexMode.TIME_SERIES,
+ true
+ );
+
private static final SourceFieldMapper TSDB_DEFAULT_NO_RECOVERY_SOURCE = new SourceFieldMapper(
Mode.SYNTHETIC,
Explicit.IMPLICIT_TRUE,
@@ -105,6 +124,15 @@ private enum Mode {
false
);
+ private static final SourceFieldMapper TSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED = new SourceFieldMapper(
+ Mode.STORED,
+ Explicit.IMPLICIT_TRUE,
+ Strings.EMPTY_ARRAY,
+ Strings.EMPTY_ARRAY,
+ IndexMode.TIME_SERIES,
+ false
+ );
+
private static final SourceFieldMapper LOGSDB_DEFAULT = new SourceFieldMapper(
Mode.SYNTHETIC,
Explicit.IMPLICIT_TRUE,
@@ -114,6 +142,15 @@ private enum Mode {
true
);
+ private static final SourceFieldMapper LOGSDB_DEFAULT_STORED = new SourceFieldMapper(
+ Mode.STORED,
+ Explicit.IMPLICIT_TRUE,
+ Strings.EMPTY_ARRAY,
+ Strings.EMPTY_ARRAY,
+ IndexMode.LOGSDB,
+ true
+ );
+
private static final SourceFieldMapper LOGSDB_DEFAULT_NO_RECOVERY_SOURCE = new SourceFieldMapper(
Mode.SYNTHETIC,
Explicit.IMPLICIT_TRUE,
@@ -123,6 +160,15 @@ private enum Mode {
false
);
+ private static final SourceFieldMapper LOGSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED = new SourceFieldMapper(
+ Mode.STORED,
+ Explicit.IMPLICIT_TRUE,
+ Strings.EMPTY_ARRAY,
+ Strings.EMPTY_ARRAY,
+ IndexMode.LOGSDB,
+ false
+ );
+
/*
* Synthetic source was added as the default for TSDB in v.8.7. The legacy field mapper below
* is used in bwc tests and mixed clusters containing time series indexes created in an earlier version.
@@ -197,6 +243,8 @@ public static class Builder extends MetadataFieldMapper.Builder {
m -> Arrays.asList(toType(m).excludes)
);
+ private final Settings settings;
+
private final IndexMode indexMode;
private final boolean supportsNonDefaultParameterValues;
@@ -210,6 +258,7 @@ public Builder(
boolean enableRecoverySource
) {
super(Defaults.NAME);
+ this.settings = settings;
this.indexMode = indexMode;
this.supportsNonDefaultParameterValues = supportsCheckForNonDefaultParams == false
|| settings.getAsBoolean(LOSSY_PARAMETERS_ALLOWED_SETTING_NAME, true);
@@ -226,10 +275,10 @@ protected Parameter>[] getParameters() {
return new Parameter>[] { enabled, mode, includes, excludes };
}
- private boolean isDefault() {
- Mode m = mode.get();
- if (m != null
- && (((indexMode != null && indexMode.isSyntheticSourceEnabled() && m == Mode.SYNTHETIC) == false) || m == Mode.DISABLED)) {
+ private boolean isDefault(final Mode sourceMode) {
+ if (sourceMode != null
+ && (((indexMode != null && indexMode.isSyntheticSourceEnabled() && sourceMode == Mode.SYNTHETIC) == false)
+ || sourceMode == Mode.DISABLED)) {
return false;
}
return enabled.get().value() && includes.getValue().isEmpty() && excludes.getValue().isEmpty();
@@ -242,12 +291,14 @@ public SourceFieldMapper build() {
throw new MapperParsingException("Cannot set both [mode] and [enabled] parameters");
}
}
- if (isDefault()) {
- return switch (indexMode) {
- case TIME_SERIES -> enableRecoverySource ? TSDB_DEFAULT : TSDB_DEFAULT_NO_RECOVERY_SOURCE;
- case LOGSDB -> enableRecoverySource ? LOGSDB_DEFAULT : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE;
- default -> enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE;
- };
+ // NOTE: if the `index.mapper.source.mode` exists it takes precedence to determine the source mode for `_source`
+ // otherwise the mode is determined according to `index.mode` and `_source.mode`.
+ final Mode sourceMode = INDEX_MAPPER_SOURCE_MODE_SETTING.exists(settings)
+ ? INDEX_MAPPER_SOURCE_MODE_SETTING.get(settings)
+ : mode.get();
+ if (isDefault(sourceMode)) {
+ return resolveSourceMode(indexMode, sourceMode, enableRecoverySource);
+
}
if (supportsNonDefaultParameterValues == false) {
List disallowed = new ArrayList<>();
@@ -271,8 +322,9 @@ public SourceFieldMapper build() {
);
}
}
+
SourceFieldMapper sourceFieldMapper = new SourceFieldMapper(
- mode.get(),
+ sourceMode,
enabled.get(),
includes.getValue().toArray(Strings.EMPTY_ARRAY),
excludes.getValue().toArray(Strings.EMPTY_ARRAY),
@@ -287,21 +339,39 @@ public SourceFieldMapper build() {
}
+ private static SourceFieldMapper resolveSourceMode(final IndexMode indexMode, final Mode sourceMode, boolean enableRecoverySource) {
+ if (indexMode == IndexMode.STANDARD) {
+ return enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE;
+ }
+ final SourceFieldMapper syntheticWithoutRecoverySource = indexMode == IndexMode.TIME_SERIES
+ ? TSDB_DEFAULT_NO_RECOVERY_SOURCE
+ : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE;
+ final SourceFieldMapper syntheticWithRecoverySource = indexMode == IndexMode.TIME_SERIES ? TSDB_DEFAULT : LOGSDB_DEFAULT;
+ final SourceFieldMapper storedWithoutRecoverySource = indexMode == IndexMode.TIME_SERIES
+ ? TSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED
+ : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED;
+ final SourceFieldMapper storedWithRecoverySource = indexMode == IndexMode.TIME_SERIES ? TSDB_DEFAULT_STORED : LOGSDB_DEFAULT_STORED;
+
+ return switch (sourceMode) {
+ case SYNTHETIC -> enableRecoverySource ? syntheticWithRecoverySource : syntheticWithoutRecoverySource;
+ case STORED -> enableRecoverySource ? storedWithRecoverySource : storedWithoutRecoverySource;
+ case DISABLED -> throw new IllegalArgumentException(
+ "_source can not be disabled in index using [" + indexMode + "] index mode"
+ );
+ };
+ }
+
public static final TypeParser PARSER = new ConfigurableTypeParser(c -> {
- var indexMode = c.getIndexSettings().getMode();
+ final IndexMode indexMode = c.getIndexSettings().getMode();
boolean enableRecoverySource = INDICES_RECOVERY_SOURCE_ENABLED_SETTING.get(c.getSettings());
+ final Mode settingSourceMode = INDEX_MAPPER_SOURCE_MODE_SETTING.get(c.getSettings());
+
if (indexMode.isSyntheticSourceEnabled()) {
- if (indexMode == IndexMode.TIME_SERIES) {
- if (c.getIndexSettings().getIndexVersionCreated().onOrAfter(IndexVersions.V_8_7_0)) {
- return enableRecoverySource ? TSDB_DEFAULT : TSDB_DEFAULT_NO_RECOVERY_SOURCE;
- } else {
- return enableRecoverySource ? TSDB_LEGACY_DEFAULT : TSDB_LEGACY_DEFAULT_NO_RECOVERY_SOURCE;
- }
- } else if (indexMode == IndexMode.LOGSDB) {
- return enableRecoverySource ? LOGSDB_DEFAULT : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE;
+ if (indexMode == IndexMode.TIME_SERIES && c.getIndexSettings().getIndexVersionCreated().before(IndexVersions.V_8_7_0)) {
+ return enableRecoverySource ? TSDB_LEGACY_DEFAULT : TSDB_LEGACY_DEFAULT_NO_RECOVERY_SOURCE;
}
}
- return enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE;
+ return resolveSourceMode(indexMode, settingSourceMode, enableRecoverySource);
},
c -> new Builder(
c.getIndexSettings().getMode(),
diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
index b4be0b33a464e..357e1bca38e8f 100644
--- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
+++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
@@ -18,6 +18,7 @@
import org.elasticsearch.index.MapperTestUtils;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
import org.elasticsearch.index.mapper.MapperService;
+import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.ccr.Ccr;
import org.elasticsearch.xpack.ccr.CcrSettings;
@@ -334,6 +335,7 @@ public void testDynamicIndexSettingsAreClassified() {
replicatedSettings.add(IndexSettings.PREFER_ILM_SETTING);
replicatedSettings.add(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
replicatedSettings.add(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING);
+ replicatedSettings.add(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING);
for (Setting> setting : IndexScopedSettings.BUILT_IN_INDEX_SETTINGS) {
// removed settings have no effect, they are only there for BWC
diff --git a/x-pack/plugin/logsdb/src/yamlRestTest/resources/rest-api-spec/test/40_source_mode_setting.yml b/x-pack/plugin/logsdb/src/yamlRestTest/resources/rest-api-spec/test/40_source_mode_setting.yml
new file mode 100644
index 0000000000000..33fedce3b59c1
--- /dev/null
+++ b/x-pack/plugin/logsdb/src/yamlRestTest/resources/rest-api-spec/test/40_source_mode_setting.yml
@@ -0,0 +1,847 @@
+---
+create an index with disabled source mode and standard index mode without setting:
+ - do:
+ indices.create:
+ index: test_disabled_standard
+ body:
+ settings:
+ index:
+ mode: standard
+ mappings:
+ _source:
+ mode: disabled
+
+ - do:
+ indices.get_mapping:
+ index: test_disabled_standard
+
+ - match: { test_disabled_standard.mappings._source.mode: disabled }
+
+---
+create an index with stored source mode and standard index mode without setting:
+ - do:
+ indices.create:
+ index: test_stored_standard
+ body:
+ settings:
+ index:
+ mode: standard
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_standard
+
+ - match: { test_stored_standard.mappings._source.mode: stored }
+
+---
+create an index with synthetic source mode and standard index mode without setting:
+ - do:
+ indices.create:
+ index: test_synthetic_standard
+ body:
+ settings:
+ index:
+ mode: standard
+ mappings:
+ _source:
+ mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_standard
+
+ - match: { test_synthetic_standard.mappings._source.mode: synthetic }
+
+---
+create an index with disabled source mode and logsdb index mode without setting:
+ - do:
+ catch: bad_request
+ indices.create:
+ index: test_disabled_logsdb
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mappings:
+ _source:
+ mode: disabled
+
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [logsdb] index mode" }
+
+---
+create an index with stored source mode and logsdb index mode without setting:
+ - do:
+ indices.create:
+ index: test_stored_logsdb
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_settings:
+ index: "test_stored_logsdb"
+ - match: { test_stored_logsdb.settings.index.mode: logsdb }
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_logsdb
+
+ - match: { test_stored_logsdb.mappings._source.mode: stored }
+
+---
+create an index with synthetic source mode and logsdb index mode without setting:
+ - do:
+ indices.create:
+ index: test_synthetic_logsdb
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mappings:
+ _source:
+ mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_logsdb
+
+ - match: { test_synthetic_logsdb.mappings._source.mode: synthetic }
+
+---
+create an index with disabled source mode and time series index mode without setting:
+ - do:
+ catch: bad_request
+ indices.create:
+ index: test_disabled_time_series
+ body:
+ settings:
+ index:
+ mode: time_series
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ _source:
+ mode: disabled
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [time_series] index mode" }
+
+---
+create an index with stored source mode and time series index mode without setting:
+ - do:
+ indices.create:
+ index: test_stored_time_series
+ body:
+ settings:
+ index:
+ mode: time_series
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ _source:
+ mode: stored
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ indices.get_settings:
+ index: "test_stored_time_series"
+ - match: { test_stored_time_series.settings.index.mode: time_series }
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_time_series
+
+ - match: { test_stored_time_series.mappings._source.mode: stored }
+
+
+---
+create an index with synthetic source mode and time series index mode without setting:
+ - do:
+ indices.create:
+ index: test_synthetic_time_series
+ body:
+ settings:
+ index:
+ mode: time_series
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ _source:
+ mode: synthetic
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ indices.get_settings:
+ index: "test_synthetic_time_series"
+ - match: { test_synthetic_time_series.settings.index.mode: time_series }
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_time_series
+
+ - match: { test_synthetic_time_series.mappings._source.mode: synthetic }
+
+---
+create an index with stored source mode:
+ - do:
+ indices.create:
+ index: test_stored_default
+ body:
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_default
+
+ - match: { test_stored_default.mappings._source.mode: stored }
+
+---
+override stored to synthetic source mode:
+ - do:
+ indices.create:
+ index: test_stored_override
+ body:
+ settings:
+ index:
+ mapping.source.mode: synthetic
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_override
+
+ - match: { test_stored_override.mappings._source.mode: synthetic }
+
+---
+override stored to disabled source mode:
+ - do:
+ indices.create:
+ index: test_stored_disabled
+ body:
+ settings:
+ index:
+ mapping.source.mode: disabled
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_stored_disabled
+
+ - match: { test_stored_disabled.mappings._source.mode: disabled }
+
+---
+create an index with disabled source mode:
+ - do:
+ indices.create:
+ index: test_disabled_default
+ body:
+ mappings:
+ _source:
+ mode: disabled
+
+ - do:
+ indices.get_mapping:
+ index: test_disabled_default
+
+ - match: { test_disabled_default.mappings._source.mode: disabled }
+
+---
+override disabled to synthetic source mode:
+ - do:
+ indices.create:
+ index: test_disabled_synthetic
+ body:
+ settings:
+ index:
+ mapping.source.mode: synthetic
+ mappings:
+ _source:
+ mode: disabled
+
+ - do:
+ indices.get_mapping:
+ index: test_disabled_synthetic
+
+ - match: { test_disabled_synthetic.mappings._source.mode: synthetic }
+
+---
+override disabled to stored source mode:
+ - do:
+ indices.create:
+ index: test_disabled_stored
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+ mappings:
+ _source:
+ mode: disabled
+
+ - do:
+ indices.get_mapping:
+ index: test_disabled_stored
+
+ - match: { test_disabled_stored.mappings._source.mode: stored }
+
+---
+create an index with synthetic source mode:
+ - do:
+ indices.create:
+ index: test_synthetic_default
+ body:
+ mappings:
+ _source:
+ mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_default
+
+ - match: { test_synthetic_default.mappings._source.mode: synthetic }
+
+---
+override synthetic to stored source mode:
+ - do:
+ indices.create:
+ index: test_synthetic_stored
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+ mappings:
+ _source:
+ mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_stored
+
+ - match: { test_synthetic_stored.mappings._source.mode: stored }
+
+---
+override synthetic to disabled source mode:
+ - do:
+ indices.create:
+ index: test_synthetic_disabled
+ body:
+ settings:
+ index:
+ mapping.source.mode: disabled
+ mappings:
+ _source:
+ mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_synthetic_disabled
+
+ - match: { test_synthetic_disabled.mappings._source.mode: disabled }
+
+---
+create an index with unspecified source mode:
+ - do:
+ indices.create:
+ index: test_unset_default
+
+ - do:
+ indices.get_mapping:
+ index: test_unset_default
+
+ - match: { test_unset_default.mappings._source.mode: null }
+
+---
+override unspecified to stored source mode:
+ - do:
+ indices.create:
+ index: test_unset_stored
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_unset_stored
+
+ - match: { test_unset_stored.mappings: { } }
+
+---
+override unspecified to disabled source mode:
+ - do:
+ indices.create:
+ index: test_unset_disabled
+ body:
+ settings:
+ index:
+ mapping.source.mode: disabled
+
+ - do:
+ indices.get_mapping:
+ index: test_unset_disabled
+
+ - match: { test_unset_disabled.mappings: { } }
+
+---
+override unspecified to synthetic source mode:
+ - do:
+ indices.create:
+ index: test_unset_synthetic
+ body:
+ settings:
+ index:
+ mapping.source.mode: synthetic
+
+ - do:
+ indices.get_mapping:
+ index: test_unset_synthetic
+
+ - match: { test_unset_synthetic.mappings: { } }
+
+---
+create an index with standard index mode:
+ - do:
+ indices.create:
+ index: test_standard_index_mode
+ body:
+ settings:
+ index:
+ mode: standard
+ mappings:
+ _source:
+ mode: stored
+
+ - do:
+ indices.get_mapping:
+ index: test_standard_index_mode
+
+ - match: { test_standard_index_mode.mappings._source.mode: stored }
+
+---
+create an index with time_series index mode and synthetic source:
+ - do:
+ indices.create:
+ index: test_time_series_index_mode_synthetic
+ body:
+ settings:
+ index:
+ mode: time_series
+ mapping.source.mode: synthetic
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ indices.get_settings:
+ index: "test_time_series_index_mode_synthetic"
+ - match: { test_time_series_index_mode_synthetic.settings.index.mode: time_series }
+
+
+ - do:
+ indices.get_mapping:
+ index: test_time_series_index_mode_synthetic
+
+ - match: { test_time_series_index_mode_synthetic.mappings._source.mode: synthetic }
+
+---
+create an index with logsdb index mode and synthetic source:
+ - do:
+ indices.create:
+ index: test_logsdb_index_mode_synthetic
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mapping.source.mode: synthetic
+
+ - do:
+ indices.get_settings:
+ index: "test_logsdb_index_mode_synthetic"
+ - match: { test_logsdb_index_mode_synthetic.settings.index.mode: logsdb }
+
+ - do:
+ indices.get_mapping:
+ index: test_logsdb_index_mode_synthetic
+
+ - match: { test_logsdb_index_mode_synthetic.mappings._source.mode: synthetic }
+
+---
+create an index with time_series index mode and stored source:
+ - do:
+ indices.create:
+ index: test_time_series_index_mode_undefined
+ body:
+ settings:
+ index:
+ mode: time_series
+ mapping.source.mode: stored
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ indices.get_settings:
+ index: "test_time_series_index_mode_undefined"
+ - match: { test_time_series_index_mode_undefined.settings.index.mode: time_series }
+
+ - do:
+ indices.get_mapping:
+ index: test_time_series_index_mode_undefined
+
+ - match: { test_time_series_index_mode_undefined.mappings._source.mode: stored }
+
+---
+create an index with logsdb index mode and stored source:
+ - do:
+ indices.create:
+ index: test_logsdb_index_mode_undefined
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mapping.source.mode: stored
+
+ - do:
+ indices.get_settings:
+ index: "test_logsdb_index_mode_undefined"
+ - match: { test_logsdb_index_mode_undefined.settings.index.mode: logsdb }
+
+ - do:
+ indices.get_mapping:
+ index: test_logsdb_index_mode_undefined
+
+ - match: { test_logsdb_index_mode_undefined.mappings._source.mode: stored }
+
+---
+create an index with time_series index mode and disabled source:
+ - do:
+ catch: bad_request
+ indices.create:
+ index: test_time_series_index_mode
+ body:
+ settings:
+ index:
+ mode: time_series
+ mapping.source.mode: disabled
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [time_series] index mode" }
+
+---
+create an index with logsdb index mode and disabled source:
+ - do:
+ catch: bad_request
+ indices.create:
+ index: test_logsdb_index_mode
+ body:
+ settings:
+ index:
+ mode: logsdb
+ mapping.source.mode: disabled
+
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [logsdb] index mode" }
+
+---
+modify final setting after index creation:
+ - do:
+ indices.create:
+ index: test_modify_setting
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+
+ - do:
+ catch: /.*Can't update non dynamic setting.*/
+ indices.put_settings:
+ index: test_modify_setting
+ body:
+ index:
+ mapping.source.mode: synthetic
+
+---
+modify source mapping from stored to disabled after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_stored_disabled
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_stored_disabled
+ body:
+ _source:
+ mode: disabled
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_stored_disabled
+ - match: { test_modify_source_mode_stored_disabled.mappings._source.mode: stored }
+
+---
+modify source mapping from stored to synthetic after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_stored_synthetic
+ body:
+ settings:
+ index:
+ mapping.source.mode: stored
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_stored_synthetic
+ body:
+ _source:
+ mode: synthetic
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_stored_synthetic
+ - match: { test_modify_source_mode_stored_synthetic.mappings._source.mode: stored }
+
+---
+modify source mapping from disabled to stored after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_disabled_stored
+ body:
+ settings:
+ index:
+ mapping.source.mode: disabled
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_disabled_stored
+ body:
+ _source:
+ mode: stored
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_disabled_stored
+ - match: { test_modify_source_mode_disabled_stored.mappings._source.mode: disabled }
+
+---
+modify source mapping from disabled to synthetic after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_disabled_synthetic
+ body:
+ settings:
+ index:
+ mapping.source.mode: disabled
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_disabled_synthetic
+ body:
+ _source:
+ mode: synthetic
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_disabled_synthetic
+ - match: { test_modify_source_mode_disabled_synthetic.mappings._source.mode: disabled }
+
+---
+modify source mapping from synthetic to stored after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_synthetic_stored
+ body:
+ settings:
+ index:
+ mapping.source.mode: synthetic
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_synthetic_stored
+ body:
+ _source:
+ mode: stored
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_synthetic_stored
+ - match: { test_modify_source_mode_synthetic_stored.mappings._source.mode: synthetic }
+
+---
+modify source mapping from synthetic to disabled after index creation:
+ - do:
+ indices.create:
+ index: test_modify_source_mode_synthetic_disabled
+ body:
+ settings:
+ index:
+ mapping.source.mode: synthetic
+
+ - do:
+ indices.put_mapping:
+ index: test_modify_source_mode_synthetic_disabled
+ body:
+ _source:
+ mode: disabled
+ - is_true: acknowledged
+
+ - do:
+ indices.get_mapping:
+ index: test_modify_source_mode_synthetic_disabled
+ - match: { test_modify_source_mode_synthetic_disabled.mappings._source.mode: synthetic }
+
+---
+modify logsdb index source mode to disabled after index creation:
+ - do:
+ indices.create:
+ index: test_modify_logsdb_disabled_after_creation
+ body:
+ settings:
+ index:
+ mode: logsdb
+
+ - do:
+ catch: bad_request
+ indices.put_mapping:
+ index: test_modify_logsdb_disabled_after_creation
+ body:
+ _source:
+ mode: disabled
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [logsdb] index mode" }
+
+---
+modify logsdb index source mode to stored after index creation:
+ - do:
+ indices.create:
+ index: test_modify_logsdb_stored_after_creation
+ body:
+ settings:
+ index:
+ mode: logsdb
+
+ - do:
+ catch: bad_request
+ indices.put_mapping:
+ index: test_modify_logsdb_stored_after_creation
+ body:
+ _source:
+ mode: stored
+ - match: { error.type: "illegal_argument_exception" }
+ - match: { error.reason: "Mapper for [_source] conflicts with existing mapper:\n\tCannot update parameter [mode] from [synthetic] to [stored]" }
+
+---
+modify time_series index source mode to disabled after index creation:
+ - do:
+ indices.create:
+ index: test_modify_time_series_disabled_after_creation
+ body:
+ settings:
+ index:
+ mode: time_series
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ catch: bad_request
+ indices.put_mapping:
+ index: test_modify_time_series_disabled_after_creation
+ body:
+ _source:
+ mode: disabled
+ - match: { error.type: "mapper_parsing_exception" }
+ - match: { error.reason: "Failed to parse mapping: _source can not be disabled in index using [time_series] index mode" }
+
+---
+modify time_series index source mode to stored after index creation:
+ - do:
+ indices.create:
+ index: test_modify_time_series_stored_after_creation
+ body:
+ settings:
+ index:
+ mode: time_series
+ routing_path: [ keyword ]
+ time_series:
+ start_time: 2021-04-28T00:00:00Z
+ end_time: 2021-04-29T00:00:00Z
+ mappings:
+ properties:
+ keyword:
+ type: keyword
+ time_series_dimension: true
+
+ - do:
+ catch: bad_request
+ indices.put_mapping:
+ index: test_modify_time_series_stored_after_creation
+ body:
+ _source:
+ mode: stored
+ - match: { error.type: "illegal_argument_exception" }
+ - match: { error.reason: "Mapper for [_source] conflicts with existing mapper:\n\tCannot update parameter [mode] from [synthetic] to [stored]" }
From e833e7b6c4e81284ef4e5bcb29cea9d9dad6b963 Mon Sep 17 00:00:00 2001
From: Martijn van Groningen
Date: Sat, 12 Oct 2024 18:55:27 +0200
Subject: [PATCH 02/77] Add feature flag for subobjects auto (#114616)
---
.../rest/yaml/CcsCommonYamlTestSuiteIT.java | 3 +-
.../yaml/RcsCcsCommonYamlTestSuiteIT.java | 1 +
...okeTestMultiNodeClientYamlTestSuiteIT.java | 1 +
.../test/rest/ClientYamlTestSuiteIT.java | 1 +
.../index/mapper/ObjectMapper.java | 4 +-
.../index/mapper/DynamicTemplatesTests.java | 8 +++
.../index/mapper/ObjectMapperTests.java | 50 +++++++++++--------
.../test/cluster/FeatureFlag.java | 1 +
.../xpack/test/rest/XPackRestIT.java | 1 +
...CoreWithSecurityClientYamlTestSuiteIT.java | 1 +
x-pack/qa/runtime-fields/build.gradle | 1 +
11 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java
index 8ce1bfdc61f6b..3a24427df24a3 100644
--- a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java
+++ b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/CcsCommonYamlTestSuiteIT.java
@@ -89,7 +89,8 @@ public class CcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.setting("xpack.security.enabled", "false")
// geohex_grid requires gold license
.setting("xpack.license.self_generated.type", "trial")
- .feature(FeatureFlag.TIME_SERIES_MODE);
+ .feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED);
private static ElasticsearchCluster remoteCluster = ElasticsearchCluster.local()
.name(REMOTE_CLUSTER_NAME)
diff --git a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java
index acdd540ca7b9d..5ada1e941266a 100644
--- a/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java
+++ b/qa/ccs-common-rest/src/yamlRestTest/java/org/elasticsearch/test/rest/yaml/RcsCcsCommonYamlTestSuiteIT.java
@@ -91,6 +91,7 @@ public class RcsCcsCommonYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.setting("xpack.security.remote_cluster_server.ssl.enabled", "false")
.setting("xpack.security.remote_cluster_client.ssl.enabled", "false")
.feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.user("test_admin", "x-pack-test-password");
private static ElasticsearchCluster fulfillingCluster = ElasticsearchCluster.local()
diff --git a/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java b/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java
index c68d27b883c53..e53c0564be297 100644
--- a/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java
+++ b/qa/smoke-test-multinode/src/yamlRestTest/java/org/elasticsearch/smoketest/SmokeTestMultiNodeClientYamlTestSuiteIT.java
@@ -35,6 +35,7 @@ public class SmokeTestMultiNodeClientYamlTestSuiteIT extends ESClientYamlSuiteTe
// The first node does not have the ingest role so we're sure ingest requests are forwarded:
.node(0, n -> n.setting("node.roles", "[master,data,ml,remote_cluster_client,transform]"))
.feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();
public SmokeTestMultiNodeClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
diff --git a/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java b/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java
index 2b20e35019424..084e212a913b2 100644
--- a/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java
+++ b/rest-api-spec/src/yamlRestTest/java/org/elasticsearch/test/rest/ClientYamlTestSuiteIT.java
@@ -36,6 +36,7 @@ public class ClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
.module("health-shards-availability")
.module("data-streams")
.feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();
public ClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
index 5e63fee8c5adc..70c4a3ac213a2 100644
--- a/server/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
+++ b/server/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
@@ -15,6 +15,7 @@
import org.elasticsearch.common.Explicit;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
+import org.elasticsearch.common.util.FeatureFlag;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.features.NodeFeature;
@@ -41,6 +42,7 @@
public class ObjectMapper extends Mapper {
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(ObjectMapper.class);
+ public static final FeatureFlag SUB_OBJECTS_AUTO_FEATURE_FLAG = new FeatureFlag("sub_objects_auto");
public static final String CONTENT_TYPE = "object";
static final String STORE_ARRAY_SOURCE_PARAM = "store_array_source";
@@ -74,7 +76,7 @@ public static Subobjects from(Object node) {
if (value.equalsIgnoreCase("false")) {
return DISABLED;
}
- if (value.equalsIgnoreCase("auto")) {
+ if (SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled() && value.equalsIgnoreCase("auto")) {
return AUTO;
}
}
diff --git a/server/src/test/java/org/elasticsearch/index/mapper/DynamicTemplatesTests.java b/server/src/test/java/org/elasticsearch/index/mapper/DynamicTemplatesTests.java
index 7f430cf676809..7e9a196faaa26 100644
--- a/server/src/test/java/org/elasticsearch/index/mapper/DynamicTemplatesTests.java
+++ b/server/src/test/java/org/elasticsearch/index/mapper/DynamicTemplatesTests.java
@@ -1377,6 +1377,7 @@ public void testSubobjectsFalseWithInnerNestedFromDynamicTemplate() {
}
public void testSubobjectsAutoFlatPaths() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.field("foo.metric.count", 10);
@@ -1389,6 +1390,7 @@ public void testSubobjectsAutoFlatPaths() throws IOException {
}
public void testSubobjectsAutoStructuredPaths() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.startObject("foo");
@@ -1411,6 +1413,7 @@ public void testSubobjectsAutoStructuredPaths() throws IOException {
}
public void testSubobjectsAutoArrayOfObjects() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createDynamicTemplateAutoSubobjects();
ParsedDocument doc = mapperService.documentMapper().parse(source(b -> {
b.startObject("foo");
@@ -1444,6 +1447,7 @@ public void testSubobjectsAutoArrayOfObjects() throws IOException {
}
public void testSubobjectAutoDynamicNested() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
@@ -1482,6 +1486,7 @@ public void testSubobjectAutoDynamicNested() throws IOException {
}
public void testRootSubobjectAutoDynamicNested() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
@@ -1515,6 +1520,7 @@ public void testRootSubobjectAutoDynamicNested() throws IOException {
}
public void testDynamicSubobjectsAutoDynamicFalse() throws Exception {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
// verify that we read the dynamic value properly from the parent mapper. DocumentParser#dynamicOrDefault splits the field
// name where dots are found, but it does that only for the parent prefix e.g. metrics.service and not for the leaf suffix time.max
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
@@ -1578,6 +1584,7 @@ public void testDynamicSubobjectsAutoDynamicFalse() throws Exception {
}
public void testSubobjectsAutoWithInnerNestedFromDynamicTemplate() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
DocumentMapper mapper = createDocumentMapper(topMapping(b -> {
b.startArray("dynamic_templates");
{
@@ -2045,6 +2052,7 @@ public void testSubobjectsFalseFlattened() throws IOException {
}
public void testSubobjectsAutoFlattened() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
String mapping = """
{
"_doc": {
diff --git a/server/src/test/java/org/elasticsearch/index/mapper/ObjectMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/ObjectMapperTests.java
index 64eee39532c31..3b77015fde415 100644
--- a/server/src/test/java/org/elasticsearch/index/mapper/ObjectMapperTests.java
+++ b/server/src/test/java/org/elasticsearch/index/mapper/ObjectMapperTests.java
@@ -169,27 +169,29 @@ public void testMergeEnabledForIndexTemplates() throws IOException {
assertEquals(ObjectMapper.Subobjects.ENABLED, objectMapper.subobjects());
assertTrue(objectMapper.sourceKeepMode().isEmpty());
- // Setting 'enabled' to true is allowed, and updates the mapping.
- update = Strings.toString(
- XContentFactory.jsonBuilder()
- .startObject()
- .startObject("properties")
- .startObject("object")
- .field("type", "object")
- .field("enabled", true)
- .field("subobjects", "auto")
- .field(ObjectMapper.STORE_ARRAY_SOURCE_PARAM, true)
- .endObject()
- .endObject()
- .endObject()
- );
- mapper = mapperService.merge("type", new CompressedXContent(update), MergeReason.INDEX_TEMPLATE);
-
- objectMapper = mapper.mappers().objectMappers().get("object");
- assertNotNull(objectMapper);
- assertTrue(objectMapper.isEnabled());
- assertEquals(ObjectMapper.Subobjects.AUTO, objectMapper.subobjects());
- assertEquals(Mapper.SourceKeepMode.ARRAYS, objectMapper.sourceKeepMode().orElse(Mapper.SourceKeepMode.NONE));
+ if (ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled()) {
+ // Setting 'enabled' to true is allowed, and updates the mapping.
+ update = Strings.toString(
+ XContentFactory.jsonBuilder()
+ .startObject()
+ .startObject("properties")
+ .startObject("object")
+ .field("type", "object")
+ .field("enabled", true)
+ .field("subobjects", "auto")
+ .field(ObjectMapper.STORE_ARRAY_SOURCE_PARAM, true)
+ .endObject()
+ .endObject()
+ .endObject()
+ );
+ mapper = mapperService.merge("type", new CompressedXContent(update), MergeReason.INDEX_TEMPLATE);
+
+ objectMapper = mapper.mappers().objectMappers().get("object");
+ assertNotNull(objectMapper);
+ assertTrue(objectMapper.isEnabled());
+ assertEquals(ObjectMapper.Subobjects.AUTO, objectMapper.subobjects());
+ assertEquals(Mapper.SourceKeepMode.ARRAYS, objectMapper.sourceKeepMode().orElse(Mapper.SourceKeepMode.NONE));
+ }
}
public void testFieldReplacementForIndexTemplates() throws IOException {
@@ -503,6 +505,7 @@ public void testSubobjectsCannotBeUpdatedOnRoot() throws IOException {
}
public void testSubobjectsAuto() throws Exception {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
@@ -532,6 +535,7 @@ public void testSubobjectsAuto() throws Exception {
}
public void testSubobjectsAutoWithInnerObject() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
@@ -565,6 +569,7 @@ public void testSubobjectsAutoWithInnerObject() throws IOException {
}
public void testSubobjectsAutoWithInnerNested() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mapping(b -> {
b.startObject("metrics.service");
{
@@ -586,6 +591,7 @@ public void testSubobjectsAutoWithInnerNested() throws IOException {
}
public void testSubobjectsAutoRoot() throws Exception {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service.time");
b.field("type", "long");
@@ -606,6 +612,7 @@ public void testSubobjectsAutoRoot() throws Exception {
}
public void testSubobjectsAutoRootWithInnerObject() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service.time");
{
@@ -626,6 +633,7 @@ public void testSubobjectsAutoRootWithInnerObject() throws IOException {
}
public void testSubobjectsAutoRootWithInnerNested() throws IOException {
+ assumeTrue("only test when feature flag for subobjects auto is enabled", ObjectMapper.SUB_OBJECTS_AUTO_FEATURE_FLAG.isEnabled());
MapperService mapperService = createMapperService(mappingWithSubobjects(b -> {
b.startObject("metrics.service");
b.field("type", "nested");
diff --git a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java
index aa72d3248812e..ca2300611b4fd 100644
--- a/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java
+++ b/test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java
@@ -18,6 +18,7 @@
public enum FeatureFlag {
TIME_SERIES_MODE("es.index_mode_feature_flag_registered=true", Version.fromString("8.0.0"), null),
FAILURE_STORE_ENABLED("es.failure_store_feature_flag_enabled=true", Version.fromString("8.12.0"), null),
+ SUB_OBJECTS_AUTO_ENABLED("es.sub_objects_auto_feature_flag_enabled=true", Version.fromString("8.16.0"), null),
CHUNKING_SETTINGS_ENABLED("es.inference_chunking_settings_feature_flag_enabled=true", Version.fromString("8.16.0"), null),
INFERENCE_DEFAULT_ELSER("es.inference_default_elser_feature_flag_enabled=true", Version.fromString("8.16.0"), null);
diff --git a/x-pack/plugin/src/yamlRestTest/java/org/elasticsearch/xpack/test/rest/XPackRestIT.java b/x-pack/plugin/src/yamlRestTest/java/org/elasticsearch/xpack/test/rest/XPackRestIT.java
index 556a417fb5e79..988ee93bda6b4 100644
--- a/x-pack/plugin/src/yamlRestTest/java/org/elasticsearch/xpack/test/rest/XPackRestIT.java
+++ b/x-pack/plugin/src/yamlRestTest/java/org/elasticsearch/xpack/test/rest/XPackRestIT.java
@@ -43,6 +43,7 @@ public class XPackRestIT extends AbstractXPackRestTest {
.setting("xpack.searchable.snapshot.shared_cache.region_size", "256KB")
.user("x_pack_rest_user", "x-pack-test-password")
.feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.configFile("testnode.pem", Resource.fromClasspath("org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.pem"))
.configFile("testnode.crt", Resource.fromClasspath("org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt"))
.configFile("service_tokens", Resource.fromClasspath("service_tokens"))
diff --git a/x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java b/x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java
index fe62d4e2d2639..0b40828b8e86c 100644
--- a/x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java
+++ b/x-pack/qa/core-rest-tests-with-security/src/yamlRestTest/java/org/elasticsearch/xpack/security/CoreWithSecurityClientYamlTestSuiteIT.java
@@ -48,6 +48,7 @@ public class CoreWithSecurityClientYamlTestSuiteIT extends ESClientYamlSuiteTest
.setting("xpack.security.autoconfiguration.enabled", "false")
.user(USER, PASS)
.feature(FeatureFlag.TIME_SERIES_MODE)
+ .feature(FeatureFlag.SUB_OBJECTS_AUTO_ENABLED)
.build();
public CoreWithSecurityClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
diff --git a/x-pack/qa/runtime-fields/build.gradle b/x-pack/qa/runtime-fields/build.gradle
index 43d6d9463e0d1..986baf867b501 100644
--- a/x-pack/qa/runtime-fields/build.gradle
+++ b/x-pack/qa/runtime-fields/build.gradle
@@ -44,6 +44,7 @@ subprojects {
setting 'xpack.security.enabled', 'false'
requiresFeature 'es.index_mode_feature_flag_registered', Version.fromString("8.0.0")
+ requiresFeature 'es.sub_objects_auto_feature_flag_enabled', Version.fromString("8.16.0")
}
tasks.named("yamlRestTest").configure {
From bc0d1d7f3c12f8b3d26cb264ad1d7d6266b43815 Mon Sep 17 00:00:00 2001
From: Nick Tindall
Date: Mon, 14 Oct 2024 09:45:46 +1100
Subject: [PATCH 03/77] Avoid throw exception in
SyntheticSourceIndexSettingsProvider (#114479)
Co-authored-by: Nhat Nguyen
---
docs/reference/index-modules.asciidoc | 2 +-
muted-tests.yml | 6 ------
.../template/SimpleIndexTemplateIT.java | 4 ++--
.../cluster/metadata/IndexMetadata.java | 2 +-
.../SyntheticSourceIndexSettingsProvider.java | 18 ++++++++++--------
5 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/docs/reference/index-modules.asciidoc b/docs/reference/index-modules.asciidoc
index ed8cf6c1494e4..1c8f1db216b75 100644
--- a/docs/reference/index-modules.asciidoc
+++ b/docs/reference/index-modules.asciidoc
@@ -122,7 +122,7 @@ preview:[]
The number of shards a custom <> value can go to.
Defaults to 1 and can only be set at index creation time. This value must be less
- than the `index.number_of_shards` unless the `index.number_of_shards` value is also 1.
+ than the `index.number_of_routing_shards` unless the `index.number_of_routing_shards` value is also 1.
See <> for more details about how this setting is used.
[[ccr-index-soft-deletes]]
diff --git a/muted-tests.yml b/muted-tests.yml
index 31f99b0ae632a..d0fc50de31bd1 100644
--- a/muted-tests.yml
+++ b/muted-tests.yml
@@ -283,12 +283,6 @@ tests:
- class: org.elasticsearch.ingest.geoip.DatabaseNodeServiceIT
method: testGzippedDatabase
issue: https://github.com/elastic/elasticsearch/issues/113752
-- class: org.elasticsearch.backwards.MixedClusterClientYamlTestSuiteIT
- method: test {p0=indices.split/40_routing_partition_size/more than 1}
- issue: https://github.com/elastic/elasticsearch/issues/113841
-- class: org.elasticsearch.backwards.MixedClusterClientYamlTestSuiteIT
- method: test {p0=indices.split/40_routing_partition_size/nested}
- issue: https://github.com/elastic/elasticsearch/issues/113842
- class: org.elasticsearch.threadpool.SimpleThreadPoolIT
method: testThreadPoolMetrics
issue: https://github.com/elastic/elasticsearch/issues/108320
diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java
index 3ca3f20917009..0647a24aa39c8 100644
--- a/server/src/internalClusterTest/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java
+++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/template/SimpleIndexTemplateIT.java
@@ -881,7 +881,7 @@ public void testPartitionedTemplate() throws Exception {
);
assertThat(
eBadSettings.getMessage(),
- containsString("partition size [6] should be a positive number less than the number of shards [5]")
+ containsString("partition size [6] should be a positive number less than the number of routing shards [5]")
);
// provide an invalid mapping for a partitioned index
@@ -913,7 +913,7 @@ public void testPartitionedTemplate() throws Exception {
assertThat(
eBadIndex.getMessage(),
- containsString("partition size [6] should be a positive number less than the number of shards [5]")
+ containsString("partition size [6] should be a positive number less than the number of routing shards [5]")
);
// finally, create a valid index
diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java
index 9760d84c67c5b..23e8e49aa16db 100644
--- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java
+++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java
@@ -2265,7 +2265,7 @@ IndexMetadata build(boolean repair) {
"routing partition size ["
+ routingPartitionSize
+ "] should be a positive number"
- + " less than the number of shards ["
+ + " less than the number of routing shards ["
+ getRoutingNumShards()
+ "] for ["
+ index
diff --git a/x-pack/plugin/logsdb/src/main/java/org/elasticsearch/xpack/logsdb/SyntheticSourceIndexSettingsProvider.java b/x-pack/plugin/logsdb/src/main/java/org/elasticsearch/xpack/logsdb/SyntheticSourceIndexSettingsProvider.java
index 759fa6af98868..6e139cc3ce9e6 100644
--- a/x-pack/plugin/logsdb/src/main/java/org/elasticsearch/xpack/logsdb/SyntheticSourceIndexSettingsProvider.java
+++ b/x-pack/plugin/logsdb/src/main/java/org/elasticsearch/xpack/logsdb/SyntheticSourceIndexSettingsProvider.java
@@ -79,15 +79,17 @@ boolean newIndexHasSyntheticSourceUsage(
return false;
}
- var tmpIndexMetadata = buildIndexMetadataForMapperService(indexName, isTimeSeries, indexTemplateAndCreateRequestSettings);
- try (var mapperService = mapperServiceFactory.apply(tmpIndexMetadata)) {
- // combinedTemplateMappings can be null when creating system indices
- // combinedTemplateMappings can be empty when creating a normal index that doesn't match any template and without mapping.
- if (combinedTemplateMappings == null || combinedTemplateMappings.isEmpty()) {
- combinedTemplateMappings = List.of(new CompressedXContent("{}"));
+ try {
+ var tmpIndexMetadata = buildIndexMetadataForMapperService(indexName, isTimeSeries, indexTemplateAndCreateRequestSettings);
+ try (var mapperService = mapperServiceFactory.apply(tmpIndexMetadata)) {
+ // combinedTemplateMappings can be null when creating system indices
+ // combinedTemplateMappings can be empty when creating a normal index that doesn't match any template and without mapping.
+ if (combinedTemplateMappings == null || combinedTemplateMappings.isEmpty()) {
+ combinedTemplateMappings = List.of(new CompressedXContent("{}"));
+ }
+ mapperService.merge(MapperService.SINGLE_MAPPING_NAME, combinedTemplateMappings, MapperService.MergeReason.INDEX_TEMPLATE);
+ return mapperService.documentMapper().sourceMapper().isSynthetic();
}
- mapperService.merge(MapperService.SINGLE_MAPPING_NAME, combinedTemplateMappings, MapperService.MergeReason.INDEX_TEMPLATE);
- return mapperService.documentMapper().sourceMapper().isSynthetic();
} catch (AssertionError | Exception e) {
// In case invalid mappings or setting are provided, then mapper service creation can fail.
// In that case it is ok to return false here. The index creation will fail anyway later, so need to fallback to stored source.
From 5f3595bba9bc8485be58fbc0f39e440cffd87bf5 Mon Sep 17 00:00:00 2001
From: Yang Wang
Date: Mon, 14 Oct 2024 15:18:25 +1100
Subject: [PATCH 04/77] Add a callback for onConnectionClosed to
MockTransportService (#114564)
The callback is added to allow inserting additional behaviour such as
delay when handling closed connection.
---
.../test/transport/MockTransportService.java | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java b/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java
index 57a6d1e09c52d..c4e1c6c7a0681 100644
--- a/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java
+++ b/test/framework/src/main/java/org/elasticsearch/test/transport/MockTransportService.java
@@ -80,6 +80,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -104,6 +106,7 @@ public class MockTransportService extends TransportService {
private final Map> openConnections = new HashMap<>();
private final List onStopListeners = new CopyOnWriteArrayList<>();
+ private final AtomicReference> onConnectionClosedCallback = new AtomicReference<>();
public static class TestPlugin extends Plugin {
@Override
@@ -788,6 +791,19 @@ public void openConnection(DiscoveryNode node, ConnectionProfile connectionProfi
}));
}
+ public void setOnConnectionClosedCallback(Consumer callback) {
+ onConnectionClosedCallback.set(callback);
+ }
+
+ @Override
+ public void onConnectionClosed(Transport.Connection connection) {
+ final Consumer callback = onConnectionClosedCallback.get();
+ if (callback != null) {
+ callback.accept(connection);
+ }
+ super.onConnectionClosed(connection);
+ }
+
public void addOnStopListener(Runnable listener) {
onStopListeners.add(listener);
}
From a262eb6dbd6e5e73a911c07b1bcfdb302858c03f Mon Sep 17 00:00:00 2001
From: Carlos Delgado <6339205+carlosdelest@users.noreply.github.com>
Date: Mon, 14 Oct 2024 07:31:55 +0200
Subject: [PATCH 05/77] Add ESQL match function (#113374)
---
docs/changelog/113374.yaml | 5 +
.../esql/functions/description/match.asciidoc | 5 +
.../esql/functions/examples/match.asciidoc | 13 +
.../functions/kibana/definition/match.json | 85 +
.../esql/functions/kibana/docs/match.md | 14 +
.../esql/functions/layout/match.asciidoc | 17 +
.../esql/functions/parameters/match.asciidoc | 9 +
.../esql/functions/signature/match.svg | 1 +
.../esql/functions/types/match.asciidoc | 12 +
.../esql/core/expression/TypeResolutions.java | 7 +-
.../main/resources/match-function.csv-spec | 199 ++
.../src/main/resources/qstr-function.csv-spec | 73 +-
...ringFunctionIT.java => QueryStringIT.java} | 2 +-
.../esql/src/main/antlr/EsqlBaseLexer.g4 | 4 +-
.../esql/src/main/antlr/EsqlBaseLexer.tokens | 162 +-
.../esql/src/main/antlr/EsqlBaseParser.g4 | 8 +-
.../esql/src/main/antlr/EsqlBaseParser.tokens | 162 +-
.../xpack/esql/action/EsqlCapabilities.java | 5 +
.../xpack/esql/analysis/Verifier.java | 119 +-
.../function/EsqlFunctionRegistry.java | 6 +-
.../function/fulltext/FullTextFunction.java | 77 +-
.../expression/function/fulltext/Match.java | 116 +
...ryStringFunction.java => QueryString.java} | 48 +-
.../physical/local/PushFiltersToSource.java | 7 +-
.../xpack/esql/parser/EsqlBaseLexer.interp | 9 +-
.../xpack/esql/parser/EsqlBaseLexer.java | 2033 ++++++++---------
.../xpack/esql/parser/EsqlBaseParser.interp | 7 +-
.../xpack/esql/parser/EsqlBaseParser.java | 1858 ++++++++-------
.../parser/EsqlBaseParserBaseListener.java | 12 +
.../parser/EsqlBaseParserBaseVisitor.java | 7 +
.../esql/parser/EsqlBaseParserListener.java | 10 +
.../esql/parser/EsqlBaseParserVisitor.java | 6 +
.../xpack/esql/parser/EsqlParser.java | 6 +-
.../xpack/esql/parser/ExpressionBuilder.java | 25 +-
.../planner/EsqlExpressionTranslators.java | 30 +-
.../elasticsearch/xpack/esql/CsvTests.java | 4 +
.../xpack/esql/analysis/VerifierTests.java | 167 +-
.../function/fulltext/MatchTests.java | 107 +
...nctionTests.java => QueryStringTests.java} | 6 +-
.../LocalPhysicalPlanOptimizerTests.java | 228 +-
.../optimizer/LogicalPlanOptimizerTests.java | 37 +
41 files changed, 3435 insertions(+), 2273 deletions(-)
create mode 100644 docs/changelog/113374.yaml
create mode 100644 docs/reference/esql/functions/description/match.asciidoc
create mode 100644 docs/reference/esql/functions/examples/match.asciidoc
create mode 100644 docs/reference/esql/functions/kibana/definition/match.json
create mode 100644 docs/reference/esql/functions/kibana/docs/match.md
create mode 100644 docs/reference/esql/functions/layout/match.asciidoc
create mode 100644 docs/reference/esql/functions/parameters/match.asciidoc
create mode 100644 docs/reference/esql/functions/signature/match.svg
create mode 100644 docs/reference/esql/functions/types/match.asciidoc
create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec
rename x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/{QueryStringFunctionIT.java => QueryStringIT.java} (98%)
create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java
rename x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/{QueryStringFunction.java => QueryString.java} (66%)
create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchTests.java
rename x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/{QueryStringFunctionTests.java => QueryStringTests.java} (92%)
diff --git a/docs/changelog/113374.yaml b/docs/changelog/113374.yaml
new file mode 100644
index 0000000000000..f1d5750de0f60
--- /dev/null
+++ b/docs/changelog/113374.yaml
@@ -0,0 +1,5 @@
+pr: 113374
+summary: Add ESQL match function
+area: ES|QL
+type: feature
+issues: []
diff --git a/docs/reference/esql/functions/description/match.asciidoc b/docs/reference/esql/functions/description/match.asciidoc
new file mode 100644
index 0000000000000..2a27fe4814395
--- /dev/null
+++ b/docs/reference/esql/functions/description/match.asciidoc
@@ -0,0 +1,5 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Description*
+
+Performs a match query on the specified field. Returns true if the provided query matches the row.
diff --git a/docs/reference/esql/functions/examples/match.asciidoc b/docs/reference/esql/functions/examples/match.asciidoc
new file mode 100644
index 0000000000000..3f31d68ea9abb
--- /dev/null
+++ b/docs/reference/esql/functions/examples/match.asciidoc
@@ -0,0 +1,13 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Example*
+
+[source.merge.styled,esql]
+----
+include::{esql-specs}/match-function.csv-spec[tag=match-with-field]
+----
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+include::{esql-specs}/match-function.csv-spec[tag=match-with-field-result]
+|===
+
diff --git a/docs/reference/esql/functions/kibana/definition/match.json b/docs/reference/esql/functions/kibana/definition/match.json
new file mode 100644
index 0000000000000..d2fe0bba53866
--- /dev/null
+++ b/docs/reference/esql/functions/kibana/definition/match.json
@@ -0,0 +1,85 @@
+{
+ "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.",
+ "type" : "eval",
+ "name" : "match",
+ "description" : "Performs a match query on the specified field. Returns true if the provided query matches the row.",
+ "signatures" : [
+ {
+ "params" : [
+ {
+ "name" : "field",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "Field that the query will target."
+ },
+ {
+ "name" : "query",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "Text you wish to find in the provided field."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "boolean"
+ },
+ {
+ "params" : [
+ {
+ "name" : "field",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "Field that the query will target."
+ },
+ {
+ "name" : "query",
+ "type" : "text",
+ "optional" : false,
+ "description" : "Text you wish to find in the provided field."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "boolean"
+ },
+ {
+ "params" : [
+ {
+ "name" : "field",
+ "type" : "text",
+ "optional" : false,
+ "description" : "Field that the query will target."
+ },
+ {
+ "name" : "query",
+ "type" : "keyword",
+ "optional" : false,
+ "description" : "Text you wish to find in the provided field."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "boolean"
+ },
+ {
+ "params" : [
+ {
+ "name" : "field",
+ "type" : "text",
+ "optional" : false,
+ "description" : "Field that the query will target."
+ },
+ {
+ "name" : "query",
+ "type" : "text",
+ "optional" : false,
+ "description" : "Text you wish to find in the provided field."
+ }
+ ],
+ "variadic" : false,
+ "returnType" : "boolean"
+ }
+ ],
+ "examples" : [
+ "from books \n| where match(author, \"Faulkner\")\n| keep book_no, author \n| sort book_no \n| limit 5;"
+ ],
+ "preview" : true,
+ "snapshot_only" : true
+}
diff --git a/docs/reference/esql/functions/kibana/docs/match.md b/docs/reference/esql/functions/kibana/docs/match.md
new file mode 100644
index 0000000000000..3c06662982bbf
--- /dev/null
+++ b/docs/reference/esql/functions/kibana/docs/match.md
@@ -0,0 +1,14 @@
+
+
+### MATCH
+Performs a match query on the specified field. Returns true if the provided query matches the row.
+
+```
+from books
+| where match(author, "Faulkner")
+| keep book_no, author
+| sort book_no
+| limit 5;
+```
diff --git a/docs/reference/esql/functions/layout/match.asciidoc b/docs/reference/esql/functions/layout/match.asciidoc
new file mode 100644
index 0000000000000..e62c81548c2b1
--- /dev/null
+++ b/docs/reference/esql/functions/layout/match.asciidoc
@@ -0,0 +1,17 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+[discrete]
+[[esql-match]]
+=== `MATCH`
+
+preview::["Do not use on production environments. This functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features."]
+
+*Syntax*
+
+[.text-center]
+image::esql/functions/signature/match.svg[Embedded,opts=inline]
+
+include::../parameters/match.asciidoc[]
+include::../description/match.asciidoc[]
+include::../types/match.asciidoc[]
+include::../examples/match.asciidoc[]
diff --git a/docs/reference/esql/functions/parameters/match.asciidoc b/docs/reference/esql/functions/parameters/match.asciidoc
new file mode 100644
index 0000000000000..f18adb28cd20c
--- /dev/null
+++ b/docs/reference/esql/functions/parameters/match.asciidoc
@@ -0,0 +1,9 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Parameters*
+
+`field`::
+Field that the query will target.
+
+`query`::
+Text you wish to find in the provided field.
diff --git a/docs/reference/esql/functions/signature/match.svg b/docs/reference/esql/functions/signature/match.svg
new file mode 100644
index 0000000000000..e7bb001247a9d
--- /dev/null
+++ b/docs/reference/esql/functions/signature/match.svg
@@ -0,0 +1 @@
+MATCH ( field , query )
diff --git a/docs/reference/esql/functions/types/match.asciidoc b/docs/reference/esql/functions/types/match.asciidoc
new file mode 100644
index 0000000000000..7523b29c62b1d
--- /dev/null
+++ b/docs/reference/esql/functions/types/match.asciidoc
@@ -0,0 +1,12 @@
+// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.
+
+*Supported types*
+
+[%header.monospaced.styled,format=dsv,separator=|]
+|===
+field | query | result
+keyword | keyword | boolean
+keyword | text | boolean
+text | keyword | boolean
+text | text | boolean
+|===
diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java
index ab05a71b0e1c6..b817ec17c7bda 100644
--- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java
+++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/TypeResolutions.java
@@ -155,18 +155,19 @@ public static TypeResolution isNotNullAndFoldable(Expression e, String operation
return resolution;
}
- public static TypeResolution isNotFoldable(Expression e, String operationName, ParamOrdinal paramOrd) {
- if (e.foldable()) {
+ public static TypeResolution isNotNull(Expression e, String operationName, ParamOrdinal paramOrd) {
+ if (e.dataType() == DataType.NULL) {
return new TypeResolution(
format(
null,
- "{}argument of [{}] must be a table column, found constant [{}]",
+ "{}argument of [{}] cannot be null, received [{}]",
paramOrd == null || paramOrd == DEFAULT ? "" : paramOrd.name().toLowerCase(Locale.ROOT) + " ",
operationName,
Expressions.name(e)
)
);
}
+
return TypeResolution.TYPE_RESOLVED;
}
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec
new file mode 100644
index 0000000000000..b0578aa1a4ed0
--- /dev/null
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec
@@ -0,0 +1,199 @@
+###############################################
+# Tests for Match function
+#
+
+matchWithField
+required_capability: match_function
+
+// tag::match-with-field[]
+from books
+| where match(author, "Faulkner")
+| keep book_no, author
+| sort book_no
+| limit 5;
+// end::match-with-field[]
+
+// tag::match-with-field-result[]
+book_no:keyword | author:text
+2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
+2713 | William Faulkner
+2847 | Colleen Faulkner
+2883 | William Faulkner
+3293 | Danny Faulkner
+;
+// end::match-with-field-result[]
+
+matchWithMultipleFunctions
+required_capability: match_function
+
+from books
+| where match(title, "Return") AND match(author, "Tolkien")
+| keep book_no, title;
+ignoreOrder:true
+
+book_no:keyword | title:text
+2714 | Return of the King Being the Third Part of The Lord of the Rings
+7350 | Return of the Shadow
+;
+
+matchWithQueryExpressions
+required_capability: match_function
+
+from books
+| where match(title, CONCAT("Return ", " King"))
+| keep book_no, title;
+ignoreOrder:true
+
+book_no:keyword | title:text
+2714 | Return of the King Being the Third Part of The Lord of the Rings
+7350 | Return of the Shadow
+;
+
+matchAfterKeep
+required_capability: match_function
+
+from books
+| keep book_no, author
+| where match(author, "Faulkner")
+| sort book_no
+| limit 5;
+
+book_no:keyword | author:text
+2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
+2713 | William Faulkner
+2847 | Colleen Faulkner
+2883 | William Faulkner
+3293 | Danny Faulkner
+;
+
+matchAfterDrop
+required_capability: match_function
+
+from books
+| drop ratings, description, year, publisher, title, author.keyword
+| where match(author, "Faulkner")
+| keep book_no, author
+| sort book_no
+| limit 5;
+
+book_no:keyword | author:text
+2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
+2713 | William Faulkner
+2847 | Colleen Faulkner
+2883 | William Faulkner
+3293 | Danny Faulkner
+;
+
+matchAfterEval
+required_capability: match_function
+
+from books
+| eval stars = to_long(ratings / 2.0)
+| where match(author, "Faulkner")
+| sort book_no
+| keep book_no, author, stars
+| limit 5;
+
+book_no:keyword | author:text | stars:long
+2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 3
+2713 | William Faulkner | 2
+2847 | Colleen Faulkner | 3
+2883 | William Faulkner | 2
+3293 | Danny Faulkner | 2
+;
+
+matchWithConjunction
+required_capability: match_function
+
+from books
+| where match(title, "Rings") and ratings > 4.6
+| keep book_no, title;
+ignoreOrder:true
+
+book_no:keyword | title:text
+4023 |A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings
+7140 |The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1)
+;
+
+matchWithFunctionPushedToLucene
+required_capability: match_function
+
+from hosts
+| where match(host, "beta") and cidr_match(ip1, "127.0.0.2/32", "127.0.0.3/32")
+| keep card, host, ip0, ip1;
+ignoreOrder:true
+
+card:keyword |host:keyword |ip0:ip |ip1:ip
+eth1 |beta |127.0.0.1 |127.0.0.2
+;
+
+matchWithNonPushableConjunction
+required_capability: match_function
+
+from books
+| where match(title, "Rings") and length(title) > 75
+| keep book_no, title;
+ignoreOrder:true
+
+book_no:keyword | title:text
+4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings
+;
+
+matchWithMultipleWhereClauses
+required_capability: match_function
+
+from books
+| where match(title, "rings")
+| where match(title, "lord")
+| keep book_no, title;
+ignoreOrder:true
+
+book_no:keyword | title:text
+2675 | The Lord of the Rings - Boxed Set
+2714 | Return of the King Being the Third Part of The Lord of the Rings
+4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings
+7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1)
+;
+
+matchMultivaluedField
+required_capability: match_function
+
+from employees
+| where match(job_positions, "Tech Lead") and match(job_positions, "Reporting Analyst")
+| keep emp_no, first_name, last_name;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword
+10004 | Chirstian | Koblick
+10010 | Duangkaew | Piveteau
+10011 | Mary | Sluis
+10088 | Jungsoon | Syrzycki
+10093 | Sailaja | Desikan
+10097 | Remzi | Waschkowski
+;
+
+testMultiValuedFieldWithConjunction
+required_capability: match_function
+
+from employees
+| where match(job_positions, "Data Scientist") and match(job_positions, "Support Engineer")
+| keep emp_no, first_name, last_name;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword
+10043 | Yishay | Tzvieli
+;
+
+testMatchAndQueryStringFunctions
+required_capability: match_function
+required_capability: qstr_function
+
+from employees
+| where match(job_positions, "Data Scientist") and qstr("job_positions: (Support Engineer) and gender: F")
+| keep emp_no, first_name, last_name;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword
+10041 | Uri | Lenart
+10043 | Yishay | Tzvieli
+;
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/qstr-function.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/qstr-function.csv-spec
index 2f6313925032e..6dc03d0debcfa 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/qstr-function.csv-spec
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/qstr-function.csv-spec
@@ -49,20 +49,6 @@ book_no:keyword | title:text
7350 | Return of the Shadow
;
-qstrWithDisjunction
-required_capability: qstr_function
-
-from books
-| where qstr("title:Return") or year > 2020
-| keep book_no, title;
-ignoreOrder:true
-
-book_no:keyword | title:text
-2714 | Return of the King Being the Third Part of The Lord of the Rings
-6818 | Hadji Murad
-7350 | Return of the Shadow
-;
-
qstrWithConjunction
required_capability: qstr_function
@@ -88,17 +74,16 @@ card:keyword |host:keyword |ip0:ip |ip1:ip
eth1 |beta |127.0.0.1 |127.0.0.2
;
-qstrWithFunctionNotPushedToLucene
+qstrWithNonPushableConjunction
required_capability: qstr_function
from books
-| where qstr("title: rings") and length(description) > 600
+| where qstr("title: Rings") and length(title) > 75
| keep book_no, title;
ignoreOrder:true
book_no:keyword | title:text
-2675 | The Lord of the Rings - Boxed Set
-2714 | Return of the King Being the Third Part of The Lord of the Rings
+4023 |A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings
;
qstrWithMultipleWhereClauses
@@ -114,3 +99,55 @@ book_no:keyword | title:text
4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings
7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1)
;
+
+
+matchMultivaluedTextField
+required_capability: match_function
+
+from employees
+| where qstr("job_positions: (Tech Lead) AND job_positions:(Reporting Analyst)")
+| keep emp_no, first_name, last_name;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword
+10004 | Chirstian | Koblick
+10010 | Duangkaew | Piveteau
+10011 | Mary | Sluis
+10088 | Jungsoon | Syrzycki
+10093 | Sailaja | Desikan
+10097 | Remzi | Waschkowski
+;
+
+matchMultivaluedNumericField
+required_capability: match_function
+
+from employees
+| where qstr("salary_change: [14 TO *]")
+| keep emp_no, first_name, last_name, salary_change;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword | salary_change:double
+10003 | Parto | Bamford | [12.82, 14.68]
+10015 | Guoxiang | Nooteboom | [12.4, 14.25]
+10023 | Bojan | Montemayor | [0.8, 14.63]
+10040 | Weiyi | Meriste | [-8.94, 1.92, 6.97, 14.74]
+10061 | Tse | Herber | [-2.58, -0.95, 14.39]
+10065 | Satosi | Awdeh | [-9.81, -1.47, 14.44]
+10099 | Valter | Sullins | [-8.78, -3.98, 10.71, 14.26]
+;
+
+testMultiValuedFieldWithConjunction
+required_capability: match_function
+
+from employees
+| where (qstr("job_positions: (Data Scientist) OR job_positions:(Support Engineer)")) and gender == "F"
+| keep emp_no, first_name, last_name;
+ignoreOrder:true
+
+emp_no:integer | first_name:keyword | last_name:keyword
+10023 | Bojan | Montemayor
+10041 | Uri | Lenart
+10044 | Mingsen | Casley
+10053 | Sanjiv | Zschoche
+10069 | Margareta | Bierman
+;
diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringFunctionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringIT.java
similarity index 98%
rename from x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringFunctionIT.java
rename to x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringIT.java
index e6f11ca1f44d2..53b833c7e8a15 100644
--- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringFunctionIT.java
+++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/QueryStringIT.java
@@ -29,7 +29,7 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-public class QueryStringFunctionIT extends AbstractEsqlIntegTestCase {
+public class QueryStringIT extends AbstractEsqlIntegTestCase {
@Before
public void setupIndex() {
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
index 0d8d3abf77ecc..ce3947875e6c7 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.g4
@@ -86,7 +86,6 @@ WHERE : 'where' -> pushMode(EXPRESSION_MODE);
// MYCOMMAND : 'mycommand' -> ...
DEV_INLINESTATS : {this.isDevVersion()}? 'inlinestats' -> pushMode(EXPRESSION_MODE);
DEV_LOOKUP : {this.isDevVersion()}? 'lookup' -> pushMode(LOOKUP_MODE);
-DEV_MATCH : {this.isDevVersion()}? 'match' -> pushMode(EXPRESSION_MODE);
DEV_METRICS : {this.isDevVersion()}? 'metrics' -> pushMode(METRICS_MODE);
//
@@ -209,8 +208,7 @@ ASTERISK : '*';
SLASH : '/';
PERCENT : '%';
-// move it in the main section if the feature gets promoted
-DEV_MATCH_OP : {this.isDevVersion()}? DEV_MATCH -> type(DEV_MATCH);
+DEV_MATCH : {this.isDevVersion()}? 'match';
NAMED_OR_POSITIONAL_PARAM
: PARAM (LETTER | UNDERSCORE) UNQUOTED_ID_BODY*
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
index 4fd37ab9900f2..2fe262a6983f7 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseLexer.tokens
@@ -16,51 +16,51 @@ STATS=15
WHERE=16
DEV_INLINESTATS=17
DEV_LOOKUP=18
-DEV_MATCH=19
-DEV_METRICS=20
-UNKNOWN_CMD=21
-LINE_COMMENT=22
-MULTILINE_COMMENT=23
-WS=24
-PIPE=25
-QUOTED_STRING=26
-INTEGER_LITERAL=27
-DECIMAL_LITERAL=28
-BY=29
-AND=30
-ASC=31
-ASSIGN=32
-CAST_OP=33
-COMMA=34
-DESC=35
-DOT=36
-FALSE=37
-FIRST=38
-IN=39
-IS=40
-LAST=41
-LIKE=42
-LP=43
-NOT=44
-NULL=45
-NULLS=46
-OR=47
-PARAM=48
-RLIKE=49
-RP=50
-TRUE=51
-EQ=52
-CIEQ=53
-NEQ=54
-LT=55
-LTE=56
-GT=57
-GTE=58
-PLUS=59
-MINUS=60
-ASTERISK=61
-SLASH=62
-PERCENT=63
+DEV_METRICS=19
+UNKNOWN_CMD=20
+LINE_COMMENT=21
+MULTILINE_COMMENT=22
+WS=23
+PIPE=24
+QUOTED_STRING=25
+INTEGER_LITERAL=26
+DECIMAL_LITERAL=27
+BY=28
+AND=29
+ASC=30
+ASSIGN=31
+CAST_OP=32
+COMMA=33
+DESC=34
+DOT=35
+FALSE=36
+FIRST=37
+IN=38
+IS=39
+LAST=40
+LIKE=41
+LP=42
+NOT=43
+NULL=44
+NULLS=45
+OR=46
+PARAM=47
+RLIKE=48
+RP=49
+TRUE=50
+EQ=51
+CIEQ=52
+NEQ=53
+LT=54
+LTE=55
+GT=56
+GTE=57
+PLUS=58
+MINUS=59
+ASTERISK=60
+SLASH=61
+PERCENT=62
+DEV_MATCH=63
NAMED_OR_POSITIONAL_PARAM=64
OPENING_BRACKET=65
CLOSING_BRACKET=66
@@ -134,42 +134,42 @@ CLOSING_METRICS_WS=120
'sort'=14
'stats'=15
'where'=16
-'|'=25
-'by'=29
-'and'=30
-'asc'=31
-'='=32
-'::'=33
-','=34
-'desc'=35
-'.'=36
-'false'=37
-'first'=38
-'in'=39
-'is'=40
-'last'=41
-'like'=42
-'('=43
-'not'=44
-'null'=45
-'nulls'=46
-'or'=47
-'?'=48
-'rlike'=49
-')'=50
-'true'=51
-'=='=52
-'=~'=53
-'!='=54
-'<'=55
-'<='=56
-'>'=57
-'>='=58
-'+'=59
-'-'=60
-'*'=61
-'/'=62
-'%'=63
+'|'=24
+'by'=28
+'and'=29
+'asc'=30
+'='=31
+'::'=32
+','=33
+'desc'=34
+'.'=35
+'false'=36
+'first'=37
+'in'=38
+'is'=39
+'last'=40
+'like'=41
+'('=42
+'not'=43
+'null'=44
+'nulls'=45
+'or'=46
+'?'=47
+'rlike'=48
+')'=49
+'true'=50
+'=='=51
+'=~'=52
+'!='=53
+'<'=54
+'<='=55
+'>'=56
+'>='=57
+'+'=58
+'-'=59
+'*'=60
+'/'=61
+'%'=62
']'=66
'metadata'=75
'as'=84
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4 b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
index b720ba98babf0..c053824861a96 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.g4
@@ -101,7 +101,13 @@ primaryExpression
;
functionExpression
- : identifierOrParameter LP (ASTERISK | (booleanExpression (COMMA booleanExpression)*))? RP
+ : functionName LP (ASTERISK | (booleanExpression (COMMA booleanExpression)*))? RP
+ ;
+
+functionName
+ // Additional function identifiers that are already a reserved word in the language
+ : {this.isDevVersion()}? DEV_MATCH
+ | identifierOrParameter
;
dataType
diff --git a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
index 4fd37ab9900f2..2fe262a6983f7 100644
--- a/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
+++ b/x-pack/plugin/esql/src/main/antlr/EsqlBaseParser.tokens
@@ -16,51 +16,51 @@ STATS=15
WHERE=16
DEV_INLINESTATS=17
DEV_LOOKUP=18
-DEV_MATCH=19
-DEV_METRICS=20
-UNKNOWN_CMD=21
-LINE_COMMENT=22
-MULTILINE_COMMENT=23
-WS=24
-PIPE=25
-QUOTED_STRING=26
-INTEGER_LITERAL=27
-DECIMAL_LITERAL=28
-BY=29
-AND=30
-ASC=31
-ASSIGN=32
-CAST_OP=33
-COMMA=34
-DESC=35
-DOT=36
-FALSE=37
-FIRST=38
-IN=39
-IS=40
-LAST=41
-LIKE=42
-LP=43
-NOT=44
-NULL=45
-NULLS=46
-OR=47
-PARAM=48
-RLIKE=49
-RP=50
-TRUE=51
-EQ=52
-CIEQ=53
-NEQ=54
-LT=55
-LTE=56
-GT=57
-GTE=58
-PLUS=59
-MINUS=60
-ASTERISK=61
-SLASH=62
-PERCENT=63
+DEV_METRICS=19
+UNKNOWN_CMD=20
+LINE_COMMENT=21
+MULTILINE_COMMENT=22
+WS=23
+PIPE=24
+QUOTED_STRING=25
+INTEGER_LITERAL=26
+DECIMAL_LITERAL=27
+BY=28
+AND=29
+ASC=30
+ASSIGN=31
+CAST_OP=32
+COMMA=33
+DESC=34
+DOT=35
+FALSE=36
+FIRST=37
+IN=38
+IS=39
+LAST=40
+LIKE=41
+LP=42
+NOT=43
+NULL=44
+NULLS=45
+OR=46
+PARAM=47
+RLIKE=48
+RP=49
+TRUE=50
+EQ=51
+CIEQ=52
+NEQ=53
+LT=54
+LTE=55
+GT=56
+GTE=57
+PLUS=58
+MINUS=59
+ASTERISK=60
+SLASH=61
+PERCENT=62
+DEV_MATCH=63
NAMED_OR_POSITIONAL_PARAM=64
OPENING_BRACKET=65
CLOSING_BRACKET=66
@@ -134,42 +134,42 @@ CLOSING_METRICS_WS=120
'sort'=14
'stats'=15
'where'=16
-'|'=25
-'by'=29
-'and'=30
-'asc'=31
-'='=32
-'::'=33
-','=34
-'desc'=35
-'.'=36
-'false'=37
-'first'=38
-'in'=39
-'is'=40
-'last'=41
-'like'=42
-'('=43
-'not'=44
-'null'=45
-'nulls'=46
-'or'=47
-'?'=48
-'rlike'=49
-')'=50
-'true'=51
-'=='=52
-'=~'=53
-'!='=54
-'<'=55
-'<='=56
-'>'=57
-'>='=58
-'+'=59
-'-'=60
-'*'=61
-'/'=62
-'%'=63
+'|'=24
+'by'=28
+'and'=29
+'asc'=30
+'='=31
+'::'=32
+','=33
+'desc'=34
+'.'=35
+'false'=36
+'first'=37
+'in'=38
+'is'=39
+'last'=40
+'like'=41
+'('=42
+'not'=43
+'null'=44
+'nulls'=45
+'or'=46
+'?'=47
+'rlike'=48
+')'=49
+'true'=50
+'=='=51
+'=~'=52
+'!='=53
+'<'=54
+'<='=55
+'>'=56
+'>='=57
+'+'=58
+'-'=59
+'*'=60
+'/'=61
+'%'=62
']'=66
'metadata'=75
'as'=84
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
index 18ee6b9417e5c..2e979dcce1758 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
@@ -346,6 +346,11 @@ public enum Cap {
*/
QSTR_FUNCTION(true),
+ /**
+ * MATCH function
+ */
+ MATCH_FUNCTION(true),
+
/**
* Don't optimize CASE IS NOT NULL function by not requiring the fields to be not null as well.
* https://github.com/elastic/elasticsearch/issues/112704
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
index 647a29b71c5e1..e45db0c02be7e 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
@@ -19,8 +19,12 @@
import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
import org.elasticsearch.xpack.esql.core.expression.NamedExpression;
import org.elasticsearch.xpack.esql.core.expression.TypeResolutions;
+import org.elasticsearch.xpack.esql.core.expression.function.Function;
import org.elasticsearch.xpack.esql.core.expression.predicate.BinaryOperator;
import org.elasticsearch.xpack.esql.core.expression.predicate.fulltext.MatchQueryPredicate;
+import org.elasticsearch.xpack.esql.core.expression.predicate.logical.BinaryLogic;
+import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Not;
+import org.elasticsearch.xpack.esql.core.expression.predicate.logical.Or;
import org.elasticsearch.xpack.esql.core.expression.predicate.operator.comparison.BinaryComparison;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.util.Holder;
@@ -28,6 +32,8 @@
import org.elasticsearch.xpack.esql.expression.function.aggregate.AggregateFunction;
import org.elasticsearch.xpack.esql.expression.function.aggregate.Rate;
import org.elasticsearch.xpack.esql.expression.function.fulltext.FullTextFunction;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.Match;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString;
import org.elasticsearch.xpack.esql.expression.function.grouping.GroupingFunction;
import org.elasticsearch.xpack.esql.expression.predicate.operator.arithmetic.Neg;
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.Equals;
@@ -55,6 +61,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Set;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Stream;
@@ -644,27 +651,105 @@ private static void checkFilterMatchConditions(LogicalPlan plan, Set fa
private static void checkFullTextQueryFunctions(LogicalPlan plan, Set failures) {
if (plan instanceof Filter f) {
Expression condition = f.condition();
- if (condition instanceof FullTextFunction ftf) {
- // Similar to cases present in org.elasticsearch.xpack.esql.optimizer.rules.PushDownAndCombineFilters -
- // we can't check if it can be pushed down as we don't have yet information about the fields present in the
- // StringQueryPredicate
- plan.forEachDown(LogicalPlan.class, lp -> {
- if ((lp instanceof Filter || lp instanceof OrderBy || lp instanceof EsRelation) == false) {
- failures.add(
- fail(
- plan,
- "[{}] function cannot be used after {}",
- ftf.functionName(),
- lp.sourceText().split(" ")[0].toUpperCase(Locale.ROOT)
- )
- );
- }
- });
- }
+ checkCommandsBeforeQueryStringFunction(plan, condition, failures);
+ checkCommandsBeforeMatchFunction(plan, condition, failures);
+ checkFullTextFunctionsConditions(condition, failures);
+ checkFullTextFunctionsParents(condition, failures);
} else {
plan.forEachExpression(FullTextFunction.class, ftf -> {
failures.add(fail(ftf, "[{}] function is only supported in WHERE commands", ftf.functionName()));
});
}
}
+
+ private static void checkCommandsBeforeQueryStringFunction(LogicalPlan plan, Expression condition, Set failures) {
+ condition.forEachDown(QueryString.class, qsf -> {
+ plan.forEachDown(LogicalPlan.class, lp -> {
+ if ((lp instanceof Filter || lp instanceof OrderBy || lp instanceof EsRelation) == false) {
+ failures.add(
+ fail(
+ plan,
+ "[{}] function cannot be used after {}",
+ qsf.functionName(),
+ lp.sourceText().split(" ")[0].toUpperCase(Locale.ROOT)
+ )
+ );
+ }
+ });
+ });
+ }
+
+ private static void checkCommandsBeforeMatchFunction(LogicalPlan plan, Expression condition, Set failures) {
+ condition.forEachDown(Match.class, qsf -> {
+ plan.forEachDown(LogicalPlan.class, lp -> {
+ if (lp instanceof Limit) {
+ failures.add(
+ fail(
+ plan,
+ "[{}] function cannot be used after {}",
+ qsf.functionName(),
+ lp.sourceText().split(" ")[0].toUpperCase(Locale.ROOT)
+ )
+ );
+ }
+ });
+ });
+ }
+
+ private static void checkFullTextFunctionsConditions(Expression condition, Set failures) {
+ condition.forEachUp(Or.class, or -> {
+ checkFullTextFunctionInDisjunction(failures, or, or.left());
+ checkFullTextFunctionInDisjunction(failures, or, or.right());
+ });
+ }
+
+ private static void checkFullTextFunctionInDisjunction(Set failures, Or or, Expression left) {
+ left.forEachDown(FullTextFunction.class, ftf -> {
+ failures.add(
+ fail(
+ or,
+ "Invalid condition [{}]. Function {} can't be used as part of an or condition",
+ or.sourceText(),
+ ftf.functionName()
+ )
+ );
+ });
+ }
+
+ private static void checkFullTextFunctionsParents(Expression condition, Set failures) {
+ forEachFullTextFunctionParent(condition, (ftf, parent) -> {
+ if ((parent instanceof FullTextFunction == false)
+ && (parent instanceof BinaryLogic == false)
+ && (parent instanceof Not == false)) {
+ failures.add(
+ fail(
+ condition,
+ "Invalid condition [{}]. Function {} can't be used with {}",
+ condition.sourceText(),
+ ftf.functionName(),
+ ((Function) parent).functionName()
+ )
+ );
+ }
+ });
+ }
+
+ /**
+ * Executes the action on every parent of a FullTextFunction in the condition if it is found
+ *
+ * @param action the action to execute for each parent of a FullTextFunction
+ */
+ private static FullTextFunction forEachFullTextFunctionParent(Expression condition, BiConsumer action) {
+ if (condition instanceof FullTextFunction ftf) {
+ return ftf;
+ }
+ for (Expression child : condition.children()) {
+ FullTextFunction foundMatchingChild = forEachFullTextFunctionParent(child, action);
+ if (foundMatchingChild != null) {
+ action.accept(foundMatchingChild, condition);
+ return foundMatchingChild;
+ }
+ }
+ return null;
+ }
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
index 3b1225555b297..e8921c68b8913 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java
@@ -32,7 +32,8 @@
import org.elasticsearch.xpack.esql.expression.function.aggregate.Top;
import org.elasticsearch.xpack.esql.expression.function.aggregate.Values;
import org.elasticsearch.xpack.esql.expression.function.aggregate.WeightedAvg;
-import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryStringFunction;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.Match;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString;
import org.elasticsearch.xpack.esql.expression.function.grouping.Bucket;
import org.elasticsearch.xpack.esql.expression.function.grouping.Categorize;
import org.elasticsearch.xpack.esql.expression.function.scalar.conditional.Case;
@@ -395,7 +396,8 @@ private static FunctionDefinition[][] snapshotFunctions() {
def(Categorize.class, Categorize::new, "categorize"),
def(Rate.class, Rate::withUnresolvedTimestamp, "rate"),
// Full text functions
- def(QueryStringFunction.class, QueryStringFunction::new, "qstr") } };
+ def(QueryString.class, QueryString::new, "qstr"),
+ def(Match.class, Match::new, "match") } };
}
public EsqlFunctionRegistry snapshotRegistry() {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextFunction.java
index 54730eec4f317..a39c0d7bc6b50 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextFunction.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/FullTextFunction.java
@@ -7,22 +7,20 @@
package org.elasticsearch.xpack.esql.expression.function.fulltext;
+import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
-import org.elasticsearch.common.io.stream.StreamInput;
-import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
import org.elasticsearch.xpack.esql.core.expression.Expression;
+import org.elasticsearch.xpack.esql.core.expression.Nullability;
+import org.elasticsearch.xpack.esql.core.expression.TypeResolutions;
import org.elasticsearch.xpack.esql.core.expression.function.Function;
-import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
-import org.elasticsearch.xpack.esql.core.util.PlanStreamInput;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import static java.util.Collections.singletonList;
+import static org.elasticsearch.common.logging.LoggerMessageFormat.format;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNotNullAndFoldable;
import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString;
@@ -36,45 +34,84 @@ public abstract class FullTextFunction extends Function {
public static List getNamedWriteables() {
List entries = new ArrayList<>();
if (EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled()) {
- entries.add(QueryStringFunction.ENTRY);
+ entries.add(QueryString.ENTRY);
+ }
+ if (EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled()) {
+ entries.add(Match.ENTRY);
}
return entries;
}
private final Expression query;
- protected FullTextFunction(Source source, Expression query) {
- super(source, singletonList(query));
+ protected FullTextFunction(Source source, Expression query, List children) {
+ super(source, children);
this.query = query;
}
- protected FullTextFunction(StreamInput in) throws IOException {
- this(Source.readFrom((StreamInput & PlanStreamInput) in), in.readNamedWriteable(Expression.class));
- }
-
@Override
public DataType dataType() {
return DataType.BOOLEAN;
}
@Override
- protected TypeResolution resolveType() {
+ protected final TypeResolution resolveType() {
if (childrenResolved() == false) {
return new TypeResolution("Unresolved children");
}
- return isString(query(), sourceText(), DEFAULT).and(isNotNullAndFoldable(query(), functionName(), DEFAULT));
+ return resolveNonQueryParamTypes().and(resolveQueryParamType());
+ }
+
+ /**
+ * Resolves the type for the query parameter, as part of the type resolution for the function
+ *
+ * @return type resolution for query parameter
+ */
+ private TypeResolution resolveQueryParamType() {
+ return isString(query(), sourceText(), queryParamOrdinal()).and(isNotNullAndFoldable(query(), sourceText(), queryParamOrdinal()));
+ }
+
+ /**
+ * Subclasses can override this method for custom type resolution for additional function parameters
+ *
+ * @return type resolution for non-query parameter types
+ */
+ protected TypeResolution resolveNonQueryParamTypes() {
+ return TypeResolution.TYPE_RESOLVED;
}
public Expression query() {
return query;
}
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- source().writeTo(out);
- out.writeNamedWriteable(query);
+ /**
+ * Returns the resulting query as a String
+ *
+ * @return query expression as a string
+ */
+ public final String queryAsText() {
+ Object queryAsObject = query().fold();
+ if (queryAsObject instanceof BytesRef bytesRef) {
+ return bytesRef.utf8ToString();
+ }
+
+ throw new IllegalArgumentException(
+ format(null, "{} argument in {} function needs to be resolved to a string", queryParamOrdinal(), functionName())
+ );
}
- public abstract Query asQuery();
+ /**
+ * Returns the param ordinal for the query parameter so it can be used in error messages
+ *
+ * @return Query ordinal for the
+ */
+ protected TypeResolutions.ParamOrdinal queryParamOrdinal() {
+ return DEFAULT;
+ }
+
+ @Override
+ public Nullability nullable() {
+ return Nullability.FALSE;
+ }
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java
new file mode 100644
index 0000000000000..b4e0f3c743216
--- /dev/null
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.expression.function.fulltext;
+
+import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.xpack.esql.capabilities.Validatable;
+import org.elasticsearch.xpack.esql.common.Failure;
+import org.elasticsearch.xpack.esql.common.Failures;
+import org.elasticsearch.xpack.esql.core.expression.Expression;
+import org.elasticsearch.xpack.esql.core.expression.FieldAttribute;
+import org.elasticsearch.xpack.esql.core.expression.TypeResolutions;
+import org.elasticsearch.xpack.esql.core.querydsl.query.QueryStringQuery;
+import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+import org.elasticsearch.xpack.esql.expression.function.Example;
+import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
+import org.elasticsearch.xpack.esql.expression.function.Param;
+import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST;
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND;
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isNotNull;
+import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString;
+
+/**
+ * Full text function that performs a {@link QueryStringQuery} .
+ */
+public class Match extends FullTextFunction implements Validatable {
+
+ public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Match", Match::new);
+
+ private final Expression field;
+
+ @FunctionInfo(
+ returnType = "boolean",
+ preview = true,
+ description = "Performs a match query on the specified field. Returns true if the provided query matches the row.",
+ examples = { @Example(file = "match-function", tag = "match-with-field") }
+ )
+ public Match(
+ Source source,
+ @Param(name = "field", type = { "keyword", "text" }, description = "Field that the query will target.") Expression field,
+ @Param(
+ name = "query",
+ type = { "keyword", "text" },
+ description = "Text you wish to find in the provided field."
+ ) Expression matchQuery
+ ) {
+ super(source, matchQuery, List.of(field, matchQuery));
+ this.field = field;
+ }
+
+ private Match(StreamInput in) throws IOException {
+ this(Source.readFrom((PlanStreamInput) in), in.readNamedWriteable(Expression.class), in.readNamedWriteable(Expression.class));
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ source().writeTo(out);
+ out.writeNamedWriteable(field);
+ out.writeNamedWriteable(query());
+ }
+
+ @Override
+ public String getWriteableName() {
+ return ENTRY.name;
+ }
+
+ @Override
+ protected TypeResolution resolveNonQueryParamTypes() {
+ return isNotNull(field, sourceText(), FIRST).and(isString(field, sourceText(), FIRST)).and(super.resolveNonQueryParamTypes());
+ }
+
+ @Override
+ public void validate(Failures failures) {
+ if (field instanceof FieldAttribute == false) {
+ failures.add(
+ Failure.fail(
+ field,
+ "[{}] cannot operate on [{}], which is not a field from an index mapping",
+ functionName(),
+ field.sourceText()
+ )
+ );
+ }
+ }
+
+ @Override
+ public Expression replaceChildren(List newChildren) {
+ // Query is the first child, field is the second child
+ return new Match(source(), newChildren.get(0), newChildren.get(1));
+ }
+
+ @Override
+ protected NodeInfo extends Expression> info() {
+ return NodeInfo.create(this, Match::new, field, query());
+ }
+
+ protected TypeResolutions.ParamOrdinal queryParamOrdinal() {
+ return SECOND;
+ }
+
+ public Expression field() {
+ return field;
+ }
+}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryString.java
similarity index 66%
rename from x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunction.java
rename to x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryString.java
index fa331acd08655..0d7d15a13dd80 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunction.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryString.java
@@ -7,32 +7,27 @@
package org.elasticsearch.xpack.esql.expression.function.fulltext;
-import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.xpack.esql.core.expression.Expression;
-import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
import org.elasticsearch.xpack.esql.core.querydsl.query.QueryStringQuery;
import org.elasticsearch.xpack.esql.core.tree.NodeInfo;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.expression.function.Example;
import org.elasticsearch.xpack.esql.expression.function.FunctionInfo;
import org.elasticsearch.xpack.esql.expression.function.Param;
+import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput;
import java.io.IOException;
import java.util.List;
-import java.util.Map;
/**
* Full text function that performs a {@link QueryStringQuery} .
*/
-public class QueryStringFunction extends FullTextFunction {
+public class QueryString extends FullTextFunction {
- public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
- Expression.class,
- "QStr",
- QueryStringFunction::new
- );
+ public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "QStr", QueryString::new);
@FunctionInfo(
returnType = "boolean",
@@ -40,7 +35,7 @@ public class QueryStringFunction extends FullTextFunction {
description = "Performs a query string query. Returns true if the provided query string matches the row.",
examples = { @Example(file = "qstr-function", tag = "qstr-with-field") }
)
- public QueryStringFunction(
+ public QueryString(
Source source,
@Param(
name = "query",
@@ -48,40 +43,37 @@ public QueryStringFunction(
description = "Query string in Lucene query string format."
) Expression queryString
) {
- super(source, queryString);
+ super(source, queryString, List.of(queryString));
}
- private QueryStringFunction(StreamInput in) throws IOException {
- super(in);
+ private QueryString(StreamInput in) throws IOException {
+ this(Source.readFrom((PlanStreamInput) in), in.readNamedWriteable(Expression.class));
}
@Override
- public String functionName() {
- return "QSTR";
+ public void writeTo(StreamOutput out) throws IOException {
+ source().writeTo(out);
+ out.writeNamedWriteable(query());
}
@Override
- public Query asQuery() {
- Object queryAsObject = query().fold();
- if (queryAsObject instanceof BytesRef queryAsBytesRef) {
- return new QueryStringQuery(source(), queryAsBytesRef.utf8ToString(), Map.of(), null);
- } else {
- throw new IllegalArgumentException("Query in QSTR needs to be resolved to a string");
- }
+ public String getWriteableName() {
+ return ENTRY.name;
}
@Override
- public Expression replaceChildren(List newChildren) {
- return new QueryStringFunction(source(), newChildren.get(0));
+ public String functionName() {
+ return "QSTR";
}
@Override
- protected NodeInfo extends Expression> info() {
- return NodeInfo.create(this, QueryStringFunction::new, query());
+ public Expression replaceChildren(List newChildren) {
+ return new QueryString(source(), newChildren.get(0));
}
@Override
- public String getWriteableName() {
- return ENTRY.name;
+ protected NodeInfo extends Expression> info() {
+ return NodeInfo.create(this, QueryString::new, query());
}
+
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushFiltersToSource.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushFiltersToSource.java
index 1ba966e318219..2209dffe5af06 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushFiltersToSource.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/optimizer/rules/physical/local/PushFiltersToSource.java
@@ -32,7 +32,8 @@
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.util.CollectionUtils;
import org.elasticsearch.xpack.esql.core.util.Queries;
-import org.elasticsearch.xpack.esql.expression.function.fulltext.FullTextFunction;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.Match;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString;
import org.elasticsearch.xpack.esql.expression.function.scalar.ip.CIDRMatch;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.BinarySpatialFunction;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction;
@@ -250,8 +251,10 @@ public static boolean canPushToSource(Expression exp, Predicate
return mqp.field() instanceof FieldAttribute && DataType.isString(mqp.field().dataType());
} else if (exp instanceof StringQueryPredicate) {
return true;
- } else if (exp instanceof FullTextFunction) {
+ } else if (exp instanceof QueryString) {
return true;
+ } else if (exp instanceof Match mf) {
+ return mf.field() instanceof FieldAttribute && DataType.isString(mf.field().dataType());
}
return false;
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
index b5ca44826c051..e9e6f45bdc30f 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.interp
@@ -23,7 +23,6 @@ null
null
null
null
-null
'|'
null
null
@@ -65,6 +64,7 @@ null
'%'
null
null
+null
']'
null
null
@@ -141,7 +141,6 @@ STATS
WHERE
DEV_INLINESTATS
DEV_LOOKUP
-DEV_MATCH
DEV_METRICS
UNKNOWN_CMD
LINE_COMMENT
@@ -186,6 +185,7 @@ MINUS
ASTERISK
SLASH
PERCENT
+DEV_MATCH
NAMED_OR_POSITIONAL_PARAM
OPENING_BRACKET
CLOSING_BRACKET
@@ -263,7 +263,6 @@ STATS
WHERE
DEV_INLINESTATS
DEV_LOOKUP
-DEV_MATCH
DEV_METRICS
UNKNOWN_CMD
LINE_COMMENT
@@ -318,7 +317,7 @@ MINUS
ASTERISK
SLASH
PERCENT
-DEV_MATCH_OP
+DEV_MATCH
NAMED_OR_POSITIONAL_PARAM
OPENING_BRACKET
CLOSING_BRACKET
@@ -466,4 +465,4 @@ METRICS_MODE
CLOSING_METRICS_MODE
atn:
-[4, 0, 120, 1475, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 2, 196, 7, 196, 2, 197, 7, 197, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 4, 20, 587, 8, 20, 11, 20, 12, 20, 588, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 597, 8, 21, 10, 21, 12, 21, 600, 9, 21, 1, 21, 3, 21, 603, 8, 21, 1, 21, 3, 21, 606, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 615, 8, 22, 10, 22, 12, 22, 618, 9, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 4, 23, 626, 8, 23, 11, 23, 12, 23, 627, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 3, 29, 647, 8, 29, 1, 29, 4, 29, 650, 8, 29, 11, 29, 12, 29, 651, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 3, 32, 661, 8, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 3, 34, 668, 8, 34, 1, 35, 1, 35, 1, 35, 5, 35, 673, 8, 35, 10, 35, 12, 35, 676, 9, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 684, 8, 35, 10, 35, 12, 35, 687, 9, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 694, 8, 35, 1, 35, 3, 35, 697, 8, 35, 3, 35, 699, 8, 35, 1, 36, 4, 36, 702, 8, 36, 11, 36, 12, 36, 703, 1, 37, 4, 37, 707, 8, 37, 11, 37, 12, 37, 708, 1, 37, 1, 37, 5, 37, 713, 8, 37, 10, 37, 12, 37, 716, 9, 37, 1, 37, 1, 37, 4, 37, 720, 8, 37, 11, 37, 12, 37, 721, 1, 37, 4, 37, 725, 8, 37, 11, 37, 12, 37, 726, 1, 37, 1, 37, 5, 37, 731, 8, 37, 10, 37, 12, 37, 734, 9, 37, 3, 37, 736, 8, 37, 1, 37, 1, 37, 1, 37, 1, 37, 4, 37, 742, 8, 37, 11, 37, 12, 37, 743, 1, 37, 1, 37, 3, 37, 748, 8, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 3, 74, 875, 8, 74, 1, 74, 5, 74, 878, 8, 74, 10, 74, 12, 74, 881, 9, 74, 1, 74, 1, 74, 4, 74, 885, 8, 74, 11, 74, 12, 74, 886, 3, 74, 889, 8, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 5, 77, 903, 8, 77, 10, 77, 12, 77, 906, 9, 77, 1, 77, 1, 77, 3, 77, 910, 8, 77, 1, 77, 4, 77, 913, 8, 77, 11, 77, 12, 77, 914, 3, 77, 917, 8, 77, 1, 78, 1, 78, 4, 78, 921, 8, 78, 11, 78, 12, 78, 922, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 3, 95, 1000, 8, 95, 1, 96, 4, 96, 1003, 8, 96, 11, 96, 12, 96, 1004, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 3, 107, 1052, 8, 107, 1, 108, 1, 108, 3, 108, 1056, 8, 108, 1, 108, 5, 108, 1059, 8, 108, 10, 108, 12, 108, 1062, 9, 108, 1, 108, 1, 108, 3, 108, 1066, 8, 108, 1, 108, 4, 108, 1069, 8, 108, 11, 108, 12, 108, 1070, 3, 108, 1073, 8, 108, 1, 109, 1, 109, 4, 109, 1077, 8, 109, 11, 109, 12, 109, 1078, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 1, 122, 1, 123, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 129, 4, 129, 1162, 8, 129, 11, 129, 12, 129, 1163, 1, 129, 1, 129, 3, 129, 1168, 8, 129, 1, 129, 4, 129, 1171, 8, 129, 11, 129, 12, 129, 1172, 1, 130, 1, 130, 1, 130, 1, 130, 1, 131, 1, 131, 1, 131, 1, 131, 1, 132, 1, 132, 1, 132, 1, 132, 1, 133, 1, 133, 1, 133, 1, 133, 1, 134, 1, 134, 1, 134, 1, 134, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 1, 137, 1, 138, 1, 138, 1, 138, 1, 138, 1, 139, 1, 139, 1, 139, 1, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 1, 143, 1, 143, 1, 144, 1, 144, 1, 144, 1, 144, 1, 145, 1, 145, 1, 145, 1, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 1, 158, 1, 159, 1, 159, 1, 159, 1, 159, 1, 160, 1, 160, 1, 160, 1, 160, 1, 160, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 162, 4, 162, 1312, 8, 162, 11, 162, 12, 162, 1313, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 190, 1, 190, 1, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 193, 1, 193, 1, 193, 1, 193, 1, 194, 1, 194, 1, 194, 1, 194, 1, 194, 1, 194, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 1, 197, 1, 197, 1, 197, 1, 197, 1, 197, 2, 616, 685, 0, 198, 15, 1, 17, 2, 19, 3, 21, 4, 23, 5, 25, 6, 27, 7, 29, 8, 31, 9, 33, 10, 35, 11, 37, 12, 39, 13, 41, 14, 43, 15, 45, 16, 47, 17, 49, 18, 51, 19, 53, 20, 55, 21, 57, 22, 59, 23, 61, 24, 63, 25, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 0, 85, 26, 87, 27, 89, 28, 91, 29, 93, 30, 95, 31, 97, 32, 99, 33, 101, 34, 103, 35, 105, 36, 107, 37, 109, 38, 111, 39, 113, 40, 115, 41, 117, 42, 119, 43, 121, 44, 123, 45, 125, 46, 127, 47, 129, 48, 131, 49, 133, 50, 135, 51, 137, 52, 139, 53, 141, 54, 143, 55, 145, 56, 147, 57, 149, 58, 151, 59, 153, 60, 155, 61, 157, 62, 159, 63, 161, 0, 163, 64, 165, 65, 167, 66, 169, 67, 171, 0, 173, 68, 175, 69, 177, 70, 179, 71, 181, 0, 183, 0, 185, 72, 187, 73, 189, 74, 191, 0, 193, 0, 195, 0, 197, 0, 199, 0, 201, 0, 203, 75, 205, 0, 207, 76, 209, 0, 211, 0, 213, 77, 215, 78, 217, 79, 219, 0, 221, 0, 223, 0, 225, 0, 227, 0, 229, 0, 231, 0, 233, 80, 235, 81, 237, 82, 239, 83, 241, 0, 243, 0, 245, 0, 247, 0, 249, 0, 251, 0, 253, 84, 255, 0, 257, 85, 259, 86, 261, 87, 263, 0, 265, 0, 267, 88, 269, 89, 271, 0, 273, 90, 275, 0, 277, 91, 279, 92, 281, 93, 283, 0, 285, 0, 287, 0, 289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 94, 303, 95, 305, 96, 307, 0, 309, 0, 311, 0, 313, 0, 315, 0, 317, 0, 319, 97, 321, 98, 323, 99, 325, 0, 327, 100, 329, 101, 331, 102, 333, 103, 335, 0, 337, 104, 339, 105, 341, 106, 343, 107, 345, 108, 347, 0, 349, 0, 351, 0, 353, 0, 355, 0, 357, 0, 359, 0, 361, 109, 363, 110, 365, 111, 367, 0, 369, 0, 371, 0, 373, 0, 375, 112, 377, 113, 379, 114, 381, 0, 383, 0, 385, 0, 387, 115, 389, 116, 391, 117, 393, 0, 395, 0, 397, 118, 399, 119, 401, 120, 403, 0, 405, 0, 407, 0, 409, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 35, 2, 0, 68, 68, 100, 100, 2, 0, 73, 73, 105, 105, 2, 0, 83, 83, 115, 115, 2, 0, 69, 69, 101, 101, 2, 0, 67, 67, 99, 99, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 79, 79, 111, 111, 2, 0, 80, 80, 112, 112, 2, 0, 78, 78, 110, 110, 2, 0, 72, 72, 104, 104, 2, 0, 86, 86, 118, 118, 2, 0, 65, 65, 97, 97, 2, 0, 76, 76, 108, 108, 2, 0, 88, 88, 120, 120, 2, 0, 70, 70, 102, 102, 2, 0, 77, 77, 109, 109, 2, 0, 71, 71, 103, 103, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87, 119, 119, 2, 0, 85, 85, 117, 117, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 8, 0, 34, 34, 78, 78, 82, 82, 84, 84, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 2, 0, 66, 66, 98, 98, 2, 0, 89, 89, 121, 121, 11, 0, 9, 10, 13, 13, 32, 32, 34, 34, 44, 44, 47, 47, 58, 58, 61, 61, 91, 91, 93, 93, 124, 124, 2, 0, 42, 42, 47, 47, 11, 0, 9, 10, 13, 13, 32, 32, 34, 35, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1503, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 1, 63, 1, 0, 0, 0, 1, 85, 1, 0, 0, 0, 1, 87, 1, 0, 0, 0, 1, 89, 1, 0, 0, 0, 1, 91, 1, 0, 0, 0, 1, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, 1, 97, 1, 0, 0, 0, 1, 99, 1, 0, 0, 0, 1, 101, 1, 0, 0, 0, 1, 103, 1, 0, 0, 0, 1, 105, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 1, 109, 1, 0, 0, 0, 1, 111, 1, 0, 0, 0, 1, 113, 1, 0, 0, 0, 1, 115, 1, 0, 0, 0, 1, 117, 1, 0, 0, 0, 1, 119, 1, 0, 0, 0, 1, 121, 1, 0, 0, 0, 1, 123, 1, 0, 0, 0, 1, 125, 1, 0, 0, 0, 1, 127, 1, 0, 0, 0, 1, 129, 1, 0, 0, 0, 1, 131, 1, 0, 0, 0, 1, 133, 1, 0, 0, 0, 1, 135, 1, 0, 0, 0, 1, 137, 1, 0, 0, 0, 1, 139, 1, 0, 0, 0, 1, 141, 1, 0, 0, 0, 1, 143, 1, 0, 0, 0, 1, 145, 1, 0, 0, 0, 1, 147, 1, 0, 0, 0, 1, 149, 1, 0, 0, 0, 1, 151, 1, 0, 0, 0, 1, 153, 1, 0, 0, 0, 1, 155, 1, 0, 0, 0, 1, 157, 1, 0, 0, 0, 1, 159, 1, 0, 0, 0, 1, 161, 1, 0, 0, 0, 1, 163, 1, 0, 0, 0, 1, 165, 1, 0, 0, 0, 1, 167, 1, 0, 0, 0, 1, 169, 1, 0, 0, 0, 1, 173, 1, 0, 0, 0, 1, 175, 1, 0, 0, 0, 1, 177, 1, 0, 0, 0, 1, 179, 1, 0, 0, 0, 2, 181, 1, 0, 0, 0, 2, 183, 1, 0, 0, 0, 2, 185, 1, 0, 0, 0, 2, 187, 1, 0, 0, 0, 2, 189, 1, 0, 0, 0, 3, 191, 1, 0, 0, 0, 3, 193, 1, 0, 0, 0, 3, 195, 1, 0, 0, 0, 3, 197, 1, 0, 0, 0, 3, 199, 1, 0, 0, 0, 3, 201, 1, 0, 0, 0, 3, 203, 1, 0, 0, 0, 3, 207, 1, 0, 0, 0, 3, 209, 1, 0, 0, 0, 3, 211, 1, 0, 0, 0, 3, 213, 1, 0, 0, 0, 3, 215, 1, 0, 0, 0, 3, 217, 1, 0, 0, 0, 4, 219, 1, 0, 0, 0, 4, 221, 1, 0, 0, 0, 4, 223, 1, 0, 0, 0, 4, 225, 1, 0, 0, 0, 4, 227, 1, 0, 0, 0, 4, 233, 1, 0, 0, 0, 4, 235, 1, 0, 0, 0, 4, 237, 1, 0, 0, 0, 4, 239, 1, 0, 0, 0, 5, 241, 1, 0, 0, 0, 5, 243, 1, 0, 0, 0, 5, 245, 1, 0, 0, 0, 5, 247, 1, 0, 0, 0, 5, 249, 1, 0, 0, 0, 5, 251, 1, 0, 0, 0, 5, 253, 1, 0, 0, 0, 5, 255, 1, 0, 0, 0, 5, 257, 1, 0, 0, 0, 5, 259, 1, 0, 0, 0, 5, 261, 1, 0, 0, 0, 6, 263, 1, 0, 0, 0, 6, 265, 1, 0, 0, 0, 6, 267, 1, 0, 0, 0, 6, 269, 1, 0, 0, 0, 6, 273, 1, 0, 0, 0, 6, 275, 1, 0, 0, 0, 6, 277, 1, 0, 0, 0, 6, 279, 1, 0, 0, 0, 6, 281, 1, 0, 0, 0, 7, 283, 1, 0, 0, 0, 7, 285, 1, 0, 0, 0, 7, 287, 1, 0, 0, 0, 7, 289, 1, 0, 0, 0, 7, 291, 1, 0, 0, 0, 7, 293, 1, 0, 0, 0, 7, 295, 1, 0, 0, 0, 7, 297, 1, 0, 0, 0, 7, 299, 1, 0, 0, 0, 7, 301, 1, 0, 0, 0, 7, 303, 1, 0, 0, 0, 7, 305, 1, 0, 0, 0, 8, 307, 1, 0, 0, 0, 8, 309, 1, 0, 0, 0, 8, 311, 1, 0, 0, 0, 8, 313, 1, 0, 0, 0, 8, 315, 1, 0, 0, 0, 8, 317, 1, 0, 0, 0, 8, 319, 1, 0, 0, 0, 8, 321, 1, 0, 0, 0, 8, 323, 1, 0, 0, 0, 9, 325, 1, 0, 0, 0, 9, 327, 1, 0, 0, 0, 9, 329, 1, 0, 0, 0, 9, 331, 1, 0, 0, 0, 9, 333, 1, 0, 0, 0, 10, 335, 1, 0, 0, 0, 10, 337, 1, 0, 0, 0, 10, 339, 1, 0, 0, 0, 10, 341, 1, 0, 0, 0, 10, 343, 1, 0, 0, 0, 10, 345, 1, 0, 0, 0, 11, 347, 1, 0, 0, 0, 11, 349, 1, 0, 0, 0, 11, 351, 1, 0, 0, 0, 11, 353, 1, 0, 0, 0, 11, 355, 1, 0, 0, 0, 11, 357, 1, 0, 0, 0, 11, 359, 1, 0, 0, 0, 11, 361, 1, 0, 0, 0, 11, 363, 1, 0, 0, 0, 11, 365, 1, 0, 0, 0, 12, 367, 1, 0, 0, 0, 12, 369, 1, 0, 0, 0, 12, 371, 1, 0, 0, 0, 12, 373, 1, 0, 0, 0, 12, 375, 1, 0, 0, 0, 12, 377, 1, 0, 0, 0, 12, 379, 1, 0, 0, 0, 13, 381, 1, 0, 0, 0, 13, 383, 1, 0, 0, 0, 13, 385, 1, 0, 0, 0, 13, 387, 1, 0, 0, 0, 13, 389, 1, 0, 0, 0, 13, 391, 1, 0, 0, 0, 14, 393, 1, 0, 0, 0, 14, 395, 1, 0, 0, 0, 14, 397, 1, 0, 0, 0, 14, 399, 1, 0, 0, 0, 14, 401, 1, 0, 0, 0, 14, 403, 1, 0, 0, 0, 14, 405, 1, 0, 0, 0, 14, 407, 1, 0, 0, 0, 14, 409, 1, 0, 0, 0, 15, 411, 1, 0, 0, 0, 17, 421, 1, 0, 0, 0, 19, 428, 1, 0, 0, 0, 21, 437, 1, 0, 0, 0, 23, 444, 1, 0, 0, 0, 25, 454, 1, 0, 0, 0, 27, 461, 1, 0, 0, 0, 29, 468, 1, 0, 0, 0, 31, 475, 1, 0, 0, 0, 33, 483, 1, 0, 0, 0, 35, 495, 1, 0, 0, 0, 37, 504, 1, 0, 0, 0, 39, 510, 1, 0, 0, 0, 41, 517, 1, 0, 0, 0, 43, 524, 1, 0, 0, 0, 45, 532, 1, 0, 0, 0, 47, 540, 1, 0, 0, 0, 49, 555, 1, 0, 0, 0, 51, 565, 1, 0, 0, 0, 53, 574, 1, 0, 0, 0, 55, 586, 1, 0, 0, 0, 57, 592, 1, 0, 0, 0, 59, 609, 1, 0, 0, 0, 61, 625, 1, 0, 0, 0, 63, 631, 1, 0, 0, 0, 65, 635, 1, 0, 0, 0, 67, 637, 1, 0, 0, 0, 69, 639, 1, 0, 0, 0, 71, 642, 1, 0, 0, 0, 73, 644, 1, 0, 0, 0, 75, 653, 1, 0, 0, 0, 77, 655, 1, 0, 0, 0, 79, 660, 1, 0, 0, 0, 81, 662, 1, 0, 0, 0, 83, 667, 1, 0, 0, 0, 85, 698, 1, 0, 0, 0, 87, 701, 1, 0, 0, 0, 89, 747, 1, 0, 0, 0, 91, 749, 1, 0, 0, 0, 93, 752, 1, 0, 0, 0, 95, 756, 1, 0, 0, 0, 97, 760, 1, 0, 0, 0, 99, 762, 1, 0, 0, 0, 101, 765, 1, 0, 0, 0, 103, 767, 1, 0, 0, 0, 105, 772, 1, 0, 0, 0, 107, 774, 1, 0, 0, 0, 109, 780, 1, 0, 0, 0, 111, 786, 1, 0, 0, 0, 113, 789, 1, 0, 0, 0, 115, 792, 1, 0, 0, 0, 117, 797, 1, 0, 0, 0, 119, 802, 1, 0, 0, 0, 121, 804, 1, 0, 0, 0, 123, 808, 1, 0, 0, 0, 125, 813, 1, 0, 0, 0, 127, 819, 1, 0, 0, 0, 129, 822, 1, 0, 0, 0, 131, 824, 1, 0, 0, 0, 133, 830, 1, 0, 0, 0, 135, 832, 1, 0, 0, 0, 137, 837, 1, 0, 0, 0, 139, 840, 1, 0, 0, 0, 141, 843, 1, 0, 0, 0, 143, 846, 1, 0, 0, 0, 145, 848, 1, 0, 0, 0, 147, 851, 1, 0, 0, 0, 149, 853, 1, 0, 0, 0, 151, 856, 1, 0, 0, 0, 153, 858, 1, 0, 0, 0, 155, 860, 1, 0, 0, 0, 157, 862, 1, 0, 0, 0, 159, 864, 1, 0, 0, 0, 161, 866, 1, 0, 0, 0, 163, 888, 1, 0, 0, 0, 165, 890, 1, 0, 0, 0, 167, 895, 1, 0, 0, 0, 169, 916, 1, 0, 0, 0, 171, 918, 1, 0, 0, 0, 173, 926, 1, 0, 0, 0, 175, 928, 1, 0, 0, 0, 177, 932, 1, 0, 0, 0, 179, 936, 1, 0, 0, 0, 181, 940, 1, 0, 0, 0, 183, 945, 1, 0, 0, 0, 185, 950, 1, 0, 0, 0, 187, 954, 1, 0, 0, 0, 189, 958, 1, 0, 0, 0, 191, 962, 1, 0, 0, 0, 193, 967, 1, 0, 0, 0, 195, 971, 1, 0, 0, 0, 197, 975, 1, 0, 0, 0, 199, 979, 1, 0, 0, 0, 201, 983, 1, 0, 0, 0, 203, 987, 1, 0, 0, 0, 205, 999, 1, 0, 0, 0, 207, 1002, 1, 0, 0, 0, 209, 1006, 1, 0, 0, 0, 211, 1010, 1, 0, 0, 0, 213, 1014, 1, 0, 0, 0, 215, 1018, 1, 0, 0, 0, 217, 1022, 1, 0, 0, 0, 219, 1026, 1, 0, 0, 0, 221, 1031, 1, 0, 0, 0, 223, 1035, 1, 0, 0, 0, 225, 1039, 1, 0, 0, 0, 227, 1043, 1, 0, 0, 0, 229, 1051, 1, 0, 0, 0, 231, 1072, 1, 0, 0, 0, 233, 1076, 1, 0, 0, 0, 235, 1080, 1, 0, 0, 0, 237, 1084, 1, 0, 0, 0, 239, 1088, 1, 0, 0, 0, 241, 1092, 1, 0, 0, 0, 243, 1097, 1, 0, 0, 0, 245, 1101, 1, 0, 0, 0, 247, 1105, 1, 0, 0, 0, 249, 1109, 1, 0, 0, 0, 251, 1113, 1, 0, 0, 0, 253, 1117, 1, 0, 0, 0, 255, 1120, 1, 0, 0, 0, 257, 1124, 1, 0, 0, 0, 259, 1128, 1, 0, 0, 0, 261, 1132, 1, 0, 0, 0, 263, 1136, 1, 0, 0, 0, 265, 1141, 1, 0, 0, 0, 267, 1146, 1, 0, 0, 0, 269, 1151, 1, 0, 0, 0, 271, 1158, 1, 0, 0, 0, 273, 1167, 1, 0, 0, 0, 275, 1174, 1, 0, 0, 0, 277, 1178, 1, 0, 0, 0, 279, 1182, 1, 0, 0, 0, 281, 1186, 1, 0, 0, 0, 283, 1190, 1, 0, 0, 0, 285, 1196, 1, 0, 0, 0, 287, 1200, 1, 0, 0, 0, 289, 1204, 1, 0, 0, 0, 291, 1208, 1, 0, 0, 0, 293, 1212, 1, 0, 0, 0, 295, 1216, 1, 0, 0, 0, 297, 1220, 1, 0, 0, 0, 299, 1224, 1, 0, 0, 0, 301, 1228, 1, 0, 0, 0, 303, 1232, 1, 0, 0, 0, 305, 1236, 1, 0, 0, 0, 307, 1240, 1, 0, 0, 0, 309, 1245, 1, 0, 0, 0, 311, 1249, 1, 0, 0, 0, 313, 1253, 1, 0, 0, 0, 315, 1257, 1, 0, 0, 0, 317, 1261, 1, 0, 0, 0, 319, 1265, 1, 0, 0, 0, 321, 1269, 1, 0, 0, 0, 323, 1273, 1, 0, 0, 0, 325, 1277, 1, 0, 0, 0, 327, 1282, 1, 0, 0, 0, 329, 1287, 1, 0, 0, 0, 331, 1291, 1, 0, 0, 0, 333, 1295, 1, 0, 0, 0, 335, 1299, 1, 0, 0, 0, 337, 1304, 1, 0, 0, 0, 339, 1311, 1, 0, 0, 0, 341, 1315, 1, 0, 0, 0, 343, 1319, 1, 0, 0, 0, 345, 1323, 1, 0, 0, 0, 347, 1327, 1, 0, 0, 0, 349, 1332, 1, 0, 0, 0, 351, 1336, 1, 0, 0, 0, 353, 1340, 1, 0, 0, 0, 355, 1344, 1, 0, 0, 0, 357, 1349, 1, 0, 0, 0, 359, 1353, 1, 0, 0, 0, 361, 1357, 1, 0, 0, 0, 363, 1361, 1, 0, 0, 0, 365, 1365, 1, 0, 0, 0, 367, 1369, 1, 0, 0, 0, 369, 1375, 1, 0, 0, 0, 371, 1379, 1, 0, 0, 0, 373, 1383, 1, 0, 0, 0, 375, 1387, 1, 0, 0, 0, 377, 1391, 1, 0, 0, 0, 379, 1395, 1, 0, 0, 0, 381, 1399, 1, 0, 0, 0, 383, 1404, 1, 0, 0, 0, 385, 1410, 1, 0, 0, 0, 387, 1416, 1, 0, 0, 0, 389, 1420, 1, 0, 0, 0, 391, 1424, 1, 0, 0, 0, 393, 1428, 1, 0, 0, 0, 395, 1434, 1, 0, 0, 0, 397, 1440, 1, 0, 0, 0, 399, 1444, 1, 0, 0, 0, 401, 1448, 1, 0, 0, 0, 403, 1452, 1, 0, 0, 0, 405, 1458, 1, 0, 0, 0, 407, 1464, 1, 0, 0, 0, 409, 1470, 1, 0, 0, 0, 411, 412, 7, 0, 0, 0, 412, 413, 7, 1, 0, 0, 413, 414, 7, 2, 0, 0, 414, 415, 7, 2, 0, 0, 415, 416, 7, 3, 0, 0, 416, 417, 7, 4, 0, 0, 417, 418, 7, 5, 0, 0, 418, 419, 1, 0, 0, 0, 419, 420, 6, 0, 0, 0, 420, 16, 1, 0, 0, 0, 421, 422, 7, 0, 0, 0, 422, 423, 7, 6, 0, 0, 423, 424, 7, 7, 0, 0, 424, 425, 7, 8, 0, 0, 425, 426, 1, 0, 0, 0, 426, 427, 6, 1, 1, 0, 427, 18, 1, 0, 0, 0, 428, 429, 7, 3, 0, 0, 429, 430, 7, 9, 0, 0, 430, 431, 7, 6, 0, 0, 431, 432, 7, 1, 0, 0, 432, 433, 7, 4, 0, 0, 433, 434, 7, 10, 0, 0, 434, 435, 1, 0, 0, 0, 435, 436, 6, 2, 2, 0, 436, 20, 1, 0, 0, 0, 437, 438, 7, 3, 0, 0, 438, 439, 7, 11, 0, 0, 439, 440, 7, 12, 0, 0, 440, 441, 7, 13, 0, 0, 441, 442, 1, 0, 0, 0, 442, 443, 6, 3, 0, 0, 443, 22, 1, 0, 0, 0, 444, 445, 7, 3, 0, 0, 445, 446, 7, 14, 0, 0, 446, 447, 7, 8, 0, 0, 447, 448, 7, 13, 0, 0, 448, 449, 7, 12, 0, 0, 449, 450, 7, 1, 0, 0, 450, 451, 7, 9, 0, 0, 451, 452, 1, 0, 0, 0, 452, 453, 6, 4, 3, 0, 453, 24, 1, 0, 0, 0, 454, 455, 7, 15, 0, 0, 455, 456, 7, 6, 0, 0, 456, 457, 7, 7, 0, 0, 457, 458, 7, 16, 0, 0, 458, 459, 1, 0, 0, 0, 459, 460, 6, 5, 4, 0, 460, 26, 1, 0, 0, 0, 461, 462, 7, 17, 0, 0, 462, 463, 7, 6, 0, 0, 463, 464, 7, 7, 0, 0, 464, 465, 7, 18, 0, 0, 465, 466, 1, 0, 0, 0, 466, 467, 6, 6, 0, 0, 467, 28, 1, 0, 0, 0, 468, 469, 7, 18, 0, 0, 469, 470, 7, 3, 0, 0, 470, 471, 7, 3, 0, 0, 471, 472, 7, 8, 0, 0, 472, 473, 1, 0, 0, 0, 473, 474, 6, 7, 1, 0, 474, 30, 1, 0, 0, 0, 475, 476, 7, 13, 0, 0, 476, 477, 7, 1, 0, 0, 477, 478, 7, 16, 0, 0, 478, 479, 7, 1, 0, 0, 479, 480, 7, 5, 0, 0, 480, 481, 1, 0, 0, 0, 481, 482, 6, 8, 0, 0, 482, 32, 1, 0, 0, 0, 483, 484, 7, 16, 0, 0, 484, 485, 7, 11, 0, 0, 485, 486, 5, 95, 0, 0, 486, 487, 7, 3, 0, 0, 487, 488, 7, 14, 0, 0, 488, 489, 7, 8, 0, 0, 489, 490, 7, 12, 0, 0, 490, 491, 7, 9, 0, 0, 491, 492, 7, 0, 0, 0, 492, 493, 1, 0, 0, 0, 493, 494, 6, 9, 5, 0, 494, 34, 1, 0, 0, 0, 495, 496, 7, 6, 0, 0, 496, 497, 7, 3, 0, 0, 497, 498, 7, 9, 0, 0, 498, 499, 7, 12, 0, 0, 499, 500, 7, 16, 0, 0, 500, 501, 7, 3, 0, 0, 501, 502, 1, 0, 0, 0, 502, 503, 6, 10, 6, 0, 503, 36, 1, 0, 0, 0, 504, 505, 7, 6, 0, 0, 505, 506, 7, 7, 0, 0, 506, 507, 7, 19, 0, 0, 507, 508, 1, 0, 0, 0, 508, 509, 6, 11, 0, 0, 509, 38, 1, 0, 0, 0, 510, 511, 7, 2, 0, 0, 511, 512, 7, 10, 0, 0, 512, 513, 7, 7, 0, 0, 513, 514, 7, 19, 0, 0, 514, 515, 1, 0, 0, 0, 515, 516, 6, 12, 7, 0, 516, 40, 1, 0, 0, 0, 517, 518, 7, 2, 0, 0, 518, 519, 7, 7, 0, 0, 519, 520, 7, 6, 0, 0, 520, 521, 7, 5, 0, 0, 521, 522, 1, 0, 0, 0, 522, 523, 6, 13, 0, 0, 523, 42, 1, 0, 0, 0, 524, 525, 7, 2, 0, 0, 525, 526, 7, 5, 0, 0, 526, 527, 7, 12, 0, 0, 527, 528, 7, 5, 0, 0, 528, 529, 7, 2, 0, 0, 529, 530, 1, 0, 0, 0, 530, 531, 6, 14, 0, 0, 531, 44, 1, 0, 0, 0, 532, 533, 7, 19, 0, 0, 533, 534, 7, 10, 0, 0, 534, 535, 7, 3, 0, 0, 535, 536, 7, 6, 0, 0, 536, 537, 7, 3, 0, 0, 537, 538, 1, 0, 0, 0, 538, 539, 6, 15, 0, 0, 539, 46, 1, 0, 0, 0, 540, 541, 4, 16, 0, 0, 541, 542, 7, 1, 0, 0, 542, 543, 7, 9, 0, 0, 543, 544, 7, 13, 0, 0, 544, 545, 7, 1, 0, 0, 545, 546, 7, 9, 0, 0, 546, 547, 7, 3, 0, 0, 547, 548, 7, 2, 0, 0, 548, 549, 7, 5, 0, 0, 549, 550, 7, 12, 0, 0, 550, 551, 7, 5, 0, 0, 551, 552, 7, 2, 0, 0, 552, 553, 1, 0, 0, 0, 553, 554, 6, 16, 0, 0, 554, 48, 1, 0, 0, 0, 555, 556, 4, 17, 1, 0, 556, 557, 7, 13, 0, 0, 557, 558, 7, 7, 0, 0, 558, 559, 7, 7, 0, 0, 559, 560, 7, 18, 0, 0, 560, 561, 7, 20, 0, 0, 561, 562, 7, 8, 0, 0, 562, 563, 1, 0, 0, 0, 563, 564, 6, 17, 8, 0, 564, 50, 1, 0, 0, 0, 565, 566, 4, 18, 2, 0, 566, 567, 7, 16, 0, 0, 567, 568, 7, 12, 0, 0, 568, 569, 7, 5, 0, 0, 569, 570, 7, 4, 0, 0, 570, 571, 7, 10, 0, 0, 571, 572, 1, 0, 0, 0, 572, 573, 6, 18, 0, 0, 573, 52, 1, 0, 0, 0, 574, 575, 4, 19, 3, 0, 575, 576, 7, 16, 0, 0, 576, 577, 7, 3, 0, 0, 577, 578, 7, 5, 0, 0, 578, 579, 7, 6, 0, 0, 579, 580, 7, 1, 0, 0, 580, 581, 7, 4, 0, 0, 581, 582, 7, 2, 0, 0, 582, 583, 1, 0, 0, 0, 583, 584, 6, 19, 9, 0, 584, 54, 1, 0, 0, 0, 585, 587, 8, 21, 0, 0, 586, 585, 1, 0, 0, 0, 587, 588, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 590, 1, 0, 0, 0, 590, 591, 6, 20, 0, 0, 591, 56, 1, 0, 0, 0, 592, 593, 5, 47, 0, 0, 593, 594, 5, 47, 0, 0, 594, 598, 1, 0, 0, 0, 595, 597, 8, 22, 0, 0, 596, 595, 1, 0, 0, 0, 597, 600, 1, 0, 0, 0, 598, 596, 1, 0, 0, 0, 598, 599, 1, 0, 0, 0, 599, 602, 1, 0, 0, 0, 600, 598, 1, 0, 0, 0, 601, 603, 5, 13, 0, 0, 602, 601, 1, 0, 0, 0, 602, 603, 1, 0, 0, 0, 603, 605, 1, 0, 0, 0, 604, 606, 5, 10, 0, 0, 605, 604, 1, 0, 0, 0, 605, 606, 1, 0, 0, 0, 606, 607, 1, 0, 0, 0, 607, 608, 6, 21, 10, 0, 608, 58, 1, 0, 0, 0, 609, 610, 5, 47, 0, 0, 610, 611, 5, 42, 0, 0, 611, 616, 1, 0, 0, 0, 612, 615, 3, 59, 22, 0, 613, 615, 9, 0, 0, 0, 614, 612, 1, 0, 0, 0, 614, 613, 1, 0, 0, 0, 615, 618, 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 616, 614, 1, 0, 0, 0, 617, 619, 1, 0, 0, 0, 618, 616, 1, 0, 0, 0, 619, 620, 5, 42, 0, 0, 620, 621, 5, 47, 0, 0, 621, 622, 1, 0, 0, 0, 622, 623, 6, 22, 10, 0, 623, 60, 1, 0, 0, 0, 624, 626, 7, 23, 0, 0, 625, 624, 1, 0, 0, 0, 626, 627, 1, 0, 0, 0, 627, 625, 1, 0, 0, 0, 627, 628, 1, 0, 0, 0, 628, 629, 1, 0, 0, 0, 629, 630, 6, 23, 10, 0, 630, 62, 1, 0, 0, 0, 631, 632, 5, 124, 0, 0, 632, 633, 1, 0, 0, 0, 633, 634, 6, 24, 11, 0, 634, 64, 1, 0, 0, 0, 635, 636, 7, 24, 0, 0, 636, 66, 1, 0, 0, 0, 637, 638, 7, 25, 0, 0, 638, 68, 1, 0, 0, 0, 639, 640, 5, 92, 0, 0, 640, 641, 7, 26, 0, 0, 641, 70, 1, 0, 0, 0, 642, 643, 8, 27, 0, 0, 643, 72, 1, 0, 0, 0, 644, 646, 7, 3, 0, 0, 645, 647, 7, 28, 0, 0, 646, 645, 1, 0, 0, 0, 646, 647, 1, 0, 0, 0, 647, 649, 1, 0, 0, 0, 648, 650, 3, 65, 25, 0, 649, 648, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 649, 1, 0, 0, 0, 651, 652, 1, 0, 0, 0, 652, 74, 1, 0, 0, 0, 653, 654, 5, 64, 0, 0, 654, 76, 1, 0, 0, 0, 655, 656, 5, 96, 0, 0, 656, 78, 1, 0, 0, 0, 657, 661, 8, 29, 0, 0, 658, 659, 5, 96, 0, 0, 659, 661, 5, 96, 0, 0, 660, 657, 1, 0, 0, 0, 660, 658, 1, 0, 0, 0, 661, 80, 1, 0, 0, 0, 662, 663, 5, 95, 0, 0, 663, 82, 1, 0, 0, 0, 664, 668, 3, 67, 26, 0, 665, 668, 3, 65, 25, 0, 666, 668, 3, 81, 33, 0, 667, 664, 1, 0, 0, 0, 667, 665, 1, 0, 0, 0, 667, 666, 1, 0, 0, 0, 668, 84, 1, 0, 0, 0, 669, 674, 5, 34, 0, 0, 670, 673, 3, 69, 27, 0, 671, 673, 3, 71, 28, 0, 672, 670, 1, 0, 0, 0, 672, 671, 1, 0, 0, 0, 673, 676, 1, 0, 0, 0, 674, 672, 1, 0, 0, 0, 674, 675, 1, 0, 0, 0, 675, 677, 1, 0, 0, 0, 676, 674, 1, 0, 0, 0, 677, 699, 5, 34, 0, 0, 678, 679, 5, 34, 0, 0, 679, 680, 5, 34, 0, 0, 680, 681, 5, 34, 0, 0, 681, 685, 1, 0, 0, 0, 682, 684, 8, 22, 0, 0, 683, 682, 1, 0, 0, 0, 684, 687, 1, 0, 0, 0, 685, 686, 1, 0, 0, 0, 685, 683, 1, 0, 0, 0, 686, 688, 1, 0, 0, 0, 687, 685, 1, 0, 0, 0, 688, 689, 5, 34, 0, 0, 689, 690, 5, 34, 0, 0, 690, 691, 5, 34, 0, 0, 691, 693, 1, 0, 0, 0, 692, 694, 5, 34, 0, 0, 693, 692, 1, 0, 0, 0, 693, 694, 1, 0, 0, 0, 694, 696, 1, 0, 0, 0, 695, 697, 5, 34, 0, 0, 696, 695, 1, 0, 0, 0, 696, 697, 1, 0, 0, 0, 697, 699, 1, 0, 0, 0, 698, 669, 1, 0, 0, 0, 698, 678, 1, 0, 0, 0, 699, 86, 1, 0, 0, 0, 700, 702, 3, 65, 25, 0, 701, 700, 1, 0, 0, 0, 702, 703, 1, 0, 0, 0, 703, 701, 1, 0, 0, 0, 703, 704, 1, 0, 0, 0, 704, 88, 1, 0, 0, 0, 705, 707, 3, 65, 25, 0, 706, 705, 1, 0, 0, 0, 707, 708, 1, 0, 0, 0, 708, 706, 1, 0, 0, 0, 708, 709, 1, 0, 0, 0, 709, 710, 1, 0, 0, 0, 710, 714, 3, 105, 45, 0, 711, 713, 3, 65, 25, 0, 712, 711, 1, 0, 0, 0, 713, 716, 1, 0, 0, 0, 714, 712, 1, 0, 0, 0, 714, 715, 1, 0, 0, 0, 715, 748, 1, 0, 0, 0, 716, 714, 1, 0, 0, 0, 717, 719, 3, 105, 45, 0, 718, 720, 3, 65, 25, 0, 719, 718, 1, 0, 0, 0, 720, 721, 1, 0, 0, 0, 721, 719, 1, 0, 0, 0, 721, 722, 1, 0, 0, 0, 722, 748, 1, 0, 0, 0, 723, 725, 3, 65, 25, 0, 724, 723, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 724, 1, 0, 0, 0, 726, 727, 1, 0, 0, 0, 727, 735, 1, 0, 0, 0, 728, 732, 3, 105, 45, 0, 729, 731, 3, 65, 25, 0, 730, 729, 1, 0, 0, 0, 731, 734, 1, 0, 0, 0, 732, 730, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 736, 1, 0, 0, 0, 734, 732, 1, 0, 0, 0, 735, 728, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 738, 3, 73, 29, 0, 738, 748, 1, 0, 0, 0, 739, 741, 3, 105, 45, 0, 740, 742, 3, 65, 25, 0, 741, 740, 1, 0, 0, 0, 742, 743, 1, 0, 0, 0, 743, 741, 1, 0, 0, 0, 743, 744, 1, 0, 0, 0, 744, 745, 1, 0, 0, 0, 745, 746, 3, 73, 29, 0, 746, 748, 1, 0, 0, 0, 747, 706, 1, 0, 0, 0, 747, 717, 1, 0, 0, 0, 747, 724, 1, 0, 0, 0, 747, 739, 1, 0, 0, 0, 748, 90, 1, 0, 0, 0, 749, 750, 7, 30, 0, 0, 750, 751, 7, 31, 0, 0, 751, 92, 1, 0, 0, 0, 752, 753, 7, 12, 0, 0, 753, 754, 7, 9, 0, 0, 754, 755, 7, 0, 0, 0, 755, 94, 1, 0, 0, 0, 756, 757, 7, 12, 0, 0, 757, 758, 7, 2, 0, 0, 758, 759, 7, 4, 0, 0, 759, 96, 1, 0, 0, 0, 760, 761, 5, 61, 0, 0, 761, 98, 1, 0, 0, 0, 762, 763, 5, 58, 0, 0, 763, 764, 5, 58, 0, 0, 764, 100, 1, 0, 0, 0, 765, 766, 5, 44, 0, 0, 766, 102, 1, 0, 0, 0, 767, 768, 7, 0, 0, 0, 768, 769, 7, 3, 0, 0, 769, 770, 7, 2, 0, 0, 770, 771, 7, 4, 0, 0, 771, 104, 1, 0, 0, 0, 772, 773, 5, 46, 0, 0, 773, 106, 1, 0, 0, 0, 774, 775, 7, 15, 0, 0, 775, 776, 7, 12, 0, 0, 776, 777, 7, 13, 0, 0, 777, 778, 7, 2, 0, 0, 778, 779, 7, 3, 0, 0, 779, 108, 1, 0, 0, 0, 780, 781, 7, 15, 0, 0, 781, 782, 7, 1, 0, 0, 782, 783, 7, 6, 0, 0, 783, 784, 7, 2, 0, 0, 784, 785, 7, 5, 0, 0, 785, 110, 1, 0, 0, 0, 786, 787, 7, 1, 0, 0, 787, 788, 7, 9, 0, 0, 788, 112, 1, 0, 0, 0, 789, 790, 7, 1, 0, 0, 790, 791, 7, 2, 0, 0, 791, 114, 1, 0, 0, 0, 792, 793, 7, 13, 0, 0, 793, 794, 7, 12, 0, 0, 794, 795, 7, 2, 0, 0, 795, 796, 7, 5, 0, 0, 796, 116, 1, 0, 0, 0, 797, 798, 7, 13, 0, 0, 798, 799, 7, 1, 0, 0, 799, 800, 7, 18, 0, 0, 800, 801, 7, 3, 0, 0, 801, 118, 1, 0, 0, 0, 802, 803, 5, 40, 0, 0, 803, 120, 1, 0, 0, 0, 804, 805, 7, 9, 0, 0, 805, 806, 7, 7, 0, 0, 806, 807, 7, 5, 0, 0, 807, 122, 1, 0, 0, 0, 808, 809, 7, 9, 0, 0, 809, 810, 7, 20, 0, 0, 810, 811, 7, 13, 0, 0, 811, 812, 7, 13, 0, 0, 812, 124, 1, 0, 0, 0, 813, 814, 7, 9, 0, 0, 814, 815, 7, 20, 0, 0, 815, 816, 7, 13, 0, 0, 816, 817, 7, 13, 0, 0, 817, 818, 7, 2, 0, 0, 818, 126, 1, 0, 0, 0, 819, 820, 7, 7, 0, 0, 820, 821, 7, 6, 0, 0, 821, 128, 1, 0, 0, 0, 822, 823, 5, 63, 0, 0, 823, 130, 1, 0, 0, 0, 824, 825, 7, 6, 0, 0, 825, 826, 7, 13, 0, 0, 826, 827, 7, 1, 0, 0, 827, 828, 7, 18, 0, 0, 828, 829, 7, 3, 0, 0, 829, 132, 1, 0, 0, 0, 830, 831, 5, 41, 0, 0, 831, 134, 1, 0, 0, 0, 832, 833, 7, 5, 0, 0, 833, 834, 7, 6, 0, 0, 834, 835, 7, 20, 0, 0, 835, 836, 7, 3, 0, 0, 836, 136, 1, 0, 0, 0, 837, 838, 5, 61, 0, 0, 838, 839, 5, 61, 0, 0, 839, 138, 1, 0, 0, 0, 840, 841, 5, 61, 0, 0, 841, 842, 5, 126, 0, 0, 842, 140, 1, 0, 0, 0, 843, 844, 5, 33, 0, 0, 844, 845, 5, 61, 0, 0, 845, 142, 1, 0, 0, 0, 846, 847, 5, 60, 0, 0, 847, 144, 1, 0, 0, 0, 848, 849, 5, 60, 0, 0, 849, 850, 5, 61, 0, 0, 850, 146, 1, 0, 0, 0, 851, 852, 5, 62, 0, 0, 852, 148, 1, 0, 0, 0, 853, 854, 5, 62, 0, 0, 854, 855, 5, 61, 0, 0, 855, 150, 1, 0, 0, 0, 856, 857, 5, 43, 0, 0, 857, 152, 1, 0, 0, 0, 858, 859, 5, 45, 0, 0, 859, 154, 1, 0, 0, 0, 860, 861, 5, 42, 0, 0, 861, 156, 1, 0, 0, 0, 862, 863, 5, 47, 0, 0, 863, 158, 1, 0, 0, 0, 864, 865, 5, 37, 0, 0, 865, 160, 1, 0, 0, 0, 866, 867, 4, 73, 4, 0, 867, 868, 3, 51, 18, 0, 868, 869, 1, 0, 0, 0, 869, 870, 6, 73, 12, 0, 870, 162, 1, 0, 0, 0, 871, 874, 3, 129, 57, 0, 872, 875, 3, 67, 26, 0, 873, 875, 3, 81, 33, 0, 874, 872, 1, 0, 0, 0, 874, 873, 1, 0, 0, 0, 875, 879, 1, 0, 0, 0, 876, 878, 3, 83, 34, 0, 877, 876, 1, 0, 0, 0, 878, 881, 1, 0, 0, 0, 879, 877, 1, 0, 0, 0, 879, 880, 1, 0, 0, 0, 880, 889, 1, 0, 0, 0, 881, 879, 1, 0, 0, 0, 882, 884, 3, 129, 57, 0, 883, 885, 3, 65, 25, 0, 884, 883, 1, 0, 0, 0, 885, 886, 1, 0, 0, 0, 886, 884, 1, 0, 0, 0, 886, 887, 1, 0, 0, 0, 887, 889, 1, 0, 0, 0, 888, 871, 1, 0, 0, 0, 888, 882, 1, 0, 0, 0, 889, 164, 1, 0, 0, 0, 890, 891, 5, 91, 0, 0, 891, 892, 1, 0, 0, 0, 892, 893, 6, 75, 0, 0, 893, 894, 6, 75, 0, 0, 894, 166, 1, 0, 0, 0, 895, 896, 5, 93, 0, 0, 896, 897, 1, 0, 0, 0, 897, 898, 6, 76, 11, 0, 898, 899, 6, 76, 11, 0, 899, 168, 1, 0, 0, 0, 900, 904, 3, 67, 26, 0, 901, 903, 3, 83, 34, 0, 902, 901, 1, 0, 0, 0, 903, 906, 1, 0, 0, 0, 904, 902, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 917, 1, 0, 0, 0, 906, 904, 1, 0, 0, 0, 907, 910, 3, 81, 33, 0, 908, 910, 3, 75, 30, 0, 909, 907, 1, 0, 0, 0, 909, 908, 1, 0, 0, 0, 910, 912, 1, 0, 0, 0, 911, 913, 3, 83, 34, 0, 912, 911, 1, 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 912, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 917, 1, 0, 0, 0, 916, 900, 1, 0, 0, 0, 916, 909, 1, 0, 0, 0, 917, 170, 1, 0, 0, 0, 918, 920, 3, 77, 31, 0, 919, 921, 3, 79, 32, 0, 920, 919, 1, 0, 0, 0, 921, 922, 1, 0, 0, 0, 922, 920, 1, 0, 0, 0, 922, 923, 1, 0, 0, 0, 923, 924, 1, 0, 0, 0, 924, 925, 3, 77, 31, 0, 925, 172, 1, 0, 0, 0, 926, 927, 3, 171, 78, 0, 927, 174, 1, 0, 0, 0, 928, 929, 3, 57, 21, 0, 929, 930, 1, 0, 0, 0, 930, 931, 6, 80, 10, 0, 931, 176, 1, 0, 0, 0, 932, 933, 3, 59, 22, 0, 933, 934, 1, 0, 0, 0, 934, 935, 6, 81, 10, 0, 935, 178, 1, 0, 0, 0, 936, 937, 3, 61, 23, 0, 937, 938, 1, 0, 0, 0, 938, 939, 6, 82, 10, 0, 939, 180, 1, 0, 0, 0, 940, 941, 3, 165, 75, 0, 941, 942, 1, 0, 0, 0, 942, 943, 6, 83, 13, 0, 943, 944, 6, 83, 14, 0, 944, 182, 1, 0, 0, 0, 945, 946, 3, 63, 24, 0, 946, 947, 1, 0, 0, 0, 947, 948, 6, 84, 15, 0, 948, 949, 6, 84, 11, 0, 949, 184, 1, 0, 0, 0, 950, 951, 3, 61, 23, 0, 951, 952, 1, 0, 0, 0, 952, 953, 6, 85, 10, 0, 953, 186, 1, 0, 0, 0, 954, 955, 3, 57, 21, 0, 955, 956, 1, 0, 0, 0, 956, 957, 6, 86, 10, 0, 957, 188, 1, 0, 0, 0, 958, 959, 3, 59, 22, 0, 959, 960, 1, 0, 0, 0, 960, 961, 6, 87, 10, 0, 961, 190, 1, 0, 0, 0, 962, 963, 3, 63, 24, 0, 963, 964, 1, 0, 0, 0, 964, 965, 6, 88, 15, 0, 965, 966, 6, 88, 11, 0, 966, 192, 1, 0, 0, 0, 967, 968, 3, 165, 75, 0, 968, 969, 1, 0, 0, 0, 969, 970, 6, 89, 13, 0, 970, 194, 1, 0, 0, 0, 971, 972, 3, 167, 76, 0, 972, 973, 1, 0, 0, 0, 973, 974, 6, 90, 16, 0, 974, 196, 1, 0, 0, 0, 975, 976, 3, 337, 161, 0, 976, 977, 1, 0, 0, 0, 977, 978, 6, 91, 17, 0, 978, 198, 1, 0, 0, 0, 979, 980, 3, 101, 43, 0, 980, 981, 1, 0, 0, 0, 981, 982, 6, 92, 18, 0, 982, 200, 1, 0, 0, 0, 983, 984, 3, 97, 41, 0, 984, 985, 1, 0, 0, 0, 985, 986, 6, 93, 19, 0, 986, 202, 1, 0, 0, 0, 987, 988, 7, 16, 0, 0, 988, 989, 7, 3, 0, 0, 989, 990, 7, 5, 0, 0, 990, 991, 7, 12, 0, 0, 991, 992, 7, 0, 0, 0, 992, 993, 7, 12, 0, 0, 993, 994, 7, 5, 0, 0, 994, 995, 7, 12, 0, 0, 995, 204, 1, 0, 0, 0, 996, 1000, 8, 32, 0, 0, 997, 998, 5, 47, 0, 0, 998, 1000, 8, 33, 0, 0, 999, 996, 1, 0, 0, 0, 999, 997, 1, 0, 0, 0, 1000, 206, 1, 0, 0, 0, 1001, 1003, 3, 205, 95, 0, 1002, 1001, 1, 0, 0, 0, 1003, 1004, 1, 0, 0, 0, 1004, 1002, 1, 0, 0, 0, 1004, 1005, 1, 0, 0, 0, 1005, 208, 1, 0, 0, 0, 1006, 1007, 3, 207, 96, 0, 1007, 1008, 1, 0, 0, 0, 1008, 1009, 6, 97, 20, 0, 1009, 210, 1, 0, 0, 0, 1010, 1011, 3, 85, 35, 0, 1011, 1012, 1, 0, 0, 0, 1012, 1013, 6, 98, 21, 0, 1013, 212, 1, 0, 0, 0, 1014, 1015, 3, 57, 21, 0, 1015, 1016, 1, 0, 0, 0, 1016, 1017, 6, 99, 10, 0, 1017, 214, 1, 0, 0, 0, 1018, 1019, 3, 59, 22, 0, 1019, 1020, 1, 0, 0, 0, 1020, 1021, 6, 100, 10, 0, 1021, 216, 1, 0, 0, 0, 1022, 1023, 3, 61, 23, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, 6, 101, 10, 0, 1025, 218, 1, 0, 0, 0, 1026, 1027, 3, 63, 24, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1029, 6, 102, 15, 0, 1029, 1030, 6, 102, 11, 0, 1030, 220, 1, 0, 0, 0, 1031, 1032, 3, 105, 45, 0, 1032, 1033, 1, 0, 0, 0, 1033, 1034, 6, 103, 22, 0, 1034, 222, 1, 0, 0, 0, 1035, 1036, 3, 101, 43, 0, 1036, 1037, 1, 0, 0, 0, 1037, 1038, 6, 104, 18, 0, 1038, 224, 1, 0, 0, 0, 1039, 1040, 3, 129, 57, 0, 1040, 1041, 1, 0, 0, 0, 1041, 1042, 6, 105, 23, 0, 1042, 226, 1, 0, 0, 0, 1043, 1044, 3, 163, 74, 0, 1044, 1045, 1, 0, 0, 0, 1045, 1046, 6, 106, 24, 0, 1046, 228, 1, 0, 0, 0, 1047, 1052, 3, 67, 26, 0, 1048, 1052, 3, 65, 25, 0, 1049, 1052, 3, 81, 33, 0, 1050, 1052, 3, 155, 70, 0, 1051, 1047, 1, 0, 0, 0, 1051, 1048, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1051, 1050, 1, 0, 0, 0, 1052, 230, 1, 0, 0, 0, 1053, 1056, 3, 67, 26, 0, 1054, 1056, 3, 155, 70, 0, 1055, 1053, 1, 0, 0, 0, 1055, 1054, 1, 0, 0, 0, 1056, 1060, 1, 0, 0, 0, 1057, 1059, 3, 229, 107, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1062, 1, 0, 0, 0, 1060, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1073, 1, 0, 0, 0, 1062, 1060, 1, 0, 0, 0, 1063, 1066, 3, 81, 33, 0, 1064, 1066, 3, 75, 30, 0, 1065, 1063, 1, 0, 0, 0, 1065, 1064, 1, 0, 0, 0, 1066, 1068, 1, 0, 0, 0, 1067, 1069, 3, 229, 107, 0, 1068, 1067, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 1068, 1, 0, 0, 0, 1070, 1071, 1, 0, 0, 0, 1071, 1073, 1, 0, 0, 0, 1072, 1055, 1, 0, 0, 0, 1072, 1065, 1, 0, 0, 0, 1073, 232, 1, 0, 0, 0, 1074, 1077, 3, 231, 108, 0, 1075, 1077, 3, 171, 78, 0, 1076, 1074, 1, 0, 0, 0, 1076, 1075, 1, 0, 0, 0, 1077, 1078, 1, 0, 0, 0, 1078, 1076, 1, 0, 0, 0, 1078, 1079, 1, 0, 0, 0, 1079, 234, 1, 0, 0, 0, 1080, 1081, 3, 57, 21, 0, 1081, 1082, 1, 0, 0, 0, 1082, 1083, 6, 110, 10, 0, 1083, 236, 1, 0, 0, 0, 1084, 1085, 3, 59, 22, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 6, 111, 10, 0, 1087, 238, 1, 0, 0, 0, 1088, 1089, 3, 61, 23, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 112, 10, 0, 1091, 240, 1, 0, 0, 0, 1092, 1093, 3, 63, 24, 0, 1093, 1094, 1, 0, 0, 0, 1094, 1095, 6, 113, 15, 0, 1095, 1096, 6, 113, 11, 0, 1096, 242, 1, 0, 0, 0, 1097, 1098, 3, 97, 41, 0, 1098, 1099, 1, 0, 0, 0, 1099, 1100, 6, 114, 19, 0, 1100, 244, 1, 0, 0, 0, 1101, 1102, 3, 101, 43, 0, 1102, 1103, 1, 0, 0, 0, 1103, 1104, 6, 115, 18, 0, 1104, 246, 1, 0, 0, 0, 1105, 1106, 3, 105, 45, 0, 1106, 1107, 1, 0, 0, 0, 1107, 1108, 6, 116, 22, 0, 1108, 248, 1, 0, 0, 0, 1109, 1110, 3, 129, 57, 0, 1110, 1111, 1, 0, 0, 0, 1111, 1112, 6, 117, 23, 0, 1112, 250, 1, 0, 0, 0, 1113, 1114, 3, 163, 74, 0, 1114, 1115, 1, 0, 0, 0, 1115, 1116, 6, 118, 24, 0, 1116, 252, 1, 0, 0, 0, 1117, 1118, 7, 12, 0, 0, 1118, 1119, 7, 2, 0, 0, 1119, 254, 1, 0, 0, 0, 1120, 1121, 3, 233, 109, 0, 1121, 1122, 1, 0, 0, 0, 1122, 1123, 6, 120, 25, 0, 1123, 256, 1, 0, 0, 0, 1124, 1125, 3, 57, 21, 0, 1125, 1126, 1, 0, 0, 0, 1126, 1127, 6, 121, 10, 0, 1127, 258, 1, 0, 0, 0, 1128, 1129, 3, 59, 22, 0, 1129, 1130, 1, 0, 0, 0, 1130, 1131, 6, 122, 10, 0, 1131, 260, 1, 0, 0, 0, 1132, 1133, 3, 61, 23, 0, 1133, 1134, 1, 0, 0, 0, 1134, 1135, 6, 123, 10, 0, 1135, 262, 1, 0, 0, 0, 1136, 1137, 3, 63, 24, 0, 1137, 1138, 1, 0, 0, 0, 1138, 1139, 6, 124, 15, 0, 1139, 1140, 6, 124, 11, 0, 1140, 264, 1, 0, 0, 0, 1141, 1142, 3, 165, 75, 0, 1142, 1143, 1, 0, 0, 0, 1143, 1144, 6, 125, 13, 0, 1144, 1145, 6, 125, 26, 0, 1145, 266, 1, 0, 0, 0, 1146, 1147, 7, 7, 0, 0, 1147, 1148, 7, 9, 0, 0, 1148, 1149, 1, 0, 0, 0, 1149, 1150, 6, 126, 27, 0, 1150, 268, 1, 0, 0, 0, 1151, 1152, 7, 19, 0, 0, 1152, 1153, 7, 1, 0, 0, 1153, 1154, 7, 5, 0, 0, 1154, 1155, 7, 10, 0, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1157, 6, 127, 27, 0, 1157, 270, 1, 0, 0, 0, 1158, 1159, 8, 34, 0, 0, 1159, 272, 1, 0, 0, 0, 1160, 1162, 3, 271, 128, 0, 1161, 1160, 1, 0, 0, 0, 1162, 1163, 1, 0, 0, 0, 1163, 1161, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 1, 0, 0, 0, 1165, 1166, 3, 337, 161, 0, 1166, 1168, 1, 0, 0, 0, 1167, 1161, 1, 0, 0, 0, 1167, 1168, 1, 0, 0, 0, 1168, 1170, 1, 0, 0, 0, 1169, 1171, 3, 271, 128, 0, 1170, 1169, 1, 0, 0, 0, 1171, 1172, 1, 0, 0, 0, 1172, 1170, 1, 0, 0, 0, 1172, 1173, 1, 0, 0, 0, 1173, 274, 1, 0, 0, 0, 1174, 1175, 3, 273, 129, 0, 1175, 1176, 1, 0, 0, 0, 1176, 1177, 6, 130, 28, 0, 1177, 276, 1, 0, 0, 0, 1178, 1179, 3, 57, 21, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 6, 131, 10, 0, 1181, 278, 1, 0, 0, 0, 1182, 1183, 3, 59, 22, 0, 1183, 1184, 1, 0, 0, 0, 1184, 1185, 6, 132, 10, 0, 1185, 280, 1, 0, 0, 0, 1186, 1187, 3, 61, 23, 0, 1187, 1188, 1, 0, 0, 0, 1188, 1189, 6, 133, 10, 0, 1189, 282, 1, 0, 0, 0, 1190, 1191, 3, 63, 24, 0, 1191, 1192, 1, 0, 0, 0, 1192, 1193, 6, 134, 15, 0, 1193, 1194, 6, 134, 11, 0, 1194, 1195, 6, 134, 11, 0, 1195, 284, 1, 0, 0, 0, 1196, 1197, 3, 97, 41, 0, 1197, 1198, 1, 0, 0, 0, 1198, 1199, 6, 135, 19, 0, 1199, 286, 1, 0, 0, 0, 1200, 1201, 3, 101, 43, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 6, 136, 18, 0, 1203, 288, 1, 0, 0, 0, 1204, 1205, 3, 105, 45, 0, 1205, 1206, 1, 0, 0, 0, 1206, 1207, 6, 137, 22, 0, 1207, 290, 1, 0, 0, 0, 1208, 1209, 3, 269, 127, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 6, 138, 29, 0, 1211, 292, 1, 0, 0, 0, 1212, 1213, 3, 233, 109, 0, 1213, 1214, 1, 0, 0, 0, 1214, 1215, 6, 139, 25, 0, 1215, 294, 1, 0, 0, 0, 1216, 1217, 3, 173, 79, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1219, 6, 140, 30, 0, 1219, 296, 1, 0, 0, 0, 1220, 1221, 3, 129, 57, 0, 1221, 1222, 1, 0, 0, 0, 1222, 1223, 6, 141, 23, 0, 1223, 298, 1, 0, 0, 0, 1224, 1225, 3, 163, 74, 0, 1225, 1226, 1, 0, 0, 0, 1226, 1227, 6, 142, 24, 0, 1227, 300, 1, 0, 0, 0, 1228, 1229, 3, 57, 21, 0, 1229, 1230, 1, 0, 0, 0, 1230, 1231, 6, 143, 10, 0, 1231, 302, 1, 0, 0, 0, 1232, 1233, 3, 59, 22, 0, 1233, 1234, 1, 0, 0, 0, 1234, 1235, 6, 144, 10, 0, 1235, 304, 1, 0, 0, 0, 1236, 1237, 3, 61, 23, 0, 1237, 1238, 1, 0, 0, 0, 1238, 1239, 6, 145, 10, 0, 1239, 306, 1, 0, 0, 0, 1240, 1241, 3, 63, 24, 0, 1241, 1242, 1, 0, 0, 0, 1242, 1243, 6, 146, 15, 0, 1243, 1244, 6, 146, 11, 0, 1244, 308, 1, 0, 0, 0, 1245, 1246, 3, 105, 45, 0, 1246, 1247, 1, 0, 0, 0, 1247, 1248, 6, 147, 22, 0, 1248, 310, 1, 0, 0, 0, 1249, 1250, 3, 129, 57, 0, 1250, 1251, 1, 0, 0, 0, 1251, 1252, 6, 148, 23, 0, 1252, 312, 1, 0, 0, 0, 1253, 1254, 3, 163, 74, 0, 1254, 1255, 1, 0, 0, 0, 1255, 1256, 6, 149, 24, 0, 1256, 314, 1, 0, 0, 0, 1257, 1258, 3, 173, 79, 0, 1258, 1259, 1, 0, 0, 0, 1259, 1260, 6, 150, 30, 0, 1260, 316, 1, 0, 0, 0, 1261, 1262, 3, 169, 77, 0, 1262, 1263, 1, 0, 0, 0, 1263, 1264, 6, 151, 31, 0, 1264, 318, 1, 0, 0, 0, 1265, 1266, 3, 57, 21, 0, 1266, 1267, 1, 0, 0, 0, 1267, 1268, 6, 152, 10, 0, 1268, 320, 1, 0, 0, 0, 1269, 1270, 3, 59, 22, 0, 1270, 1271, 1, 0, 0, 0, 1271, 1272, 6, 153, 10, 0, 1272, 322, 1, 0, 0, 0, 1273, 1274, 3, 61, 23, 0, 1274, 1275, 1, 0, 0, 0, 1275, 1276, 6, 154, 10, 0, 1276, 324, 1, 0, 0, 0, 1277, 1278, 3, 63, 24, 0, 1278, 1279, 1, 0, 0, 0, 1279, 1280, 6, 155, 15, 0, 1280, 1281, 6, 155, 11, 0, 1281, 326, 1, 0, 0, 0, 1282, 1283, 7, 1, 0, 0, 1283, 1284, 7, 9, 0, 0, 1284, 1285, 7, 15, 0, 0, 1285, 1286, 7, 7, 0, 0, 1286, 328, 1, 0, 0, 0, 1287, 1288, 3, 57, 21, 0, 1288, 1289, 1, 0, 0, 0, 1289, 1290, 6, 157, 10, 0, 1290, 330, 1, 0, 0, 0, 1291, 1292, 3, 59, 22, 0, 1292, 1293, 1, 0, 0, 0, 1293, 1294, 6, 158, 10, 0, 1294, 332, 1, 0, 0, 0, 1295, 1296, 3, 61, 23, 0, 1296, 1297, 1, 0, 0, 0, 1297, 1298, 6, 159, 10, 0, 1298, 334, 1, 0, 0, 0, 1299, 1300, 3, 167, 76, 0, 1300, 1301, 1, 0, 0, 0, 1301, 1302, 6, 160, 16, 0, 1302, 1303, 6, 160, 11, 0, 1303, 336, 1, 0, 0, 0, 1304, 1305, 5, 58, 0, 0, 1305, 338, 1, 0, 0, 0, 1306, 1312, 3, 75, 30, 0, 1307, 1312, 3, 65, 25, 0, 1308, 1312, 3, 105, 45, 0, 1309, 1312, 3, 67, 26, 0, 1310, 1312, 3, 81, 33, 0, 1311, 1306, 1, 0, 0, 0, 1311, 1307, 1, 0, 0, 0, 1311, 1308, 1, 0, 0, 0, 1311, 1309, 1, 0, 0, 0, 1311, 1310, 1, 0, 0, 0, 1312, 1313, 1, 0, 0, 0, 1313, 1311, 1, 0, 0, 0, 1313, 1314, 1, 0, 0, 0, 1314, 340, 1, 0, 0, 0, 1315, 1316, 3, 57, 21, 0, 1316, 1317, 1, 0, 0, 0, 1317, 1318, 6, 163, 10, 0, 1318, 342, 1, 0, 0, 0, 1319, 1320, 3, 59, 22, 0, 1320, 1321, 1, 0, 0, 0, 1321, 1322, 6, 164, 10, 0, 1322, 344, 1, 0, 0, 0, 1323, 1324, 3, 61, 23, 0, 1324, 1325, 1, 0, 0, 0, 1325, 1326, 6, 165, 10, 0, 1326, 346, 1, 0, 0, 0, 1327, 1328, 3, 63, 24, 0, 1328, 1329, 1, 0, 0, 0, 1329, 1330, 6, 166, 15, 0, 1330, 1331, 6, 166, 11, 0, 1331, 348, 1, 0, 0, 0, 1332, 1333, 3, 337, 161, 0, 1333, 1334, 1, 0, 0, 0, 1334, 1335, 6, 167, 17, 0, 1335, 350, 1, 0, 0, 0, 1336, 1337, 3, 101, 43, 0, 1337, 1338, 1, 0, 0, 0, 1338, 1339, 6, 168, 18, 0, 1339, 352, 1, 0, 0, 0, 1340, 1341, 3, 105, 45, 0, 1341, 1342, 1, 0, 0, 0, 1342, 1343, 6, 169, 22, 0, 1343, 354, 1, 0, 0, 0, 1344, 1345, 3, 267, 126, 0, 1345, 1346, 1, 0, 0, 0, 1346, 1347, 6, 170, 32, 0, 1347, 1348, 6, 170, 33, 0, 1348, 356, 1, 0, 0, 0, 1349, 1350, 3, 207, 96, 0, 1350, 1351, 1, 0, 0, 0, 1351, 1352, 6, 171, 20, 0, 1352, 358, 1, 0, 0, 0, 1353, 1354, 3, 85, 35, 0, 1354, 1355, 1, 0, 0, 0, 1355, 1356, 6, 172, 21, 0, 1356, 360, 1, 0, 0, 0, 1357, 1358, 3, 57, 21, 0, 1358, 1359, 1, 0, 0, 0, 1359, 1360, 6, 173, 10, 0, 1360, 362, 1, 0, 0, 0, 1361, 1362, 3, 59, 22, 0, 1362, 1363, 1, 0, 0, 0, 1363, 1364, 6, 174, 10, 0, 1364, 364, 1, 0, 0, 0, 1365, 1366, 3, 61, 23, 0, 1366, 1367, 1, 0, 0, 0, 1367, 1368, 6, 175, 10, 0, 1368, 366, 1, 0, 0, 0, 1369, 1370, 3, 63, 24, 0, 1370, 1371, 1, 0, 0, 0, 1371, 1372, 6, 176, 15, 0, 1372, 1373, 6, 176, 11, 0, 1373, 1374, 6, 176, 11, 0, 1374, 368, 1, 0, 0, 0, 1375, 1376, 3, 101, 43, 0, 1376, 1377, 1, 0, 0, 0, 1377, 1378, 6, 177, 18, 0, 1378, 370, 1, 0, 0, 0, 1379, 1380, 3, 105, 45, 0, 1380, 1381, 1, 0, 0, 0, 1381, 1382, 6, 178, 22, 0, 1382, 372, 1, 0, 0, 0, 1383, 1384, 3, 233, 109, 0, 1384, 1385, 1, 0, 0, 0, 1385, 1386, 6, 179, 25, 0, 1386, 374, 1, 0, 0, 0, 1387, 1388, 3, 57, 21, 0, 1388, 1389, 1, 0, 0, 0, 1389, 1390, 6, 180, 10, 0, 1390, 376, 1, 0, 0, 0, 1391, 1392, 3, 59, 22, 0, 1392, 1393, 1, 0, 0, 0, 1393, 1394, 6, 181, 10, 0, 1394, 378, 1, 0, 0, 0, 1395, 1396, 3, 61, 23, 0, 1396, 1397, 1, 0, 0, 0, 1397, 1398, 6, 182, 10, 0, 1398, 380, 1, 0, 0, 0, 1399, 1400, 3, 63, 24, 0, 1400, 1401, 1, 0, 0, 0, 1401, 1402, 6, 183, 15, 0, 1402, 1403, 6, 183, 11, 0, 1403, 382, 1, 0, 0, 0, 1404, 1405, 3, 207, 96, 0, 1405, 1406, 1, 0, 0, 0, 1406, 1407, 6, 184, 20, 0, 1407, 1408, 6, 184, 11, 0, 1408, 1409, 6, 184, 34, 0, 1409, 384, 1, 0, 0, 0, 1410, 1411, 3, 85, 35, 0, 1411, 1412, 1, 0, 0, 0, 1412, 1413, 6, 185, 21, 0, 1413, 1414, 6, 185, 11, 0, 1414, 1415, 6, 185, 34, 0, 1415, 386, 1, 0, 0, 0, 1416, 1417, 3, 57, 21, 0, 1417, 1418, 1, 0, 0, 0, 1418, 1419, 6, 186, 10, 0, 1419, 388, 1, 0, 0, 0, 1420, 1421, 3, 59, 22, 0, 1421, 1422, 1, 0, 0, 0, 1422, 1423, 6, 187, 10, 0, 1423, 390, 1, 0, 0, 0, 1424, 1425, 3, 61, 23, 0, 1425, 1426, 1, 0, 0, 0, 1426, 1427, 6, 188, 10, 0, 1427, 392, 1, 0, 0, 0, 1428, 1429, 3, 337, 161, 0, 1429, 1430, 1, 0, 0, 0, 1430, 1431, 6, 189, 17, 0, 1431, 1432, 6, 189, 11, 0, 1432, 1433, 6, 189, 9, 0, 1433, 394, 1, 0, 0, 0, 1434, 1435, 3, 101, 43, 0, 1435, 1436, 1, 0, 0, 0, 1436, 1437, 6, 190, 18, 0, 1437, 1438, 6, 190, 11, 0, 1438, 1439, 6, 190, 9, 0, 1439, 396, 1, 0, 0, 0, 1440, 1441, 3, 57, 21, 0, 1441, 1442, 1, 0, 0, 0, 1442, 1443, 6, 191, 10, 0, 1443, 398, 1, 0, 0, 0, 1444, 1445, 3, 59, 22, 0, 1445, 1446, 1, 0, 0, 0, 1446, 1447, 6, 192, 10, 0, 1447, 400, 1, 0, 0, 0, 1448, 1449, 3, 61, 23, 0, 1449, 1450, 1, 0, 0, 0, 1450, 1451, 6, 193, 10, 0, 1451, 402, 1, 0, 0, 0, 1452, 1453, 3, 173, 79, 0, 1453, 1454, 1, 0, 0, 0, 1454, 1455, 6, 194, 11, 0, 1455, 1456, 6, 194, 0, 0, 1456, 1457, 6, 194, 30, 0, 1457, 404, 1, 0, 0, 0, 1458, 1459, 3, 169, 77, 0, 1459, 1460, 1, 0, 0, 0, 1460, 1461, 6, 195, 11, 0, 1461, 1462, 6, 195, 0, 0, 1462, 1463, 6, 195, 31, 0, 1463, 406, 1, 0, 0, 0, 1464, 1465, 3, 91, 38, 0, 1465, 1466, 1, 0, 0, 0, 1466, 1467, 6, 196, 11, 0, 1467, 1468, 6, 196, 0, 0, 1468, 1469, 6, 196, 35, 0, 1469, 408, 1, 0, 0, 0, 1470, 1471, 3, 63, 24, 0, 1471, 1472, 1, 0, 0, 0, 1472, 1473, 6, 197, 15, 0, 1473, 1474, 6, 197, 11, 0, 1474, 410, 1, 0, 0, 0, 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 588, 598, 602, 605, 614, 616, 627, 646, 651, 660, 667, 672, 674, 685, 693, 696, 698, 703, 708, 714, 721, 726, 732, 735, 743, 747, 874, 879, 886, 888, 904, 909, 914, 916, 922, 999, 1004, 1051, 1055, 1060, 1065, 1070, 1072, 1076, 1078, 1163, 1167, 1172, 1311, 1313, 36, 5, 1, 0, 5, 4, 0, 5, 6, 0, 5, 2, 0, 5, 3, 0, 5, 8, 0, 5, 5, 0, 5, 9, 0, 5, 11, 0, 5, 13, 0, 0, 1, 0, 4, 0, 0, 7, 19, 0, 7, 65, 0, 5, 0, 0, 7, 25, 0, 7, 66, 0, 7, 104, 0, 7, 34, 0, 7, 32, 0, 7, 76, 0, 7, 26, 0, 7, 36, 0, 7, 48, 0, 7, 64, 0, 7, 80, 0, 5, 10, 0, 5, 7, 0, 7, 90, 0, 7, 89, 0, 7, 68, 0, 7, 67, 0, 7, 88, 0, 5, 12, 0, 5, 14, 0, 7, 29, 0]
\ No newline at end of file
+[4, 0, 120, 1466, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 2, 196, 7, 196, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 4, 19, 576, 8, 19, 11, 19, 12, 19, 577, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 5, 20, 586, 8, 20, 10, 20, 12, 20, 589, 9, 20, 1, 20, 3, 20, 592, 8, 20, 1, 20, 3, 20, 595, 8, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 604, 8, 21, 10, 21, 12, 21, 607, 9, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 4, 22, 615, 8, 22, 11, 22, 12, 22, 616, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 3, 28, 636, 8, 28, 1, 28, 4, 28, 639, 8, 28, 11, 28, 12, 28, 640, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 3, 31, 650, 8, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 3, 33, 657, 8, 33, 1, 34, 1, 34, 1, 34, 5, 34, 662, 8, 34, 10, 34, 12, 34, 665, 9, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 5, 34, 673, 8, 34, 10, 34, 12, 34, 676, 9, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 683, 8, 34, 1, 34, 3, 34, 686, 8, 34, 3, 34, 688, 8, 34, 1, 35, 4, 35, 691, 8, 35, 11, 35, 12, 35, 692, 1, 36, 4, 36, 696, 8, 36, 11, 36, 12, 36, 697, 1, 36, 1, 36, 5, 36, 702, 8, 36, 10, 36, 12, 36, 705, 9, 36, 1, 36, 1, 36, 4, 36, 709, 8, 36, 11, 36, 12, 36, 710, 1, 36, 4, 36, 714, 8, 36, 11, 36, 12, 36, 715, 1, 36, 1, 36, 5, 36, 720, 8, 36, 10, 36, 12, 36, 723, 9, 36, 3, 36, 725, 8, 36, 1, 36, 1, 36, 1, 36, 1, 36, 4, 36, 731, 8, 36, 11, 36, 12, 36, 732, 1, 36, 1, 36, 3, 36, 737, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 3, 73, 866, 8, 73, 1, 73, 5, 73, 869, 8, 73, 10, 73, 12, 73, 872, 9, 73, 1, 73, 1, 73, 4, 73, 876, 8, 73, 11, 73, 12, 73, 877, 3, 73, 880, 8, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 5, 76, 894, 8, 76, 10, 76, 12, 76, 897, 9, 76, 1, 76, 1, 76, 3, 76, 901, 8, 76, 1, 76, 4, 76, 904, 8, 76, 11, 76, 12, 76, 905, 3, 76, 908, 8, 76, 1, 77, 1, 77, 4, 77, 912, 8, 77, 11, 77, 12, 77, 913, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 3, 94, 991, 8, 94, 1, 95, 4, 95, 994, 8, 95, 11, 95, 12, 95, 995, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 3, 106, 1043, 8, 106, 1, 107, 1, 107, 3, 107, 1047, 8, 107, 1, 107, 5, 107, 1050, 8, 107, 10, 107, 12, 107, 1053, 9, 107, 1, 107, 1, 107, 3, 107, 1057, 8, 107, 1, 107, 4, 107, 1060, 8, 107, 11, 107, 12, 107, 1061, 3, 107, 1064, 8, 107, 1, 108, 1, 108, 4, 108, 1068, 8, 108, 11, 108, 12, 108, 1069, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 1, 122, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 128, 4, 128, 1153, 8, 128, 11, 128, 12, 128, 1154, 1, 128, 1, 128, 3, 128, 1159, 8, 128, 1, 128, 4, 128, 1162, 8, 128, 11, 128, 12, 128, 1163, 1, 129, 1, 129, 1, 129, 1, 129, 1, 130, 1, 130, 1, 130, 1, 130, 1, 131, 1, 131, 1, 131, 1, 131, 1, 132, 1, 132, 1, 132, 1, 132, 1, 133, 1, 133, 1, 133, 1, 133, 1, 133, 1, 133, 1, 134, 1, 134, 1, 134, 1, 134, 1, 135, 1, 135, 1, 135, 1, 135, 1, 136, 1, 136, 1, 136, 1, 136, 1, 137, 1, 137, 1, 137, 1, 137, 1, 138, 1, 138, 1, 138, 1, 138, 1, 139, 1, 139, 1, 139, 1, 139, 1, 140, 1, 140, 1, 140, 1, 140, 1, 141, 1, 141, 1, 141, 1, 141, 1, 142, 1, 142, 1, 142, 1, 142, 1, 143, 1, 143, 1, 143, 1, 143, 1, 144, 1, 144, 1, 144, 1, 144, 1, 145, 1, 145, 1, 145, 1, 145, 1, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 1, 158, 1, 159, 1, 159, 1, 159, 1, 159, 1, 159, 1, 160, 1, 160, 1, 161, 1, 161, 1, 161, 1, 161, 1, 161, 4, 161, 1303, 8, 161, 11, 161, 12, 161, 1304, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 178, 1, 178, 1, 178, 1, 178, 1, 179, 1, 179, 1, 179, 1, 179, 1, 180, 1, 180, 1, 180, 1, 180, 1, 181, 1, 181, 1, 181, 1, 181, 1, 182, 1, 182, 1, 182, 1, 182, 1, 182, 1, 183, 1, 183, 1, 183, 1, 183, 1, 183, 1, 183, 1, 184, 1, 184, 1, 184, 1, 184, 1, 184, 1, 184, 1, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 1, 187, 1, 187, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 188, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 189, 1, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 193, 1, 193, 1, 193, 1, 193, 1, 193, 1, 193, 1, 194, 1, 194, 1, 194, 1, 194, 1, 194, 1, 194, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 195, 1, 196, 1, 196, 1, 196, 1, 196, 1, 196, 2, 605, 674, 0, 197, 15, 1, 17, 2, 19, 3, 21, 4, 23, 5, 25, 6, 27, 7, 29, 8, 31, 9, 33, 10, 35, 11, 37, 12, 39, 13, 41, 14, 43, 15, 45, 16, 47, 17, 49, 18, 51, 19, 53, 20, 55, 21, 57, 22, 59, 23, 61, 24, 63, 0, 65, 0, 67, 0, 69, 0, 71, 0, 73, 0, 75, 0, 77, 0, 79, 0, 81, 0, 83, 25, 85, 26, 87, 27, 89, 28, 91, 29, 93, 30, 95, 31, 97, 32, 99, 33, 101, 34, 103, 35, 105, 36, 107, 37, 109, 38, 111, 39, 113, 40, 115, 41, 117, 42, 119, 43, 121, 44, 123, 45, 125, 46, 127, 47, 129, 48, 131, 49, 133, 50, 135, 51, 137, 52, 139, 53, 141, 54, 143, 55, 145, 56, 147, 57, 149, 58, 151, 59, 153, 60, 155, 61, 157, 62, 159, 63, 161, 64, 163, 65, 165, 66, 167, 67, 169, 0, 171, 68, 173, 69, 175, 70, 177, 71, 179, 0, 181, 0, 183, 72, 185, 73, 187, 74, 189, 0, 191, 0, 193, 0, 195, 0, 197, 0, 199, 0, 201, 75, 203, 0, 205, 76, 207, 0, 209, 0, 211, 77, 213, 78, 215, 79, 217, 0, 219, 0, 221, 0, 223, 0, 225, 0, 227, 0, 229, 0, 231, 80, 233, 81, 235, 82, 237, 83, 239, 0, 241, 0, 243, 0, 245, 0, 247, 0, 249, 0, 251, 84, 253, 0, 255, 85, 257, 86, 259, 87, 261, 0, 263, 0, 265, 88, 267, 89, 269, 0, 271, 90, 273, 0, 275, 91, 277, 92, 279, 93, 281, 0, 283, 0, 285, 0, 287, 0, 289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 94, 301, 95, 303, 96, 305, 0, 307, 0, 309, 0, 311, 0, 313, 0, 315, 0, 317, 97, 319, 98, 321, 99, 323, 0, 325, 100, 327, 101, 329, 102, 331, 103, 333, 0, 335, 104, 337, 105, 339, 106, 341, 107, 343, 108, 345, 0, 347, 0, 349, 0, 351, 0, 353, 0, 355, 0, 357, 0, 359, 109, 361, 110, 363, 111, 365, 0, 367, 0, 369, 0, 371, 0, 373, 112, 375, 113, 377, 114, 379, 0, 381, 0, 383, 0, 385, 115, 387, 116, 389, 117, 391, 0, 393, 0, 395, 118, 397, 119, 399, 120, 401, 0, 403, 0, 405, 0, 407, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 35, 2, 0, 68, 68, 100, 100, 2, 0, 73, 73, 105, 105, 2, 0, 83, 83, 115, 115, 2, 0, 69, 69, 101, 101, 2, 0, 67, 67, 99, 99, 2, 0, 84, 84, 116, 116, 2, 0, 82, 82, 114, 114, 2, 0, 79, 79, 111, 111, 2, 0, 80, 80, 112, 112, 2, 0, 78, 78, 110, 110, 2, 0, 72, 72, 104, 104, 2, 0, 86, 86, 118, 118, 2, 0, 65, 65, 97, 97, 2, 0, 76, 76, 108, 108, 2, 0, 88, 88, 120, 120, 2, 0, 70, 70, 102, 102, 2, 0, 77, 77, 109, 109, 2, 0, 71, 71, 103, 103, 2, 0, 75, 75, 107, 107, 2, 0, 87, 87, 119, 119, 2, 0, 85, 85, 117, 117, 6, 0, 9, 10, 13, 13, 32, 32, 47, 47, 91, 91, 93, 93, 2, 0, 10, 10, 13, 13, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 2, 0, 65, 90, 97, 122, 8, 0, 34, 34, 78, 78, 82, 82, 84, 84, 92, 92, 110, 110, 114, 114, 116, 116, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 2, 0, 43, 43, 45, 45, 1, 0, 96, 96, 2, 0, 66, 66, 98, 98, 2, 0, 89, 89, 121, 121, 11, 0, 9, 10, 13, 13, 32, 32, 34, 34, 44, 44, 47, 47, 58, 58, 61, 61, 91, 91, 93, 93, 124, 124, 2, 0, 42, 42, 47, 47, 11, 0, 9, 10, 13, 13, 32, 32, 34, 35, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1494, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 1, 61, 1, 0, 0, 0, 1, 83, 1, 0, 0, 0, 1, 85, 1, 0, 0, 0, 1, 87, 1, 0, 0, 0, 1, 89, 1, 0, 0, 0, 1, 91, 1, 0, 0, 0, 1, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, 1, 97, 1, 0, 0, 0, 1, 99, 1, 0, 0, 0, 1, 101, 1, 0, 0, 0, 1, 103, 1, 0, 0, 0, 1, 105, 1, 0, 0, 0, 1, 107, 1, 0, 0, 0, 1, 109, 1, 0, 0, 0, 1, 111, 1, 0, 0, 0, 1, 113, 1, 0, 0, 0, 1, 115, 1, 0, 0, 0, 1, 117, 1, 0, 0, 0, 1, 119, 1, 0, 0, 0, 1, 121, 1, 0, 0, 0, 1, 123, 1, 0, 0, 0, 1, 125, 1, 0, 0, 0, 1, 127, 1, 0, 0, 0, 1, 129, 1, 0, 0, 0, 1, 131, 1, 0, 0, 0, 1, 133, 1, 0, 0, 0, 1, 135, 1, 0, 0, 0, 1, 137, 1, 0, 0, 0, 1, 139, 1, 0, 0, 0, 1, 141, 1, 0, 0, 0, 1, 143, 1, 0, 0, 0, 1, 145, 1, 0, 0, 0, 1, 147, 1, 0, 0, 0, 1, 149, 1, 0, 0, 0, 1, 151, 1, 0, 0, 0, 1, 153, 1, 0, 0, 0, 1, 155, 1, 0, 0, 0, 1, 157, 1, 0, 0, 0, 1, 159, 1, 0, 0, 0, 1, 161, 1, 0, 0, 0, 1, 163, 1, 0, 0, 0, 1, 165, 1, 0, 0, 0, 1, 167, 1, 0, 0, 0, 1, 171, 1, 0, 0, 0, 1, 173, 1, 0, 0, 0, 1, 175, 1, 0, 0, 0, 1, 177, 1, 0, 0, 0, 2, 179, 1, 0, 0, 0, 2, 181, 1, 0, 0, 0, 2, 183, 1, 0, 0, 0, 2, 185, 1, 0, 0, 0, 2, 187, 1, 0, 0, 0, 3, 189, 1, 0, 0, 0, 3, 191, 1, 0, 0, 0, 3, 193, 1, 0, 0, 0, 3, 195, 1, 0, 0, 0, 3, 197, 1, 0, 0, 0, 3, 199, 1, 0, 0, 0, 3, 201, 1, 0, 0, 0, 3, 205, 1, 0, 0, 0, 3, 207, 1, 0, 0, 0, 3, 209, 1, 0, 0, 0, 3, 211, 1, 0, 0, 0, 3, 213, 1, 0, 0, 0, 3, 215, 1, 0, 0, 0, 4, 217, 1, 0, 0, 0, 4, 219, 1, 0, 0, 0, 4, 221, 1, 0, 0, 0, 4, 223, 1, 0, 0, 0, 4, 225, 1, 0, 0, 0, 4, 231, 1, 0, 0, 0, 4, 233, 1, 0, 0, 0, 4, 235, 1, 0, 0, 0, 4, 237, 1, 0, 0, 0, 5, 239, 1, 0, 0, 0, 5, 241, 1, 0, 0, 0, 5, 243, 1, 0, 0, 0, 5, 245, 1, 0, 0, 0, 5, 247, 1, 0, 0, 0, 5, 249, 1, 0, 0, 0, 5, 251, 1, 0, 0, 0, 5, 253, 1, 0, 0, 0, 5, 255, 1, 0, 0, 0, 5, 257, 1, 0, 0, 0, 5, 259, 1, 0, 0, 0, 6, 261, 1, 0, 0, 0, 6, 263, 1, 0, 0, 0, 6, 265, 1, 0, 0, 0, 6, 267, 1, 0, 0, 0, 6, 271, 1, 0, 0, 0, 6, 273, 1, 0, 0, 0, 6, 275, 1, 0, 0, 0, 6, 277, 1, 0, 0, 0, 6, 279, 1, 0, 0, 0, 7, 281, 1, 0, 0, 0, 7, 283, 1, 0, 0, 0, 7, 285, 1, 0, 0, 0, 7, 287, 1, 0, 0, 0, 7, 289, 1, 0, 0, 0, 7, 291, 1, 0, 0, 0, 7, 293, 1, 0, 0, 0, 7, 295, 1, 0, 0, 0, 7, 297, 1, 0, 0, 0, 7, 299, 1, 0, 0, 0, 7, 301, 1, 0, 0, 0, 7, 303, 1, 0, 0, 0, 8, 305, 1, 0, 0, 0, 8, 307, 1, 0, 0, 0, 8, 309, 1, 0, 0, 0, 8, 311, 1, 0, 0, 0, 8, 313, 1, 0, 0, 0, 8, 315, 1, 0, 0, 0, 8, 317, 1, 0, 0, 0, 8, 319, 1, 0, 0, 0, 8, 321, 1, 0, 0, 0, 9, 323, 1, 0, 0, 0, 9, 325, 1, 0, 0, 0, 9, 327, 1, 0, 0, 0, 9, 329, 1, 0, 0, 0, 9, 331, 1, 0, 0, 0, 10, 333, 1, 0, 0, 0, 10, 335, 1, 0, 0, 0, 10, 337, 1, 0, 0, 0, 10, 339, 1, 0, 0, 0, 10, 341, 1, 0, 0, 0, 10, 343, 1, 0, 0, 0, 11, 345, 1, 0, 0, 0, 11, 347, 1, 0, 0, 0, 11, 349, 1, 0, 0, 0, 11, 351, 1, 0, 0, 0, 11, 353, 1, 0, 0, 0, 11, 355, 1, 0, 0, 0, 11, 357, 1, 0, 0, 0, 11, 359, 1, 0, 0, 0, 11, 361, 1, 0, 0, 0, 11, 363, 1, 0, 0, 0, 12, 365, 1, 0, 0, 0, 12, 367, 1, 0, 0, 0, 12, 369, 1, 0, 0, 0, 12, 371, 1, 0, 0, 0, 12, 373, 1, 0, 0, 0, 12, 375, 1, 0, 0, 0, 12, 377, 1, 0, 0, 0, 13, 379, 1, 0, 0, 0, 13, 381, 1, 0, 0, 0, 13, 383, 1, 0, 0, 0, 13, 385, 1, 0, 0, 0, 13, 387, 1, 0, 0, 0, 13, 389, 1, 0, 0, 0, 14, 391, 1, 0, 0, 0, 14, 393, 1, 0, 0, 0, 14, 395, 1, 0, 0, 0, 14, 397, 1, 0, 0, 0, 14, 399, 1, 0, 0, 0, 14, 401, 1, 0, 0, 0, 14, 403, 1, 0, 0, 0, 14, 405, 1, 0, 0, 0, 14, 407, 1, 0, 0, 0, 15, 409, 1, 0, 0, 0, 17, 419, 1, 0, 0, 0, 19, 426, 1, 0, 0, 0, 21, 435, 1, 0, 0, 0, 23, 442, 1, 0, 0, 0, 25, 452, 1, 0, 0, 0, 27, 459, 1, 0, 0, 0, 29, 466, 1, 0, 0, 0, 31, 473, 1, 0, 0, 0, 33, 481, 1, 0, 0, 0, 35, 493, 1, 0, 0, 0, 37, 502, 1, 0, 0, 0, 39, 508, 1, 0, 0, 0, 41, 515, 1, 0, 0, 0, 43, 522, 1, 0, 0, 0, 45, 530, 1, 0, 0, 0, 47, 538, 1, 0, 0, 0, 49, 553, 1, 0, 0, 0, 51, 563, 1, 0, 0, 0, 53, 575, 1, 0, 0, 0, 55, 581, 1, 0, 0, 0, 57, 598, 1, 0, 0, 0, 59, 614, 1, 0, 0, 0, 61, 620, 1, 0, 0, 0, 63, 624, 1, 0, 0, 0, 65, 626, 1, 0, 0, 0, 67, 628, 1, 0, 0, 0, 69, 631, 1, 0, 0, 0, 71, 633, 1, 0, 0, 0, 73, 642, 1, 0, 0, 0, 75, 644, 1, 0, 0, 0, 77, 649, 1, 0, 0, 0, 79, 651, 1, 0, 0, 0, 81, 656, 1, 0, 0, 0, 83, 687, 1, 0, 0, 0, 85, 690, 1, 0, 0, 0, 87, 736, 1, 0, 0, 0, 89, 738, 1, 0, 0, 0, 91, 741, 1, 0, 0, 0, 93, 745, 1, 0, 0, 0, 95, 749, 1, 0, 0, 0, 97, 751, 1, 0, 0, 0, 99, 754, 1, 0, 0, 0, 101, 756, 1, 0, 0, 0, 103, 761, 1, 0, 0, 0, 105, 763, 1, 0, 0, 0, 107, 769, 1, 0, 0, 0, 109, 775, 1, 0, 0, 0, 111, 778, 1, 0, 0, 0, 113, 781, 1, 0, 0, 0, 115, 786, 1, 0, 0, 0, 117, 791, 1, 0, 0, 0, 119, 793, 1, 0, 0, 0, 121, 797, 1, 0, 0, 0, 123, 802, 1, 0, 0, 0, 125, 808, 1, 0, 0, 0, 127, 811, 1, 0, 0, 0, 129, 813, 1, 0, 0, 0, 131, 819, 1, 0, 0, 0, 133, 821, 1, 0, 0, 0, 135, 826, 1, 0, 0, 0, 137, 829, 1, 0, 0, 0, 139, 832, 1, 0, 0, 0, 141, 835, 1, 0, 0, 0, 143, 837, 1, 0, 0, 0, 145, 840, 1, 0, 0, 0, 147, 842, 1, 0, 0, 0, 149, 845, 1, 0, 0, 0, 151, 847, 1, 0, 0, 0, 153, 849, 1, 0, 0, 0, 155, 851, 1, 0, 0, 0, 157, 853, 1, 0, 0, 0, 159, 855, 1, 0, 0, 0, 161, 879, 1, 0, 0, 0, 163, 881, 1, 0, 0, 0, 165, 886, 1, 0, 0, 0, 167, 907, 1, 0, 0, 0, 169, 909, 1, 0, 0, 0, 171, 917, 1, 0, 0, 0, 173, 919, 1, 0, 0, 0, 175, 923, 1, 0, 0, 0, 177, 927, 1, 0, 0, 0, 179, 931, 1, 0, 0, 0, 181, 936, 1, 0, 0, 0, 183, 941, 1, 0, 0, 0, 185, 945, 1, 0, 0, 0, 187, 949, 1, 0, 0, 0, 189, 953, 1, 0, 0, 0, 191, 958, 1, 0, 0, 0, 193, 962, 1, 0, 0, 0, 195, 966, 1, 0, 0, 0, 197, 970, 1, 0, 0, 0, 199, 974, 1, 0, 0, 0, 201, 978, 1, 0, 0, 0, 203, 990, 1, 0, 0, 0, 205, 993, 1, 0, 0, 0, 207, 997, 1, 0, 0, 0, 209, 1001, 1, 0, 0, 0, 211, 1005, 1, 0, 0, 0, 213, 1009, 1, 0, 0, 0, 215, 1013, 1, 0, 0, 0, 217, 1017, 1, 0, 0, 0, 219, 1022, 1, 0, 0, 0, 221, 1026, 1, 0, 0, 0, 223, 1030, 1, 0, 0, 0, 225, 1034, 1, 0, 0, 0, 227, 1042, 1, 0, 0, 0, 229, 1063, 1, 0, 0, 0, 231, 1067, 1, 0, 0, 0, 233, 1071, 1, 0, 0, 0, 235, 1075, 1, 0, 0, 0, 237, 1079, 1, 0, 0, 0, 239, 1083, 1, 0, 0, 0, 241, 1088, 1, 0, 0, 0, 243, 1092, 1, 0, 0, 0, 245, 1096, 1, 0, 0, 0, 247, 1100, 1, 0, 0, 0, 249, 1104, 1, 0, 0, 0, 251, 1108, 1, 0, 0, 0, 253, 1111, 1, 0, 0, 0, 255, 1115, 1, 0, 0, 0, 257, 1119, 1, 0, 0, 0, 259, 1123, 1, 0, 0, 0, 261, 1127, 1, 0, 0, 0, 263, 1132, 1, 0, 0, 0, 265, 1137, 1, 0, 0, 0, 267, 1142, 1, 0, 0, 0, 269, 1149, 1, 0, 0, 0, 271, 1158, 1, 0, 0, 0, 273, 1165, 1, 0, 0, 0, 275, 1169, 1, 0, 0, 0, 277, 1173, 1, 0, 0, 0, 279, 1177, 1, 0, 0, 0, 281, 1181, 1, 0, 0, 0, 283, 1187, 1, 0, 0, 0, 285, 1191, 1, 0, 0, 0, 287, 1195, 1, 0, 0, 0, 289, 1199, 1, 0, 0, 0, 291, 1203, 1, 0, 0, 0, 293, 1207, 1, 0, 0, 0, 295, 1211, 1, 0, 0, 0, 297, 1215, 1, 0, 0, 0, 299, 1219, 1, 0, 0, 0, 301, 1223, 1, 0, 0, 0, 303, 1227, 1, 0, 0, 0, 305, 1231, 1, 0, 0, 0, 307, 1236, 1, 0, 0, 0, 309, 1240, 1, 0, 0, 0, 311, 1244, 1, 0, 0, 0, 313, 1248, 1, 0, 0, 0, 315, 1252, 1, 0, 0, 0, 317, 1256, 1, 0, 0, 0, 319, 1260, 1, 0, 0, 0, 321, 1264, 1, 0, 0, 0, 323, 1268, 1, 0, 0, 0, 325, 1273, 1, 0, 0, 0, 327, 1278, 1, 0, 0, 0, 329, 1282, 1, 0, 0, 0, 331, 1286, 1, 0, 0, 0, 333, 1290, 1, 0, 0, 0, 335, 1295, 1, 0, 0, 0, 337, 1302, 1, 0, 0, 0, 339, 1306, 1, 0, 0, 0, 341, 1310, 1, 0, 0, 0, 343, 1314, 1, 0, 0, 0, 345, 1318, 1, 0, 0, 0, 347, 1323, 1, 0, 0, 0, 349, 1327, 1, 0, 0, 0, 351, 1331, 1, 0, 0, 0, 353, 1335, 1, 0, 0, 0, 355, 1340, 1, 0, 0, 0, 357, 1344, 1, 0, 0, 0, 359, 1348, 1, 0, 0, 0, 361, 1352, 1, 0, 0, 0, 363, 1356, 1, 0, 0, 0, 365, 1360, 1, 0, 0, 0, 367, 1366, 1, 0, 0, 0, 369, 1370, 1, 0, 0, 0, 371, 1374, 1, 0, 0, 0, 373, 1378, 1, 0, 0, 0, 375, 1382, 1, 0, 0, 0, 377, 1386, 1, 0, 0, 0, 379, 1390, 1, 0, 0, 0, 381, 1395, 1, 0, 0, 0, 383, 1401, 1, 0, 0, 0, 385, 1407, 1, 0, 0, 0, 387, 1411, 1, 0, 0, 0, 389, 1415, 1, 0, 0, 0, 391, 1419, 1, 0, 0, 0, 393, 1425, 1, 0, 0, 0, 395, 1431, 1, 0, 0, 0, 397, 1435, 1, 0, 0, 0, 399, 1439, 1, 0, 0, 0, 401, 1443, 1, 0, 0, 0, 403, 1449, 1, 0, 0, 0, 405, 1455, 1, 0, 0, 0, 407, 1461, 1, 0, 0, 0, 409, 410, 7, 0, 0, 0, 410, 411, 7, 1, 0, 0, 411, 412, 7, 2, 0, 0, 412, 413, 7, 2, 0, 0, 413, 414, 7, 3, 0, 0, 414, 415, 7, 4, 0, 0, 415, 416, 7, 5, 0, 0, 416, 417, 1, 0, 0, 0, 417, 418, 6, 0, 0, 0, 418, 16, 1, 0, 0, 0, 419, 420, 7, 0, 0, 0, 420, 421, 7, 6, 0, 0, 421, 422, 7, 7, 0, 0, 422, 423, 7, 8, 0, 0, 423, 424, 1, 0, 0, 0, 424, 425, 6, 1, 1, 0, 425, 18, 1, 0, 0, 0, 426, 427, 7, 3, 0, 0, 427, 428, 7, 9, 0, 0, 428, 429, 7, 6, 0, 0, 429, 430, 7, 1, 0, 0, 430, 431, 7, 4, 0, 0, 431, 432, 7, 10, 0, 0, 432, 433, 1, 0, 0, 0, 433, 434, 6, 2, 2, 0, 434, 20, 1, 0, 0, 0, 435, 436, 7, 3, 0, 0, 436, 437, 7, 11, 0, 0, 437, 438, 7, 12, 0, 0, 438, 439, 7, 13, 0, 0, 439, 440, 1, 0, 0, 0, 440, 441, 6, 3, 0, 0, 441, 22, 1, 0, 0, 0, 442, 443, 7, 3, 0, 0, 443, 444, 7, 14, 0, 0, 444, 445, 7, 8, 0, 0, 445, 446, 7, 13, 0, 0, 446, 447, 7, 12, 0, 0, 447, 448, 7, 1, 0, 0, 448, 449, 7, 9, 0, 0, 449, 450, 1, 0, 0, 0, 450, 451, 6, 4, 3, 0, 451, 24, 1, 0, 0, 0, 452, 453, 7, 15, 0, 0, 453, 454, 7, 6, 0, 0, 454, 455, 7, 7, 0, 0, 455, 456, 7, 16, 0, 0, 456, 457, 1, 0, 0, 0, 457, 458, 6, 5, 4, 0, 458, 26, 1, 0, 0, 0, 459, 460, 7, 17, 0, 0, 460, 461, 7, 6, 0, 0, 461, 462, 7, 7, 0, 0, 462, 463, 7, 18, 0, 0, 463, 464, 1, 0, 0, 0, 464, 465, 6, 6, 0, 0, 465, 28, 1, 0, 0, 0, 466, 467, 7, 18, 0, 0, 467, 468, 7, 3, 0, 0, 468, 469, 7, 3, 0, 0, 469, 470, 7, 8, 0, 0, 470, 471, 1, 0, 0, 0, 471, 472, 6, 7, 1, 0, 472, 30, 1, 0, 0, 0, 473, 474, 7, 13, 0, 0, 474, 475, 7, 1, 0, 0, 475, 476, 7, 16, 0, 0, 476, 477, 7, 1, 0, 0, 477, 478, 7, 5, 0, 0, 478, 479, 1, 0, 0, 0, 479, 480, 6, 8, 0, 0, 480, 32, 1, 0, 0, 0, 481, 482, 7, 16, 0, 0, 482, 483, 7, 11, 0, 0, 483, 484, 5, 95, 0, 0, 484, 485, 7, 3, 0, 0, 485, 486, 7, 14, 0, 0, 486, 487, 7, 8, 0, 0, 487, 488, 7, 12, 0, 0, 488, 489, 7, 9, 0, 0, 489, 490, 7, 0, 0, 0, 490, 491, 1, 0, 0, 0, 491, 492, 6, 9, 5, 0, 492, 34, 1, 0, 0, 0, 493, 494, 7, 6, 0, 0, 494, 495, 7, 3, 0, 0, 495, 496, 7, 9, 0, 0, 496, 497, 7, 12, 0, 0, 497, 498, 7, 16, 0, 0, 498, 499, 7, 3, 0, 0, 499, 500, 1, 0, 0, 0, 500, 501, 6, 10, 6, 0, 501, 36, 1, 0, 0, 0, 502, 503, 7, 6, 0, 0, 503, 504, 7, 7, 0, 0, 504, 505, 7, 19, 0, 0, 505, 506, 1, 0, 0, 0, 506, 507, 6, 11, 0, 0, 507, 38, 1, 0, 0, 0, 508, 509, 7, 2, 0, 0, 509, 510, 7, 10, 0, 0, 510, 511, 7, 7, 0, 0, 511, 512, 7, 19, 0, 0, 512, 513, 1, 0, 0, 0, 513, 514, 6, 12, 7, 0, 514, 40, 1, 0, 0, 0, 515, 516, 7, 2, 0, 0, 516, 517, 7, 7, 0, 0, 517, 518, 7, 6, 0, 0, 518, 519, 7, 5, 0, 0, 519, 520, 1, 0, 0, 0, 520, 521, 6, 13, 0, 0, 521, 42, 1, 0, 0, 0, 522, 523, 7, 2, 0, 0, 523, 524, 7, 5, 0, 0, 524, 525, 7, 12, 0, 0, 525, 526, 7, 5, 0, 0, 526, 527, 7, 2, 0, 0, 527, 528, 1, 0, 0, 0, 528, 529, 6, 14, 0, 0, 529, 44, 1, 0, 0, 0, 530, 531, 7, 19, 0, 0, 531, 532, 7, 10, 0, 0, 532, 533, 7, 3, 0, 0, 533, 534, 7, 6, 0, 0, 534, 535, 7, 3, 0, 0, 535, 536, 1, 0, 0, 0, 536, 537, 6, 15, 0, 0, 537, 46, 1, 0, 0, 0, 538, 539, 4, 16, 0, 0, 539, 540, 7, 1, 0, 0, 540, 541, 7, 9, 0, 0, 541, 542, 7, 13, 0, 0, 542, 543, 7, 1, 0, 0, 543, 544, 7, 9, 0, 0, 544, 545, 7, 3, 0, 0, 545, 546, 7, 2, 0, 0, 546, 547, 7, 5, 0, 0, 547, 548, 7, 12, 0, 0, 548, 549, 7, 5, 0, 0, 549, 550, 7, 2, 0, 0, 550, 551, 1, 0, 0, 0, 551, 552, 6, 16, 0, 0, 552, 48, 1, 0, 0, 0, 553, 554, 4, 17, 1, 0, 554, 555, 7, 13, 0, 0, 555, 556, 7, 7, 0, 0, 556, 557, 7, 7, 0, 0, 557, 558, 7, 18, 0, 0, 558, 559, 7, 20, 0, 0, 559, 560, 7, 8, 0, 0, 560, 561, 1, 0, 0, 0, 561, 562, 6, 17, 8, 0, 562, 50, 1, 0, 0, 0, 563, 564, 4, 18, 2, 0, 564, 565, 7, 16, 0, 0, 565, 566, 7, 3, 0, 0, 566, 567, 7, 5, 0, 0, 567, 568, 7, 6, 0, 0, 568, 569, 7, 1, 0, 0, 569, 570, 7, 4, 0, 0, 570, 571, 7, 2, 0, 0, 571, 572, 1, 0, 0, 0, 572, 573, 6, 18, 9, 0, 573, 52, 1, 0, 0, 0, 574, 576, 8, 21, 0, 0, 575, 574, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 575, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 579, 1, 0, 0, 0, 579, 580, 6, 19, 0, 0, 580, 54, 1, 0, 0, 0, 581, 582, 5, 47, 0, 0, 582, 583, 5, 47, 0, 0, 583, 587, 1, 0, 0, 0, 584, 586, 8, 22, 0, 0, 585, 584, 1, 0, 0, 0, 586, 589, 1, 0, 0, 0, 587, 585, 1, 0, 0, 0, 587, 588, 1, 0, 0, 0, 588, 591, 1, 0, 0, 0, 589, 587, 1, 0, 0, 0, 590, 592, 5, 13, 0, 0, 591, 590, 1, 0, 0, 0, 591, 592, 1, 0, 0, 0, 592, 594, 1, 0, 0, 0, 593, 595, 5, 10, 0, 0, 594, 593, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 596, 1, 0, 0, 0, 596, 597, 6, 20, 10, 0, 597, 56, 1, 0, 0, 0, 598, 599, 5, 47, 0, 0, 599, 600, 5, 42, 0, 0, 600, 605, 1, 0, 0, 0, 601, 604, 3, 57, 21, 0, 602, 604, 9, 0, 0, 0, 603, 601, 1, 0, 0, 0, 603, 602, 1, 0, 0, 0, 604, 607, 1, 0, 0, 0, 605, 606, 1, 0, 0, 0, 605, 603, 1, 0, 0, 0, 606, 608, 1, 0, 0, 0, 607, 605, 1, 0, 0, 0, 608, 609, 5, 42, 0, 0, 609, 610, 5, 47, 0, 0, 610, 611, 1, 0, 0, 0, 611, 612, 6, 21, 10, 0, 612, 58, 1, 0, 0, 0, 613, 615, 7, 23, 0, 0, 614, 613, 1, 0, 0, 0, 615, 616, 1, 0, 0, 0, 616, 614, 1, 0, 0, 0, 616, 617, 1, 0, 0, 0, 617, 618, 1, 0, 0, 0, 618, 619, 6, 22, 10, 0, 619, 60, 1, 0, 0, 0, 620, 621, 5, 124, 0, 0, 621, 622, 1, 0, 0, 0, 622, 623, 6, 23, 11, 0, 623, 62, 1, 0, 0, 0, 624, 625, 7, 24, 0, 0, 625, 64, 1, 0, 0, 0, 626, 627, 7, 25, 0, 0, 627, 66, 1, 0, 0, 0, 628, 629, 5, 92, 0, 0, 629, 630, 7, 26, 0, 0, 630, 68, 1, 0, 0, 0, 631, 632, 8, 27, 0, 0, 632, 70, 1, 0, 0, 0, 633, 635, 7, 3, 0, 0, 634, 636, 7, 28, 0, 0, 635, 634, 1, 0, 0, 0, 635, 636, 1, 0, 0, 0, 636, 638, 1, 0, 0, 0, 637, 639, 3, 63, 24, 0, 638, 637, 1, 0, 0, 0, 639, 640, 1, 0, 0, 0, 640, 638, 1, 0, 0, 0, 640, 641, 1, 0, 0, 0, 641, 72, 1, 0, 0, 0, 642, 643, 5, 64, 0, 0, 643, 74, 1, 0, 0, 0, 644, 645, 5, 96, 0, 0, 645, 76, 1, 0, 0, 0, 646, 650, 8, 29, 0, 0, 647, 648, 5, 96, 0, 0, 648, 650, 5, 96, 0, 0, 649, 646, 1, 0, 0, 0, 649, 647, 1, 0, 0, 0, 650, 78, 1, 0, 0, 0, 651, 652, 5, 95, 0, 0, 652, 80, 1, 0, 0, 0, 653, 657, 3, 65, 25, 0, 654, 657, 3, 63, 24, 0, 655, 657, 3, 79, 32, 0, 656, 653, 1, 0, 0, 0, 656, 654, 1, 0, 0, 0, 656, 655, 1, 0, 0, 0, 657, 82, 1, 0, 0, 0, 658, 663, 5, 34, 0, 0, 659, 662, 3, 67, 26, 0, 660, 662, 3, 69, 27, 0, 661, 659, 1, 0, 0, 0, 661, 660, 1, 0, 0, 0, 662, 665, 1, 0, 0, 0, 663, 661, 1, 0, 0, 0, 663, 664, 1, 0, 0, 0, 664, 666, 1, 0, 0, 0, 665, 663, 1, 0, 0, 0, 666, 688, 5, 34, 0, 0, 667, 668, 5, 34, 0, 0, 668, 669, 5, 34, 0, 0, 669, 670, 5, 34, 0, 0, 670, 674, 1, 0, 0, 0, 671, 673, 8, 22, 0, 0, 672, 671, 1, 0, 0, 0, 673, 676, 1, 0, 0, 0, 674, 675, 1, 0, 0, 0, 674, 672, 1, 0, 0, 0, 675, 677, 1, 0, 0, 0, 676, 674, 1, 0, 0, 0, 677, 678, 5, 34, 0, 0, 678, 679, 5, 34, 0, 0, 679, 680, 5, 34, 0, 0, 680, 682, 1, 0, 0, 0, 681, 683, 5, 34, 0, 0, 682, 681, 1, 0, 0, 0, 682, 683, 1, 0, 0, 0, 683, 685, 1, 0, 0, 0, 684, 686, 5, 34, 0, 0, 685, 684, 1, 0, 0, 0, 685, 686, 1, 0, 0, 0, 686, 688, 1, 0, 0, 0, 687, 658, 1, 0, 0, 0, 687, 667, 1, 0, 0, 0, 688, 84, 1, 0, 0, 0, 689, 691, 3, 63, 24, 0, 690, 689, 1, 0, 0, 0, 691, 692, 1, 0, 0, 0, 692, 690, 1, 0, 0, 0, 692, 693, 1, 0, 0, 0, 693, 86, 1, 0, 0, 0, 694, 696, 3, 63, 24, 0, 695, 694, 1, 0, 0, 0, 696, 697, 1, 0, 0, 0, 697, 695, 1, 0, 0, 0, 697, 698, 1, 0, 0, 0, 698, 699, 1, 0, 0, 0, 699, 703, 3, 103, 44, 0, 700, 702, 3, 63, 24, 0, 701, 700, 1, 0, 0, 0, 702, 705, 1, 0, 0, 0, 703, 701, 1, 0, 0, 0, 703, 704, 1, 0, 0, 0, 704, 737, 1, 0, 0, 0, 705, 703, 1, 0, 0, 0, 706, 708, 3, 103, 44, 0, 707, 709, 3, 63, 24, 0, 708, 707, 1, 0, 0, 0, 709, 710, 1, 0, 0, 0, 710, 708, 1, 0, 0, 0, 710, 711, 1, 0, 0, 0, 711, 737, 1, 0, 0, 0, 712, 714, 3, 63, 24, 0, 713, 712, 1, 0, 0, 0, 714, 715, 1, 0, 0, 0, 715, 713, 1, 0, 0, 0, 715, 716, 1, 0, 0, 0, 716, 724, 1, 0, 0, 0, 717, 721, 3, 103, 44, 0, 718, 720, 3, 63, 24, 0, 719, 718, 1, 0, 0, 0, 720, 723, 1, 0, 0, 0, 721, 719, 1, 0, 0, 0, 721, 722, 1, 0, 0, 0, 722, 725, 1, 0, 0, 0, 723, 721, 1, 0, 0, 0, 724, 717, 1, 0, 0, 0, 724, 725, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 727, 3, 71, 28, 0, 727, 737, 1, 0, 0, 0, 728, 730, 3, 103, 44, 0, 729, 731, 3, 63, 24, 0, 730, 729, 1, 0, 0, 0, 731, 732, 1, 0, 0, 0, 732, 730, 1, 0, 0, 0, 732, 733, 1, 0, 0, 0, 733, 734, 1, 0, 0, 0, 734, 735, 3, 71, 28, 0, 735, 737, 1, 0, 0, 0, 736, 695, 1, 0, 0, 0, 736, 706, 1, 0, 0, 0, 736, 713, 1, 0, 0, 0, 736, 728, 1, 0, 0, 0, 737, 88, 1, 0, 0, 0, 738, 739, 7, 30, 0, 0, 739, 740, 7, 31, 0, 0, 740, 90, 1, 0, 0, 0, 741, 742, 7, 12, 0, 0, 742, 743, 7, 9, 0, 0, 743, 744, 7, 0, 0, 0, 744, 92, 1, 0, 0, 0, 745, 746, 7, 12, 0, 0, 746, 747, 7, 2, 0, 0, 747, 748, 7, 4, 0, 0, 748, 94, 1, 0, 0, 0, 749, 750, 5, 61, 0, 0, 750, 96, 1, 0, 0, 0, 751, 752, 5, 58, 0, 0, 752, 753, 5, 58, 0, 0, 753, 98, 1, 0, 0, 0, 754, 755, 5, 44, 0, 0, 755, 100, 1, 0, 0, 0, 756, 757, 7, 0, 0, 0, 757, 758, 7, 3, 0, 0, 758, 759, 7, 2, 0, 0, 759, 760, 7, 4, 0, 0, 760, 102, 1, 0, 0, 0, 761, 762, 5, 46, 0, 0, 762, 104, 1, 0, 0, 0, 763, 764, 7, 15, 0, 0, 764, 765, 7, 12, 0, 0, 765, 766, 7, 13, 0, 0, 766, 767, 7, 2, 0, 0, 767, 768, 7, 3, 0, 0, 768, 106, 1, 0, 0, 0, 769, 770, 7, 15, 0, 0, 770, 771, 7, 1, 0, 0, 771, 772, 7, 6, 0, 0, 772, 773, 7, 2, 0, 0, 773, 774, 7, 5, 0, 0, 774, 108, 1, 0, 0, 0, 775, 776, 7, 1, 0, 0, 776, 777, 7, 9, 0, 0, 777, 110, 1, 0, 0, 0, 778, 779, 7, 1, 0, 0, 779, 780, 7, 2, 0, 0, 780, 112, 1, 0, 0, 0, 781, 782, 7, 13, 0, 0, 782, 783, 7, 12, 0, 0, 783, 784, 7, 2, 0, 0, 784, 785, 7, 5, 0, 0, 785, 114, 1, 0, 0, 0, 786, 787, 7, 13, 0, 0, 787, 788, 7, 1, 0, 0, 788, 789, 7, 18, 0, 0, 789, 790, 7, 3, 0, 0, 790, 116, 1, 0, 0, 0, 791, 792, 5, 40, 0, 0, 792, 118, 1, 0, 0, 0, 793, 794, 7, 9, 0, 0, 794, 795, 7, 7, 0, 0, 795, 796, 7, 5, 0, 0, 796, 120, 1, 0, 0, 0, 797, 798, 7, 9, 0, 0, 798, 799, 7, 20, 0, 0, 799, 800, 7, 13, 0, 0, 800, 801, 7, 13, 0, 0, 801, 122, 1, 0, 0, 0, 802, 803, 7, 9, 0, 0, 803, 804, 7, 20, 0, 0, 804, 805, 7, 13, 0, 0, 805, 806, 7, 13, 0, 0, 806, 807, 7, 2, 0, 0, 807, 124, 1, 0, 0, 0, 808, 809, 7, 7, 0, 0, 809, 810, 7, 6, 0, 0, 810, 126, 1, 0, 0, 0, 811, 812, 5, 63, 0, 0, 812, 128, 1, 0, 0, 0, 813, 814, 7, 6, 0, 0, 814, 815, 7, 13, 0, 0, 815, 816, 7, 1, 0, 0, 816, 817, 7, 18, 0, 0, 817, 818, 7, 3, 0, 0, 818, 130, 1, 0, 0, 0, 819, 820, 5, 41, 0, 0, 820, 132, 1, 0, 0, 0, 821, 822, 7, 5, 0, 0, 822, 823, 7, 6, 0, 0, 823, 824, 7, 20, 0, 0, 824, 825, 7, 3, 0, 0, 825, 134, 1, 0, 0, 0, 826, 827, 5, 61, 0, 0, 827, 828, 5, 61, 0, 0, 828, 136, 1, 0, 0, 0, 829, 830, 5, 61, 0, 0, 830, 831, 5, 126, 0, 0, 831, 138, 1, 0, 0, 0, 832, 833, 5, 33, 0, 0, 833, 834, 5, 61, 0, 0, 834, 140, 1, 0, 0, 0, 835, 836, 5, 60, 0, 0, 836, 142, 1, 0, 0, 0, 837, 838, 5, 60, 0, 0, 838, 839, 5, 61, 0, 0, 839, 144, 1, 0, 0, 0, 840, 841, 5, 62, 0, 0, 841, 146, 1, 0, 0, 0, 842, 843, 5, 62, 0, 0, 843, 844, 5, 61, 0, 0, 844, 148, 1, 0, 0, 0, 845, 846, 5, 43, 0, 0, 846, 150, 1, 0, 0, 0, 847, 848, 5, 45, 0, 0, 848, 152, 1, 0, 0, 0, 849, 850, 5, 42, 0, 0, 850, 154, 1, 0, 0, 0, 851, 852, 5, 47, 0, 0, 852, 156, 1, 0, 0, 0, 853, 854, 5, 37, 0, 0, 854, 158, 1, 0, 0, 0, 855, 856, 4, 72, 3, 0, 856, 857, 7, 16, 0, 0, 857, 858, 7, 12, 0, 0, 858, 859, 7, 5, 0, 0, 859, 860, 7, 4, 0, 0, 860, 861, 7, 10, 0, 0, 861, 160, 1, 0, 0, 0, 862, 865, 3, 127, 56, 0, 863, 866, 3, 65, 25, 0, 864, 866, 3, 79, 32, 0, 865, 863, 1, 0, 0, 0, 865, 864, 1, 0, 0, 0, 866, 870, 1, 0, 0, 0, 867, 869, 3, 81, 33, 0, 868, 867, 1, 0, 0, 0, 869, 872, 1, 0, 0, 0, 870, 868, 1, 0, 0, 0, 870, 871, 1, 0, 0, 0, 871, 880, 1, 0, 0, 0, 872, 870, 1, 0, 0, 0, 873, 875, 3, 127, 56, 0, 874, 876, 3, 63, 24, 0, 875, 874, 1, 0, 0, 0, 876, 877, 1, 0, 0, 0, 877, 875, 1, 0, 0, 0, 877, 878, 1, 0, 0, 0, 878, 880, 1, 0, 0, 0, 879, 862, 1, 0, 0, 0, 879, 873, 1, 0, 0, 0, 880, 162, 1, 0, 0, 0, 881, 882, 5, 91, 0, 0, 882, 883, 1, 0, 0, 0, 883, 884, 6, 74, 0, 0, 884, 885, 6, 74, 0, 0, 885, 164, 1, 0, 0, 0, 886, 887, 5, 93, 0, 0, 887, 888, 1, 0, 0, 0, 888, 889, 6, 75, 11, 0, 889, 890, 6, 75, 11, 0, 890, 166, 1, 0, 0, 0, 891, 895, 3, 65, 25, 0, 892, 894, 3, 81, 33, 0, 893, 892, 1, 0, 0, 0, 894, 897, 1, 0, 0, 0, 895, 893, 1, 0, 0, 0, 895, 896, 1, 0, 0, 0, 896, 908, 1, 0, 0, 0, 897, 895, 1, 0, 0, 0, 898, 901, 3, 79, 32, 0, 899, 901, 3, 73, 29, 0, 900, 898, 1, 0, 0, 0, 900, 899, 1, 0, 0, 0, 901, 903, 1, 0, 0, 0, 902, 904, 3, 81, 33, 0, 903, 902, 1, 0, 0, 0, 904, 905, 1, 0, 0, 0, 905, 903, 1, 0, 0, 0, 905, 906, 1, 0, 0, 0, 906, 908, 1, 0, 0, 0, 907, 891, 1, 0, 0, 0, 907, 900, 1, 0, 0, 0, 908, 168, 1, 0, 0, 0, 909, 911, 3, 75, 30, 0, 910, 912, 3, 77, 31, 0, 911, 910, 1, 0, 0, 0, 912, 913, 1, 0, 0, 0, 913, 911, 1, 0, 0, 0, 913, 914, 1, 0, 0, 0, 914, 915, 1, 0, 0, 0, 915, 916, 3, 75, 30, 0, 916, 170, 1, 0, 0, 0, 917, 918, 3, 169, 77, 0, 918, 172, 1, 0, 0, 0, 919, 920, 3, 55, 20, 0, 920, 921, 1, 0, 0, 0, 921, 922, 6, 79, 10, 0, 922, 174, 1, 0, 0, 0, 923, 924, 3, 57, 21, 0, 924, 925, 1, 0, 0, 0, 925, 926, 6, 80, 10, 0, 926, 176, 1, 0, 0, 0, 927, 928, 3, 59, 22, 0, 928, 929, 1, 0, 0, 0, 929, 930, 6, 81, 10, 0, 930, 178, 1, 0, 0, 0, 931, 932, 3, 163, 74, 0, 932, 933, 1, 0, 0, 0, 933, 934, 6, 82, 12, 0, 934, 935, 6, 82, 13, 0, 935, 180, 1, 0, 0, 0, 936, 937, 3, 61, 23, 0, 937, 938, 1, 0, 0, 0, 938, 939, 6, 83, 14, 0, 939, 940, 6, 83, 11, 0, 940, 182, 1, 0, 0, 0, 941, 942, 3, 59, 22, 0, 942, 943, 1, 0, 0, 0, 943, 944, 6, 84, 10, 0, 944, 184, 1, 0, 0, 0, 945, 946, 3, 55, 20, 0, 946, 947, 1, 0, 0, 0, 947, 948, 6, 85, 10, 0, 948, 186, 1, 0, 0, 0, 949, 950, 3, 57, 21, 0, 950, 951, 1, 0, 0, 0, 951, 952, 6, 86, 10, 0, 952, 188, 1, 0, 0, 0, 953, 954, 3, 61, 23, 0, 954, 955, 1, 0, 0, 0, 955, 956, 6, 87, 14, 0, 956, 957, 6, 87, 11, 0, 957, 190, 1, 0, 0, 0, 958, 959, 3, 163, 74, 0, 959, 960, 1, 0, 0, 0, 960, 961, 6, 88, 12, 0, 961, 192, 1, 0, 0, 0, 962, 963, 3, 165, 75, 0, 963, 964, 1, 0, 0, 0, 964, 965, 6, 89, 15, 0, 965, 194, 1, 0, 0, 0, 966, 967, 3, 335, 160, 0, 967, 968, 1, 0, 0, 0, 968, 969, 6, 90, 16, 0, 969, 196, 1, 0, 0, 0, 970, 971, 3, 99, 42, 0, 971, 972, 1, 0, 0, 0, 972, 973, 6, 91, 17, 0, 973, 198, 1, 0, 0, 0, 974, 975, 3, 95, 40, 0, 975, 976, 1, 0, 0, 0, 976, 977, 6, 92, 18, 0, 977, 200, 1, 0, 0, 0, 978, 979, 7, 16, 0, 0, 979, 980, 7, 3, 0, 0, 980, 981, 7, 5, 0, 0, 981, 982, 7, 12, 0, 0, 982, 983, 7, 0, 0, 0, 983, 984, 7, 12, 0, 0, 984, 985, 7, 5, 0, 0, 985, 986, 7, 12, 0, 0, 986, 202, 1, 0, 0, 0, 987, 991, 8, 32, 0, 0, 988, 989, 5, 47, 0, 0, 989, 991, 8, 33, 0, 0, 990, 987, 1, 0, 0, 0, 990, 988, 1, 0, 0, 0, 991, 204, 1, 0, 0, 0, 992, 994, 3, 203, 94, 0, 993, 992, 1, 0, 0, 0, 994, 995, 1, 0, 0, 0, 995, 993, 1, 0, 0, 0, 995, 996, 1, 0, 0, 0, 996, 206, 1, 0, 0, 0, 997, 998, 3, 205, 95, 0, 998, 999, 1, 0, 0, 0, 999, 1000, 6, 96, 19, 0, 1000, 208, 1, 0, 0, 0, 1001, 1002, 3, 83, 34, 0, 1002, 1003, 1, 0, 0, 0, 1003, 1004, 6, 97, 20, 0, 1004, 210, 1, 0, 0, 0, 1005, 1006, 3, 55, 20, 0, 1006, 1007, 1, 0, 0, 0, 1007, 1008, 6, 98, 10, 0, 1008, 212, 1, 0, 0, 0, 1009, 1010, 3, 57, 21, 0, 1010, 1011, 1, 0, 0, 0, 1011, 1012, 6, 99, 10, 0, 1012, 214, 1, 0, 0, 0, 1013, 1014, 3, 59, 22, 0, 1014, 1015, 1, 0, 0, 0, 1015, 1016, 6, 100, 10, 0, 1016, 216, 1, 0, 0, 0, 1017, 1018, 3, 61, 23, 0, 1018, 1019, 1, 0, 0, 0, 1019, 1020, 6, 101, 14, 0, 1020, 1021, 6, 101, 11, 0, 1021, 218, 1, 0, 0, 0, 1022, 1023, 3, 103, 44, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, 6, 102, 21, 0, 1025, 220, 1, 0, 0, 0, 1026, 1027, 3, 99, 42, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1029, 6, 103, 17, 0, 1029, 222, 1, 0, 0, 0, 1030, 1031, 3, 127, 56, 0, 1031, 1032, 1, 0, 0, 0, 1032, 1033, 6, 104, 22, 0, 1033, 224, 1, 0, 0, 0, 1034, 1035, 3, 161, 73, 0, 1035, 1036, 1, 0, 0, 0, 1036, 1037, 6, 105, 23, 0, 1037, 226, 1, 0, 0, 0, 1038, 1043, 3, 65, 25, 0, 1039, 1043, 3, 63, 24, 0, 1040, 1043, 3, 79, 32, 0, 1041, 1043, 3, 153, 69, 0, 1042, 1038, 1, 0, 0, 0, 1042, 1039, 1, 0, 0, 0, 1042, 1040, 1, 0, 0, 0, 1042, 1041, 1, 0, 0, 0, 1043, 228, 1, 0, 0, 0, 1044, 1047, 3, 65, 25, 0, 1045, 1047, 3, 153, 69, 0, 1046, 1044, 1, 0, 0, 0, 1046, 1045, 1, 0, 0, 0, 1047, 1051, 1, 0, 0, 0, 1048, 1050, 3, 227, 106, 0, 1049, 1048, 1, 0, 0, 0, 1050, 1053, 1, 0, 0, 0, 1051, 1049, 1, 0, 0, 0, 1051, 1052, 1, 0, 0, 0, 1052, 1064, 1, 0, 0, 0, 1053, 1051, 1, 0, 0, 0, 1054, 1057, 3, 79, 32, 0, 1055, 1057, 3, 73, 29, 0, 1056, 1054, 1, 0, 0, 0, 1056, 1055, 1, 0, 0, 0, 1057, 1059, 1, 0, 0, 0, 1058, 1060, 3, 227, 106, 0, 1059, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1059, 1, 0, 0, 0, 1061, 1062, 1, 0, 0, 0, 1062, 1064, 1, 0, 0, 0, 1063, 1046, 1, 0, 0, 0, 1063, 1056, 1, 0, 0, 0, 1064, 230, 1, 0, 0, 0, 1065, 1068, 3, 229, 107, 0, 1066, 1068, 3, 169, 77, 0, 1067, 1065, 1, 0, 0, 0, 1067, 1066, 1, 0, 0, 0, 1068, 1069, 1, 0, 0, 0, 1069, 1067, 1, 0, 0, 0, 1069, 1070, 1, 0, 0, 0, 1070, 232, 1, 0, 0, 0, 1071, 1072, 3, 55, 20, 0, 1072, 1073, 1, 0, 0, 0, 1073, 1074, 6, 109, 10, 0, 1074, 234, 1, 0, 0, 0, 1075, 1076, 3, 57, 21, 0, 1076, 1077, 1, 0, 0, 0, 1077, 1078, 6, 110, 10, 0, 1078, 236, 1, 0, 0, 0, 1079, 1080, 3, 59, 22, 0, 1080, 1081, 1, 0, 0, 0, 1081, 1082, 6, 111, 10, 0, 1082, 238, 1, 0, 0, 0, 1083, 1084, 3, 61, 23, 0, 1084, 1085, 1, 0, 0, 0, 1085, 1086, 6, 112, 14, 0, 1086, 1087, 6, 112, 11, 0, 1087, 240, 1, 0, 0, 0, 1088, 1089, 3, 95, 40, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 113, 18, 0, 1091, 242, 1, 0, 0, 0, 1092, 1093, 3, 99, 42, 0, 1093, 1094, 1, 0, 0, 0, 1094, 1095, 6, 114, 17, 0, 1095, 244, 1, 0, 0, 0, 1096, 1097, 3, 103, 44, 0, 1097, 1098, 1, 0, 0, 0, 1098, 1099, 6, 115, 21, 0, 1099, 246, 1, 0, 0, 0, 1100, 1101, 3, 127, 56, 0, 1101, 1102, 1, 0, 0, 0, 1102, 1103, 6, 116, 22, 0, 1103, 248, 1, 0, 0, 0, 1104, 1105, 3, 161, 73, 0, 1105, 1106, 1, 0, 0, 0, 1106, 1107, 6, 117, 23, 0, 1107, 250, 1, 0, 0, 0, 1108, 1109, 7, 12, 0, 0, 1109, 1110, 7, 2, 0, 0, 1110, 252, 1, 0, 0, 0, 1111, 1112, 3, 231, 108, 0, 1112, 1113, 1, 0, 0, 0, 1113, 1114, 6, 119, 24, 0, 1114, 254, 1, 0, 0, 0, 1115, 1116, 3, 55, 20, 0, 1116, 1117, 1, 0, 0, 0, 1117, 1118, 6, 120, 10, 0, 1118, 256, 1, 0, 0, 0, 1119, 1120, 3, 57, 21, 0, 1120, 1121, 1, 0, 0, 0, 1121, 1122, 6, 121, 10, 0, 1122, 258, 1, 0, 0, 0, 1123, 1124, 3, 59, 22, 0, 1124, 1125, 1, 0, 0, 0, 1125, 1126, 6, 122, 10, 0, 1126, 260, 1, 0, 0, 0, 1127, 1128, 3, 61, 23, 0, 1128, 1129, 1, 0, 0, 0, 1129, 1130, 6, 123, 14, 0, 1130, 1131, 6, 123, 11, 0, 1131, 262, 1, 0, 0, 0, 1132, 1133, 3, 163, 74, 0, 1133, 1134, 1, 0, 0, 0, 1134, 1135, 6, 124, 12, 0, 1135, 1136, 6, 124, 25, 0, 1136, 264, 1, 0, 0, 0, 1137, 1138, 7, 7, 0, 0, 1138, 1139, 7, 9, 0, 0, 1139, 1140, 1, 0, 0, 0, 1140, 1141, 6, 125, 26, 0, 1141, 266, 1, 0, 0, 0, 1142, 1143, 7, 19, 0, 0, 1143, 1144, 7, 1, 0, 0, 1144, 1145, 7, 5, 0, 0, 1145, 1146, 7, 10, 0, 0, 1146, 1147, 1, 0, 0, 0, 1147, 1148, 6, 126, 26, 0, 1148, 268, 1, 0, 0, 0, 1149, 1150, 8, 34, 0, 0, 1150, 270, 1, 0, 0, 0, 1151, 1153, 3, 269, 127, 0, 1152, 1151, 1, 0, 0, 0, 1153, 1154, 1, 0, 0, 0, 1154, 1152, 1, 0, 0, 0, 1154, 1155, 1, 0, 0, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1157, 3, 335, 160, 0, 1157, 1159, 1, 0, 0, 0, 1158, 1152, 1, 0, 0, 0, 1158, 1159, 1, 0, 0, 0, 1159, 1161, 1, 0, 0, 0, 1160, 1162, 3, 269, 127, 0, 1161, 1160, 1, 0, 0, 0, 1162, 1163, 1, 0, 0, 0, 1163, 1161, 1, 0, 0, 0, 1163, 1164, 1, 0, 0, 0, 1164, 272, 1, 0, 0, 0, 1165, 1166, 3, 271, 128, 0, 1166, 1167, 1, 0, 0, 0, 1167, 1168, 6, 129, 27, 0, 1168, 274, 1, 0, 0, 0, 1169, 1170, 3, 55, 20, 0, 1170, 1171, 1, 0, 0, 0, 1171, 1172, 6, 130, 10, 0, 1172, 276, 1, 0, 0, 0, 1173, 1174, 3, 57, 21, 0, 1174, 1175, 1, 0, 0, 0, 1175, 1176, 6, 131, 10, 0, 1176, 278, 1, 0, 0, 0, 1177, 1178, 3, 59, 22, 0, 1178, 1179, 1, 0, 0, 0, 1179, 1180, 6, 132, 10, 0, 1180, 280, 1, 0, 0, 0, 1181, 1182, 3, 61, 23, 0, 1182, 1183, 1, 0, 0, 0, 1183, 1184, 6, 133, 14, 0, 1184, 1185, 6, 133, 11, 0, 1185, 1186, 6, 133, 11, 0, 1186, 282, 1, 0, 0, 0, 1187, 1188, 3, 95, 40, 0, 1188, 1189, 1, 0, 0, 0, 1189, 1190, 6, 134, 18, 0, 1190, 284, 1, 0, 0, 0, 1191, 1192, 3, 99, 42, 0, 1192, 1193, 1, 0, 0, 0, 1193, 1194, 6, 135, 17, 0, 1194, 286, 1, 0, 0, 0, 1195, 1196, 3, 103, 44, 0, 1196, 1197, 1, 0, 0, 0, 1197, 1198, 6, 136, 21, 0, 1198, 288, 1, 0, 0, 0, 1199, 1200, 3, 267, 126, 0, 1200, 1201, 1, 0, 0, 0, 1201, 1202, 6, 137, 28, 0, 1202, 290, 1, 0, 0, 0, 1203, 1204, 3, 231, 108, 0, 1204, 1205, 1, 0, 0, 0, 1205, 1206, 6, 138, 24, 0, 1206, 292, 1, 0, 0, 0, 1207, 1208, 3, 171, 78, 0, 1208, 1209, 1, 0, 0, 0, 1209, 1210, 6, 139, 29, 0, 1210, 294, 1, 0, 0, 0, 1211, 1212, 3, 127, 56, 0, 1212, 1213, 1, 0, 0, 0, 1213, 1214, 6, 140, 22, 0, 1214, 296, 1, 0, 0, 0, 1215, 1216, 3, 161, 73, 0, 1216, 1217, 1, 0, 0, 0, 1217, 1218, 6, 141, 23, 0, 1218, 298, 1, 0, 0, 0, 1219, 1220, 3, 55, 20, 0, 1220, 1221, 1, 0, 0, 0, 1221, 1222, 6, 142, 10, 0, 1222, 300, 1, 0, 0, 0, 1223, 1224, 3, 57, 21, 0, 1224, 1225, 1, 0, 0, 0, 1225, 1226, 6, 143, 10, 0, 1226, 302, 1, 0, 0, 0, 1227, 1228, 3, 59, 22, 0, 1228, 1229, 1, 0, 0, 0, 1229, 1230, 6, 144, 10, 0, 1230, 304, 1, 0, 0, 0, 1231, 1232, 3, 61, 23, 0, 1232, 1233, 1, 0, 0, 0, 1233, 1234, 6, 145, 14, 0, 1234, 1235, 6, 145, 11, 0, 1235, 306, 1, 0, 0, 0, 1236, 1237, 3, 103, 44, 0, 1237, 1238, 1, 0, 0, 0, 1238, 1239, 6, 146, 21, 0, 1239, 308, 1, 0, 0, 0, 1240, 1241, 3, 127, 56, 0, 1241, 1242, 1, 0, 0, 0, 1242, 1243, 6, 147, 22, 0, 1243, 310, 1, 0, 0, 0, 1244, 1245, 3, 161, 73, 0, 1245, 1246, 1, 0, 0, 0, 1246, 1247, 6, 148, 23, 0, 1247, 312, 1, 0, 0, 0, 1248, 1249, 3, 171, 78, 0, 1249, 1250, 1, 0, 0, 0, 1250, 1251, 6, 149, 29, 0, 1251, 314, 1, 0, 0, 0, 1252, 1253, 3, 167, 76, 0, 1253, 1254, 1, 0, 0, 0, 1254, 1255, 6, 150, 30, 0, 1255, 316, 1, 0, 0, 0, 1256, 1257, 3, 55, 20, 0, 1257, 1258, 1, 0, 0, 0, 1258, 1259, 6, 151, 10, 0, 1259, 318, 1, 0, 0, 0, 1260, 1261, 3, 57, 21, 0, 1261, 1262, 1, 0, 0, 0, 1262, 1263, 6, 152, 10, 0, 1263, 320, 1, 0, 0, 0, 1264, 1265, 3, 59, 22, 0, 1265, 1266, 1, 0, 0, 0, 1266, 1267, 6, 153, 10, 0, 1267, 322, 1, 0, 0, 0, 1268, 1269, 3, 61, 23, 0, 1269, 1270, 1, 0, 0, 0, 1270, 1271, 6, 154, 14, 0, 1271, 1272, 6, 154, 11, 0, 1272, 324, 1, 0, 0, 0, 1273, 1274, 7, 1, 0, 0, 1274, 1275, 7, 9, 0, 0, 1275, 1276, 7, 15, 0, 0, 1276, 1277, 7, 7, 0, 0, 1277, 326, 1, 0, 0, 0, 1278, 1279, 3, 55, 20, 0, 1279, 1280, 1, 0, 0, 0, 1280, 1281, 6, 156, 10, 0, 1281, 328, 1, 0, 0, 0, 1282, 1283, 3, 57, 21, 0, 1283, 1284, 1, 0, 0, 0, 1284, 1285, 6, 157, 10, 0, 1285, 330, 1, 0, 0, 0, 1286, 1287, 3, 59, 22, 0, 1287, 1288, 1, 0, 0, 0, 1288, 1289, 6, 158, 10, 0, 1289, 332, 1, 0, 0, 0, 1290, 1291, 3, 165, 75, 0, 1291, 1292, 1, 0, 0, 0, 1292, 1293, 6, 159, 15, 0, 1293, 1294, 6, 159, 11, 0, 1294, 334, 1, 0, 0, 0, 1295, 1296, 5, 58, 0, 0, 1296, 336, 1, 0, 0, 0, 1297, 1303, 3, 73, 29, 0, 1298, 1303, 3, 63, 24, 0, 1299, 1303, 3, 103, 44, 0, 1300, 1303, 3, 65, 25, 0, 1301, 1303, 3, 79, 32, 0, 1302, 1297, 1, 0, 0, 0, 1302, 1298, 1, 0, 0, 0, 1302, 1299, 1, 0, 0, 0, 1302, 1300, 1, 0, 0, 0, 1302, 1301, 1, 0, 0, 0, 1303, 1304, 1, 0, 0, 0, 1304, 1302, 1, 0, 0, 0, 1304, 1305, 1, 0, 0, 0, 1305, 338, 1, 0, 0, 0, 1306, 1307, 3, 55, 20, 0, 1307, 1308, 1, 0, 0, 0, 1308, 1309, 6, 162, 10, 0, 1309, 340, 1, 0, 0, 0, 1310, 1311, 3, 57, 21, 0, 1311, 1312, 1, 0, 0, 0, 1312, 1313, 6, 163, 10, 0, 1313, 342, 1, 0, 0, 0, 1314, 1315, 3, 59, 22, 0, 1315, 1316, 1, 0, 0, 0, 1316, 1317, 6, 164, 10, 0, 1317, 344, 1, 0, 0, 0, 1318, 1319, 3, 61, 23, 0, 1319, 1320, 1, 0, 0, 0, 1320, 1321, 6, 165, 14, 0, 1321, 1322, 6, 165, 11, 0, 1322, 346, 1, 0, 0, 0, 1323, 1324, 3, 335, 160, 0, 1324, 1325, 1, 0, 0, 0, 1325, 1326, 6, 166, 16, 0, 1326, 348, 1, 0, 0, 0, 1327, 1328, 3, 99, 42, 0, 1328, 1329, 1, 0, 0, 0, 1329, 1330, 6, 167, 17, 0, 1330, 350, 1, 0, 0, 0, 1331, 1332, 3, 103, 44, 0, 1332, 1333, 1, 0, 0, 0, 1333, 1334, 6, 168, 21, 0, 1334, 352, 1, 0, 0, 0, 1335, 1336, 3, 265, 125, 0, 1336, 1337, 1, 0, 0, 0, 1337, 1338, 6, 169, 31, 0, 1338, 1339, 6, 169, 32, 0, 1339, 354, 1, 0, 0, 0, 1340, 1341, 3, 205, 95, 0, 1341, 1342, 1, 0, 0, 0, 1342, 1343, 6, 170, 19, 0, 1343, 356, 1, 0, 0, 0, 1344, 1345, 3, 83, 34, 0, 1345, 1346, 1, 0, 0, 0, 1346, 1347, 6, 171, 20, 0, 1347, 358, 1, 0, 0, 0, 1348, 1349, 3, 55, 20, 0, 1349, 1350, 1, 0, 0, 0, 1350, 1351, 6, 172, 10, 0, 1351, 360, 1, 0, 0, 0, 1352, 1353, 3, 57, 21, 0, 1353, 1354, 1, 0, 0, 0, 1354, 1355, 6, 173, 10, 0, 1355, 362, 1, 0, 0, 0, 1356, 1357, 3, 59, 22, 0, 1357, 1358, 1, 0, 0, 0, 1358, 1359, 6, 174, 10, 0, 1359, 364, 1, 0, 0, 0, 1360, 1361, 3, 61, 23, 0, 1361, 1362, 1, 0, 0, 0, 1362, 1363, 6, 175, 14, 0, 1363, 1364, 6, 175, 11, 0, 1364, 1365, 6, 175, 11, 0, 1365, 366, 1, 0, 0, 0, 1366, 1367, 3, 99, 42, 0, 1367, 1368, 1, 0, 0, 0, 1368, 1369, 6, 176, 17, 0, 1369, 368, 1, 0, 0, 0, 1370, 1371, 3, 103, 44, 0, 1371, 1372, 1, 0, 0, 0, 1372, 1373, 6, 177, 21, 0, 1373, 370, 1, 0, 0, 0, 1374, 1375, 3, 231, 108, 0, 1375, 1376, 1, 0, 0, 0, 1376, 1377, 6, 178, 24, 0, 1377, 372, 1, 0, 0, 0, 1378, 1379, 3, 55, 20, 0, 1379, 1380, 1, 0, 0, 0, 1380, 1381, 6, 179, 10, 0, 1381, 374, 1, 0, 0, 0, 1382, 1383, 3, 57, 21, 0, 1383, 1384, 1, 0, 0, 0, 1384, 1385, 6, 180, 10, 0, 1385, 376, 1, 0, 0, 0, 1386, 1387, 3, 59, 22, 0, 1387, 1388, 1, 0, 0, 0, 1388, 1389, 6, 181, 10, 0, 1389, 378, 1, 0, 0, 0, 1390, 1391, 3, 61, 23, 0, 1391, 1392, 1, 0, 0, 0, 1392, 1393, 6, 182, 14, 0, 1393, 1394, 6, 182, 11, 0, 1394, 380, 1, 0, 0, 0, 1395, 1396, 3, 205, 95, 0, 1396, 1397, 1, 0, 0, 0, 1397, 1398, 6, 183, 19, 0, 1398, 1399, 6, 183, 11, 0, 1399, 1400, 6, 183, 33, 0, 1400, 382, 1, 0, 0, 0, 1401, 1402, 3, 83, 34, 0, 1402, 1403, 1, 0, 0, 0, 1403, 1404, 6, 184, 20, 0, 1404, 1405, 6, 184, 11, 0, 1405, 1406, 6, 184, 33, 0, 1406, 384, 1, 0, 0, 0, 1407, 1408, 3, 55, 20, 0, 1408, 1409, 1, 0, 0, 0, 1409, 1410, 6, 185, 10, 0, 1410, 386, 1, 0, 0, 0, 1411, 1412, 3, 57, 21, 0, 1412, 1413, 1, 0, 0, 0, 1413, 1414, 6, 186, 10, 0, 1414, 388, 1, 0, 0, 0, 1415, 1416, 3, 59, 22, 0, 1416, 1417, 1, 0, 0, 0, 1417, 1418, 6, 187, 10, 0, 1418, 390, 1, 0, 0, 0, 1419, 1420, 3, 335, 160, 0, 1420, 1421, 1, 0, 0, 0, 1421, 1422, 6, 188, 16, 0, 1422, 1423, 6, 188, 11, 0, 1423, 1424, 6, 188, 9, 0, 1424, 392, 1, 0, 0, 0, 1425, 1426, 3, 99, 42, 0, 1426, 1427, 1, 0, 0, 0, 1427, 1428, 6, 189, 17, 0, 1428, 1429, 6, 189, 11, 0, 1429, 1430, 6, 189, 9, 0, 1430, 394, 1, 0, 0, 0, 1431, 1432, 3, 55, 20, 0, 1432, 1433, 1, 0, 0, 0, 1433, 1434, 6, 190, 10, 0, 1434, 396, 1, 0, 0, 0, 1435, 1436, 3, 57, 21, 0, 1436, 1437, 1, 0, 0, 0, 1437, 1438, 6, 191, 10, 0, 1438, 398, 1, 0, 0, 0, 1439, 1440, 3, 59, 22, 0, 1440, 1441, 1, 0, 0, 0, 1441, 1442, 6, 192, 10, 0, 1442, 400, 1, 0, 0, 0, 1443, 1444, 3, 171, 78, 0, 1444, 1445, 1, 0, 0, 0, 1445, 1446, 6, 193, 11, 0, 1446, 1447, 6, 193, 0, 0, 1447, 1448, 6, 193, 29, 0, 1448, 402, 1, 0, 0, 0, 1449, 1450, 3, 167, 76, 0, 1450, 1451, 1, 0, 0, 0, 1451, 1452, 6, 194, 11, 0, 1452, 1453, 6, 194, 0, 0, 1453, 1454, 6, 194, 30, 0, 1454, 404, 1, 0, 0, 0, 1455, 1456, 3, 89, 37, 0, 1456, 1457, 1, 0, 0, 0, 1457, 1458, 6, 195, 11, 0, 1458, 1459, 6, 195, 0, 0, 1459, 1460, 6, 195, 34, 0, 1460, 406, 1, 0, 0, 0, 1461, 1462, 3, 61, 23, 0, 1462, 1463, 1, 0, 0, 0, 1463, 1464, 6, 196, 14, 0, 1464, 1465, 6, 196, 11, 0, 1465, 408, 1, 0, 0, 0, 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 577, 587, 591, 594, 603, 605, 616, 635, 640, 649, 656, 661, 663, 674, 682, 685, 687, 692, 697, 703, 710, 715, 721, 724, 732, 736, 865, 870, 877, 879, 895, 900, 905, 907, 913, 990, 995, 1042, 1046, 1051, 1056, 1061, 1063, 1067, 1069, 1154, 1158, 1163, 1302, 1304, 35, 5, 1, 0, 5, 4, 0, 5, 6, 0, 5, 2, 0, 5, 3, 0, 5, 8, 0, 5, 5, 0, 5, 9, 0, 5, 11, 0, 5, 13, 0, 0, 1, 0, 4, 0, 0, 7, 65, 0, 5, 0, 0, 7, 24, 0, 7, 66, 0, 7, 104, 0, 7, 33, 0, 7, 31, 0, 7, 76, 0, 7, 25, 0, 7, 35, 0, 7, 47, 0, 7, 64, 0, 7, 80, 0, 5, 10, 0, 5, 7, 0, 7, 90, 0, 7, 89, 0, 7, 68, 0, 7, 67, 0, 7, 88, 0, 5, 12, 0, 5, 14, 0, 7, 28, 0]
\ No newline at end of file
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
index f67daa29ab059..563e2418e7eff 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseLexer.java
@@ -8,14 +8,16 @@
* 2.0.
*/
-import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
-import org.antlr.v4.runtime.Token;
-import org.antlr.v4.runtime.TokenStream;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.RuntimeMetaData;
+import org.antlr.v4.runtime.Vocabulary;
+import org.antlr.v4.runtime.VocabularyImpl;
+import org.antlr.v4.runtime.atn.ATN;
+import org.antlr.v4.runtime.atn.ATNDeserializer;
+import org.antlr.v4.runtime.atn.LexerATNSimulator;
+import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
-import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
public class EsqlBaseLexer extends LexerConfig {
@@ -25,90 +27,90 @@ public class EsqlBaseLexer extends LexerConfig {
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
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, DEV_INLINESTATS=17, DEV_LOOKUP=18, DEV_MATCH=19, DEV_METRICS=20,
- UNKNOWN_CMD=21, LINE_COMMENT=22, MULTILINE_COMMENT=23, WS=24, PIPE=25,
- QUOTED_STRING=26, INTEGER_LITERAL=27, DECIMAL_LITERAL=28, BY=29, AND=30,
- ASC=31, ASSIGN=32, CAST_OP=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38,
- IN=39, IS=40, LAST=41, LIKE=42, LP=43, NOT=44, NULL=45, NULLS=46, OR=47,
- PARAM=48, RLIKE=49, RP=50, TRUE=51, EQ=52, CIEQ=53, NEQ=54, LT=55, LTE=56,
- GT=57, GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, NAMED_OR_POSITIONAL_PARAM=64,
- OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
- EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, EXPLAIN_WS=72,
- EXPLAIN_LINE_COMMENT=73, EXPLAIN_MULTILINE_COMMENT=74, METADATA=75, UNQUOTED_SOURCE=76,
- FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80,
- PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83,
- AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87,
- ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92,
- ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95,
- ENRICH_FIELD_WS=96, MVEXPAND_LINE_COMMENT=97, MVEXPAND_MULTILINE_COMMENT=98,
- MVEXPAND_WS=99, INFO=100, SHOW_LINE_COMMENT=101, SHOW_MULTILINE_COMMENT=102,
- SHOW_WS=103, COLON=104, SETTING=105, SETTING_LINE_COMMENT=106, SETTTING_MULTILINE_COMMENT=107,
- SETTING_WS=108, LOOKUP_LINE_COMMENT=109, LOOKUP_MULTILINE_COMMENT=110,
- LOOKUP_WS=111, LOOKUP_FIELD_LINE_COMMENT=112, LOOKUP_FIELD_MULTILINE_COMMENT=113,
- LOOKUP_FIELD_WS=114, METRICS_LINE_COMMENT=115, METRICS_MULTILINE_COMMENT=116,
- METRICS_WS=117, CLOSING_METRICS_LINE_COMMENT=118, CLOSING_METRICS_MULTILINE_COMMENT=119,
+ 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, DEV_INLINESTATS=17, DEV_LOOKUP=18, DEV_METRICS=19, UNKNOWN_CMD=20,
+ LINE_COMMENT=21, MULTILINE_COMMENT=22, WS=23, PIPE=24, QUOTED_STRING=25,
+ INTEGER_LITERAL=26, DECIMAL_LITERAL=27, BY=28, AND=29, ASC=30, ASSIGN=31,
+ CAST_OP=32, COMMA=33, DESC=34, DOT=35, FALSE=36, FIRST=37, IN=38, IS=39,
+ LAST=40, LIKE=41, LP=42, NOT=43, NULL=44, NULLS=45, OR=46, PARAM=47, RLIKE=48,
+ RP=49, TRUE=50, EQ=51, CIEQ=52, NEQ=53, LT=54, LTE=55, GT=56, GTE=57,
+ PLUS=58, MINUS=59, ASTERISK=60, SLASH=61, PERCENT=62, DEV_MATCH=63, NAMED_OR_POSITIONAL_PARAM=64,
+ OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
+ EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, EXPLAIN_WS=72,
+ EXPLAIN_LINE_COMMENT=73, EXPLAIN_MULTILINE_COMMENT=74, METADATA=75, UNQUOTED_SOURCE=76,
+ FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80,
+ PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83,
+ AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87,
+ ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92,
+ ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95,
+ ENRICH_FIELD_WS=96, MVEXPAND_LINE_COMMENT=97, MVEXPAND_MULTILINE_COMMENT=98,
+ MVEXPAND_WS=99, INFO=100, SHOW_LINE_COMMENT=101, SHOW_MULTILINE_COMMENT=102,
+ SHOW_WS=103, COLON=104, SETTING=105, SETTING_LINE_COMMENT=106, SETTTING_MULTILINE_COMMENT=107,
+ SETTING_WS=108, LOOKUP_LINE_COMMENT=109, LOOKUP_MULTILINE_COMMENT=110,
+ LOOKUP_WS=111, LOOKUP_FIELD_LINE_COMMENT=112, LOOKUP_FIELD_MULTILINE_COMMENT=113,
+ LOOKUP_FIELD_WS=114, METRICS_LINE_COMMENT=115, METRICS_MULTILINE_COMMENT=116,
+ METRICS_WS=117, CLOSING_METRICS_LINE_COMMENT=118, CLOSING_METRICS_MULTILINE_COMMENT=119,
CLOSING_METRICS_WS=120;
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,
+ 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, METRICS_MODE=13, CLOSING_METRICS_MODE=14;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
- "DEFAULT_MODE", "EXPRESSION_MODE", "EXPLAIN_MODE", "FROM_MODE", "PROJECT_MODE",
- "RENAME_MODE", "ENRICH_MODE", "ENRICH_FIELD_MODE", "MVEXPAND_MODE", "SHOW_MODE",
+ "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", "METRICS_MODE", "CLOSING_METRICS_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",
- "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_MATCH", "DEV_METRICS", "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",
- "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", "DEV_MATCH_OP", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET",
- "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_ID", "QUOTED_IDENTIFIER",
- "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", "EXPLAIN_OPENING_BRACKET",
- "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
- "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", "FROM_COLON",
- "FROM_COMMA", "FROM_ASSIGN", "METADATA", "UNQUOTED_SOURCE_PART", "UNQUOTED_SOURCE",
- "FROM_UNQUOTED_SOURCE", "FROM_QUOTED_SOURCE", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT",
- "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", "PROJECT_PARAM",
- "PROJECT_NAMED_OR_POSITIONAL_PARAM", "UNQUOTED_ID_BODY_WITH_PATTERN",
- "UNQUOTED_ID_PATTERN", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT",
- "PROJECT_WS", "RENAME_PIPE", "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT",
- "RENAME_PARAM", "RENAME_NAMED_OR_POSITIONAL_PARAM", "AS", "RENAME_ID_PATTERN",
- "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ENRICH_PIPE",
- "ENRICH_OPENING_BRACKET", "ON", "WITH", "ENRICH_POLICY_NAME_BODY", "ENRICH_POLICY_NAME",
- "ENRICH_MODE_UNQUOTED_VALUE", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT",
- "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA",
- "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_ID_PATTERN", "ENRICH_FIELD_QUOTED_IDENTIFIER",
- "ENRICH_FIELD_PARAM", "ENRICH_FIELD_NAMED_OR_POSITIONAL_PARAM", "ENRICH_FIELD_LINE_COMMENT",
- "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_PIPE",
- "MVEXPAND_DOT", "MVEXPAND_PARAM", "MVEXPAND_NAMED_OR_POSITIONAL_PARAM",
- "MVEXPAND_QUOTED_IDENTIFIER", "MVEXPAND_UNQUOTED_IDENTIFIER", "MVEXPAND_LINE_COMMENT",
- "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "SHOW_PIPE", "INFO", "SHOW_LINE_COMMENT",
- "SHOW_MULTILINE_COMMENT", "SHOW_WS", "SETTING_CLOSING_BRACKET", "COLON",
- "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", "SETTING_WS",
- "LOOKUP_PIPE", "LOOKUP_COLON", "LOOKUP_COMMA", "LOOKUP_DOT", "LOOKUP_ON",
- "LOOKUP_UNQUOTED_SOURCE", "LOOKUP_QUOTED_SOURCE", "LOOKUP_LINE_COMMENT",
- "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_PIPE", "LOOKUP_FIELD_COMMA",
- "LOOKUP_FIELD_DOT", "LOOKUP_FIELD_ID_PATTERN", "LOOKUP_FIELD_LINE_COMMENT",
- "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "METRICS_PIPE",
- "METRICS_UNQUOTED_SOURCE", "METRICS_QUOTED_SOURCE", "METRICS_LINE_COMMENT",
- "METRICS_MULTILINE_COMMENT", "METRICS_WS", "CLOSING_METRICS_COLON", "CLOSING_METRICS_COMMA",
- "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
- "CLOSING_METRICS_WS", "CLOSING_METRICS_QUOTED_IDENTIFIER", "CLOSING_METRICS_UNQUOTED_IDENTIFIER",
+ "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "KEEP",
+ "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", "WHERE",
+ "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_METRICS", "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", "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", "DEV_MATCH", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET",
+ "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_ID", "QUOTED_IDENTIFIER",
+ "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT", "EXPR_WS", "EXPLAIN_OPENING_BRACKET",
+ "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
+ "FROM_PIPE", "FROM_OPENING_BRACKET", "FROM_CLOSING_BRACKET", "FROM_COLON",
+ "FROM_COMMA", "FROM_ASSIGN", "METADATA", "UNQUOTED_SOURCE_PART", "UNQUOTED_SOURCE",
+ "FROM_UNQUOTED_SOURCE", "FROM_QUOTED_SOURCE", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT",
+ "FROM_WS", "PROJECT_PIPE", "PROJECT_DOT", "PROJECT_COMMA", "PROJECT_PARAM",
+ "PROJECT_NAMED_OR_POSITIONAL_PARAM", "UNQUOTED_ID_BODY_WITH_PATTERN",
+ "UNQUOTED_ID_PATTERN", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT",
+ "PROJECT_WS", "RENAME_PIPE", "RENAME_ASSIGN", "RENAME_COMMA", "RENAME_DOT",
+ "RENAME_PARAM", "RENAME_NAMED_OR_POSITIONAL_PARAM", "AS", "RENAME_ID_PATTERN",
+ "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ENRICH_PIPE",
+ "ENRICH_OPENING_BRACKET", "ON", "WITH", "ENRICH_POLICY_NAME_BODY", "ENRICH_POLICY_NAME",
+ "ENRICH_MODE_UNQUOTED_VALUE", "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT",
+ "ENRICH_WS", "ENRICH_FIELD_PIPE", "ENRICH_FIELD_ASSIGN", "ENRICH_FIELD_COMMA",
+ "ENRICH_FIELD_DOT", "ENRICH_FIELD_WITH", "ENRICH_FIELD_ID_PATTERN", "ENRICH_FIELD_QUOTED_IDENTIFIER",
+ "ENRICH_FIELD_PARAM", "ENRICH_FIELD_NAMED_OR_POSITIONAL_PARAM", "ENRICH_FIELD_LINE_COMMENT",
+ "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_PIPE",
+ "MVEXPAND_DOT", "MVEXPAND_PARAM", "MVEXPAND_NAMED_OR_POSITIONAL_PARAM",
+ "MVEXPAND_QUOTED_IDENTIFIER", "MVEXPAND_UNQUOTED_IDENTIFIER", "MVEXPAND_LINE_COMMENT",
+ "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "SHOW_PIPE", "INFO", "SHOW_LINE_COMMENT",
+ "SHOW_MULTILINE_COMMENT", "SHOW_WS", "SETTING_CLOSING_BRACKET", "COLON",
+ "SETTING", "SETTING_LINE_COMMENT", "SETTTING_MULTILINE_COMMENT", "SETTING_WS",
+ "LOOKUP_PIPE", "LOOKUP_COLON", "LOOKUP_COMMA", "LOOKUP_DOT", "LOOKUP_ON",
+ "LOOKUP_UNQUOTED_SOURCE", "LOOKUP_QUOTED_SOURCE", "LOOKUP_LINE_COMMENT",
+ "LOOKUP_MULTILINE_COMMENT", "LOOKUP_WS", "LOOKUP_FIELD_PIPE", "LOOKUP_FIELD_COMMA",
+ "LOOKUP_FIELD_DOT", "LOOKUP_FIELD_ID_PATTERN", "LOOKUP_FIELD_LINE_COMMENT",
+ "LOOKUP_FIELD_MULTILINE_COMMENT", "LOOKUP_FIELD_WS", "METRICS_PIPE",
+ "METRICS_UNQUOTED_SOURCE", "METRICS_QUOTED_SOURCE", "METRICS_LINE_COMMENT",
+ "METRICS_MULTILINE_COMMENT", "METRICS_WS", "CLOSING_METRICS_COLON", "CLOSING_METRICS_COMMA",
+ "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
+ "CLOSING_METRICS_WS", "CLOSING_METRICS_QUOTED_IDENTIFIER", "CLOSING_METRICS_UNQUOTED_IDENTIFIER",
"CLOSING_METRICS_BY", "CLOSING_METRICS_PIPE"
};
}
@@ -116,46 +118,46 @@ private static String[] makeRuleNames() {
private static String[] makeLiteralNames() {
return new String[] {
- null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'",
- "'grok'", "'keep'", "'limit'", "'mv_expand'", "'rename'", "'row'", "'show'",
- "'sort'", "'stats'", "'where'", null, 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'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='",
- "'+'", "'-'", "'*'", "'/'", "'%'", null, null, "']'", null, null, null,
- null, null, null, null, null, "'metadata'", null, null, null, null, null,
- null, null, null, "'as'", null, null, null, "'on'", "'with'", null, null,
- null, null, null, null, null, null, null, null, "'info'", null, null,
+ null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'",
+ "'grok'", "'keep'", "'limit'", "'mv_expand'", "'rename'", "'row'", "'show'",
+ "'sort'", "'stats'", "'where'", 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'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'",
+ "'-'", "'*'", "'/'", "'%'", null, null, null, "']'", null, null, null,
+ null, null, null, null, null, "'metadata'", null, null, null, null, null,
+ null, null, null, "'as'", null, null, null, "'on'", "'with'", null, null,
+ null, null, null, null, null, null, null, null, "'info'", null, null,
null, "':'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
- null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK",
- "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS",
- "WHERE", "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_MATCH", "DEV_METRICS",
- "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING",
- "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP",
- "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", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET", "CLOSING_BRACKET",
- "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT",
- "EXPR_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
- "METADATA", "UNQUOTED_SOURCE", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT",
- "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT",
- "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT",
- "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT",
- "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT",
- "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT",
- "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT",
- "SHOW_MULTILINE_COMMENT", "SHOW_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT",
- "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT",
- "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT",
- "LOOKUP_FIELD_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT",
- "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
+ null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK",
+ "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS",
+ "WHERE", "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_METRICS", "UNKNOWN_CMD",
+ "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING", "INTEGER_LITERAL",
+ "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", "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", "DEV_MATCH", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET",
+ "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT",
+ "EXPR_MULTILINE_COMMENT", "EXPR_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT",
+ "EXPLAIN_MULTILINE_COMMENT", "METADATA", "UNQUOTED_SOURCE", "FROM_LINE_COMMENT",
+ "FROM_MULTILINE_COMMENT", "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT",
+ "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "AS", "RENAME_LINE_COMMENT",
+ "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME",
+ "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT",
+ "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT",
+ "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT",
+ "SHOW_MULTILINE_COMMENT", "SHOW_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT",
+ "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT",
+ "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT",
+ "LOOKUP_FIELD_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT",
+ "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
"CLOSING_METRICS_WS"
};
}
@@ -226,11 +228,9 @@ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
case 17:
return DEV_LOOKUP_sempred((RuleContext)_localctx, predIndex);
case 18:
- return DEV_MATCH_sempred((RuleContext)_localctx, predIndex);
- case 19:
return DEV_METRICS_sempred((RuleContext)_localctx, predIndex);
- case 73:
- return DEV_MATCH_OP_sempred((RuleContext)_localctx, predIndex);
+ case 72:
+ return DEV_MATCH_sempred((RuleContext)_localctx, predIndex);
}
return true;
}
@@ -248,30 +248,23 @@ private boolean DEV_LOOKUP_sempred(RuleContext _localctx, int predIndex) {
}
return true;
}
- private boolean DEV_MATCH_sempred(RuleContext _localctx, int predIndex) {
+ private boolean DEV_METRICS_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_MATCH_sempred(RuleContext _localctx, int predIndex) {
switch (predIndex) {
case 3:
return this.isDevVersion();
}
return true;
}
- private boolean DEV_MATCH_OP_sempred(RuleContext _localctx, int predIndex) {
- switch (predIndex) {
- case 4:
- return this.isDevVersion();
- }
- return true;
- }
public static final String _serializedATN =
- "\u0004\u0000x\u05c3\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff"+
+ "\u0004\u0000x\u05ba\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"+
@@ -327,908 +320,902 @@ private boolean DEV_MATCH_OP_sempred(RuleContext _localctx, int predIndex) {
"\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\u0001"+
+ "\u00c3\u0007\u00c3\u0002\u00c4\u0007\u00c4\u0001\u0000\u0001\u0000\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"+
+ "\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"+
- "\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"+
+ "\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\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010"+
- "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0011\u0001\u0011\u0001\u0011"+
- "\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
- "\u0001\u0011\u0001\u0012\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\u0013\u0001\u0013\u0001\u0013"+
- "\u0001\u0013\u0001\u0013\u0001\u0013\u0001\u0014\u0004\u0014\u024b\b\u0014"+
- "\u000b\u0014\f\u0014\u024c\u0001\u0014\u0001\u0014\u0001\u0015\u0001\u0015"+
- "\u0001\u0015\u0001\u0015\u0005\u0015\u0255\b\u0015\n\u0015\f\u0015\u0258"+
- "\t\u0015\u0001\u0015\u0003\u0015\u025b\b\u0015\u0001\u0015\u0003\u0015"+
- "\u025e\b\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001\u0016\u0001\u0016"+
- "\u0001\u0016\u0001\u0016\u0005\u0016\u0267\b\u0016\n\u0016\f\u0016\u026a"+
- "\t\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001"+
- "\u0017\u0004\u0017\u0272\b\u0017\u000b\u0017\f\u0017\u0273\u0001\u0017"+
- "\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0018\u0001\u0019"+
- "\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001b"+
- "\u0001\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0003\u001d\u0287\b\u001d"+
- "\u0001\u001d\u0004\u001d\u028a\b\u001d\u000b\u001d\f\u001d\u028b\u0001"+
- "\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001 \u0003"+
- " \u0295\b \u0001!\u0001!\u0001\"\u0001\"\u0001\"\u0003\"\u029c\b\"\u0001"+
- "#\u0001#\u0001#\u0005#\u02a1\b#\n#\f#\u02a4\t#\u0001#\u0001#\u0001#\u0001"+
- "#\u0001#\u0001#\u0005#\u02ac\b#\n#\f#\u02af\t#\u0001#\u0001#\u0001#\u0001"+
- "#\u0001#\u0003#\u02b6\b#\u0001#\u0003#\u02b9\b#\u0003#\u02bb\b#\u0001"+
- "$\u0004$\u02be\b$\u000b$\f$\u02bf\u0001%\u0004%\u02c3\b%\u000b%\f%\u02c4"+
- "\u0001%\u0001%\u0005%\u02c9\b%\n%\f%\u02cc\t%\u0001%\u0001%\u0004%\u02d0"+
- "\b%\u000b%\f%\u02d1\u0001%\u0004%\u02d5\b%\u000b%\f%\u02d6\u0001%\u0001"+
- "%\u0005%\u02db\b%\n%\f%\u02de\t%\u0003%\u02e0\b%\u0001%\u0001%\u0001%"+
- "\u0001%\u0004%\u02e6\b%\u000b%\f%\u02e7\u0001%\u0001%\u0003%\u02ec\b%"+
- "\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0001(\u0001(\u0001"+
- "(\u0001(\u0001)\u0001)\u0001*\u0001*\u0001*\u0001+\u0001+\u0001,\u0001"+
- ",\u0001,\u0001,\u0001,\u0001-\u0001-\u0001.\u0001.\u0001.\u0001.\u0001"+
- ".\u0001.\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u00010\u00010\u0001"+
- "0\u00011\u00011\u00011\u00012\u00012\u00012\u00012\u00012\u00013\u0001"+
- "3\u00013\u00013\u00013\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+
- "6\u00016\u00016\u00016\u00016\u00017\u00017\u00017\u00017\u00017\u0001"+
- "7\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"+
- "A\u0001A\u0001A\u0001B\u0001B\u0001C\u0001C\u0001C\u0001D\u0001D\u0001"+
- "E\u0001E\u0001F\u0001F\u0001G\u0001G\u0001H\u0001H\u0001I\u0001I\u0001"+
- "I\u0001I\u0001I\u0001J\u0001J\u0001J\u0003J\u036b\bJ\u0001J\u0005J\u036e"+
- "\bJ\nJ\fJ\u0371\tJ\u0001J\u0001J\u0004J\u0375\bJ\u000bJ\fJ\u0376\u0003"+
- "J\u0379\bJ\u0001K\u0001K\u0001K\u0001K\u0001K\u0001L\u0001L\u0001L\u0001"+
- "L\u0001L\u0001M\u0001M\u0005M\u0387\bM\nM\fM\u038a\tM\u0001M\u0001M\u0003"+
- "M\u038e\bM\u0001M\u0004M\u0391\bM\u000bM\fM\u0392\u0003M\u0395\bM\u0001"+
- "N\u0001N\u0004N\u0399\bN\u000bN\fN\u039a\u0001N\u0001N\u0001O\u0001O\u0001"+
- "P\u0001P\u0001P\u0001P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001"+
- "R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001S\u0001T\u0001T\u0001T\u0001"+
- "T\u0001T\u0001U\u0001U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001V\u0001"+
- "W\u0001W\u0001W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001"+
- "Y\u0001Y\u0001Y\u0001Z\u0001Z\u0001Z\u0001Z\u0001[\u0001[\u0001[\u0001"+
- "[\u0001\\\u0001\\\u0001\\\u0001\\\u0001]\u0001]\u0001]\u0001]\u0001^\u0001"+
- "^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001_\u0001_\u0001"+
- "_\u0003_\u03e8\b_\u0001`\u0004`\u03eb\b`\u000b`\f`\u03ec\u0001a\u0001"+
- "a\u0001a\u0001a\u0001b\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001"+
- "c\u0001d\u0001d\u0001d\u0001d\u0001e\u0001e\u0001e\u0001e\u0001f\u0001"+
- "f\u0001f\u0001f\u0001f\u0001g\u0001g\u0001g\u0001g\u0001h\u0001h\u0001"+
- "h\u0001h\u0001i\u0001i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0001"+
- "k\u0001k\u0001k\u0001k\u0003k\u041c\bk\u0001l\u0001l\u0003l\u0420\bl\u0001"+
- "l\u0005l\u0423\bl\nl\fl\u0426\tl\u0001l\u0001l\u0003l\u042a\bl\u0001l"+
- "\u0004l\u042d\bl\u000bl\fl\u042e\u0003l\u0431\bl\u0001m\u0001m\u0004m"+
- "\u0435\bm\u000bm\fm\u0436\u0001n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001"+
- "o\u0001o\u0001p\u0001p\u0001p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001"+
- "q\u0001r\u0001r\u0001r\u0001r\u0001s\u0001s\u0001s\u0001s\u0001t\u0001"+
- "t\u0001t\u0001t\u0001u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001"+
- "v\u0001w\u0001w\u0001w\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~\u0001~\u0001~\u0001~\u0001\u007f\u0001\u007f\u0001\u007f\u0001"+
- "\u007f\u0001\u007f\u0001\u007f\u0001\u007f\u0001\u0080\u0001\u0080\u0001"+
- "\u0081\u0004\u0081\u048a\b\u0081\u000b\u0081\f\u0081\u048b\u0001\u0081"+
- "\u0001\u0081\u0003\u0081\u0490\b\u0081\u0001\u0081\u0004\u0081\u0493\b"+
- "\u0081\u000b\u0081\f\u0081\u0494\u0001\u0082\u0001\u0082\u0001\u0082\u0001"+
- "\u0082\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0083\u0001\u0084\u0001"+
- "\u0084\u0001\u0084\u0001\u0084\u0001\u0085\u0001\u0085\u0001\u0085\u0001"+
- "\u0085\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001"+
- "\u0086\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0087\u0001\u0088\u0001"+
- "\u0088\u0001\u0088\u0001\u0088\u0001\u0089\u0001\u0089\u0001\u0089\u0001"+
- "\u0089\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008a\u0001\u008b\u0001"+
- "\u008b\u0001\u008b\u0001\u008b\u0001\u008c\u0001\u008c\u0001\u008c\u0001"+
- "\u008c\u0001\u008d\u0001\u008d\u0001\u008d\u0001\u008d\u0001\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\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\u009b\u0001\u009b\u0001"+
- "\u009b\u0001\u009b\u0001\u009b\u0001\u009c\u0001\u009c\u0001\u009c\u0001"+
- "\u009c\u0001\u009c\u0001\u009d\u0001\u009d\u0001\u009d\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"+
- "\u00a0\u0001\u00a1\u0001\u00a1\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001"+
- "\u00a2\u0001\u00a2\u0004\u00a2\u0520\b\u00a2\u000b\u00a2\f\u00a2\u0521"+
- "\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\u00a6\u0001\u00a7"+
- "\u0001\u00a7\u0001\u00a7\u0001\u00a7\u0001\u00a8\u0001\u00a8\u0001\u00a8"+
- "\u0001\u00a8\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00a9\u0001\u00aa"+
- "\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00aa\u0001\u00ab\u0001\u00ab"+
- "\u0001\u00ab\u0001\u00ab\u0001\u00ac\u0001\u00ac\u0001\u00ac\u0001\u00ac"+
- "\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\u00b0\u0001\u00b0"+
- "\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b1\u0001\u00b2\u0001\u00b2"+
- "\u0001\u00b2\u0001\u00b2\u0001\u00b3\u0001\u00b3\u0001\u00b3\u0001\u00b3"+
- "\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\u00b4\u0001\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\u00b8"+
- "\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b8\u0001\u00b9"+
- "\u0001\u00b9\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\u00bd\u0001\u00bd\u0001\u00be"+
- "\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00be\u0001\u00bf"+
- "\u0001\u00bf\u0001\u00bf\u0001\u00bf\u0001\u00c0\u0001\u00c0\u0001\u00c0"+
- "\u0001\u00c0\u0001\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\u00c4"+
- "\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0001\u00c5"+
- "\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0001\u00c5\u0002\u0268\u02ad\u0000"+
- "\u00c6\u000f\u0001\u0011\u0002\u0013\u0003\u0015\u0004\u0017\u0005\u0019"+
- "\u0006\u001b\u0007\u001d\b\u001f\t!\n#\u000b%\f\'\r)\u000e+\u000f-\u0010"+
- "/\u00111\u00123\u00135\u00147\u00159\u0016;\u0017=\u0018?\u0019A\u0000"+
- "C\u0000E\u0000G\u0000I\u0000K\u0000M\u0000O\u0000Q\u0000S\u0000U\u001a"+
- "W\u001bY\u001c[\u001d]\u001e_\u001fa c!e\"g#i$k%m&o\'q(s)u*w+y,{-}.\u007f"+
- "/\u00810\u00831\u00852\u00873\u00894\u008b5\u008d6\u008f7\u00918\u0093"+
- "9\u0095:\u0097;\u0099<\u009b=\u009d>\u009f?\u00a1\u0000\u00a3@\u00a5A"+
- "\u00a7B\u00a9C\u00ab\u0000\u00adD\u00afE\u00b1F\u00b3G\u00b5\u0000\u00b7"+
- "\u0000\u00b9H\u00bbI\u00bdJ\u00bf\u0000\u00c1\u0000\u00c3\u0000\u00c5"+
- "\u0000\u00c7\u0000\u00c9\u0000\u00cbK\u00cd\u0000\u00cfL\u00d1\u0000\u00d3"+
- "\u0000\u00d5M\u00d7N\u00d9O\u00db\u0000\u00dd\u0000\u00df\u0000\u00e1"+
- "\u0000\u00e3\u0000\u00e5\u0000\u00e7\u0000\u00e9P\u00ebQ\u00edR\u00ef"+
- "S\u00f1\u0000\u00f3\u0000\u00f5\u0000\u00f7\u0000\u00f9\u0000\u00fb\u0000"+
- "\u00fdT\u00ff\u0000\u0101U\u0103V\u0105W\u0107\u0000\u0109\u0000\u010b"+
- "X\u010dY\u010f\u0000\u0111Z\u0113\u0000\u0115[\u0117\\\u0119]\u011b\u0000"+
- "\u011d\u0000\u011f\u0000\u0121\u0000\u0123\u0000\u0125\u0000\u0127\u0000"+
- "\u0129\u0000\u012b\u0000\u012d^\u012f_\u0131`\u0133\u0000\u0135\u0000"+
- "\u0137\u0000\u0139\u0000\u013b\u0000\u013d\u0000\u013fa\u0141b\u0143c"+
- "\u0145\u0000\u0147d\u0149e\u014bf\u014dg\u014f\u0000\u0151h\u0153i\u0155"+
- "j\u0157k\u0159l\u015b\u0000\u015d\u0000\u015f\u0000\u0161\u0000\u0163"+
- "\u0000\u0165\u0000\u0167\u0000\u0169m\u016bn\u016do\u016f\u0000\u0171"+
- "\u0000\u0173\u0000\u0175\u0000\u0177p\u0179q\u017br\u017d\u0000\u017f"+
- "\u0000\u0181\u0000\u0183s\u0185t\u0187u\u0189\u0000\u018b\u0000\u018d"+
- "v\u018fw\u0191x\u0193\u0000\u0195\u0000\u0197\u0000\u0199\u0000\u000f"+
- "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e"+
- "#\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 \"#,,"+
- "//::<<>?\\\\||\u05df\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011\u0001"+
- "\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001"+
- "\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001"+
- "\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001"+
- "\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000\u0000!\u0001\u0000"+
- "\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%\u0001\u0000\u0000\u0000"+
- "\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001\u0000\u0000\u0000\u0000"+
- "+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000\u0000\u0000/\u0001"+
- "\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u00003\u0001\u0000\u0000"+
- "\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001\u0000\u0000\u0000\u0000"+
- "9\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000\u0000\u0000=\u0001"+
- "\u0000\u0000\u0000\u0001?\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_\u0001"+
- "\u0000\u0000\u0000\u0001a\u0001\u0000\u0000\u0000\u0001c\u0001\u0000\u0000"+
- "\u0000\u0001e\u0001\u0000\u0000\u0000\u0001g\u0001\u0000\u0000\u0000\u0001"+
- "i\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\u0001"+
- "w\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\u00ad\u0001\u0000"+
- "\u0000\u0000\u0001\u00af\u0001\u0000\u0000\u0000\u0001\u00b1\u0001\u0000"+
- "\u0000\u0000\u0001\u00b3\u0001\u0000\u0000\u0000\u0002\u00b5\u0001\u0000"+
- "\u0000\u0000\u0002\u00b7\u0001\u0000\u0000\u0000\u0002\u00b9\u0001\u0000"+
- "\u0000\u0000\u0002\u00bb\u0001\u0000\u0000\u0000\u0002\u00bd\u0001\u0000"+
- "\u0000\u0000\u0003\u00bf\u0001\u0000\u0000\u0000\u0003\u00c1\u0001\u0000"+
- "\u0000\u0000\u0003\u00c3\u0001\u0000\u0000\u0000\u0003\u00c5\u0001\u0000"+
- "\u0000\u0000\u0003\u00c7\u0001\u0000\u0000\u0000\u0003\u00c9\u0001\u0000"+
- "\u0000\u0000\u0003\u00cb\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\u0004\u00db\u0001\u0000"+
- "\u0000\u0000\u0004\u00dd\u0001\u0000\u0000\u0000\u0004\u00df\u0001\u0000"+
- "\u0000\u0000\u0004\u00e1\u0001\u0000\u0000\u0000\u0004\u00e3\u0001\u0000"+
- "\u0000\u0000\u0004\u00e9\u0001\u0000\u0000\u0000\u0004\u00eb\u0001\u0000"+
- "\u0000\u0000\u0004\u00ed\u0001\u0000\u0000\u0000\u0004\u00ef\u0001\u0000"+
- "\u0000\u0000\u0005\u00f1\u0001\u0000\u0000\u0000\u0005\u00f3\u0001\u0000"+
- "\u0000\u0000\u0005\u00f5\u0001\u0000\u0000\u0000\u0005\u00f7\u0001\u0000"+
- "\u0000\u0000\u0005\u00f9\u0001\u0000\u0000\u0000\u0005\u00fb\u0001\u0000"+
- "\u0000\u0000\u0005\u00fd\u0001\u0000\u0000\u0000\u0005\u00ff\u0001\u0000"+
- "\u0000\u0000\u0005\u0101\u0001\u0000\u0000\u0000\u0005\u0103\u0001\u0000"+
- "\u0000\u0000\u0005\u0105\u0001\u0000\u0000\u0000\u0006\u0107\u0001\u0000"+
- "\u0000\u0000\u0006\u0109\u0001\u0000\u0000\u0000\u0006\u010b\u0001\u0000"+
- "\u0000\u0000\u0006\u010d\u0001\u0000\u0000\u0000\u0006\u0111\u0001\u0000"+
- "\u0000\u0000\u0006\u0113\u0001\u0000\u0000\u0000\u0006\u0115\u0001\u0000"+
- "\u0000\u0000\u0006\u0117\u0001\u0000\u0000\u0000\u0006\u0119\u0001\u0000"+
- "\u0000\u0000\u0007\u011b\u0001\u0000\u0000\u0000\u0007\u011d\u0001\u0000"+
- "\u0000\u0000\u0007\u011f\u0001\u0000\u0000\u0000\u0007\u0121\u0001\u0000"+
- "\u0000\u0000\u0007\u0123\u0001\u0000\u0000\u0000\u0007\u0125\u0001\u0000"+
- "\u0000\u0000\u0007\u0127\u0001\u0000\u0000\u0000\u0007\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\b\u0133\u0001\u0000\u0000\u0000\b\u0135\u0001\u0000\u0000"+
- "\u0000\b\u0137\u0001\u0000\u0000\u0000\b\u0139\u0001\u0000\u0000\u0000"+
- "\b\u013b\u0001\u0000\u0000\u0000\b\u013d\u0001\u0000\u0000\u0000\b\u013f"+
- "\u0001\u0000\u0000\u0000\b\u0141\u0001\u0000\u0000\u0000\b\u0143\u0001"+
- "\u0000\u0000\u0000\t\u0145\u0001\u0000\u0000\u0000\t\u0147\u0001\u0000"+
- "\u0000\u0000\t\u0149\u0001\u0000\u0000\u0000\t\u014b\u0001\u0000\u0000"+
- "\u0000\t\u014d\u0001\u0000\u0000\u0000\n\u014f\u0001\u0000\u0000\u0000"+
- "\n\u0151\u0001\u0000\u0000\u0000\n\u0153\u0001\u0000\u0000\u0000\n\u0155"+
- "\u0001\u0000\u0000\u0000\n\u0157\u0001\u0000\u0000\u0000\n\u0159\u0001"+
- "\u0000\u0000\u0000\u000b\u015b\u0001\u0000\u0000\u0000\u000b\u015d\u0001"+
- "\u0000\u0000\u0000\u000b\u015f\u0001\u0000\u0000\u0000\u000b\u0161\u0001"+
- "\u0000\u0000\u0000\u000b\u0163\u0001\u0000\u0000\u0000\u000b\u0165\u0001"+
- "\u0000\u0000\u0000\u000b\u0167\u0001\u0000\u0000\u0000\u000b\u0169\u0001"+
- "\u0000\u0000\u0000\u000b\u016b\u0001\u0000\u0000\u0000\u000b\u016d\u0001"+
- "\u0000\u0000\u0000\f\u016f\u0001\u0000\u0000\u0000\f\u0171\u0001\u0000"+
- "\u0000\u0000\f\u0173\u0001\u0000\u0000\u0000\f\u0175\u0001\u0000\u0000"+
- "\u0000\f\u0177\u0001\u0000\u0000\u0000\f\u0179\u0001\u0000\u0000\u0000"+
- "\f\u017b\u0001\u0000\u0000\u0000\r\u017d\u0001\u0000\u0000\u0000\r\u017f"+
- "\u0001\u0000\u0000\u0000\r\u0181\u0001\u0000\u0000\u0000\r\u0183\u0001"+
- "\u0000\u0000\u0000\r\u0185\u0001\u0000\u0000\u0000\r\u0187\u0001\u0000"+
- "\u0000\u0000\u000e\u0189\u0001\u0000\u0000\u0000\u000e\u018b\u0001\u0000"+
- "\u0000\u0000\u000e\u018d\u0001\u0000\u0000\u0000\u000e\u018f\u0001\u0000"+
- "\u0000\u0000\u000e\u0191\u0001\u0000\u0000\u0000\u000e\u0193\u0001\u0000"+
- "\u0000\u0000\u000e\u0195\u0001\u0000\u0000\u0000\u000e\u0197\u0001\u0000"+
- "\u0000\u0000\u000e\u0199\u0001\u0000\u0000\u0000\u000f\u019b\u0001\u0000"+
- "\u0000\u0000\u0011\u01a5\u0001\u0000\u0000\u0000\u0013\u01ac\u0001\u0000"+
- "\u0000\u0000\u0015\u01b5\u0001\u0000\u0000\u0000\u0017\u01bc\u0001\u0000"+
- "\u0000\u0000\u0019\u01c6\u0001\u0000\u0000\u0000\u001b\u01cd\u0001\u0000"+
- "\u0000\u0000\u001d\u01d4\u0001\u0000\u0000\u0000\u001f\u01db\u0001\u0000"+
- "\u0000\u0000!\u01e3\u0001\u0000\u0000\u0000#\u01ef\u0001\u0000\u0000\u0000"+
- "%\u01f8\u0001\u0000\u0000\u0000\'\u01fe\u0001\u0000\u0000\u0000)\u0205"+
- "\u0001\u0000\u0000\u0000+\u020c\u0001\u0000\u0000\u0000-\u0214\u0001\u0000"+
- "\u0000\u0000/\u021c\u0001\u0000\u0000\u00001\u022b\u0001\u0000\u0000\u0000"+
- "3\u0235\u0001\u0000\u0000\u00005\u023e\u0001\u0000\u0000\u00007\u024a"+
- "\u0001\u0000\u0000\u00009\u0250\u0001\u0000\u0000\u0000;\u0261\u0001\u0000"+
- "\u0000\u0000=\u0271\u0001\u0000\u0000\u0000?\u0277\u0001\u0000\u0000\u0000"+
- "A\u027b\u0001\u0000\u0000\u0000C\u027d\u0001\u0000\u0000\u0000E\u027f"+
- "\u0001\u0000\u0000\u0000G\u0282\u0001\u0000\u0000\u0000I\u0284\u0001\u0000"+
- "\u0000\u0000K\u028d\u0001\u0000\u0000\u0000M\u028f\u0001\u0000\u0000\u0000"+
- "O\u0294\u0001\u0000\u0000\u0000Q\u0296\u0001\u0000\u0000\u0000S\u029b"+
- "\u0001\u0000\u0000\u0000U\u02ba\u0001\u0000\u0000\u0000W\u02bd\u0001\u0000"+
- "\u0000\u0000Y\u02eb\u0001\u0000\u0000\u0000[\u02ed\u0001\u0000\u0000\u0000"+
- "]\u02f0\u0001\u0000\u0000\u0000_\u02f4\u0001\u0000\u0000\u0000a\u02f8"+
- "\u0001\u0000\u0000\u0000c\u02fa\u0001\u0000\u0000\u0000e\u02fd\u0001\u0000"+
- "\u0000\u0000g\u02ff\u0001\u0000\u0000\u0000i\u0304\u0001\u0000\u0000\u0000"+
- "k\u0306\u0001\u0000\u0000\u0000m\u030c\u0001\u0000\u0000\u0000o\u0312"+
- "\u0001\u0000\u0000\u0000q\u0315\u0001\u0000\u0000\u0000s\u0318\u0001\u0000"+
- "\u0000\u0000u\u031d\u0001\u0000\u0000\u0000w\u0322\u0001\u0000\u0000\u0000"+
- "y\u0324\u0001\u0000\u0000\u0000{\u0328\u0001\u0000\u0000\u0000}\u032d"+
- "\u0001\u0000\u0000\u0000\u007f\u0333\u0001\u0000\u0000\u0000\u0081\u0336"+
- "\u0001\u0000\u0000\u0000\u0083\u0338\u0001\u0000\u0000\u0000\u0085\u033e"+
- "\u0001\u0000\u0000\u0000\u0087\u0340\u0001\u0000\u0000\u0000\u0089\u0345"+
- "\u0001\u0000\u0000\u0000\u008b\u0348\u0001\u0000\u0000\u0000\u008d\u034b"+
- "\u0001\u0000\u0000\u0000\u008f\u034e\u0001\u0000\u0000\u0000\u0091\u0350"+
- "\u0001\u0000\u0000\u0000\u0093\u0353\u0001\u0000\u0000\u0000\u0095\u0355"+
- "\u0001\u0000\u0000\u0000\u0097\u0358\u0001\u0000\u0000\u0000\u0099\u035a"+
- "\u0001\u0000\u0000\u0000\u009b\u035c\u0001\u0000\u0000\u0000\u009d\u035e"+
- "\u0001\u0000\u0000\u0000\u009f\u0360\u0001\u0000\u0000\u0000\u00a1\u0362"+
- "\u0001\u0000\u0000\u0000\u00a3\u0378\u0001\u0000\u0000\u0000\u00a5\u037a"+
- "\u0001\u0000\u0000\u0000\u00a7\u037f\u0001\u0000\u0000\u0000\u00a9\u0394"+
- "\u0001\u0000\u0000\u0000\u00ab\u0396\u0001\u0000\u0000\u0000\u00ad\u039e"+
- "\u0001\u0000\u0000\u0000\u00af\u03a0\u0001\u0000\u0000\u0000\u00b1\u03a4"+
- "\u0001\u0000\u0000\u0000\u00b3\u03a8\u0001\u0000\u0000\u0000\u00b5\u03ac"+
- "\u0001\u0000\u0000\u0000\u00b7\u03b1\u0001\u0000\u0000\u0000\u00b9\u03b6"+
- "\u0001\u0000\u0000\u0000\u00bb\u03ba\u0001\u0000\u0000\u0000\u00bd\u03be"+
- "\u0001\u0000\u0000\u0000\u00bf\u03c2\u0001\u0000\u0000\u0000\u00c1\u03c7"+
- "\u0001\u0000\u0000\u0000\u00c3\u03cb\u0001\u0000\u0000\u0000\u00c5\u03cf"+
- "\u0001\u0000\u0000\u0000\u00c7\u03d3\u0001\u0000\u0000\u0000\u00c9\u03d7"+
- "\u0001\u0000\u0000\u0000\u00cb\u03db\u0001\u0000\u0000\u0000\u00cd\u03e7"+
- "\u0001\u0000\u0000\u0000\u00cf\u03ea\u0001\u0000\u0000\u0000\u00d1\u03ee"+
- "\u0001\u0000\u0000\u0000\u00d3\u03f2\u0001\u0000\u0000\u0000\u00d5\u03f6"+
- "\u0001\u0000\u0000\u0000\u00d7\u03fa\u0001\u0000\u0000\u0000\u00d9\u03fe"+
- "\u0001\u0000\u0000\u0000\u00db\u0402\u0001\u0000\u0000\u0000\u00dd\u0407"+
- "\u0001\u0000\u0000\u0000\u00df\u040b\u0001\u0000\u0000\u0000\u00e1\u040f"+
- "\u0001\u0000\u0000\u0000\u00e3\u0413\u0001\u0000\u0000\u0000\u00e5\u041b"+
- "\u0001\u0000\u0000\u0000\u00e7\u0430\u0001\u0000\u0000\u0000\u00e9\u0434"+
- "\u0001\u0000\u0000\u0000\u00eb\u0438\u0001\u0000\u0000\u0000\u00ed\u043c"+
- "\u0001\u0000\u0000\u0000\u00ef\u0440\u0001\u0000\u0000\u0000\u00f1\u0444"+
- "\u0001\u0000\u0000\u0000\u00f3\u0449\u0001\u0000\u0000\u0000\u00f5\u044d"+
- "\u0001\u0000\u0000\u0000\u00f7\u0451\u0001\u0000\u0000\u0000\u00f9\u0455"+
- "\u0001\u0000\u0000\u0000\u00fb\u0459\u0001\u0000\u0000\u0000\u00fd\u045d"+
- "\u0001\u0000\u0000\u0000\u00ff\u0460\u0001\u0000\u0000\u0000\u0101\u0464"+
- "\u0001\u0000\u0000\u0000\u0103\u0468\u0001\u0000\u0000\u0000\u0105\u046c"+
- "\u0001\u0000\u0000\u0000\u0107\u0470\u0001\u0000\u0000\u0000\u0109\u0475"+
- "\u0001\u0000\u0000\u0000\u010b\u047a\u0001\u0000\u0000\u0000\u010d\u047f"+
- "\u0001\u0000\u0000\u0000\u010f\u0486\u0001\u0000\u0000\u0000\u0111\u048f"+
- "\u0001\u0000\u0000\u0000\u0113\u0496\u0001\u0000\u0000\u0000\u0115\u049a"+
- "\u0001\u0000\u0000\u0000\u0117\u049e\u0001\u0000\u0000\u0000\u0119\u04a2"+
- "\u0001\u0000\u0000\u0000\u011b\u04a6\u0001\u0000\u0000\u0000\u011d\u04ac"+
- "\u0001\u0000\u0000\u0000\u011f\u04b0\u0001\u0000\u0000\u0000\u0121\u04b4"+
- "\u0001\u0000\u0000\u0000\u0123\u04b8\u0001\u0000\u0000\u0000\u0125\u04bc"+
- "\u0001\u0000\u0000\u0000\u0127\u04c0\u0001\u0000\u0000\u0000\u0129\u04c4"+
- "\u0001\u0000\u0000\u0000\u012b\u04c8\u0001\u0000\u0000\u0000\u012d\u04cc"+
- "\u0001\u0000\u0000\u0000\u012f\u04d0\u0001\u0000\u0000\u0000\u0131\u04d4"+
- "\u0001\u0000\u0000\u0000\u0133\u04d8\u0001\u0000\u0000\u0000\u0135\u04dd"+
- "\u0001\u0000\u0000\u0000\u0137\u04e1\u0001\u0000\u0000\u0000\u0139\u04e5"+
- "\u0001\u0000\u0000\u0000\u013b\u04e9\u0001\u0000\u0000\u0000\u013d\u04ed"+
- "\u0001\u0000\u0000\u0000\u013f\u04f1\u0001\u0000\u0000\u0000\u0141\u04f5"+
- "\u0001\u0000\u0000\u0000\u0143\u04f9\u0001\u0000\u0000\u0000\u0145\u04fd"+
- "\u0001\u0000\u0000\u0000\u0147\u0502\u0001\u0000\u0000\u0000\u0149\u0507"+
- "\u0001\u0000\u0000\u0000\u014b\u050b\u0001\u0000\u0000\u0000\u014d\u050f"+
- "\u0001\u0000\u0000\u0000\u014f\u0513\u0001\u0000\u0000\u0000\u0151\u0518"+
- "\u0001\u0000\u0000\u0000\u0153\u051f\u0001\u0000\u0000\u0000\u0155\u0523"+
- "\u0001\u0000\u0000\u0000\u0157\u0527\u0001\u0000\u0000\u0000\u0159\u052b"+
- "\u0001\u0000\u0000\u0000\u015b\u052f\u0001\u0000\u0000\u0000\u015d\u0534"+
- "\u0001\u0000\u0000\u0000\u015f\u0538\u0001\u0000\u0000\u0000\u0161\u053c"+
- "\u0001\u0000\u0000\u0000\u0163\u0540\u0001\u0000\u0000\u0000\u0165\u0545"+
- "\u0001\u0000\u0000\u0000\u0167\u0549\u0001\u0000\u0000\u0000\u0169\u054d"+
- "\u0001\u0000\u0000\u0000\u016b\u0551\u0001\u0000\u0000\u0000\u016d\u0555"+
- "\u0001\u0000\u0000\u0000\u016f\u0559\u0001\u0000\u0000\u0000\u0171\u055f"+
- "\u0001\u0000\u0000\u0000\u0173\u0563\u0001\u0000\u0000\u0000\u0175\u0567"+
- "\u0001\u0000\u0000\u0000\u0177\u056b\u0001\u0000\u0000\u0000\u0179\u056f"+
- "\u0001\u0000\u0000\u0000\u017b\u0573\u0001\u0000\u0000\u0000\u017d\u0577"+
- "\u0001\u0000\u0000\u0000\u017f\u057c\u0001\u0000\u0000\u0000\u0181\u0582"+
- "\u0001\u0000\u0000\u0000\u0183\u0588\u0001\u0000\u0000\u0000\u0185\u058c"+
- "\u0001\u0000\u0000\u0000\u0187\u0590\u0001\u0000\u0000\u0000\u0189\u0594"+
- "\u0001\u0000\u0000\u0000\u018b\u059a\u0001\u0000\u0000\u0000\u018d\u05a0"+
- "\u0001\u0000\u0000\u0000\u018f\u05a4\u0001\u0000\u0000\u0000\u0191\u05a8"+
- "\u0001\u0000\u0000\u0000\u0193\u05ac\u0001\u0000\u0000\u0000\u0195\u05b2"+
- "\u0001\u0000\u0000\u0000\u0197\u05b8\u0001\u0000\u0000\u0000\u0199\u05be"+
- "\u0001\u0000\u0000\u0000\u019b\u019c\u0007\u0000\u0000\u0000\u019c\u019d"+
- "\u0007\u0001\u0000\u0000\u019d\u019e\u0007\u0002\u0000\u0000\u019e\u019f"+
- "\u0007\u0002\u0000\u0000\u019f\u01a0\u0007\u0003\u0000\u0000\u01a0\u01a1"+
- "\u0007\u0004\u0000\u0000\u01a1\u01a2\u0007\u0005\u0000\u0000\u01a2\u01a3"+
- "\u0001\u0000\u0000\u0000\u01a3\u01a4\u0006\u0000\u0000\u0000\u01a4\u0010"+
- "\u0001\u0000\u0000\u0000\u01a5\u01a6\u0007\u0000\u0000\u0000\u01a6\u01a7"+
- "\u0007\u0006\u0000\u0000\u01a7\u01a8\u0007\u0007\u0000\u0000\u01a8\u01a9"+
- "\u0007\b\u0000\u0000\u01a9\u01aa\u0001\u0000\u0000\u0000\u01aa\u01ab\u0006"+
- "\u0001\u0001\u0000\u01ab\u0012\u0001\u0000\u0000\u0000\u01ac\u01ad\u0007"+
- "\u0003\u0000\u0000\u01ad\u01ae\u0007\t\u0000\u0000\u01ae\u01af\u0007\u0006"+
- "\u0000\u0000\u01af\u01b0\u0007\u0001\u0000\u0000\u01b0\u01b1\u0007\u0004"+
- "\u0000\u0000\u01b1\u01b2\u0007\n\u0000\u0000\u01b2\u01b3\u0001\u0000\u0000"+
- "\u0000\u01b3\u01b4\u0006\u0002\u0002\u0000\u01b4\u0014\u0001\u0000\u0000"+
- "\u0000\u01b5\u01b6\u0007\u0003\u0000\u0000\u01b6\u01b7\u0007\u000b\u0000"+
- "\u0000\u01b7\u01b8\u0007\f\u0000\u0000\u01b8\u01b9\u0007\r\u0000\u0000"+
- "\u01b9\u01ba\u0001\u0000\u0000\u0000\u01ba\u01bb\u0006\u0003\u0000\u0000"+
- "\u01bb\u0016\u0001\u0000\u0000\u0000\u01bc\u01bd\u0007\u0003\u0000\u0000"+
- "\u01bd\u01be\u0007\u000e\u0000\u0000\u01be\u01bf\u0007\b\u0000\u0000\u01bf"+
- "\u01c0\u0007\r\u0000\u0000\u01c0\u01c1\u0007\f\u0000\u0000\u01c1\u01c2"+
- "\u0007\u0001\u0000\u0000\u01c2\u01c3\u0007\t\u0000\u0000\u01c3\u01c4\u0001"+
- "\u0000\u0000\u0000\u01c4\u01c5\u0006\u0004\u0003\u0000\u01c5\u0018\u0001"+
- "\u0000\u0000\u0000\u01c6\u01c7\u0007\u000f\u0000\u0000\u01c7\u01c8\u0007"+
- "\u0006\u0000\u0000\u01c8\u01c9\u0007\u0007\u0000\u0000\u01c9\u01ca\u0007"+
- "\u0010\u0000\u0000\u01ca\u01cb\u0001\u0000\u0000\u0000\u01cb\u01cc\u0006"+
- "\u0005\u0004\u0000\u01cc\u001a\u0001\u0000\u0000\u0000\u01cd\u01ce\u0007"+
- "\u0011\u0000\u0000\u01ce\u01cf\u0007\u0006\u0000\u0000\u01cf\u01d0\u0007"+
- "\u0007\u0000\u0000\u01d0\u01d1\u0007\u0012\u0000\u0000\u01d1\u01d2\u0001"+
- "\u0000\u0000\u0000\u01d2\u01d3\u0006\u0006\u0000\u0000\u01d3\u001c\u0001"+
- "\u0000\u0000\u0000\u01d4\u01d5\u0007\u0012\u0000\u0000\u01d5\u01d6\u0007"+
- "\u0003\u0000\u0000\u01d6\u01d7\u0007\u0003\u0000\u0000\u01d7\u01d8\u0007"+
- "\b\u0000\u0000\u01d8\u01d9\u0001\u0000\u0000\u0000\u01d9\u01da\u0006\u0007"+
- "\u0001\u0000\u01da\u001e\u0001\u0000\u0000\u0000\u01db\u01dc\u0007\r\u0000"+
- "\u0000\u01dc\u01dd\u0007\u0001\u0000\u0000\u01dd\u01de\u0007\u0010\u0000"+
- "\u0000\u01de\u01df\u0007\u0001\u0000\u0000\u01df\u01e0\u0007\u0005\u0000"+
- "\u0000\u01e0\u01e1\u0001\u0000\u0000\u0000\u01e1\u01e2\u0006\b\u0000\u0000"+
- "\u01e2 \u0001\u0000\u0000\u0000\u01e3\u01e4\u0007\u0010\u0000\u0000\u01e4"+
- "\u01e5\u0007\u000b\u0000\u0000\u01e5\u01e6\u0005_\u0000\u0000\u01e6\u01e7"+
- "\u0007\u0003\u0000\u0000\u01e7\u01e8\u0007\u000e\u0000\u0000\u01e8\u01e9"+
- "\u0007\b\u0000\u0000\u01e9\u01ea\u0007\f\u0000\u0000\u01ea\u01eb\u0007"+
- "\t\u0000\u0000\u01eb\u01ec\u0007\u0000\u0000\u0000\u01ec\u01ed\u0001\u0000"+
- "\u0000\u0000\u01ed\u01ee\u0006\t\u0005\u0000\u01ee\"\u0001\u0000\u0000"+
- "\u0000\u01ef\u01f0\u0007\u0006\u0000\u0000\u01f0\u01f1\u0007\u0003\u0000"+
- "\u0000\u01f1\u01f2\u0007\t\u0000\u0000\u01f2\u01f3\u0007\f\u0000\u0000"+
- "\u01f3\u01f4\u0007\u0010\u0000\u0000\u01f4\u01f5\u0007\u0003\u0000\u0000"+
- "\u01f5\u01f6\u0001\u0000\u0000\u0000\u01f6\u01f7\u0006\n\u0006\u0000\u01f7"+
- "$\u0001\u0000\u0000\u0000\u01f8\u01f9\u0007\u0006\u0000\u0000\u01f9\u01fa"+
- "\u0007\u0007\u0000\u0000\u01fa\u01fb\u0007\u0013\u0000\u0000\u01fb\u01fc"+
- "\u0001\u0000\u0000\u0000\u01fc\u01fd\u0006\u000b\u0000\u0000\u01fd&\u0001"+
- "\u0000\u0000\u0000\u01fe\u01ff\u0007\u0002\u0000\u0000\u01ff\u0200\u0007"+
- "\n\u0000\u0000\u0200\u0201\u0007\u0007\u0000\u0000\u0201\u0202\u0007\u0013"+
- "\u0000\u0000\u0202\u0203\u0001\u0000\u0000\u0000\u0203\u0204\u0006\f\u0007"+
- "\u0000\u0204(\u0001\u0000\u0000\u0000\u0205\u0206\u0007\u0002\u0000\u0000"+
- "\u0206\u0207\u0007\u0007\u0000\u0000\u0207\u0208\u0007\u0006\u0000\u0000"+
- "\u0208\u0209\u0007\u0005\u0000\u0000\u0209\u020a\u0001\u0000\u0000\u0000"+
- "\u020a\u020b\u0006\r\u0000\u0000\u020b*\u0001\u0000\u0000\u0000\u020c"+
- "\u020d\u0007\u0002\u0000\u0000\u020d\u020e\u0007\u0005\u0000\u0000\u020e"+
- "\u020f\u0007\f\u0000\u0000\u020f\u0210\u0007\u0005\u0000\u0000\u0210\u0211"+
- "\u0007\u0002\u0000\u0000\u0211\u0212\u0001\u0000\u0000\u0000\u0212\u0213"+
- "\u0006\u000e\u0000\u0000\u0213,\u0001\u0000\u0000\u0000\u0214\u0215\u0007"+
- "\u0013\u0000\u0000\u0215\u0216\u0007\n\u0000\u0000\u0216\u0217\u0007\u0003"+
- "\u0000\u0000\u0217\u0218\u0007\u0006\u0000\u0000\u0218\u0219\u0007\u0003"+
- "\u0000\u0000\u0219\u021a\u0001\u0000\u0000\u0000\u021a\u021b\u0006\u000f"+
- "\u0000\u0000\u021b.\u0001\u0000\u0000\u0000\u021c\u021d\u0004\u0010\u0000"+
- "\u0000\u021d\u021e\u0007\u0001\u0000\u0000\u021e\u021f\u0007\t\u0000\u0000"+
- "\u021f\u0220\u0007\r\u0000\u0000\u0220\u0221\u0007\u0001\u0000\u0000\u0221"+
- "\u0222\u0007\t\u0000\u0000\u0222\u0223\u0007\u0003\u0000\u0000\u0223\u0224"+
- "\u0007\u0002\u0000\u0000\u0224\u0225\u0007\u0005\u0000\u0000\u0225\u0226"+
- "\u0007\f\u0000\u0000\u0226\u0227\u0007\u0005\u0000\u0000\u0227\u0228\u0007"+
- "\u0002\u0000\u0000\u0228\u0229\u0001\u0000\u0000\u0000\u0229\u022a\u0006"+
- "\u0010\u0000\u0000\u022a0\u0001\u0000\u0000\u0000\u022b\u022c\u0004\u0011"+
- "\u0001\u0000\u022c\u022d\u0007\r\u0000\u0000\u022d\u022e\u0007\u0007\u0000"+
- "\u0000\u022e\u022f\u0007\u0007\u0000\u0000\u022f\u0230\u0007\u0012\u0000"+
- "\u0000\u0230\u0231\u0007\u0014\u0000\u0000\u0231\u0232\u0007\b\u0000\u0000"+
- "\u0232\u0233\u0001\u0000\u0000\u0000\u0233\u0234\u0006\u0011\b\u0000\u0234"+
- "2\u0001\u0000\u0000\u0000\u0235\u0236\u0004\u0012\u0002\u0000\u0236\u0237"+
- "\u0007\u0010\u0000\u0000\u0237\u0238\u0007\f\u0000\u0000\u0238\u0239\u0007"+
- "\u0005\u0000\u0000\u0239\u023a\u0007\u0004\u0000\u0000\u023a\u023b\u0007"+
- "\n\u0000\u0000\u023b\u023c\u0001\u0000\u0000\u0000\u023c\u023d\u0006\u0012"+
- "\u0000\u0000\u023d4\u0001\u0000\u0000\u0000\u023e\u023f\u0004\u0013\u0003"+
- "\u0000\u023f\u0240\u0007\u0010\u0000\u0000\u0240\u0241\u0007\u0003\u0000"+
- "\u0000\u0241\u0242\u0007\u0005\u0000\u0000\u0242\u0243\u0007\u0006\u0000"+
- "\u0000\u0243\u0244\u0007\u0001\u0000\u0000\u0244\u0245\u0007\u0004\u0000"+
- "\u0000\u0245\u0246\u0007\u0002\u0000\u0000\u0246\u0247\u0001\u0000\u0000"+
- "\u0000\u0247\u0248\u0006\u0013\t\u0000\u02486\u0001\u0000\u0000\u0000"+
- "\u0249\u024b\b\u0015\u0000\u0000\u024a\u0249\u0001\u0000\u0000\u0000\u024b"+
- "\u024c\u0001\u0000\u0000\u0000\u024c\u024a\u0001\u0000\u0000\u0000\u024c"+
- "\u024d\u0001\u0000\u0000\u0000\u024d\u024e\u0001\u0000\u0000\u0000\u024e"+
- "\u024f\u0006\u0014\u0000\u0000\u024f8\u0001\u0000\u0000\u0000\u0250\u0251"+
- "\u0005/\u0000\u0000\u0251\u0252\u0005/\u0000\u0000\u0252\u0256\u0001\u0000"+
- "\u0000\u0000\u0253\u0255\b\u0016\u0000\u0000\u0254\u0253\u0001\u0000\u0000"+
- "\u0000\u0255\u0258\u0001\u0000\u0000\u0000\u0256\u0254\u0001\u0000\u0000"+
- "\u0000\u0256\u0257\u0001\u0000\u0000\u0000\u0257\u025a\u0001\u0000\u0000"+
- "\u0000\u0258\u0256\u0001\u0000\u0000\u0000\u0259\u025b\u0005\r\u0000\u0000"+
- "\u025a\u0259\u0001\u0000\u0000\u0000\u025a\u025b\u0001\u0000\u0000\u0000"+
- "\u025b\u025d\u0001\u0000\u0000\u0000\u025c\u025e\u0005\n\u0000\u0000\u025d"+
- "\u025c\u0001\u0000\u0000\u0000\u025d\u025e\u0001\u0000\u0000\u0000\u025e"+
- "\u025f\u0001\u0000\u0000\u0000\u025f\u0260\u0006\u0015\n\u0000\u0260:"+
- "\u0001\u0000\u0000\u0000\u0261\u0262\u0005/\u0000\u0000\u0262\u0263\u0005"+
- "*\u0000\u0000\u0263\u0268\u0001\u0000\u0000\u0000\u0264\u0267\u0003;\u0016"+
- "\u0000\u0265\u0267\t\u0000\u0000\u0000\u0266\u0264\u0001\u0000\u0000\u0000"+
- "\u0266\u0265\u0001\u0000\u0000\u0000\u0267\u026a\u0001\u0000\u0000\u0000"+
- "\u0268\u0269\u0001\u0000\u0000\u0000\u0268\u0266\u0001\u0000\u0000\u0000"+
- "\u0269\u026b\u0001\u0000\u0000\u0000\u026a\u0268\u0001\u0000\u0000\u0000"+
- "\u026b\u026c\u0005*\u0000\u0000\u026c\u026d\u0005/\u0000\u0000\u026d\u026e"+
- "\u0001\u0000\u0000\u0000\u026e\u026f\u0006\u0016\n\u0000\u026f<\u0001"+
- "\u0000\u0000\u0000\u0270\u0272\u0007\u0017\u0000\u0000\u0271\u0270\u0001"+
- "\u0000\u0000\u0000\u0272\u0273\u0001\u0000\u0000\u0000\u0273\u0271\u0001"+
- "\u0000\u0000\u0000\u0273\u0274\u0001\u0000\u0000\u0000\u0274\u0275\u0001"+
- "\u0000\u0000\u0000\u0275\u0276\u0006\u0017\n\u0000\u0276>\u0001\u0000"+
- "\u0000\u0000\u0277\u0278\u0005|\u0000\u0000\u0278\u0279\u0001\u0000\u0000"+
- "\u0000\u0279\u027a\u0006\u0018\u000b\u0000\u027a@\u0001\u0000\u0000\u0000"+
- "\u027b\u027c\u0007\u0018\u0000\u0000\u027cB\u0001\u0000\u0000\u0000\u027d"+
- "\u027e\u0007\u0019\u0000\u0000\u027eD\u0001\u0000\u0000\u0000\u027f\u0280"+
- "\u0005\\\u0000\u0000\u0280\u0281\u0007\u001a\u0000\u0000\u0281F\u0001"+
- "\u0000\u0000\u0000\u0282\u0283\b\u001b\u0000\u0000\u0283H\u0001\u0000"+
- "\u0000\u0000\u0284\u0286\u0007\u0003\u0000\u0000\u0285\u0287\u0007\u001c"+
- "\u0000\u0000\u0286\u0285\u0001\u0000\u0000\u0000\u0286\u0287\u0001\u0000"+
- "\u0000\u0000\u0287\u0289\u0001\u0000\u0000\u0000\u0288\u028a\u0003A\u0019"+
- "\u0000\u0289\u0288\u0001\u0000\u0000\u0000\u028a\u028b\u0001\u0000\u0000"+
- "\u0000\u028b\u0289\u0001\u0000\u0000\u0000\u028b\u028c\u0001\u0000\u0000"+
- "\u0000\u028cJ\u0001\u0000\u0000\u0000\u028d\u028e\u0005@\u0000\u0000\u028e"+
- "L\u0001\u0000\u0000\u0000\u028f\u0290\u0005`\u0000\u0000\u0290N\u0001"+
- "\u0000\u0000\u0000\u0291\u0295\b\u001d\u0000\u0000\u0292\u0293\u0005`"+
- "\u0000\u0000\u0293\u0295\u0005`\u0000\u0000\u0294\u0291\u0001\u0000\u0000"+
- "\u0000\u0294\u0292\u0001\u0000\u0000\u0000\u0295P\u0001\u0000\u0000\u0000"+
- "\u0296\u0297\u0005_\u0000\u0000\u0297R\u0001\u0000\u0000\u0000\u0298\u029c"+
- "\u0003C\u001a\u0000\u0299\u029c\u0003A\u0019\u0000\u029a\u029c\u0003Q"+
- "!\u0000\u029b\u0298\u0001\u0000\u0000\u0000\u029b\u0299\u0001\u0000\u0000"+
- "\u0000\u029b\u029a\u0001\u0000\u0000\u0000\u029cT\u0001\u0000\u0000\u0000"+
- "\u029d\u02a2\u0005\"\u0000\u0000\u029e\u02a1\u0003E\u001b\u0000\u029f"+
- "\u02a1\u0003G\u001c\u0000\u02a0\u029e\u0001\u0000\u0000\u0000\u02a0\u029f"+
- "\u0001\u0000\u0000\u0000\u02a1\u02a4\u0001\u0000\u0000\u0000\u02a2\u02a0"+
- "\u0001\u0000\u0000\u0000\u02a2\u02a3\u0001\u0000\u0000\u0000\u02a3\u02a5"+
- "\u0001\u0000\u0000\u0000\u02a4\u02a2\u0001\u0000\u0000\u0000\u02a5\u02bb"+
- "\u0005\"\u0000\u0000\u02a6\u02a7\u0005\"\u0000\u0000\u02a7\u02a8\u0005"+
- "\"\u0000\u0000\u02a8\u02a9\u0005\"\u0000\u0000\u02a9\u02ad\u0001\u0000"+
- "\u0000\u0000\u02aa\u02ac\b\u0016\u0000\u0000\u02ab\u02aa\u0001\u0000\u0000"+
- "\u0000\u02ac\u02af\u0001\u0000\u0000\u0000\u02ad\u02ae\u0001\u0000\u0000"+
- "\u0000\u02ad\u02ab\u0001\u0000\u0000\u0000\u02ae\u02b0\u0001\u0000\u0000"+
- "\u0000\u02af\u02ad\u0001\u0000\u0000\u0000\u02b0\u02b1\u0005\"\u0000\u0000"+
- "\u02b1\u02b2\u0005\"\u0000\u0000\u02b2\u02b3\u0005\"\u0000\u0000\u02b3"+
- "\u02b5\u0001\u0000\u0000\u0000\u02b4\u02b6\u0005\"\u0000\u0000\u02b5\u02b4"+
- "\u0001\u0000\u0000\u0000\u02b5\u02b6\u0001\u0000\u0000\u0000\u02b6\u02b8"+
- "\u0001\u0000\u0000\u0000\u02b7\u02b9\u0005\"\u0000\u0000\u02b8\u02b7\u0001"+
- "\u0000\u0000\u0000\u02b8\u02b9\u0001\u0000\u0000\u0000\u02b9\u02bb\u0001"+
- "\u0000\u0000\u0000\u02ba\u029d\u0001\u0000\u0000\u0000\u02ba\u02a6\u0001"+
- "\u0000\u0000\u0000\u02bbV\u0001\u0000\u0000\u0000\u02bc\u02be\u0003A\u0019"+
- "\u0000\u02bd\u02bc\u0001\u0000\u0000\u0000\u02be\u02bf\u0001\u0000\u0000"+
- "\u0000\u02bf\u02bd\u0001\u0000\u0000\u0000\u02bf\u02c0\u0001\u0000\u0000"+
- "\u0000\u02c0X\u0001\u0000\u0000\u0000\u02c1\u02c3\u0003A\u0019\u0000\u02c2"+
- "\u02c1\u0001\u0000\u0000\u0000\u02c3\u02c4\u0001\u0000\u0000\u0000\u02c4"+
- "\u02c2\u0001\u0000\u0000\u0000\u02c4\u02c5\u0001\u0000\u0000\u0000\u02c5"+
- "\u02c6\u0001\u0000\u0000\u0000\u02c6\u02ca\u0003i-\u0000\u02c7\u02c9\u0003"+
- "A\u0019\u0000\u02c8\u02c7\u0001\u0000\u0000\u0000\u02c9\u02cc\u0001\u0000"+
- "\u0000\u0000\u02ca\u02c8\u0001\u0000\u0000\u0000\u02ca\u02cb\u0001\u0000"+
- "\u0000\u0000\u02cb\u02ec\u0001\u0000\u0000\u0000\u02cc\u02ca\u0001\u0000"+
- "\u0000\u0000\u02cd\u02cf\u0003i-\u0000\u02ce\u02d0\u0003A\u0019\u0000"+
- "\u02cf\u02ce\u0001\u0000\u0000\u0000\u02d0\u02d1\u0001\u0000\u0000\u0000"+
- "\u02d1\u02cf\u0001\u0000\u0000\u0000\u02d1\u02d2\u0001\u0000\u0000\u0000"+
- "\u02d2\u02ec\u0001\u0000\u0000\u0000\u02d3\u02d5\u0003A\u0019\u0000\u02d4"+
- "\u02d3\u0001\u0000\u0000\u0000\u02d5\u02d6\u0001\u0000\u0000\u0000\u02d6"+
- "\u02d4\u0001\u0000\u0000\u0000\u02d6\u02d7\u0001\u0000\u0000\u0000\u02d7"+
- "\u02df\u0001\u0000\u0000\u0000\u02d8\u02dc\u0003i-\u0000\u02d9\u02db\u0003"+
- "A\u0019\u0000\u02da\u02d9\u0001\u0000\u0000\u0000\u02db\u02de\u0001\u0000"+
- "\u0000\u0000\u02dc\u02da\u0001\u0000\u0000\u0000\u02dc\u02dd\u0001\u0000"+
- "\u0000\u0000\u02dd\u02e0\u0001\u0000\u0000\u0000\u02de\u02dc\u0001\u0000"+
- "\u0000\u0000\u02df\u02d8\u0001\u0000\u0000\u0000\u02df\u02e0\u0001\u0000"+
- "\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000\u0000\u02e1\u02e2\u0003I\u001d"+
- "\u0000\u02e2\u02ec\u0001\u0000\u0000\u0000\u02e3\u02e5\u0003i-\u0000\u02e4"+
- "\u02e6\u0003A\u0019\u0000\u02e5\u02e4\u0001\u0000\u0000\u0000\u02e6\u02e7"+
- "\u0001\u0000\u0000\u0000\u02e7\u02e5\u0001\u0000\u0000\u0000\u02e7\u02e8"+
- "\u0001\u0000\u0000\u0000\u02e8\u02e9\u0001\u0000\u0000\u0000\u02e9\u02ea"+
- "\u0003I\u001d\u0000\u02ea\u02ec\u0001\u0000\u0000\u0000\u02eb\u02c2\u0001"+
- "\u0000\u0000\u0000\u02eb\u02cd\u0001\u0000\u0000\u0000\u02eb\u02d4\u0001"+
- "\u0000\u0000\u0000\u02eb\u02e3\u0001\u0000\u0000\u0000\u02ecZ\u0001\u0000"+
- "\u0000\u0000\u02ed\u02ee\u0007\u001e\u0000\u0000\u02ee\u02ef\u0007\u001f"+
- "\u0000\u0000\u02ef\\\u0001\u0000\u0000\u0000\u02f0\u02f1\u0007\f\u0000"+
- "\u0000\u02f1\u02f2\u0007\t\u0000\u0000\u02f2\u02f3\u0007\u0000\u0000\u0000"+
- "\u02f3^\u0001\u0000\u0000\u0000\u02f4\u02f5\u0007\f\u0000\u0000\u02f5"+
- "\u02f6\u0007\u0002\u0000\u0000\u02f6\u02f7\u0007\u0004\u0000\u0000\u02f7"+
- "`\u0001\u0000\u0000\u0000\u02f8\u02f9\u0005=\u0000\u0000\u02f9b\u0001"+
- "\u0000\u0000\u0000\u02fa\u02fb\u0005:\u0000\u0000\u02fb\u02fc\u0005:\u0000"+
- "\u0000\u02fcd\u0001\u0000\u0000\u0000\u02fd\u02fe\u0005,\u0000\u0000\u02fe"+
- "f\u0001\u0000\u0000\u0000\u02ff\u0300\u0007\u0000\u0000\u0000\u0300\u0301"+
- "\u0007\u0003\u0000\u0000\u0301\u0302\u0007\u0002\u0000\u0000\u0302\u0303"+
- "\u0007\u0004\u0000\u0000\u0303h\u0001\u0000\u0000\u0000\u0304\u0305\u0005"+
- ".\u0000\u0000\u0305j\u0001\u0000\u0000\u0000\u0306\u0307\u0007\u000f\u0000"+
- "\u0000\u0307\u0308\u0007\f\u0000\u0000\u0308\u0309\u0007\r\u0000\u0000"+
- "\u0309\u030a\u0007\u0002\u0000\u0000\u030a\u030b\u0007\u0003\u0000\u0000"+
- "\u030bl\u0001\u0000\u0000\u0000\u030c\u030d\u0007\u000f\u0000\u0000\u030d"+
- "\u030e\u0007\u0001\u0000\u0000\u030e\u030f\u0007\u0006\u0000\u0000\u030f"+
- "\u0310\u0007\u0002\u0000\u0000\u0310\u0311\u0007\u0005\u0000\u0000\u0311"+
- "n\u0001\u0000\u0000\u0000\u0312\u0313\u0007\u0001\u0000\u0000\u0313\u0314"+
- "\u0007\t\u0000\u0000\u0314p\u0001\u0000\u0000\u0000\u0315\u0316\u0007"+
- "\u0001\u0000\u0000\u0316\u0317\u0007\u0002\u0000\u0000\u0317r\u0001\u0000"+
- "\u0000\u0000\u0318\u0319\u0007\r\u0000\u0000\u0319\u031a\u0007\f\u0000"+
- "\u0000\u031a\u031b\u0007\u0002\u0000\u0000\u031b\u031c\u0007\u0005\u0000"+
- "\u0000\u031ct\u0001\u0000\u0000\u0000\u031d\u031e\u0007\r\u0000\u0000"+
- "\u031e\u031f\u0007\u0001\u0000\u0000\u031f\u0320\u0007\u0012\u0000\u0000"+
- "\u0320\u0321\u0007\u0003\u0000\u0000\u0321v\u0001\u0000\u0000\u0000\u0322"+
- "\u0323\u0005(\u0000\u0000\u0323x\u0001\u0000\u0000\u0000\u0324\u0325\u0007"+
- "\t\u0000\u0000\u0325\u0326\u0007\u0007\u0000\u0000\u0326\u0327\u0007\u0005"+
- "\u0000\u0000\u0327z\u0001\u0000\u0000\u0000\u0328\u0329\u0007\t\u0000"+
- "\u0000\u0329\u032a\u0007\u0014\u0000\u0000\u032a\u032b\u0007\r\u0000\u0000"+
- "\u032b\u032c\u0007\r\u0000\u0000\u032c|\u0001\u0000\u0000\u0000\u032d"+
- "\u032e\u0007\t\u0000\u0000\u032e\u032f\u0007\u0014\u0000\u0000\u032f\u0330"+
- "\u0007\r\u0000\u0000\u0330\u0331\u0007\r\u0000\u0000\u0331\u0332\u0007"+
- "\u0002\u0000\u0000\u0332~\u0001\u0000\u0000\u0000\u0333\u0334\u0007\u0007"+
- "\u0000\u0000\u0334\u0335\u0007\u0006\u0000\u0000\u0335\u0080\u0001\u0000"+
- "\u0000\u0000\u0336\u0337\u0005?\u0000\u0000\u0337\u0082\u0001\u0000\u0000"+
- "\u0000\u0338\u0339\u0007\u0006\u0000\u0000\u0339\u033a\u0007\r\u0000\u0000"+
- "\u033a\u033b\u0007\u0001\u0000\u0000\u033b\u033c\u0007\u0012\u0000\u0000"+
- "\u033c\u033d\u0007\u0003\u0000\u0000\u033d\u0084\u0001\u0000\u0000\u0000"+
- "\u033e\u033f\u0005)\u0000\u0000\u033f\u0086\u0001\u0000\u0000\u0000\u0340"+
- "\u0341\u0007\u0005\u0000\u0000\u0341\u0342\u0007\u0006\u0000\u0000\u0342"+
- "\u0343\u0007\u0014\u0000\u0000\u0343\u0344\u0007\u0003\u0000\u0000\u0344"+
- "\u0088\u0001\u0000\u0000\u0000\u0345\u0346\u0005=\u0000\u0000\u0346\u0347"+
- "\u0005=\u0000\u0000\u0347\u008a\u0001\u0000\u0000\u0000\u0348\u0349\u0005"+
- "=\u0000\u0000\u0349\u034a\u0005~\u0000\u0000\u034a\u008c\u0001\u0000\u0000"+
- "\u0000\u034b\u034c\u0005!\u0000\u0000\u034c\u034d\u0005=\u0000\u0000\u034d"+
- "\u008e\u0001\u0000\u0000\u0000\u034e\u034f\u0005<\u0000\u0000\u034f\u0090"+
- "\u0001\u0000\u0000\u0000\u0350\u0351\u0005<\u0000\u0000\u0351\u0352\u0005"+
- "=\u0000\u0000\u0352\u0092\u0001\u0000\u0000\u0000\u0353\u0354\u0005>\u0000"+
- "\u0000\u0354\u0094\u0001\u0000\u0000\u0000\u0355\u0356\u0005>\u0000\u0000"+
- "\u0356\u0357\u0005=\u0000\u0000\u0357\u0096\u0001\u0000\u0000\u0000\u0358"+
- "\u0359\u0005+\u0000\u0000\u0359\u0098\u0001\u0000\u0000\u0000\u035a\u035b"+
- "\u0005-\u0000\u0000\u035b\u009a\u0001\u0000\u0000\u0000\u035c\u035d\u0005"+
- "*\u0000\u0000\u035d\u009c\u0001\u0000\u0000\u0000\u035e\u035f\u0005/\u0000"+
- "\u0000\u035f\u009e\u0001\u0000\u0000\u0000\u0360\u0361\u0005%\u0000\u0000"+
- "\u0361\u00a0\u0001\u0000\u0000\u0000\u0362\u0363\u0004I\u0004\u0000\u0363"+
- "\u0364\u00033\u0012\u0000\u0364\u0365\u0001\u0000\u0000\u0000\u0365\u0366"+
- "\u0006I\f\u0000\u0366\u00a2\u0001\u0000\u0000\u0000\u0367\u036a\u0003"+
- "\u00819\u0000\u0368\u036b\u0003C\u001a\u0000\u0369\u036b\u0003Q!\u0000"+
- "\u036a\u0368\u0001\u0000\u0000\u0000\u036a\u0369\u0001\u0000\u0000\u0000"+
- "\u036b\u036f\u0001\u0000\u0000\u0000\u036c\u036e\u0003S\"\u0000\u036d"+
- "\u036c\u0001\u0000\u0000\u0000\u036e\u0371\u0001\u0000\u0000\u0000\u036f"+
- "\u036d\u0001\u0000\u0000\u0000\u036f\u0370\u0001\u0000\u0000\u0000\u0370"+
- "\u0379\u0001\u0000\u0000\u0000\u0371\u036f\u0001\u0000\u0000\u0000\u0372"+
- "\u0374\u0003\u00819\u0000\u0373\u0375\u0003A\u0019\u0000\u0374\u0373\u0001"+
- "\u0000\u0000\u0000\u0375\u0376\u0001\u0000\u0000\u0000\u0376\u0374\u0001"+
- "\u0000\u0000\u0000\u0376\u0377\u0001\u0000\u0000\u0000\u0377\u0379\u0001"+
- "\u0000\u0000\u0000\u0378\u0367\u0001\u0000\u0000\u0000\u0378\u0372\u0001"+
- "\u0000\u0000\u0000\u0379\u00a4\u0001\u0000\u0000\u0000\u037a\u037b\u0005"+
- "[\u0000\u0000\u037b\u037c\u0001\u0000\u0000\u0000\u037c\u037d\u0006K\u0000"+
- "\u0000\u037d\u037e\u0006K\u0000\u0000\u037e\u00a6\u0001\u0000\u0000\u0000"+
- "\u037f\u0380\u0005]\u0000\u0000\u0380\u0381\u0001\u0000\u0000\u0000\u0381"+
- "\u0382\u0006L\u000b\u0000\u0382\u0383\u0006L\u000b\u0000\u0383\u00a8\u0001"+
- "\u0000\u0000\u0000\u0384\u0388\u0003C\u001a\u0000\u0385\u0387\u0003S\""+
- "\u0000\u0386\u0385\u0001\u0000\u0000\u0000\u0387\u038a\u0001\u0000\u0000"+
- "\u0000\u0388\u0386\u0001\u0000\u0000\u0000\u0388\u0389\u0001\u0000\u0000"+
- "\u0000\u0389\u0395\u0001\u0000\u0000\u0000\u038a\u0388\u0001\u0000\u0000"+
- "\u0000\u038b\u038e\u0003Q!\u0000\u038c\u038e\u0003K\u001e\u0000\u038d"+
- "\u038b\u0001\u0000\u0000\u0000\u038d\u038c\u0001\u0000\u0000\u0000\u038e"+
- "\u0390\u0001\u0000\u0000\u0000\u038f\u0391\u0003S\"\u0000\u0390\u038f"+
- "\u0001\u0000\u0000\u0000\u0391\u0392\u0001\u0000\u0000\u0000\u0392\u0390"+
- "\u0001\u0000\u0000\u0000\u0392\u0393\u0001\u0000\u0000\u0000\u0393\u0395"+
- "\u0001\u0000\u0000\u0000\u0394\u0384\u0001\u0000\u0000\u0000\u0394\u038d"+
- "\u0001\u0000\u0000\u0000\u0395\u00aa\u0001\u0000\u0000\u0000\u0396\u0398"+
- "\u0003M\u001f\u0000\u0397\u0399\u0003O \u0000\u0398\u0397\u0001\u0000"+
- "\u0000\u0000\u0399\u039a\u0001\u0000\u0000\u0000\u039a\u0398\u0001\u0000"+
- "\u0000\u0000\u039a\u039b\u0001\u0000\u0000\u0000\u039b\u039c\u0001\u0000"+
- "\u0000\u0000\u039c\u039d\u0003M\u001f\u0000\u039d\u00ac\u0001\u0000\u0000"+
- "\u0000\u039e\u039f\u0003\u00abN\u0000\u039f\u00ae\u0001\u0000\u0000\u0000"+
- "\u03a0\u03a1\u00039\u0015\u0000\u03a1\u03a2\u0001\u0000\u0000\u0000\u03a2"+
- "\u03a3\u0006P\n\u0000\u03a3\u00b0\u0001\u0000\u0000\u0000\u03a4\u03a5"+
- "\u0003;\u0016\u0000\u03a5\u03a6\u0001\u0000\u0000\u0000\u03a6\u03a7\u0006"+
- "Q\n\u0000\u03a7\u00b2\u0001\u0000\u0000\u0000\u03a8\u03a9\u0003=\u0017"+
- "\u0000\u03a9\u03aa\u0001\u0000\u0000\u0000\u03aa\u03ab\u0006R\n\u0000"+
- "\u03ab\u00b4\u0001\u0000\u0000\u0000\u03ac\u03ad\u0003\u00a5K\u0000\u03ad"+
- "\u03ae\u0001\u0000\u0000\u0000\u03ae\u03af\u0006S\r\u0000\u03af\u03b0"+
- "\u0006S\u000e\u0000\u03b0\u00b6\u0001\u0000\u0000\u0000\u03b1\u03b2\u0003"+
- "?\u0018\u0000\u03b2\u03b3\u0001\u0000\u0000\u0000\u03b3\u03b4\u0006T\u000f"+
- "\u0000\u03b4\u03b5\u0006T\u000b\u0000\u03b5\u00b8\u0001\u0000\u0000\u0000"+
- "\u03b6\u03b7\u0003=\u0017\u0000\u03b7\u03b8\u0001\u0000\u0000\u0000\u03b8"+
- "\u03b9\u0006U\n\u0000\u03b9\u00ba\u0001\u0000\u0000\u0000\u03ba\u03bb"+
- "\u00039\u0015\u0000\u03bb\u03bc\u0001\u0000\u0000\u0000\u03bc\u03bd\u0006"+
- "V\n\u0000\u03bd\u00bc\u0001\u0000\u0000\u0000\u03be\u03bf\u0003;\u0016"+
- "\u0000\u03bf\u03c0\u0001\u0000\u0000\u0000\u03c0\u03c1\u0006W\n\u0000"+
- "\u03c1\u00be\u0001\u0000\u0000\u0000\u03c2\u03c3\u0003?\u0018\u0000\u03c3"+
- "\u03c4\u0001\u0000\u0000\u0000\u03c4\u03c5\u0006X\u000f\u0000\u03c5\u03c6"+
- "\u0006X\u000b\u0000\u03c6\u00c0\u0001\u0000\u0000\u0000\u03c7\u03c8\u0003"+
- "\u00a5K\u0000\u03c8\u03c9\u0001\u0000\u0000\u0000\u03c9\u03ca\u0006Y\r"+
- "\u0000\u03ca\u00c2\u0001\u0000\u0000\u0000\u03cb\u03cc\u0003\u00a7L\u0000"+
- "\u03cc\u03cd\u0001\u0000\u0000\u0000\u03cd\u03ce\u0006Z\u0010\u0000\u03ce"+
- "\u00c4\u0001\u0000\u0000\u0000\u03cf\u03d0\u0003\u0151\u00a1\u0000\u03d0"+
- "\u03d1\u0001\u0000\u0000\u0000\u03d1\u03d2\u0006[\u0011\u0000\u03d2\u00c6"+
- "\u0001\u0000\u0000\u0000\u03d3\u03d4\u0003e+\u0000\u03d4\u03d5\u0001\u0000"+
- "\u0000\u0000\u03d5\u03d6\u0006\\\u0012\u0000\u03d6\u00c8\u0001\u0000\u0000"+
- "\u0000\u03d7\u03d8\u0003a)\u0000\u03d8\u03d9\u0001\u0000\u0000\u0000\u03d9"+
- "\u03da\u0006]\u0013\u0000\u03da\u00ca\u0001\u0000\u0000\u0000\u03db\u03dc"+
- "\u0007\u0010\u0000\u0000\u03dc\u03dd\u0007\u0003\u0000\u0000\u03dd\u03de"+
- "\u0007\u0005\u0000\u0000\u03de\u03df\u0007\f\u0000\u0000\u03df\u03e0\u0007"+
- "\u0000\u0000\u0000\u03e0\u03e1\u0007\f\u0000\u0000\u03e1\u03e2\u0007\u0005"+
- "\u0000\u0000\u03e2\u03e3\u0007\f\u0000\u0000\u03e3\u00cc\u0001\u0000\u0000"+
- "\u0000\u03e4\u03e8\b \u0000\u0000\u03e5\u03e6\u0005/\u0000\u0000\u03e6"+
- "\u03e8\b!\u0000\u0000\u03e7\u03e4\u0001\u0000\u0000\u0000\u03e7\u03e5"+
- "\u0001\u0000\u0000\u0000\u03e8\u00ce\u0001\u0000\u0000\u0000\u03e9\u03eb"+
- "\u0003\u00cd_\u0000\u03ea\u03e9\u0001\u0000\u0000\u0000\u03eb\u03ec\u0001"+
- "\u0000\u0000\u0000\u03ec\u03ea\u0001\u0000\u0000\u0000\u03ec\u03ed\u0001"+
- "\u0000\u0000\u0000\u03ed\u00d0\u0001\u0000\u0000\u0000\u03ee\u03ef\u0003"+
- "\u00cf`\u0000\u03ef\u03f0\u0001\u0000\u0000\u0000\u03f0\u03f1\u0006a\u0014"+
- "\u0000\u03f1\u00d2\u0001\u0000\u0000\u0000\u03f2\u03f3\u0003U#\u0000\u03f3"+
- "\u03f4\u0001\u0000\u0000\u0000\u03f4\u03f5\u0006b\u0015\u0000\u03f5\u00d4"+
- "\u0001\u0000\u0000\u0000\u03f6\u03f7\u00039\u0015\u0000\u03f7\u03f8\u0001"+
- "\u0000\u0000\u0000\u03f8\u03f9\u0006c\n\u0000\u03f9\u00d6\u0001\u0000"+
- "\u0000\u0000\u03fa\u03fb\u0003;\u0016\u0000\u03fb\u03fc\u0001\u0000\u0000"+
- "\u0000\u03fc\u03fd\u0006d\n\u0000\u03fd\u00d8\u0001\u0000\u0000\u0000"+
- "\u03fe\u03ff\u0003=\u0017\u0000\u03ff\u0400\u0001\u0000\u0000\u0000\u0400"+
- "\u0401\u0006e\n\u0000\u0401\u00da\u0001\u0000\u0000\u0000\u0402\u0403"+
- "\u0003?\u0018\u0000\u0403\u0404\u0001\u0000\u0000\u0000\u0404\u0405\u0006"+
- "f\u000f\u0000\u0405\u0406\u0006f\u000b\u0000\u0406\u00dc\u0001\u0000\u0000"+
- "\u0000\u0407\u0408\u0003i-\u0000\u0408\u0409\u0001\u0000\u0000\u0000\u0409"+
- "\u040a\u0006g\u0016\u0000\u040a\u00de\u0001\u0000\u0000\u0000\u040b\u040c"+
- "\u0003e+\u0000\u040c\u040d\u0001\u0000\u0000\u0000\u040d\u040e\u0006h"+
- "\u0012\u0000\u040e\u00e0\u0001\u0000\u0000\u0000\u040f\u0410\u0003\u0081"+
- "9\u0000\u0410\u0411\u0001\u0000\u0000\u0000\u0411\u0412\u0006i\u0017\u0000"+
- "\u0412\u00e2\u0001\u0000\u0000\u0000\u0413\u0414\u0003\u00a3J\u0000\u0414"+
- "\u0415\u0001\u0000\u0000\u0000\u0415\u0416\u0006j\u0018\u0000\u0416\u00e4"+
- "\u0001\u0000\u0000\u0000\u0417\u041c\u0003C\u001a\u0000\u0418\u041c\u0003"+
- "A\u0019\u0000\u0419\u041c\u0003Q!\u0000\u041a\u041c\u0003\u009bF\u0000"+
- "\u041b\u0417\u0001\u0000\u0000\u0000\u041b\u0418\u0001\u0000\u0000\u0000"+
- "\u041b\u0419\u0001\u0000\u0000\u0000\u041b\u041a\u0001\u0000\u0000\u0000"+
- "\u041c\u00e6\u0001\u0000\u0000\u0000\u041d\u0420\u0003C\u001a\u0000\u041e"+
- "\u0420\u0003\u009bF\u0000\u041f\u041d\u0001\u0000\u0000\u0000\u041f\u041e"+
- "\u0001\u0000\u0000\u0000\u0420\u0424\u0001\u0000\u0000\u0000\u0421\u0423"+
- "\u0003\u00e5k\u0000\u0422\u0421\u0001\u0000\u0000\u0000\u0423\u0426\u0001"+
- "\u0000\u0000\u0000\u0424\u0422\u0001\u0000\u0000\u0000\u0424\u0425\u0001"+
- "\u0000\u0000\u0000\u0425\u0431\u0001\u0000\u0000\u0000\u0426\u0424\u0001"+
- "\u0000\u0000\u0000\u0427\u042a\u0003Q!\u0000\u0428\u042a\u0003K\u001e"+
- "\u0000\u0429\u0427\u0001\u0000\u0000\u0000\u0429\u0428\u0001\u0000\u0000"+
- "\u0000\u042a\u042c\u0001\u0000\u0000\u0000\u042b\u042d\u0003\u00e5k\u0000"+
- "\u042c\u042b\u0001\u0000\u0000\u0000\u042d\u042e\u0001\u0000\u0000\u0000"+
- "\u042e\u042c\u0001\u0000\u0000\u0000\u042e\u042f\u0001\u0000\u0000\u0000"+
- "\u042f\u0431\u0001\u0000\u0000\u0000\u0430\u041f\u0001\u0000\u0000\u0000"+
- "\u0430\u0429\u0001\u0000\u0000\u0000\u0431\u00e8\u0001\u0000\u0000\u0000"+
- "\u0432\u0435\u0003\u00e7l\u0000\u0433\u0435\u0003\u00abN\u0000\u0434\u0432"+
- "\u0001\u0000\u0000\u0000\u0434\u0433\u0001\u0000\u0000\u0000\u0435\u0436"+
- "\u0001\u0000\u0000\u0000\u0436\u0434\u0001\u0000\u0000\u0000\u0436\u0437"+
- "\u0001\u0000\u0000\u0000\u0437\u00ea\u0001\u0000\u0000\u0000\u0438\u0439"+
- "\u00039\u0015\u0000\u0439\u043a\u0001\u0000\u0000\u0000\u043a\u043b\u0006"+
- "n\n\u0000\u043b\u00ec\u0001\u0000\u0000\u0000\u043c\u043d\u0003;\u0016"+
- "\u0000\u043d\u043e\u0001\u0000\u0000\u0000\u043e\u043f\u0006o\n\u0000"+
- "\u043f\u00ee\u0001\u0000\u0000\u0000\u0440\u0441\u0003=\u0017\u0000\u0441"+
- "\u0442\u0001\u0000\u0000\u0000\u0442\u0443\u0006p\n\u0000\u0443\u00f0"+
- "\u0001\u0000\u0000\u0000\u0444\u0445\u0003?\u0018\u0000\u0445\u0446\u0001"+
- "\u0000\u0000\u0000\u0446\u0447\u0006q\u000f\u0000\u0447\u0448\u0006q\u000b"+
- "\u0000\u0448\u00f2\u0001\u0000\u0000\u0000\u0449\u044a\u0003a)\u0000\u044a"+
- "\u044b\u0001\u0000\u0000\u0000\u044b\u044c\u0006r\u0013\u0000\u044c\u00f4"+
- "\u0001\u0000\u0000\u0000\u044d\u044e\u0003e+\u0000\u044e\u044f\u0001\u0000"+
- "\u0000\u0000\u044f\u0450\u0006s\u0012\u0000\u0450\u00f6\u0001\u0000\u0000"+
- "\u0000\u0451\u0452\u0003i-\u0000\u0452\u0453\u0001\u0000\u0000\u0000\u0453"+
- "\u0454\u0006t\u0016\u0000\u0454\u00f8\u0001\u0000\u0000\u0000\u0455\u0456"+
- "\u0003\u00819\u0000\u0456\u0457\u0001\u0000\u0000\u0000\u0457\u0458\u0006"+
- "u\u0017\u0000\u0458\u00fa\u0001\u0000\u0000\u0000\u0459\u045a\u0003\u00a3"+
- "J\u0000\u045a\u045b\u0001\u0000\u0000\u0000\u045b\u045c\u0006v\u0018\u0000"+
- "\u045c\u00fc\u0001\u0000\u0000\u0000\u045d\u045e\u0007\f\u0000\u0000\u045e"+
- "\u045f\u0007\u0002\u0000\u0000\u045f\u00fe\u0001\u0000\u0000\u0000\u0460"+
- "\u0461\u0003\u00e9m\u0000\u0461\u0462\u0001\u0000\u0000\u0000\u0462\u0463"+
- "\u0006x\u0019\u0000\u0463\u0100\u0001\u0000\u0000\u0000\u0464\u0465\u0003"+
- "9\u0015\u0000\u0465\u0466\u0001\u0000\u0000\u0000\u0466\u0467\u0006y\n"+
- "\u0000\u0467\u0102\u0001\u0000\u0000\u0000\u0468\u0469\u0003;\u0016\u0000"+
- "\u0469\u046a\u0001\u0000\u0000\u0000\u046a\u046b\u0006z\n\u0000\u046b"+
- "\u0104\u0001\u0000\u0000\u0000\u046c\u046d\u0003=\u0017\u0000\u046d\u046e"+
- "\u0001\u0000\u0000\u0000\u046e\u046f\u0006{\n\u0000\u046f\u0106\u0001"+
- "\u0000\u0000\u0000\u0470\u0471\u0003?\u0018\u0000\u0471\u0472\u0001\u0000"+
- "\u0000\u0000\u0472\u0473\u0006|\u000f\u0000\u0473\u0474\u0006|\u000b\u0000"+
- "\u0474\u0108\u0001\u0000\u0000\u0000\u0475\u0476\u0003\u00a5K\u0000\u0476"+
- "\u0477\u0001\u0000\u0000\u0000\u0477\u0478\u0006}\r\u0000\u0478\u0479"+
- "\u0006}\u001a\u0000\u0479\u010a\u0001\u0000\u0000\u0000\u047a\u047b\u0007"+
- "\u0007\u0000\u0000\u047b\u047c\u0007\t\u0000\u0000\u047c\u047d\u0001\u0000"+
- "\u0000\u0000\u047d\u047e\u0006~\u001b\u0000\u047e\u010c\u0001\u0000\u0000"+
- "\u0000\u047f\u0480\u0007\u0013\u0000\u0000\u0480\u0481\u0007\u0001\u0000"+
- "\u0000\u0481\u0482\u0007\u0005\u0000\u0000\u0482\u0483\u0007\n\u0000\u0000"+
- "\u0483\u0484\u0001\u0000\u0000\u0000\u0484\u0485\u0006\u007f\u001b\u0000"+
- "\u0485\u010e\u0001\u0000\u0000\u0000\u0486\u0487\b\"\u0000\u0000\u0487"+
- "\u0110\u0001\u0000\u0000\u0000\u0488\u048a\u0003\u010f\u0080\u0000\u0489"+
- "\u0488\u0001\u0000\u0000\u0000\u048a\u048b\u0001\u0000\u0000\u0000\u048b"+
- "\u0489\u0001\u0000\u0000\u0000\u048b\u048c\u0001\u0000\u0000\u0000\u048c"+
- "\u048d\u0001\u0000\u0000\u0000\u048d\u048e\u0003\u0151\u00a1\u0000\u048e"+
- "\u0490\u0001\u0000\u0000\u0000\u048f\u0489\u0001\u0000\u0000\u0000\u048f"+
- "\u0490\u0001\u0000\u0000\u0000\u0490\u0492\u0001\u0000\u0000\u0000\u0491"+
- "\u0493\u0003\u010f\u0080\u0000\u0492\u0491\u0001\u0000\u0000\u0000\u0493"+
- "\u0494\u0001\u0000\u0000\u0000\u0494\u0492\u0001\u0000\u0000\u0000\u0494"+
- "\u0495\u0001\u0000\u0000\u0000\u0495\u0112\u0001\u0000\u0000\u0000\u0496"+
- "\u0497\u0003\u0111\u0081\u0000\u0497\u0498\u0001\u0000\u0000\u0000\u0498"+
- "\u0499\u0006\u0082\u001c\u0000\u0499\u0114\u0001\u0000\u0000\u0000\u049a"+
- "\u049b\u00039\u0015\u0000\u049b\u049c\u0001\u0000\u0000\u0000\u049c\u049d"+
- "\u0006\u0083\n\u0000\u049d\u0116\u0001\u0000\u0000\u0000\u049e\u049f\u0003"+
- ";\u0016\u0000\u049f\u04a0\u0001\u0000\u0000\u0000\u04a0\u04a1\u0006\u0084"+
- "\n\u0000\u04a1\u0118\u0001\u0000\u0000\u0000\u04a2\u04a3\u0003=\u0017"+
- "\u0000\u04a3\u04a4\u0001\u0000\u0000\u0000\u04a4\u04a5\u0006\u0085\n\u0000"+
- "\u04a5\u011a\u0001\u0000\u0000\u0000\u04a6\u04a7\u0003?\u0018\u0000\u04a7"+
- "\u04a8\u0001\u0000\u0000\u0000\u04a8\u04a9\u0006\u0086\u000f\u0000\u04a9"+
- "\u04aa\u0006\u0086\u000b\u0000\u04aa\u04ab\u0006\u0086\u000b\u0000\u04ab"+
- "\u011c\u0001\u0000\u0000\u0000\u04ac\u04ad\u0003a)\u0000\u04ad\u04ae\u0001"+
- "\u0000\u0000\u0000\u04ae\u04af\u0006\u0087\u0013\u0000\u04af\u011e\u0001"+
- "\u0000\u0000\u0000\u04b0\u04b1\u0003e+\u0000\u04b1\u04b2\u0001\u0000\u0000"+
- "\u0000\u04b2\u04b3\u0006\u0088\u0012\u0000\u04b3\u0120\u0001\u0000\u0000"+
- "\u0000\u04b4\u04b5\u0003i-\u0000\u04b5\u04b6\u0001\u0000\u0000\u0000\u04b6"+
- "\u04b7\u0006\u0089\u0016\u0000\u04b7\u0122\u0001\u0000\u0000\u0000\u04b8"+
- "\u04b9\u0003\u010d\u007f\u0000\u04b9\u04ba\u0001\u0000\u0000\u0000\u04ba"+
- "\u04bb\u0006\u008a\u001d\u0000\u04bb\u0124\u0001\u0000\u0000\u0000\u04bc"+
- "\u04bd\u0003\u00e9m\u0000\u04bd\u04be\u0001\u0000\u0000\u0000\u04be\u04bf"+
- "\u0006\u008b\u0019\u0000\u04bf\u0126\u0001\u0000\u0000\u0000\u04c0\u04c1"+
- "\u0003\u00adO\u0000\u04c1\u04c2\u0001\u0000\u0000\u0000\u04c2\u04c3\u0006"+
- "\u008c\u001e\u0000\u04c3\u0128\u0001\u0000\u0000\u0000\u04c4\u04c5\u0003"+
- "\u00819\u0000\u04c5\u04c6\u0001\u0000\u0000\u0000\u04c6\u04c7\u0006\u008d"+
- "\u0017\u0000\u04c7\u012a\u0001\u0000\u0000\u0000\u04c8\u04c9\u0003\u00a3"+
- "J\u0000\u04c9\u04ca\u0001\u0000\u0000\u0000\u04ca\u04cb\u0006\u008e\u0018"+
- "\u0000\u04cb\u012c\u0001\u0000\u0000\u0000\u04cc\u04cd\u00039\u0015\u0000"+
- "\u04cd\u04ce\u0001\u0000\u0000\u0000\u04ce\u04cf\u0006\u008f\n\u0000\u04cf"+
- "\u012e\u0001\u0000\u0000\u0000\u04d0\u04d1\u0003;\u0016\u0000\u04d1\u04d2"+
- "\u0001\u0000\u0000\u0000\u04d2\u04d3\u0006\u0090\n\u0000\u04d3\u0130\u0001"+
- "\u0000\u0000\u0000\u04d4\u04d5\u0003=\u0017\u0000\u04d5\u04d6\u0001\u0000"+
- "\u0000\u0000\u04d6\u04d7\u0006\u0091\n\u0000\u04d7\u0132\u0001\u0000\u0000"+
- "\u0000\u04d8\u04d9\u0003?\u0018\u0000\u04d9\u04da\u0001\u0000\u0000\u0000"+
- "\u04da\u04db\u0006\u0092\u000f\u0000\u04db\u04dc\u0006\u0092\u000b\u0000"+
- "\u04dc\u0134\u0001\u0000\u0000\u0000\u04dd\u04de\u0003i-\u0000\u04de\u04df"+
- "\u0001\u0000\u0000\u0000\u04df\u04e0\u0006\u0093\u0016\u0000\u04e0\u0136"+
- "\u0001\u0000\u0000\u0000\u04e1\u04e2\u0003\u00819\u0000\u04e2\u04e3\u0001"+
- "\u0000\u0000\u0000\u04e3\u04e4\u0006\u0094\u0017\u0000\u04e4\u0138\u0001"+
- "\u0000\u0000\u0000\u04e5\u04e6\u0003\u00a3J\u0000\u04e6\u04e7\u0001\u0000"+
- "\u0000\u0000\u04e7\u04e8\u0006\u0095\u0018\u0000\u04e8\u013a\u0001\u0000"+
- "\u0000\u0000\u04e9\u04ea\u0003\u00adO\u0000\u04ea\u04eb\u0001\u0000\u0000"+
- "\u0000\u04eb\u04ec\u0006\u0096\u001e\u0000\u04ec\u013c\u0001\u0000\u0000"+
- "\u0000\u04ed\u04ee\u0003\u00a9M\u0000\u04ee\u04ef\u0001\u0000\u0000\u0000"+
- "\u04ef\u04f0\u0006\u0097\u001f\u0000\u04f0\u013e\u0001\u0000\u0000\u0000"+
- "\u04f1\u04f2\u00039\u0015\u0000\u04f2\u04f3\u0001\u0000\u0000\u0000\u04f3"+
- "\u04f4\u0006\u0098\n\u0000\u04f4\u0140\u0001\u0000\u0000\u0000\u04f5\u04f6"+
- "\u0003;\u0016\u0000\u04f6\u04f7\u0001\u0000\u0000\u0000\u04f7\u04f8\u0006"+
- "\u0099\n\u0000\u04f8\u0142\u0001\u0000\u0000\u0000\u04f9\u04fa\u0003="+
- "\u0017\u0000\u04fa\u04fb\u0001\u0000\u0000\u0000\u04fb\u04fc\u0006\u009a"+
- "\n\u0000\u04fc\u0144\u0001\u0000\u0000\u0000\u04fd\u04fe\u0003?\u0018"+
- "\u0000\u04fe\u04ff\u0001\u0000\u0000\u0000\u04ff\u0500\u0006\u009b\u000f"+
- "\u0000\u0500\u0501\u0006\u009b\u000b\u0000\u0501\u0146\u0001\u0000\u0000"+
- "\u0000\u0502\u0503\u0007\u0001\u0000\u0000\u0503\u0504\u0007\t\u0000\u0000"+
- "\u0504\u0505\u0007\u000f\u0000\u0000\u0505\u0506\u0007\u0007\u0000\u0000"+
- "\u0506\u0148\u0001\u0000\u0000\u0000\u0507\u0508\u00039\u0015\u0000\u0508"+
- "\u0509\u0001\u0000\u0000\u0000\u0509\u050a\u0006\u009d\n\u0000\u050a\u014a"+
- "\u0001\u0000\u0000\u0000\u050b\u050c\u0003;\u0016\u0000\u050c\u050d\u0001"+
- "\u0000\u0000\u0000\u050d\u050e\u0006\u009e\n\u0000\u050e\u014c\u0001\u0000"+
- "\u0000\u0000\u050f\u0510\u0003=\u0017\u0000\u0510\u0511\u0001\u0000\u0000"+
- "\u0000\u0511\u0512\u0006\u009f\n\u0000\u0512\u014e\u0001\u0000\u0000\u0000"+
- "\u0513\u0514\u0003\u00a7L\u0000\u0514\u0515\u0001\u0000\u0000\u0000\u0515"+
- "\u0516\u0006\u00a0\u0010\u0000\u0516\u0517\u0006\u00a0\u000b\u0000\u0517"+
- "\u0150\u0001\u0000\u0000\u0000\u0518\u0519\u0005:\u0000\u0000\u0519\u0152"+
- "\u0001\u0000\u0000\u0000\u051a\u0520\u0003K\u001e\u0000\u051b\u0520\u0003"+
- "A\u0019\u0000\u051c\u0520\u0003i-\u0000\u051d\u0520\u0003C\u001a\u0000"+
- "\u051e\u0520\u0003Q!\u0000\u051f\u051a\u0001\u0000\u0000\u0000\u051f\u051b"+
- "\u0001\u0000\u0000\u0000\u051f\u051c\u0001\u0000\u0000\u0000\u051f\u051d"+
- "\u0001\u0000\u0000\u0000\u051f\u051e\u0001\u0000\u0000\u0000\u0520\u0521"+
- "\u0001\u0000\u0000\u0000\u0521\u051f\u0001\u0000\u0000\u0000\u0521\u0522"+
- "\u0001\u0000\u0000\u0000\u0522\u0154\u0001\u0000\u0000\u0000\u0523\u0524"+
- "\u00039\u0015\u0000\u0524\u0525\u0001\u0000\u0000\u0000\u0525\u0526\u0006"+
- "\u00a3\n\u0000\u0526\u0156\u0001\u0000\u0000\u0000\u0527\u0528\u0003;"+
- "\u0016\u0000\u0528\u0529\u0001\u0000\u0000\u0000\u0529\u052a\u0006\u00a4"+
- "\n\u0000\u052a\u0158\u0001\u0000\u0000\u0000\u052b\u052c\u0003=\u0017"+
- "\u0000\u052c\u052d\u0001\u0000\u0000\u0000\u052d\u052e\u0006\u00a5\n\u0000"+
- "\u052e\u015a\u0001\u0000\u0000\u0000\u052f\u0530\u0003?\u0018\u0000\u0530"+
- "\u0531\u0001\u0000\u0000\u0000\u0531\u0532\u0006\u00a6\u000f\u0000\u0532"+
- "\u0533\u0006\u00a6\u000b\u0000\u0533\u015c\u0001\u0000\u0000\u0000\u0534"+
- "\u0535\u0003\u0151\u00a1\u0000\u0535\u0536\u0001\u0000\u0000\u0000\u0536"+
- "\u0537\u0006\u00a7\u0011\u0000\u0537\u015e\u0001\u0000\u0000\u0000\u0538"+
- "\u0539\u0003e+\u0000\u0539\u053a\u0001\u0000\u0000\u0000\u053a\u053b\u0006"+
- "\u00a8\u0012\u0000\u053b\u0160\u0001\u0000\u0000\u0000\u053c\u053d\u0003"+
- "i-\u0000\u053d\u053e\u0001\u0000\u0000\u0000\u053e\u053f\u0006\u00a9\u0016"+
- "\u0000\u053f\u0162\u0001\u0000\u0000\u0000\u0540\u0541\u0003\u010b~\u0000"+
- "\u0541\u0542\u0001\u0000\u0000\u0000\u0542\u0543\u0006\u00aa \u0000\u0543"+
- "\u0544\u0006\u00aa!\u0000\u0544\u0164\u0001\u0000\u0000\u0000\u0545\u0546"+
- "\u0003\u00cf`\u0000\u0546\u0547\u0001\u0000\u0000\u0000\u0547\u0548\u0006"+
- "\u00ab\u0014\u0000\u0548\u0166\u0001\u0000\u0000\u0000\u0549\u054a\u0003"+
- "U#\u0000\u054a\u054b\u0001\u0000\u0000\u0000\u054b\u054c\u0006\u00ac\u0015"+
- "\u0000\u054c\u0168\u0001\u0000\u0000\u0000\u054d\u054e\u00039\u0015\u0000"+
- "\u054e\u054f\u0001\u0000\u0000\u0000\u054f\u0550\u0006\u00ad\n\u0000\u0550"+
- "\u016a\u0001\u0000\u0000\u0000\u0551\u0552\u0003;\u0016\u0000\u0552\u0553"+
- "\u0001\u0000\u0000\u0000\u0553\u0554\u0006\u00ae\n\u0000\u0554\u016c\u0001"+
- "\u0000\u0000\u0000\u0555\u0556\u0003=\u0017\u0000\u0556\u0557\u0001\u0000"+
- "\u0000\u0000\u0557\u0558\u0006\u00af\n\u0000\u0558\u016e\u0001\u0000\u0000"+
- "\u0000\u0559\u055a\u0003?\u0018\u0000\u055a\u055b\u0001\u0000\u0000\u0000"+
- "\u055b\u055c\u0006\u00b0\u000f\u0000\u055c\u055d\u0006\u00b0\u000b\u0000"+
- "\u055d\u055e\u0006\u00b0\u000b\u0000\u055e\u0170\u0001\u0000\u0000\u0000"+
- "\u055f\u0560\u0003e+\u0000\u0560\u0561\u0001\u0000\u0000\u0000\u0561\u0562"+
- "\u0006\u00b1\u0012\u0000\u0562\u0172\u0001\u0000\u0000\u0000\u0563\u0564"+
- "\u0003i-\u0000\u0564\u0565\u0001\u0000\u0000\u0000\u0565\u0566\u0006\u00b2"+
- "\u0016\u0000\u0566\u0174\u0001\u0000\u0000\u0000\u0567\u0568\u0003\u00e9"+
- "m\u0000\u0568\u0569\u0001\u0000\u0000\u0000\u0569\u056a\u0006\u00b3\u0019"+
- "\u0000\u056a\u0176\u0001\u0000\u0000\u0000\u056b\u056c\u00039\u0015\u0000"+
- "\u056c\u056d\u0001\u0000\u0000\u0000\u056d\u056e\u0006\u00b4\n\u0000\u056e"+
- "\u0178\u0001\u0000\u0000\u0000\u056f\u0570\u0003;\u0016\u0000\u0570\u0571"+
- "\u0001\u0000\u0000\u0000\u0571\u0572\u0006\u00b5\n\u0000\u0572\u017a\u0001"+
- "\u0000\u0000\u0000\u0573\u0574\u0003=\u0017\u0000\u0574\u0575\u0001\u0000"+
- "\u0000\u0000\u0575\u0576\u0006\u00b6\n\u0000\u0576\u017c\u0001\u0000\u0000"+
- "\u0000\u0577\u0578\u0003?\u0018\u0000\u0578\u0579\u0001\u0000\u0000\u0000"+
- "\u0579\u057a\u0006\u00b7\u000f\u0000\u057a\u057b\u0006\u00b7\u000b\u0000"+
- "\u057b\u017e\u0001\u0000\u0000\u0000\u057c\u057d\u0003\u00cf`\u0000\u057d"+
- "\u057e\u0001\u0000\u0000\u0000\u057e\u057f\u0006\u00b8\u0014\u0000\u057f"+
- "\u0580\u0006\u00b8\u000b\u0000\u0580\u0581\u0006\u00b8\"\u0000\u0581\u0180"+
- "\u0001\u0000\u0000\u0000\u0582\u0583\u0003U#\u0000\u0583\u0584\u0001\u0000"+
- "\u0000\u0000\u0584\u0585\u0006\u00b9\u0015\u0000\u0585\u0586\u0006\u00b9"+
- "\u000b\u0000\u0586\u0587\u0006\u00b9\"\u0000\u0587\u0182\u0001\u0000\u0000"+
- "\u0000\u0588\u0589\u00039\u0015\u0000\u0589\u058a\u0001\u0000\u0000\u0000"+
- "\u058a\u058b\u0006\u00ba\n\u0000\u058b\u0184\u0001\u0000\u0000\u0000\u058c"+
- "\u058d\u0003;\u0016\u0000\u058d\u058e\u0001\u0000\u0000\u0000\u058e\u058f"+
- "\u0006\u00bb\n\u0000\u058f\u0186\u0001\u0000\u0000\u0000\u0590\u0591\u0003"+
- "=\u0017\u0000\u0591\u0592\u0001\u0000\u0000\u0000\u0592\u0593\u0006\u00bc"+
- "\n\u0000\u0593\u0188\u0001\u0000\u0000\u0000\u0594\u0595\u0003\u0151\u00a1"+
- "\u0000\u0595\u0596\u0001\u0000\u0000\u0000\u0596\u0597\u0006\u00bd\u0011"+
- "\u0000\u0597\u0598\u0006\u00bd\u000b\u0000\u0598\u0599\u0006\u00bd\t\u0000"+
- "\u0599\u018a\u0001\u0000\u0000\u0000\u059a\u059b\u0003e+\u0000\u059b\u059c"+
- "\u0001\u0000\u0000\u0000\u059c\u059d\u0006\u00be\u0012\u0000\u059d\u059e"+
- "\u0006\u00be\u000b\u0000\u059e\u059f\u0006\u00be\t\u0000\u059f\u018c\u0001"+
- "\u0000\u0000\u0000\u05a0\u05a1\u00039\u0015\u0000\u05a1\u05a2\u0001\u0000"+
- "\u0000\u0000\u05a2\u05a3\u0006\u00bf\n\u0000\u05a3\u018e\u0001\u0000\u0000"+
- "\u0000\u05a4\u05a5\u0003;\u0016\u0000\u05a5\u05a6\u0001\u0000\u0000\u0000"+
- "\u05a6\u05a7\u0006\u00c0\n\u0000\u05a7\u0190\u0001\u0000\u0000\u0000\u05a8"+
- "\u05a9\u0003=\u0017\u0000\u05a9\u05aa\u0001\u0000\u0000\u0000\u05aa\u05ab"+
- "\u0006\u00c1\n\u0000\u05ab\u0192\u0001\u0000\u0000\u0000\u05ac\u05ad\u0003"+
- "\u00adO\u0000\u05ad\u05ae\u0001\u0000\u0000\u0000\u05ae\u05af\u0006\u00c2"+
- "\u000b\u0000\u05af\u05b0\u0006\u00c2\u0000\u0000\u05b0\u05b1\u0006\u00c2"+
- "\u001e\u0000\u05b1\u0194\u0001\u0000\u0000\u0000\u05b2\u05b3\u0003\u00a9"+
- "M\u0000\u05b3\u05b4\u0001\u0000\u0000\u0000\u05b4\u05b5\u0006\u00c3\u000b"+
- "\u0000\u05b5\u05b6\u0006\u00c3\u0000\u0000\u05b6\u05b7\u0006\u00c3\u001f"+
- "\u0000\u05b7\u0196\u0001\u0000\u0000\u0000\u05b8\u05b9\u0003[&\u0000\u05b9"+
- "\u05ba\u0001\u0000\u0000\u0000\u05ba\u05bb\u0006\u00c4\u000b\u0000\u05bb"+
- "\u05bc\u0006\u00c4\u0000\u0000\u05bc\u05bd\u0006\u00c4#\u0000\u05bd\u0198"+
- "\u0001\u0000\u0000\u0000\u05be\u05bf\u0003?\u0018\u0000\u05bf\u05c0\u0001"+
- "\u0000\u0000\u0000\u05c0\u05c1\u0006\u00c5\u000f\u0000\u05c1\u05c2\u0006"+
- "\u00c5\u000b\u0000\u05c2\u019a\u0001\u0000\u0000\u0000A\u0000\u0001\u0002"+
- "\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u024c\u0256\u025a"+
- "\u025d\u0266\u0268\u0273\u0286\u028b\u0294\u029b\u02a0\u02a2\u02ad\u02b5"+
- "\u02b8\u02ba\u02bf\u02c4\u02ca\u02d1\u02d6\u02dc\u02df\u02e7\u02eb\u036a"+
- "\u036f\u0376\u0378\u0388\u038d\u0392\u0394\u039a\u03e7\u03ec\u041b\u041f"+
- "\u0424\u0429\u042e\u0430\u0434\u0436\u048b\u048f\u0494\u051f\u0521$\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\u000b"+
- "\u0000\u0005\r\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0007\u0013\u0000"+
- "\u0007A\u0000\u0005\u0000\u0000\u0007\u0019\u0000\u0007B\u0000\u0007h"+
- "\u0000\u0007\"\u0000\u0007 \u0000\u0007L\u0000\u0007\u001a\u0000\u0007"+
- "$\u0000\u00070\u0000\u0007@\u0000\u0007P\u0000\u0005\n\u0000\u0005\u0007"+
- "\u0000\u0007Z\u0000\u0007Y\u0000\u0007D\u0000\u0007C\u0000\u0007X\u0000"+
- "\u0005\f\u0000\u0005\u000e\u0000\u0007\u001d\u0000";
+ "\u0001\u0010\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\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012"+
+ "\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0013\u0004\u0013"+
+ "\u0240\b\u0013\u000b\u0013\f\u0013\u0241\u0001\u0013\u0001\u0013\u0001"+
+ "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0005\u0014\u024a\b\u0014\n"+
+ "\u0014\f\u0014\u024d\t\u0014\u0001\u0014\u0003\u0014\u0250\b\u0014\u0001"+
+ "\u0014\u0003\u0014\u0253\b\u0014\u0001\u0014\u0001\u0014\u0001\u0015\u0001"+
+ "\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0005\u0015\u025c\b\u0015\n"+
+ "\u0015\f\u0015\u025f\t\u0015\u0001\u0015\u0001\u0015\u0001\u0015\u0001"+
+ "\u0015\u0001\u0015\u0001\u0016\u0004\u0016\u0267\b\u0016\u000b\u0016\f"+
+ "\u0016\u0268\u0001\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0017"+
+ "\u0001\u0017\u0001\u0018\u0001\u0018\u0001\u0019\u0001\u0019\u0001\u001a"+
+ "\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001\u001c\u0001\u001c"+
+ "\u0003\u001c\u027c\b\u001c\u0001\u001c\u0004\u001c\u027f\b\u001c\u000b"+
+ "\u001c\f\u001c\u0280\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001"+
+ "\u001f\u0001\u001f\u0001\u001f\u0003\u001f\u028a\b\u001f\u0001 \u0001"+
+ " \u0001!\u0001!\u0001!\u0003!\u0291\b!\u0001\"\u0001\"\u0001\"\u0005\""+
+ "\u0296\b\"\n\"\f\"\u0299\t\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001\"\u0001"+
+ "\"\u0005\"\u02a1\b\"\n\"\f\"\u02a4\t\"\u0001\"\u0001\"\u0001\"\u0001\""+
+ "\u0001\"\u0003\"\u02ab\b\"\u0001\"\u0003\"\u02ae\b\"\u0003\"\u02b0\b\""+
+ "\u0001#\u0004#\u02b3\b#\u000b#\f#\u02b4\u0001$\u0004$\u02b8\b$\u000b$"+
+ "\f$\u02b9\u0001$\u0001$\u0005$\u02be\b$\n$\f$\u02c1\t$\u0001$\u0001$\u0004"+
+ "$\u02c5\b$\u000b$\f$\u02c6\u0001$\u0004$\u02ca\b$\u000b$\f$\u02cb\u0001"+
+ "$\u0001$\u0005$\u02d0\b$\n$\f$\u02d3\t$\u0003$\u02d5\b$\u0001$\u0001$"+
+ "\u0001$\u0001$\u0004$\u02db\b$\u000b$\f$\u02dc\u0001$\u0001$\u0003$\u02e1"+
+ "\b$\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001"+
+ "\'\u0001\'\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001+\u0001"+
+ "+\u0001+\u0001+\u0001+\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001"+
+ "-\u0001-\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u0001"+
+ "/\u00010\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u00012\u0001"+
+ "2\u00012\u00012\u00012\u00013\u00013\u00014\u00014\u00014\u00014\u0001"+
+ "5\u00015\u00015\u00015\u00015\u00016\u00016\u00016\u00016\u00016\u0001"+
+ "6\u00017\u00017\u00017\u00018\u00018\u00019\u00019\u00019\u00019\u0001"+
+ "9\u00019\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\u0001C\u0001C\u0001"+
+ "D\u0001D\u0001E\u0001E\u0001F\u0001F\u0001G\u0001G\u0001H\u0001H\u0001"+
+ "H\u0001H\u0001H\u0001H\u0001H\u0001I\u0001I\u0001I\u0003I\u0362\bI\u0001"+
+ "I\u0005I\u0365\bI\nI\fI\u0368\tI\u0001I\u0001I\u0004I\u036c\bI\u000bI"+
+ "\fI\u036d\u0003I\u0370\bI\u0001J\u0001J\u0001J\u0001J\u0001J\u0001K\u0001"+
+ "K\u0001K\u0001K\u0001K\u0001L\u0001L\u0005L\u037e\bL\nL\fL\u0381\tL\u0001"+
+ "L\u0001L\u0003L\u0385\bL\u0001L\u0004L\u0388\bL\u000bL\fL\u0389\u0003"+
+ "L\u038c\bL\u0001M\u0001M\u0004M\u0390\bM\u000bM\fM\u0391\u0001M\u0001"+
+ "M\u0001N\u0001N\u0001O\u0001O\u0001O\u0001O\u0001P\u0001P\u0001P\u0001"+
+ "P\u0001Q\u0001Q\u0001Q\u0001Q\u0001R\u0001R\u0001R\u0001R\u0001R\u0001"+
+ "S\u0001S\u0001S\u0001S\u0001S\u0001T\u0001T\u0001T\u0001T\u0001U\u0001"+
+ "U\u0001U\u0001U\u0001V\u0001V\u0001V\u0001V\u0001W\u0001W\u0001W\u0001"+
+ "W\u0001W\u0001X\u0001X\u0001X\u0001X\u0001Y\u0001Y\u0001Y\u0001Y\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^\u0003^\u03df\b^\u0001_\u0004_\u03e2\b_\u000b_\f"+
+ "_\u03e3\u0001`\u0001`\u0001`\u0001`\u0001a\u0001a\u0001a\u0001a\u0001"+
+ "b\u0001b\u0001b\u0001b\u0001c\u0001c\u0001c\u0001c\u0001d\u0001d\u0001"+
+ "d\u0001d\u0001e\u0001e\u0001e\u0001e\u0001e\u0001f\u0001f\u0001f\u0001"+
+ "f\u0001g\u0001g\u0001g\u0001g\u0001h\u0001h\u0001h\u0001h\u0001i\u0001"+
+ "i\u0001i\u0001i\u0001j\u0001j\u0001j\u0001j\u0003j\u0413\bj\u0001k\u0001"+
+ "k\u0003k\u0417\bk\u0001k\u0005k\u041a\bk\nk\fk\u041d\tk\u0001k\u0001k"+
+ "\u0003k\u0421\bk\u0001k\u0004k\u0424\bk\u000bk\fk\u0425\u0003k\u0428\b"+
+ "k\u0001l\u0001l\u0004l\u042c\bl\u000bl\fl\u042d\u0001m\u0001m\u0001m\u0001"+
+ "m\u0001n\u0001n\u0001n\u0001n\u0001o\u0001o\u0001o\u0001o\u0001p\u0001"+
+ "p\u0001p\u0001p\u0001p\u0001q\u0001q\u0001q\u0001q\u0001r\u0001r\u0001"+
+ "r\u0001r\u0001s\u0001s\u0001s\u0001s\u0001t\u0001t\u0001t\u0001t\u0001"+
+ "u\u0001u\u0001u\u0001u\u0001v\u0001v\u0001v\u0001w\u0001w\u0001w\u0001"+
+ "w\u0001x\u0001x\u0001x\u0001x\u0001y\u0001y\u0001y\u0001y\u0001z\u0001"+
+ "z\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\u007f\u0001\u007f\u0001\u0080\u0004"+
+ "\u0080\u0481\b\u0080\u000b\u0080\f\u0080\u0482\u0001\u0080\u0001\u0080"+
+ "\u0003\u0080\u0487\b\u0080\u0001\u0080\u0004\u0080\u048a\b\u0080\u000b"+
+ "\u0080\f\u0080\u048b\u0001\u0081\u0001\u0081\u0001\u0081\u0001\u0081\u0001"+
+ "\u0082\u0001\u0082\u0001\u0082\u0001\u0082\u0001\u0083\u0001\u0083\u0001"+
+ "\u0083\u0001\u0083\u0001\u0084\u0001\u0084\u0001\u0084\u0001\u0084\u0001"+
+ "\u0085\u0001\u0085\u0001\u0085\u0001\u0085\u0001\u0085\u0001\u0085\u0001"+
+ "\u0086\u0001\u0086\u0001\u0086\u0001\u0086\u0001\u0087\u0001\u0087\u0001"+
+ "\u0087\u0001\u0087\u0001\u0088\u0001\u0088\u0001\u0088\u0001\u0088\u0001"+
+ "\u0089\u0001\u0089\u0001\u0089\u0001\u0089\u0001\u008a\u0001\u008a\u0001"+
+ "\u008a\u0001\u008a\u0001\u008b\u0001\u008b\u0001\u008b\u0001\u008b\u0001"+
+ "\u008c\u0001\u008c\u0001\u008c\u0001\u008c\u0001\u008d\u0001\u008d\u0001"+
+ "\u008d\u0001\u008d\u0001\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"+
+ "\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"+
+ "\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\u009f\u0001"+
+ "\u00a0\u0001\u00a0\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001\u00a1\u0001"+
+ "\u00a1\u0004\u00a1\u0517\b\u00a1\u000b\u00a1\f\u00a1\u0518\u0001\u00a2"+
+ "\u0001\u00a2\u0001\u00a2\u0001\u00a2\u0001\u00a3\u0001\u00a3\u0001\u00a3"+
+ "\u0001\u00a3\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a4\u0001\u00a5"+
+ "\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\u00a9\u0001\u00a9"+
+ "\u0001\u00a9\u0001\u00a9\u0001\u00a9\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\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00ae\u0001\u00af"+
+ "\u0001\u00af\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\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\u00b6\u0001\u00b7\u0001\u00b7"+
+ "\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\u00bc\u0001\u00bc\u0001\u00bd\u0001\u00bd"+
+ "\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00bd\u0001\u00be\u0001\u00be"+
+ "\u0001\u00be\u0001\u00be\u0001\u00bf\u0001\u00bf\u0001\u00bf\u0001\u00bf"+
+ "\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c0\u0001\u00c1\u0001\u00c1"+
+ "\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\u00c4\u0001\u00c4"+
+ "\u0001\u00c4\u0001\u00c4\u0001\u00c4\u0002\u025d\u02a2\u0000\u00c5\u000f"+
+ "\u0001\u0011\u0002\u0013\u0003\u0015\u0004\u0017\u0005\u0019\u0006\u001b"+
+ "\u0007\u001d\b\u001f\t!\n#\u000b%\f\'\r)\u000e+\u000f-\u0010/\u00111\u0012"+
+ "3\u00135\u00147\u00159\u0016;\u0017=\u0018?\u0000A\u0000C\u0000E\u0000"+
+ "G\u0000I\u0000K\u0000M\u0000O\u0000Q\u0000S\u0019U\u001aW\u001bY\u001c"+
+ "[\u001d]\u001e_\u001fa c!e\"g#i$k%m&o\'q(s)u*w+y,{-}.\u007f/\u00810\u0083"+
+ "1\u00852\u00873\u00894\u008b5\u008d6\u008f7\u00918\u00939\u0095:\u0097"+
+ ";\u0099<\u009b=\u009d>\u009f?\u00a1@\u00a3A\u00a5B\u00a7C\u00a9\u0000"+
+ "\u00abD\u00adE\u00afF\u00b1G\u00b3\u0000\u00b5\u0000\u00b7H\u00b9I\u00bb"+
+ "J\u00bd\u0000\u00bf\u0000\u00c1\u0000\u00c3\u0000\u00c5\u0000\u00c7\u0000"+
+ "\u00c9K\u00cb\u0000\u00cdL\u00cf\u0000\u00d1\u0000\u00d3M\u00d5N\u00d7"+
+ "O\u00d9\u0000\u00db\u0000\u00dd\u0000\u00df\u0000\u00e1\u0000\u00e3\u0000"+
+ "\u00e5\u0000\u00e7P\u00e9Q\u00ebR\u00edS\u00ef\u0000\u00f1\u0000\u00f3"+
+ "\u0000\u00f5\u0000\u00f7\u0000\u00f9\u0000\u00fbT\u00fd\u0000\u00ffU\u0101"+
+ "V\u0103W\u0105\u0000\u0107\u0000\u0109X\u010bY\u010d\u0000\u010fZ\u0111"+
+ "\u0000\u0113[\u0115\\\u0117]\u0119\u0000\u011b\u0000\u011d\u0000\u011f"+
+ "\u0000\u0121\u0000\u0123\u0000\u0125\u0000\u0127\u0000\u0129\u0000\u012b"+
+ "^\u012d_\u012f`\u0131\u0000\u0133\u0000\u0135\u0000\u0137\u0000\u0139"+
+ "\u0000\u013b\u0000\u013da\u013fb\u0141c\u0143\u0000\u0145d\u0147e\u0149"+
+ "f\u014bg\u014d\u0000\u014fh\u0151i\u0153j\u0155k\u0157l\u0159\u0000\u015b"+
+ "\u0000\u015d\u0000\u015f\u0000\u0161\u0000\u0163\u0000\u0165\u0000\u0167"+
+ "m\u0169n\u016bo\u016d\u0000\u016f\u0000\u0171\u0000\u0173\u0000\u0175"+
+ "p\u0177q\u0179r\u017b\u0000\u017d\u0000\u017f\u0000\u0181s\u0183t\u0185"+
+ "u\u0187\u0000\u0189\u0000\u018bv\u018dw\u018fx\u0191\u0000\u0193\u0000"+
+ "\u0195\u0000\u0197\u0000\u000f\u0000\u0001\u0002\u0003\u0004\u0005\u0006"+
+ "\u0007\b\t\n\u000b\f\r\u000e#\u0002\u0000DDdd\u0002\u0000IIii\u0002\u0000"+
+ "SSss\u0002\u0000EEee\u0002\u0000CCcc\u0002\u0000TTtt\u0002\u0000RRrr\u0002"+
+ "\u0000OOoo\u0002\u0000PPpp\u0002\u0000NNnn\u0002\u0000HHhh\u0002\u0000"+
+ "VVvv\u0002\u0000AAaa\u0002\u0000LLll\u0002\u0000XXxx\u0002\u0000FFff\u0002"+
+ "\u0000MMmm\u0002\u0000GGgg\u0002\u0000KKkk\u0002\u0000WWww\u0002\u0000"+
+ "UUuu\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\u0000"+
+ "YYyy\u000b\u0000\t\n\r\r \"\",,//::==[[]]||\u0002\u0000**//\u000b\u0000"+
+ "\t\n\r\r \"#,,//::<<>?\\\\||\u05d6\u0000\u000f\u0001\u0000\u0000\u0000"+
+ "\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001\u0000\u0000\u0000"+
+ "\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001\u0000\u0000\u0000"+
+ "\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001\u0000\u0000\u0000"+
+ "\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001\u0000\u0000\u0000"+
+ "\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000\u0000\u0000%"+
+ "\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000\u0000)\u0001"+
+ "\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-\u0001\u0000\u0000"+
+ "\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000\u0000\u0000\u0000"+
+ "3\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000\u00007\u0001"+
+ "\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;\u0001\u0000\u0000"+
+ "\u0000\u0001=\u0001\u0000\u0000\u0000\u0001S\u0001\u0000\u0000\u0000\u0001"+
+ "U\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_\u0001\u0000\u0000\u0000\u0001a\u0001\u0000\u0000\u0000\u0001"+
+ "c\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\u0001"+
+ "q\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\u00ab\u0001\u0000\u0000\u0000\u0001"+
+ "\u00ad\u0001\u0000\u0000\u0000\u0001\u00af\u0001\u0000\u0000\u0000\u0001"+
+ "\u00b1\u0001\u0000\u0000\u0000\u0002\u00b3\u0001\u0000\u0000\u0000\u0002"+
+ "\u00b5\u0001\u0000\u0000\u0000\u0002\u00b7\u0001\u0000\u0000\u0000\u0002"+
+ "\u00b9\u0001\u0000\u0000\u0000\u0002\u00bb\u0001\u0000\u0000\u0000\u0003"+
+ "\u00bd\u0001\u0000\u0000\u0000\u0003\u00bf\u0001\u0000\u0000\u0000\u0003"+
+ "\u00c1\u0001\u0000\u0000\u0000\u0003\u00c3\u0001\u0000\u0000\u0000\u0003"+
+ "\u00c5\u0001\u0000\u0000\u0000\u0003\u00c7\u0001\u0000\u0000\u0000\u0003"+
+ "\u00c9\u0001\u0000\u0000\u0000\u0003\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\u0004\u00d9\u0001\u0000\u0000\u0000\u0004"+
+ "\u00db\u0001\u0000\u0000\u0000\u0004\u00dd\u0001\u0000\u0000\u0000\u0004"+
+ "\u00df\u0001\u0000\u0000\u0000\u0004\u00e1\u0001\u0000\u0000\u0000\u0004"+
+ "\u00e7\u0001\u0000\u0000\u0000\u0004\u00e9\u0001\u0000\u0000\u0000\u0004"+
+ "\u00eb\u0001\u0000\u0000\u0000\u0004\u00ed\u0001\u0000\u0000\u0000\u0005"+
+ "\u00ef\u0001\u0000\u0000\u0000\u0005\u00f1\u0001\u0000\u0000\u0000\u0005"+
+ "\u00f3\u0001\u0000\u0000\u0000\u0005\u00f5\u0001\u0000\u0000\u0000\u0005"+
+ "\u00f7\u0001\u0000\u0000\u0000\u0005\u00f9\u0001\u0000\u0000\u0000\u0005"+
+ "\u00fb\u0001\u0000\u0000\u0000\u0005\u00fd\u0001\u0000\u0000\u0000\u0005"+
+ "\u00ff\u0001\u0000\u0000\u0000\u0005\u0101\u0001\u0000\u0000\u0000\u0005"+
+ "\u0103\u0001\u0000\u0000\u0000\u0006\u0105\u0001\u0000\u0000\u0000\u0006"+
+ "\u0107\u0001\u0000\u0000\u0000\u0006\u0109\u0001\u0000\u0000\u0000\u0006"+
+ "\u010b\u0001\u0000\u0000\u0000\u0006\u010f\u0001\u0000\u0000\u0000\u0006"+
+ "\u0111\u0001\u0000\u0000\u0000\u0006\u0113\u0001\u0000\u0000\u0000\u0006"+
+ "\u0115\u0001\u0000\u0000\u0000\u0006\u0117\u0001\u0000\u0000\u0000\u0007"+
+ "\u0119\u0001\u0000\u0000\u0000\u0007\u011b\u0001\u0000\u0000\u0000\u0007"+
+ "\u011d\u0001\u0000\u0000\u0000\u0007\u011f\u0001\u0000\u0000\u0000\u0007"+
+ "\u0121\u0001\u0000\u0000\u0000\u0007\u0123\u0001\u0000\u0000\u0000\u0007"+
+ "\u0125\u0001\u0000\u0000\u0000\u0007\u0127\u0001\u0000\u0000\u0000\u0007"+
+ "\u0129\u0001\u0000\u0000\u0000\u0007\u012b\u0001\u0000\u0000\u0000\u0007"+
+ "\u012d\u0001\u0000\u0000\u0000\u0007\u012f\u0001\u0000\u0000\u0000\b\u0131"+
+ "\u0001\u0000\u0000\u0000\b\u0133\u0001\u0000\u0000\u0000\b\u0135\u0001"+
+ "\u0000\u0000\u0000\b\u0137\u0001\u0000\u0000\u0000\b\u0139\u0001\u0000"+
+ "\u0000\u0000\b\u013b\u0001\u0000\u0000\u0000\b\u013d\u0001\u0000\u0000"+
+ "\u0000\b\u013f\u0001\u0000\u0000\u0000\b\u0141\u0001\u0000\u0000\u0000"+
+ "\t\u0143\u0001\u0000\u0000\u0000\t\u0145\u0001\u0000\u0000\u0000\t\u0147"+
+ "\u0001\u0000\u0000\u0000\t\u0149\u0001\u0000\u0000\u0000\t\u014b\u0001"+
+ "\u0000\u0000\u0000\n\u014d\u0001\u0000\u0000\u0000\n\u014f\u0001\u0000"+
+ "\u0000\u0000\n\u0151\u0001\u0000\u0000\u0000\n\u0153\u0001\u0000\u0000"+
+ "\u0000\n\u0155\u0001\u0000\u0000\u0000\n\u0157\u0001\u0000\u0000\u0000"+
+ "\u000b\u0159\u0001\u0000\u0000\u0000\u000b\u015b\u0001\u0000\u0000\u0000"+
+ "\u000b\u015d\u0001\u0000\u0000\u0000\u000b\u015f\u0001\u0000\u0000\u0000"+
+ "\u000b\u0161\u0001\u0000\u0000\u0000\u000b\u0163\u0001\u0000\u0000\u0000"+
+ "\u000b\u0165\u0001\u0000\u0000\u0000\u000b\u0167\u0001\u0000\u0000\u0000"+
+ "\u000b\u0169\u0001\u0000\u0000\u0000\u000b\u016b\u0001\u0000\u0000\u0000"+
+ "\f\u016d\u0001\u0000\u0000\u0000\f\u016f\u0001\u0000\u0000\u0000\f\u0171"+
+ "\u0001\u0000\u0000\u0000\f\u0173\u0001\u0000\u0000\u0000\f\u0175\u0001"+
+ "\u0000\u0000\u0000\f\u0177\u0001\u0000\u0000\u0000\f\u0179\u0001\u0000"+
+ "\u0000\u0000\r\u017b\u0001\u0000\u0000\u0000\r\u017d\u0001\u0000\u0000"+
+ "\u0000\r\u017f\u0001\u0000\u0000\u0000\r\u0181\u0001\u0000\u0000\u0000"+
+ "\r\u0183\u0001\u0000\u0000\u0000\r\u0185\u0001\u0000\u0000\u0000\u000e"+
+ "\u0187\u0001\u0000\u0000\u0000\u000e\u0189\u0001\u0000\u0000\u0000\u000e"+
+ "\u018b\u0001\u0000\u0000\u0000\u000e\u018d\u0001\u0000\u0000\u0000\u000e"+
+ "\u018f\u0001\u0000\u0000\u0000\u000e\u0191\u0001\u0000\u0000\u0000\u000e"+
+ "\u0193\u0001\u0000\u0000\u0000\u000e\u0195\u0001\u0000\u0000\u0000\u000e"+
+ "\u0197\u0001\u0000\u0000\u0000\u000f\u0199\u0001\u0000\u0000\u0000\u0011"+
+ "\u01a3\u0001\u0000\u0000\u0000\u0013\u01aa\u0001\u0000\u0000\u0000\u0015"+
+ "\u01b3\u0001\u0000\u0000\u0000\u0017\u01ba\u0001\u0000\u0000\u0000\u0019"+
+ "\u01c4\u0001\u0000\u0000\u0000\u001b\u01cb\u0001\u0000\u0000\u0000\u001d"+
+ "\u01d2\u0001\u0000\u0000\u0000\u001f\u01d9\u0001\u0000\u0000\u0000!\u01e1"+
+ "\u0001\u0000\u0000\u0000#\u01ed\u0001\u0000\u0000\u0000%\u01f6\u0001\u0000"+
+ "\u0000\u0000\'\u01fc\u0001\u0000\u0000\u0000)\u0203\u0001\u0000\u0000"+
+ "\u0000+\u020a\u0001\u0000\u0000\u0000-\u0212\u0001\u0000\u0000\u0000/"+
+ "\u021a\u0001\u0000\u0000\u00001\u0229\u0001\u0000\u0000\u00003\u0233\u0001"+
+ "\u0000\u0000\u00005\u023f\u0001\u0000\u0000\u00007\u0245\u0001\u0000\u0000"+
+ "\u00009\u0256\u0001\u0000\u0000\u0000;\u0266\u0001\u0000\u0000\u0000="+
+ "\u026c\u0001\u0000\u0000\u0000?\u0270\u0001\u0000\u0000\u0000A\u0272\u0001"+
+ "\u0000\u0000\u0000C\u0274\u0001\u0000\u0000\u0000E\u0277\u0001\u0000\u0000"+
+ "\u0000G\u0279\u0001\u0000\u0000\u0000I\u0282\u0001\u0000\u0000\u0000K"+
+ "\u0284\u0001\u0000\u0000\u0000M\u0289\u0001\u0000\u0000\u0000O\u028b\u0001"+
+ "\u0000\u0000\u0000Q\u0290\u0001\u0000\u0000\u0000S\u02af\u0001\u0000\u0000"+
+ "\u0000U\u02b2\u0001\u0000\u0000\u0000W\u02e0\u0001\u0000\u0000\u0000Y"+
+ "\u02e2\u0001\u0000\u0000\u0000[\u02e5\u0001\u0000\u0000\u0000]\u02e9\u0001"+
+ "\u0000\u0000\u0000_\u02ed\u0001\u0000\u0000\u0000a\u02ef\u0001\u0000\u0000"+
+ "\u0000c\u02f2\u0001\u0000\u0000\u0000e\u02f4\u0001\u0000\u0000\u0000g"+
+ "\u02f9\u0001\u0000\u0000\u0000i\u02fb\u0001\u0000\u0000\u0000k\u0301\u0001"+
+ "\u0000\u0000\u0000m\u0307\u0001\u0000\u0000\u0000o\u030a\u0001\u0000\u0000"+
+ "\u0000q\u030d\u0001\u0000\u0000\u0000s\u0312\u0001\u0000\u0000\u0000u"+
+ "\u0317\u0001\u0000\u0000\u0000w\u0319\u0001\u0000\u0000\u0000y\u031d\u0001"+
+ "\u0000\u0000\u0000{\u0322\u0001\u0000\u0000\u0000}\u0328\u0001\u0000\u0000"+
+ "\u0000\u007f\u032b\u0001\u0000\u0000\u0000\u0081\u032d\u0001\u0000\u0000"+
+ "\u0000\u0083\u0333\u0001\u0000\u0000\u0000\u0085\u0335\u0001\u0000\u0000"+
+ "\u0000\u0087\u033a\u0001\u0000\u0000\u0000\u0089\u033d\u0001\u0000\u0000"+
+ "\u0000\u008b\u0340\u0001\u0000\u0000\u0000\u008d\u0343\u0001\u0000\u0000"+
+ "\u0000\u008f\u0345\u0001\u0000\u0000\u0000\u0091\u0348\u0001\u0000\u0000"+
+ "\u0000\u0093\u034a\u0001\u0000\u0000\u0000\u0095\u034d\u0001\u0000\u0000"+
+ "\u0000\u0097\u034f\u0001\u0000\u0000\u0000\u0099\u0351\u0001\u0000\u0000"+
+ "\u0000\u009b\u0353\u0001\u0000\u0000\u0000\u009d\u0355\u0001\u0000\u0000"+
+ "\u0000\u009f\u0357\u0001\u0000\u0000\u0000\u00a1\u036f\u0001\u0000\u0000"+
+ "\u0000\u00a3\u0371\u0001\u0000\u0000\u0000\u00a5\u0376\u0001\u0000\u0000"+
+ "\u0000\u00a7\u038b\u0001\u0000\u0000\u0000\u00a9\u038d\u0001\u0000\u0000"+
+ "\u0000\u00ab\u0395\u0001\u0000\u0000\u0000\u00ad\u0397\u0001\u0000\u0000"+
+ "\u0000\u00af\u039b\u0001\u0000\u0000\u0000\u00b1\u039f\u0001\u0000\u0000"+
+ "\u0000\u00b3\u03a3\u0001\u0000\u0000\u0000\u00b5\u03a8\u0001\u0000\u0000"+
+ "\u0000\u00b7\u03ad\u0001\u0000\u0000\u0000\u00b9\u03b1\u0001\u0000\u0000"+
+ "\u0000\u00bb\u03b5\u0001\u0000\u0000\u0000\u00bd\u03b9\u0001\u0000\u0000"+
+ "\u0000\u00bf\u03be\u0001\u0000\u0000\u0000\u00c1\u03c2\u0001\u0000\u0000"+
+ "\u0000\u00c3\u03c6\u0001\u0000\u0000\u0000\u00c5\u03ca\u0001\u0000\u0000"+
+ "\u0000\u00c7\u03ce\u0001\u0000\u0000\u0000\u00c9\u03d2\u0001\u0000\u0000"+
+ "\u0000\u00cb\u03de\u0001\u0000\u0000\u0000\u00cd\u03e1\u0001\u0000\u0000"+
+ "\u0000\u00cf\u03e5\u0001\u0000\u0000\u0000\u00d1\u03e9\u0001\u0000\u0000"+
+ "\u0000\u00d3\u03ed\u0001\u0000\u0000\u0000\u00d5\u03f1\u0001\u0000\u0000"+
+ "\u0000\u00d7\u03f5\u0001\u0000\u0000\u0000\u00d9\u03f9\u0001\u0000\u0000"+
+ "\u0000\u00db\u03fe\u0001\u0000\u0000\u0000\u00dd\u0402\u0001\u0000\u0000"+
+ "\u0000\u00df\u0406\u0001\u0000\u0000\u0000\u00e1\u040a\u0001\u0000\u0000"+
+ "\u0000\u00e3\u0412\u0001\u0000\u0000\u0000\u00e5\u0427\u0001\u0000\u0000"+
+ "\u0000\u00e7\u042b\u0001\u0000\u0000\u0000\u00e9\u042f\u0001\u0000\u0000"+
+ "\u0000\u00eb\u0433\u0001\u0000\u0000\u0000\u00ed\u0437\u0001\u0000\u0000"+
+ "\u0000\u00ef\u043b\u0001\u0000\u0000\u0000\u00f1\u0440\u0001\u0000\u0000"+
+ "\u0000\u00f3\u0444\u0001\u0000\u0000\u0000\u00f5\u0448\u0001\u0000\u0000"+
+ "\u0000\u00f7\u044c\u0001\u0000\u0000\u0000\u00f9\u0450\u0001\u0000\u0000"+
+ "\u0000\u00fb\u0454\u0001\u0000\u0000\u0000\u00fd\u0457\u0001\u0000\u0000"+
+ "\u0000\u00ff\u045b\u0001\u0000\u0000\u0000\u0101\u045f\u0001\u0000\u0000"+
+ "\u0000\u0103\u0463\u0001\u0000\u0000\u0000\u0105\u0467\u0001\u0000\u0000"+
+ "\u0000\u0107\u046c\u0001\u0000\u0000\u0000\u0109\u0471\u0001\u0000\u0000"+
+ "\u0000\u010b\u0476\u0001\u0000\u0000\u0000\u010d\u047d\u0001\u0000\u0000"+
+ "\u0000\u010f\u0486\u0001\u0000\u0000\u0000\u0111\u048d\u0001\u0000\u0000"+
+ "\u0000\u0113\u0491\u0001\u0000\u0000\u0000\u0115\u0495\u0001\u0000\u0000"+
+ "\u0000\u0117\u0499\u0001\u0000\u0000\u0000\u0119\u049d\u0001\u0000\u0000"+
+ "\u0000\u011b\u04a3\u0001\u0000\u0000\u0000\u011d\u04a7\u0001\u0000\u0000"+
+ "\u0000\u011f\u04ab\u0001\u0000\u0000\u0000\u0121\u04af\u0001\u0000\u0000"+
+ "\u0000\u0123\u04b3\u0001\u0000\u0000\u0000\u0125\u04b7\u0001\u0000\u0000"+
+ "\u0000\u0127\u04bb\u0001\u0000\u0000\u0000\u0129\u04bf\u0001\u0000\u0000"+
+ "\u0000\u012b\u04c3\u0001\u0000\u0000\u0000\u012d\u04c7\u0001\u0000\u0000"+
+ "\u0000\u012f\u04cb\u0001\u0000\u0000\u0000\u0131\u04cf\u0001\u0000\u0000"+
+ "\u0000\u0133\u04d4\u0001\u0000\u0000\u0000\u0135\u04d8\u0001\u0000\u0000"+
+ "\u0000\u0137\u04dc\u0001\u0000\u0000\u0000\u0139\u04e0\u0001\u0000\u0000"+
+ "\u0000\u013b\u04e4\u0001\u0000\u0000\u0000\u013d\u04e8\u0001\u0000\u0000"+
+ "\u0000\u013f\u04ec\u0001\u0000\u0000\u0000\u0141\u04f0\u0001\u0000\u0000"+
+ "\u0000\u0143\u04f4\u0001\u0000\u0000\u0000\u0145\u04f9\u0001\u0000\u0000"+
+ "\u0000\u0147\u04fe\u0001\u0000\u0000\u0000\u0149\u0502\u0001\u0000\u0000"+
+ "\u0000\u014b\u0506\u0001\u0000\u0000\u0000\u014d\u050a\u0001\u0000\u0000"+
+ "\u0000\u014f\u050f\u0001\u0000\u0000\u0000\u0151\u0516\u0001\u0000\u0000"+
+ "\u0000\u0153\u051a\u0001\u0000\u0000\u0000\u0155\u051e\u0001\u0000\u0000"+
+ "\u0000\u0157\u0522\u0001\u0000\u0000\u0000\u0159\u0526\u0001\u0000\u0000"+
+ "\u0000\u015b\u052b\u0001\u0000\u0000\u0000\u015d\u052f\u0001\u0000\u0000"+
+ "\u0000\u015f\u0533\u0001\u0000\u0000\u0000\u0161\u0537\u0001\u0000\u0000"+
+ "\u0000\u0163\u053c\u0001\u0000\u0000\u0000\u0165\u0540\u0001\u0000\u0000"+
+ "\u0000\u0167\u0544\u0001\u0000\u0000\u0000\u0169\u0548\u0001\u0000\u0000"+
+ "\u0000\u016b\u054c\u0001\u0000\u0000\u0000\u016d\u0550\u0001\u0000\u0000"+
+ "\u0000\u016f\u0556\u0001\u0000\u0000\u0000\u0171\u055a\u0001\u0000\u0000"+
+ "\u0000\u0173\u055e\u0001\u0000\u0000\u0000\u0175\u0562\u0001\u0000\u0000"+
+ "\u0000\u0177\u0566\u0001\u0000\u0000\u0000\u0179\u056a\u0001\u0000\u0000"+
+ "\u0000\u017b\u056e\u0001\u0000\u0000\u0000\u017d\u0573\u0001\u0000\u0000"+
+ "\u0000\u017f\u0579\u0001\u0000\u0000\u0000\u0181\u057f\u0001\u0000\u0000"+
+ "\u0000\u0183\u0583\u0001\u0000\u0000\u0000\u0185\u0587\u0001\u0000\u0000"+
+ "\u0000\u0187\u058b\u0001\u0000\u0000\u0000\u0189\u0591\u0001\u0000\u0000"+
+ "\u0000\u018b\u0597\u0001\u0000\u0000\u0000\u018d\u059b\u0001\u0000\u0000"+
+ "\u0000\u018f\u059f\u0001\u0000\u0000\u0000\u0191\u05a3\u0001\u0000\u0000"+
+ "\u0000\u0193\u05a9\u0001\u0000\u0000\u0000\u0195\u05af\u0001\u0000\u0000"+
+ "\u0000\u0197\u05b5\u0001\u0000\u0000\u0000\u0199\u019a\u0007\u0000\u0000"+
+ "\u0000\u019a\u019b\u0007\u0001\u0000\u0000\u019b\u019c\u0007\u0002\u0000"+
+ "\u0000\u019c\u019d\u0007\u0002\u0000\u0000\u019d\u019e\u0007\u0003\u0000"+
+ "\u0000\u019e\u019f\u0007\u0004\u0000\u0000\u019f\u01a0\u0007\u0005\u0000"+
+ "\u0000\u01a0\u01a1\u0001\u0000\u0000\u0000\u01a1\u01a2\u0006\u0000\u0000"+
+ "\u0000\u01a2\u0010\u0001\u0000\u0000\u0000\u01a3\u01a4\u0007\u0000\u0000"+
+ "\u0000\u01a4\u01a5\u0007\u0006\u0000\u0000\u01a5\u01a6\u0007\u0007\u0000"+
+ "\u0000\u01a6\u01a7\u0007\b\u0000\u0000\u01a7\u01a8\u0001\u0000\u0000\u0000"+
+ "\u01a8\u01a9\u0006\u0001\u0001\u0000\u01a9\u0012\u0001\u0000\u0000\u0000"+
+ "\u01aa\u01ab\u0007\u0003\u0000\u0000\u01ab\u01ac\u0007\t\u0000\u0000\u01ac"+
+ "\u01ad\u0007\u0006\u0000\u0000\u01ad\u01ae\u0007\u0001\u0000\u0000\u01ae"+
+ "\u01af\u0007\u0004\u0000\u0000\u01af\u01b0\u0007\n\u0000\u0000\u01b0\u01b1"+
+ "\u0001\u0000\u0000\u0000\u01b1\u01b2\u0006\u0002\u0002\u0000\u01b2\u0014"+
+ "\u0001\u0000\u0000\u0000\u01b3\u01b4\u0007\u0003\u0000\u0000\u01b4\u01b5"+
+ "\u0007\u000b\u0000\u0000\u01b5\u01b6\u0007\f\u0000\u0000\u01b6\u01b7\u0007"+
+ "\r\u0000\u0000\u01b7\u01b8\u0001\u0000\u0000\u0000\u01b8\u01b9\u0006\u0003"+
+ "\u0000\u0000\u01b9\u0016\u0001\u0000\u0000\u0000\u01ba\u01bb\u0007\u0003"+
+ "\u0000\u0000\u01bb\u01bc\u0007\u000e\u0000\u0000\u01bc\u01bd\u0007\b\u0000"+
+ "\u0000\u01bd\u01be\u0007\r\u0000\u0000\u01be\u01bf\u0007\f\u0000\u0000"+
+ "\u01bf\u01c0\u0007\u0001\u0000\u0000\u01c0\u01c1\u0007\t\u0000\u0000\u01c1"+
+ "\u01c2\u0001\u0000\u0000\u0000\u01c2\u01c3\u0006\u0004\u0003\u0000\u01c3"+
+ "\u0018\u0001\u0000\u0000\u0000\u01c4\u01c5\u0007\u000f\u0000\u0000\u01c5"+
+ "\u01c6\u0007\u0006\u0000\u0000\u01c6\u01c7\u0007\u0007\u0000\u0000\u01c7"+
+ "\u01c8\u0007\u0010\u0000\u0000\u01c8\u01c9\u0001\u0000\u0000\u0000\u01c9"+
+ "\u01ca\u0006\u0005\u0004\u0000\u01ca\u001a\u0001\u0000\u0000\u0000\u01cb"+
+ "\u01cc\u0007\u0011\u0000\u0000\u01cc\u01cd\u0007\u0006\u0000\u0000\u01cd"+
+ "\u01ce\u0007\u0007\u0000\u0000\u01ce\u01cf\u0007\u0012\u0000\u0000\u01cf"+
+ "\u01d0\u0001\u0000\u0000\u0000\u01d0\u01d1\u0006\u0006\u0000\u0000\u01d1"+
+ "\u001c\u0001\u0000\u0000\u0000\u01d2\u01d3\u0007\u0012\u0000\u0000\u01d3"+
+ "\u01d4\u0007\u0003\u0000\u0000\u01d4\u01d5\u0007\u0003\u0000\u0000\u01d5"+
+ "\u01d6\u0007\b\u0000\u0000\u01d6\u01d7\u0001\u0000\u0000\u0000\u01d7\u01d8"+
+ "\u0006\u0007\u0001\u0000\u01d8\u001e\u0001\u0000\u0000\u0000\u01d9\u01da"+
+ "\u0007\r\u0000\u0000\u01da\u01db\u0007\u0001\u0000\u0000\u01db\u01dc\u0007"+
+ "\u0010\u0000\u0000\u01dc\u01dd\u0007\u0001\u0000\u0000\u01dd\u01de\u0007"+
+ "\u0005\u0000\u0000\u01de\u01df\u0001\u0000\u0000\u0000\u01df\u01e0\u0006"+
+ "\b\u0000\u0000\u01e0 \u0001\u0000\u0000\u0000\u01e1\u01e2\u0007\u0010"+
+ "\u0000\u0000\u01e2\u01e3\u0007\u000b\u0000\u0000\u01e3\u01e4\u0005_\u0000"+
+ "\u0000\u01e4\u01e5\u0007\u0003\u0000\u0000\u01e5\u01e6\u0007\u000e\u0000"+
+ "\u0000\u01e6\u01e7\u0007\b\u0000\u0000\u01e7\u01e8\u0007\f\u0000\u0000"+
+ "\u01e8\u01e9\u0007\t\u0000\u0000\u01e9\u01ea\u0007\u0000\u0000\u0000\u01ea"+
+ "\u01eb\u0001\u0000\u0000\u0000\u01eb\u01ec\u0006\t\u0005\u0000\u01ec\""+
+ "\u0001\u0000\u0000\u0000\u01ed\u01ee\u0007\u0006\u0000\u0000\u01ee\u01ef"+
+ "\u0007\u0003\u0000\u0000\u01ef\u01f0\u0007\t\u0000\u0000\u01f0\u01f1\u0007"+
+ "\f\u0000\u0000\u01f1\u01f2\u0007\u0010\u0000\u0000\u01f2\u01f3\u0007\u0003"+
+ "\u0000\u0000\u01f3\u01f4\u0001\u0000\u0000\u0000\u01f4\u01f5\u0006\n\u0006"+
+ "\u0000\u01f5$\u0001\u0000\u0000\u0000\u01f6\u01f7\u0007\u0006\u0000\u0000"+
+ "\u01f7\u01f8\u0007\u0007\u0000\u0000\u01f8\u01f9\u0007\u0013\u0000\u0000"+
+ "\u01f9\u01fa\u0001\u0000\u0000\u0000\u01fa\u01fb\u0006\u000b\u0000\u0000"+
+ "\u01fb&\u0001\u0000\u0000\u0000\u01fc\u01fd\u0007\u0002\u0000\u0000\u01fd"+
+ "\u01fe\u0007\n\u0000\u0000\u01fe\u01ff\u0007\u0007\u0000\u0000\u01ff\u0200"+
+ "\u0007\u0013\u0000\u0000\u0200\u0201\u0001\u0000\u0000\u0000\u0201\u0202"+
+ "\u0006\f\u0007\u0000\u0202(\u0001\u0000\u0000\u0000\u0203\u0204\u0007"+
+ "\u0002\u0000\u0000\u0204\u0205\u0007\u0007\u0000\u0000\u0205\u0206\u0007"+
+ "\u0006\u0000\u0000\u0206\u0207\u0007\u0005\u0000\u0000\u0207\u0208\u0001"+
+ "\u0000\u0000\u0000\u0208\u0209\u0006\r\u0000\u0000\u0209*\u0001\u0000"+
+ "\u0000\u0000\u020a\u020b\u0007\u0002\u0000\u0000\u020b\u020c\u0007\u0005"+
+ "\u0000\u0000\u020c\u020d\u0007\f\u0000\u0000\u020d\u020e\u0007\u0005\u0000"+
+ "\u0000\u020e\u020f\u0007\u0002\u0000\u0000\u020f\u0210\u0001\u0000\u0000"+
+ "\u0000\u0210\u0211\u0006\u000e\u0000\u0000\u0211,\u0001\u0000\u0000\u0000"+
+ "\u0212\u0213\u0007\u0013\u0000\u0000\u0213\u0214\u0007\n\u0000\u0000\u0214"+
+ "\u0215\u0007\u0003\u0000\u0000\u0215\u0216\u0007\u0006\u0000\u0000\u0216"+
+ "\u0217\u0007\u0003\u0000\u0000\u0217\u0218\u0001\u0000\u0000\u0000\u0218"+
+ "\u0219\u0006\u000f\u0000\u0000\u0219.\u0001\u0000\u0000\u0000\u021a\u021b"+
+ "\u0004\u0010\u0000\u0000\u021b\u021c\u0007\u0001\u0000\u0000\u021c\u021d"+
+ "\u0007\t\u0000\u0000\u021d\u021e\u0007\r\u0000\u0000\u021e\u021f\u0007"+
+ "\u0001\u0000\u0000\u021f\u0220\u0007\t\u0000\u0000\u0220\u0221\u0007\u0003"+
+ "\u0000\u0000\u0221\u0222\u0007\u0002\u0000\u0000\u0222\u0223\u0007\u0005"+
+ "\u0000\u0000\u0223\u0224\u0007\f\u0000\u0000\u0224\u0225\u0007\u0005\u0000"+
+ "\u0000\u0225\u0226\u0007\u0002\u0000\u0000\u0226\u0227\u0001\u0000\u0000"+
+ "\u0000\u0227\u0228\u0006\u0010\u0000\u0000\u02280\u0001\u0000\u0000\u0000"+
+ "\u0229\u022a\u0004\u0011\u0001\u0000\u022a\u022b\u0007\r\u0000\u0000\u022b"+
+ "\u022c\u0007\u0007\u0000\u0000\u022c\u022d\u0007\u0007\u0000\u0000\u022d"+
+ "\u022e\u0007\u0012\u0000\u0000\u022e\u022f\u0007\u0014\u0000\u0000\u022f"+
+ "\u0230\u0007\b\u0000\u0000\u0230\u0231\u0001\u0000\u0000\u0000\u0231\u0232"+
+ "\u0006\u0011\b\u0000\u02322\u0001\u0000\u0000\u0000\u0233\u0234\u0004"+
+ "\u0012\u0002\u0000\u0234\u0235\u0007\u0010\u0000\u0000\u0235\u0236\u0007"+
+ "\u0003\u0000\u0000\u0236\u0237\u0007\u0005\u0000\u0000\u0237\u0238\u0007"+
+ "\u0006\u0000\u0000\u0238\u0239\u0007\u0001\u0000\u0000\u0239\u023a\u0007"+
+ "\u0004\u0000\u0000\u023a\u023b\u0007\u0002\u0000\u0000\u023b\u023c\u0001"+
+ "\u0000\u0000\u0000\u023c\u023d\u0006\u0012\t\u0000\u023d4\u0001\u0000"+
+ "\u0000\u0000\u023e\u0240\b\u0015\u0000\u0000\u023f\u023e\u0001\u0000\u0000"+
+ "\u0000\u0240\u0241\u0001\u0000\u0000\u0000\u0241\u023f\u0001\u0000\u0000"+
+ "\u0000\u0241\u0242\u0001\u0000\u0000\u0000\u0242\u0243\u0001\u0000\u0000"+
+ "\u0000\u0243\u0244\u0006\u0013\u0000\u0000\u02446\u0001\u0000\u0000\u0000"+
+ "\u0245\u0246\u0005/\u0000\u0000\u0246\u0247\u0005/\u0000\u0000\u0247\u024b"+
+ "\u0001\u0000\u0000\u0000\u0248\u024a\b\u0016\u0000\u0000\u0249\u0248\u0001"+
+ "\u0000\u0000\u0000\u024a\u024d\u0001\u0000\u0000\u0000\u024b\u0249\u0001"+
+ "\u0000\u0000\u0000\u024b\u024c\u0001\u0000\u0000\u0000\u024c\u024f\u0001"+
+ "\u0000\u0000\u0000\u024d\u024b\u0001\u0000\u0000\u0000\u024e\u0250\u0005"+
+ "\r\u0000\u0000\u024f\u024e\u0001\u0000\u0000\u0000\u024f\u0250\u0001\u0000"+
+ "\u0000\u0000\u0250\u0252\u0001\u0000\u0000\u0000\u0251\u0253\u0005\n\u0000"+
+ "\u0000\u0252\u0251\u0001\u0000\u0000\u0000\u0252\u0253\u0001\u0000\u0000"+
+ "\u0000\u0253\u0254\u0001\u0000\u0000\u0000\u0254\u0255\u0006\u0014\n\u0000"+
+ "\u02558\u0001\u0000\u0000\u0000\u0256\u0257\u0005/\u0000\u0000\u0257\u0258"+
+ "\u0005*\u0000\u0000\u0258\u025d\u0001\u0000\u0000\u0000\u0259\u025c\u0003"+
+ "9\u0015\u0000\u025a\u025c\t\u0000\u0000\u0000\u025b\u0259\u0001\u0000"+
+ "\u0000\u0000\u025b\u025a\u0001\u0000\u0000\u0000\u025c\u025f\u0001\u0000"+
+ "\u0000\u0000\u025d\u025e\u0001\u0000\u0000\u0000\u025d\u025b\u0001\u0000"+
+ "\u0000\u0000\u025e\u0260\u0001\u0000\u0000\u0000\u025f\u025d\u0001\u0000"+
+ "\u0000\u0000\u0260\u0261\u0005*\u0000\u0000\u0261\u0262\u0005/\u0000\u0000"+
+ "\u0262\u0263\u0001\u0000\u0000\u0000\u0263\u0264\u0006\u0015\n\u0000\u0264"+
+ ":\u0001\u0000\u0000\u0000\u0265\u0267\u0007\u0017\u0000\u0000\u0266\u0265"+
+ "\u0001\u0000\u0000\u0000\u0267\u0268\u0001\u0000\u0000\u0000\u0268\u0266"+
+ "\u0001\u0000\u0000\u0000\u0268\u0269\u0001\u0000\u0000\u0000\u0269\u026a"+
+ "\u0001\u0000\u0000\u0000\u026a\u026b\u0006\u0016\n\u0000\u026b<\u0001"+
+ "\u0000\u0000\u0000\u026c\u026d\u0005|\u0000\u0000\u026d\u026e\u0001\u0000"+
+ "\u0000\u0000\u026e\u026f\u0006\u0017\u000b\u0000\u026f>\u0001\u0000\u0000"+
+ "\u0000\u0270\u0271\u0007\u0018\u0000\u0000\u0271@\u0001\u0000\u0000\u0000"+
+ "\u0272\u0273\u0007\u0019\u0000\u0000\u0273B\u0001\u0000\u0000\u0000\u0274"+
+ "\u0275\u0005\\\u0000\u0000\u0275\u0276\u0007\u001a\u0000\u0000\u0276D"+
+ "\u0001\u0000\u0000\u0000\u0277\u0278\b\u001b\u0000\u0000\u0278F\u0001"+
+ "\u0000\u0000\u0000\u0279\u027b\u0007\u0003\u0000\u0000\u027a\u027c\u0007"+
+ "\u001c\u0000\u0000\u027b\u027a\u0001\u0000\u0000\u0000\u027b\u027c\u0001"+
+ "\u0000\u0000\u0000\u027c\u027e\u0001\u0000\u0000\u0000\u027d\u027f\u0003"+
+ "?\u0018\u0000\u027e\u027d\u0001\u0000\u0000\u0000\u027f\u0280\u0001\u0000"+
+ "\u0000\u0000\u0280\u027e\u0001\u0000\u0000\u0000\u0280\u0281\u0001\u0000"+
+ "\u0000\u0000\u0281H\u0001\u0000\u0000\u0000\u0282\u0283\u0005@\u0000\u0000"+
+ "\u0283J\u0001\u0000\u0000\u0000\u0284\u0285\u0005`\u0000\u0000\u0285L"+
+ "\u0001\u0000\u0000\u0000\u0286\u028a\b\u001d\u0000\u0000\u0287\u0288\u0005"+
+ "`\u0000\u0000\u0288\u028a\u0005`\u0000\u0000\u0289\u0286\u0001\u0000\u0000"+
+ "\u0000\u0289\u0287\u0001\u0000\u0000\u0000\u028aN\u0001\u0000\u0000\u0000"+
+ "\u028b\u028c\u0005_\u0000\u0000\u028cP\u0001\u0000\u0000\u0000\u028d\u0291"+
+ "\u0003A\u0019\u0000\u028e\u0291\u0003?\u0018\u0000\u028f\u0291\u0003O"+
+ " \u0000\u0290\u028d\u0001\u0000\u0000\u0000\u0290\u028e\u0001\u0000\u0000"+
+ "\u0000\u0290\u028f\u0001\u0000\u0000\u0000\u0291R\u0001\u0000\u0000\u0000"+
+ "\u0292\u0297\u0005\"\u0000\u0000\u0293\u0296\u0003C\u001a\u0000\u0294"+
+ "\u0296\u0003E\u001b\u0000\u0295\u0293\u0001\u0000\u0000\u0000\u0295\u0294"+
+ "\u0001\u0000\u0000\u0000\u0296\u0299\u0001\u0000\u0000\u0000\u0297\u0295"+
+ "\u0001\u0000\u0000\u0000\u0297\u0298\u0001\u0000\u0000\u0000\u0298\u029a"+
+ "\u0001\u0000\u0000\u0000\u0299\u0297\u0001\u0000\u0000\u0000\u029a\u02b0"+
+ "\u0005\"\u0000\u0000\u029b\u029c\u0005\"\u0000\u0000\u029c\u029d\u0005"+
+ "\"\u0000\u0000\u029d\u029e\u0005\"\u0000\u0000\u029e\u02a2\u0001\u0000"+
+ "\u0000\u0000\u029f\u02a1\b\u0016\u0000\u0000\u02a0\u029f\u0001\u0000\u0000"+
+ "\u0000\u02a1\u02a4\u0001\u0000\u0000\u0000\u02a2\u02a3\u0001\u0000\u0000"+
+ "\u0000\u02a2\u02a0\u0001\u0000\u0000\u0000\u02a3\u02a5\u0001\u0000\u0000"+
+ "\u0000\u02a4\u02a2\u0001\u0000\u0000\u0000\u02a5\u02a6\u0005\"\u0000\u0000"+
+ "\u02a6\u02a7\u0005\"\u0000\u0000\u02a7\u02a8\u0005\"\u0000\u0000\u02a8"+
+ "\u02aa\u0001\u0000\u0000\u0000\u02a9\u02ab\u0005\"\u0000\u0000\u02aa\u02a9"+
+ "\u0001\u0000\u0000\u0000\u02aa\u02ab\u0001\u0000\u0000\u0000\u02ab\u02ad"+
+ "\u0001\u0000\u0000\u0000\u02ac\u02ae\u0005\"\u0000\u0000\u02ad\u02ac\u0001"+
+ "\u0000\u0000\u0000\u02ad\u02ae\u0001\u0000\u0000\u0000\u02ae\u02b0\u0001"+
+ "\u0000\u0000\u0000\u02af\u0292\u0001\u0000\u0000\u0000\u02af\u029b\u0001"+
+ "\u0000\u0000\u0000\u02b0T\u0001\u0000\u0000\u0000\u02b1\u02b3\u0003?\u0018"+
+ "\u0000\u02b2\u02b1\u0001\u0000\u0000\u0000\u02b3\u02b4\u0001\u0000\u0000"+
+ "\u0000\u02b4\u02b2\u0001\u0000\u0000\u0000\u02b4\u02b5\u0001\u0000\u0000"+
+ "\u0000\u02b5V\u0001\u0000\u0000\u0000\u02b6\u02b8\u0003?\u0018\u0000\u02b7"+
+ "\u02b6\u0001\u0000\u0000\u0000\u02b8\u02b9\u0001\u0000\u0000\u0000\u02b9"+
+ "\u02b7\u0001\u0000\u0000\u0000\u02b9\u02ba\u0001\u0000\u0000\u0000\u02ba"+
+ "\u02bb\u0001\u0000\u0000\u0000\u02bb\u02bf\u0003g,\u0000\u02bc\u02be\u0003"+
+ "?\u0018\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\u02e1\u0001\u0000\u0000\u0000\u02c1\u02bf\u0001\u0000"+
+ "\u0000\u0000\u02c2\u02c4\u0003g,\u0000\u02c3\u02c5\u0003?\u0018\u0000"+
+ "\u02c4\u02c3\u0001\u0000\u0000\u0000\u02c5\u02c6\u0001\u0000\u0000\u0000"+
+ "\u02c6\u02c4\u0001\u0000\u0000\u0000\u02c6\u02c7\u0001\u0000\u0000\u0000"+
+ "\u02c7\u02e1\u0001\u0000\u0000\u0000\u02c8\u02ca\u0003?\u0018\u0000\u02c9"+
+ "\u02c8\u0001\u0000\u0000\u0000\u02ca\u02cb\u0001\u0000\u0000\u0000\u02cb"+
+ "\u02c9\u0001\u0000\u0000\u0000\u02cb\u02cc\u0001\u0000\u0000\u0000\u02cc"+
+ "\u02d4\u0001\u0000\u0000\u0000\u02cd\u02d1\u0003g,\u0000\u02ce\u02d0\u0003"+
+ "?\u0018\u0000\u02cf\u02ce\u0001\u0000\u0000\u0000\u02d0\u02d3\u0001\u0000"+
+ "\u0000\u0000\u02d1\u02cf\u0001\u0000\u0000\u0000\u02d1\u02d2\u0001\u0000"+
+ "\u0000\u0000\u02d2\u02d5\u0001\u0000\u0000\u0000\u02d3\u02d1\u0001\u0000"+
+ "\u0000\u0000\u02d4\u02cd\u0001\u0000\u0000\u0000\u02d4\u02d5\u0001\u0000"+
+ "\u0000\u0000\u02d5\u02d6\u0001\u0000\u0000\u0000\u02d6\u02d7\u0003G\u001c"+
+ "\u0000\u02d7\u02e1\u0001\u0000\u0000\u0000\u02d8\u02da\u0003g,\u0000\u02d9"+
+ "\u02db\u0003?\u0018\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"+
+ "\u0003G\u001c\u0000\u02df\u02e1\u0001\u0000\u0000\u0000\u02e0\u02b7\u0001"+
+ "\u0000\u0000\u0000\u02e0\u02c2\u0001\u0000\u0000\u0000\u02e0\u02c9\u0001"+
+ "\u0000\u0000\u0000\u02e0\u02d8\u0001\u0000\u0000\u0000\u02e1X\u0001\u0000"+
+ "\u0000\u0000\u02e2\u02e3\u0007\u001e\u0000\u0000\u02e3\u02e4\u0007\u001f"+
+ "\u0000\u0000\u02e4Z\u0001\u0000\u0000\u0000\u02e5\u02e6\u0007\f\u0000"+
+ "\u0000\u02e6\u02e7\u0007\t\u0000\u0000\u02e7\u02e8\u0007\u0000\u0000\u0000"+
+ "\u02e8\\\u0001\u0000\u0000\u0000\u02e9\u02ea\u0007\f\u0000\u0000\u02ea"+
+ "\u02eb\u0007\u0002\u0000\u0000\u02eb\u02ec\u0007\u0004\u0000\u0000\u02ec"+
+ "^\u0001\u0000\u0000\u0000\u02ed\u02ee\u0005=\u0000\u0000\u02ee`\u0001"+
+ "\u0000\u0000\u0000\u02ef\u02f0\u0005:\u0000\u0000\u02f0\u02f1\u0005:\u0000"+
+ "\u0000\u02f1b\u0001\u0000\u0000\u0000\u02f2\u02f3\u0005,\u0000\u0000\u02f3"+
+ "d\u0001\u0000\u0000\u0000\u02f4\u02f5\u0007\u0000\u0000\u0000\u02f5\u02f6"+
+ "\u0007\u0003\u0000\u0000\u02f6\u02f7\u0007\u0002\u0000\u0000\u02f7\u02f8"+
+ "\u0007\u0004\u0000\u0000\u02f8f\u0001\u0000\u0000\u0000\u02f9\u02fa\u0005"+
+ ".\u0000\u0000\u02fah\u0001\u0000\u0000\u0000\u02fb\u02fc\u0007\u000f\u0000"+
+ "\u0000\u02fc\u02fd\u0007\f\u0000\u0000\u02fd\u02fe\u0007\r\u0000\u0000"+
+ "\u02fe\u02ff\u0007\u0002\u0000\u0000\u02ff\u0300\u0007\u0003\u0000\u0000"+
+ "\u0300j\u0001\u0000\u0000\u0000\u0301\u0302\u0007\u000f\u0000\u0000\u0302"+
+ "\u0303\u0007\u0001\u0000\u0000\u0303\u0304\u0007\u0006\u0000\u0000\u0304"+
+ "\u0305\u0007\u0002\u0000\u0000\u0305\u0306\u0007\u0005\u0000\u0000\u0306"+
+ "l\u0001\u0000\u0000\u0000\u0307\u0308\u0007\u0001\u0000\u0000\u0308\u0309"+
+ "\u0007\t\u0000\u0000\u0309n\u0001\u0000\u0000\u0000\u030a\u030b\u0007"+
+ "\u0001\u0000\u0000\u030b\u030c\u0007\u0002\u0000\u0000\u030cp\u0001\u0000"+
+ "\u0000\u0000\u030d\u030e\u0007\r\u0000\u0000\u030e\u030f\u0007\f\u0000"+
+ "\u0000\u030f\u0310\u0007\u0002\u0000\u0000\u0310\u0311\u0007\u0005\u0000"+
+ "\u0000\u0311r\u0001\u0000\u0000\u0000\u0312\u0313\u0007\r\u0000\u0000"+
+ "\u0313\u0314\u0007\u0001\u0000\u0000\u0314\u0315\u0007\u0012\u0000\u0000"+
+ "\u0315\u0316\u0007\u0003\u0000\u0000\u0316t\u0001\u0000\u0000\u0000\u0317"+
+ "\u0318\u0005(\u0000\u0000\u0318v\u0001\u0000\u0000\u0000\u0319\u031a\u0007"+
+ "\t\u0000\u0000\u031a\u031b\u0007\u0007\u0000\u0000\u031b\u031c\u0007\u0005"+
+ "\u0000\u0000\u031cx\u0001\u0000\u0000\u0000\u031d\u031e\u0007\t\u0000"+
+ "\u0000\u031e\u031f\u0007\u0014\u0000\u0000\u031f\u0320\u0007\r\u0000\u0000"+
+ "\u0320\u0321\u0007\r\u0000\u0000\u0321z\u0001\u0000\u0000\u0000\u0322"+
+ "\u0323\u0007\t\u0000\u0000\u0323\u0324\u0007\u0014\u0000\u0000\u0324\u0325"+
+ "\u0007\r\u0000\u0000\u0325\u0326\u0007\r\u0000\u0000\u0326\u0327\u0007"+
+ "\u0002\u0000\u0000\u0327|\u0001\u0000\u0000\u0000\u0328\u0329\u0007\u0007"+
+ "\u0000\u0000\u0329\u032a\u0007\u0006\u0000\u0000\u032a~\u0001\u0000\u0000"+
+ "\u0000\u032b\u032c\u0005?\u0000\u0000\u032c\u0080\u0001\u0000\u0000\u0000"+
+ "\u032d\u032e\u0007\u0006\u0000\u0000\u032e\u032f\u0007\r\u0000\u0000\u032f"+
+ "\u0330\u0007\u0001\u0000\u0000\u0330\u0331\u0007\u0012\u0000\u0000\u0331"+
+ "\u0332\u0007\u0003\u0000\u0000\u0332\u0082\u0001\u0000\u0000\u0000\u0333"+
+ "\u0334\u0005)\u0000\u0000\u0334\u0084\u0001\u0000\u0000\u0000\u0335\u0336"+
+ "\u0007\u0005\u0000\u0000\u0336\u0337\u0007\u0006\u0000\u0000\u0337\u0338"+
+ "\u0007\u0014\u0000\u0000\u0338\u0339\u0007\u0003\u0000\u0000\u0339\u0086"+
+ "\u0001\u0000\u0000\u0000\u033a\u033b\u0005=\u0000\u0000\u033b\u033c\u0005"+
+ "=\u0000\u0000\u033c\u0088\u0001\u0000\u0000\u0000\u033d\u033e\u0005=\u0000"+
+ "\u0000\u033e\u033f\u0005~\u0000\u0000\u033f\u008a\u0001\u0000\u0000\u0000"+
+ "\u0340\u0341\u0005!\u0000\u0000\u0341\u0342\u0005=\u0000\u0000\u0342\u008c"+
+ "\u0001\u0000\u0000\u0000\u0343\u0344\u0005<\u0000\u0000\u0344\u008e\u0001"+
+ "\u0000\u0000\u0000\u0345\u0346\u0005<\u0000\u0000\u0346\u0347\u0005=\u0000"+
+ "\u0000\u0347\u0090\u0001\u0000\u0000\u0000\u0348\u0349\u0005>\u0000\u0000"+
+ "\u0349\u0092\u0001\u0000\u0000\u0000\u034a\u034b\u0005>\u0000\u0000\u034b"+
+ "\u034c\u0005=\u0000\u0000\u034c\u0094\u0001\u0000\u0000\u0000\u034d\u034e"+
+ "\u0005+\u0000\u0000\u034e\u0096\u0001\u0000\u0000\u0000\u034f\u0350\u0005"+
+ "-\u0000\u0000\u0350\u0098\u0001\u0000\u0000\u0000\u0351\u0352\u0005*\u0000"+
+ "\u0000\u0352\u009a\u0001\u0000\u0000\u0000\u0353\u0354\u0005/\u0000\u0000"+
+ "\u0354\u009c\u0001\u0000\u0000\u0000\u0355\u0356\u0005%\u0000\u0000\u0356"+
+ "\u009e\u0001\u0000\u0000\u0000\u0357\u0358\u0004H\u0003\u0000\u0358\u0359"+
+ "\u0007\u0010\u0000\u0000\u0359\u035a\u0007\f\u0000\u0000\u035a\u035b\u0007"+
+ "\u0005\u0000\u0000\u035b\u035c\u0007\u0004\u0000\u0000\u035c\u035d\u0007"+
+ "\n\u0000\u0000\u035d\u00a0\u0001\u0000\u0000\u0000\u035e\u0361\u0003\u007f"+
+ "8\u0000\u035f\u0362\u0003A\u0019\u0000\u0360\u0362\u0003O \u0000\u0361"+
+ "\u035f\u0001\u0000\u0000\u0000\u0361\u0360\u0001\u0000\u0000\u0000\u0362"+
+ "\u0366\u0001\u0000\u0000\u0000\u0363\u0365\u0003Q!\u0000\u0364\u0363\u0001"+
+ "\u0000\u0000\u0000\u0365\u0368\u0001\u0000\u0000\u0000\u0366\u0364\u0001"+
+ "\u0000\u0000\u0000\u0366\u0367\u0001\u0000\u0000\u0000\u0367\u0370\u0001"+
+ "\u0000\u0000\u0000\u0368\u0366\u0001\u0000\u0000\u0000\u0369\u036b\u0003"+
+ "\u007f8\u0000\u036a\u036c\u0003?\u0018\u0000\u036b\u036a\u0001\u0000\u0000"+
+ "\u0000\u036c\u036d\u0001\u0000\u0000\u0000\u036d\u036b\u0001\u0000\u0000"+
+ "\u0000\u036d\u036e\u0001\u0000\u0000\u0000\u036e\u0370\u0001\u0000\u0000"+
+ "\u0000\u036f\u035e\u0001\u0000\u0000\u0000\u036f\u0369\u0001\u0000\u0000"+
+ "\u0000\u0370\u00a2\u0001\u0000\u0000\u0000\u0371\u0372\u0005[\u0000\u0000"+
+ "\u0372\u0373\u0001\u0000\u0000\u0000\u0373\u0374\u0006J\u0000\u0000\u0374"+
+ "\u0375\u0006J\u0000\u0000\u0375\u00a4\u0001\u0000\u0000\u0000\u0376\u0377"+
+ "\u0005]\u0000\u0000\u0377\u0378\u0001\u0000\u0000\u0000\u0378\u0379\u0006"+
+ "K\u000b\u0000\u0379\u037a\u0006K\u000b\u0000\u037a\u00a6\u0001\u0000\u0000"+
+ "\u0000\u037b\u037f\u0003A\u0019\u0000\u037c\u037e\u0003Q!\u0000\u037d"+
+ "\u037c\u0001\u0000\u0000\u0000\u037e\u0381\u0001\u0000\u0000\u0000\u037f"+
+ "\u037d\u0001\u0000\u0000\u0000\u037f\u0380\u0001\u0000\u0000\u0000\u0380"+
+ "\u038c\u0001\u0000\u0000\u0000\u0381\u037f\u0001\u0000\u0000\u0000\u0382"+
+ "\u0385\u0003O \u0000\u0383\u0385\u0003I\u001d\u0000\u0384\u0382\u0001"+
+ "\u0000\u0000\u0000\u0384\u0383\u0001\u0000\u0000\u0000\u0385\u0387\u0001"+
+ "\u0000\u0000\u0000\u0386\u0388\u0003Q!\u0000\u0387\u0386\u0001\u0000\u0000"+
+ "\u0000\u0388\u0389\u0001\u0000\u0000\u0000\u0389\u0387\u0001\u0000\u0000"+
+ "\u0000\u0389\u038a\u0001\u0000\u0000\u0000\u038a\u038c\u0001\u0000\u0000"+
+ "\u0000\u038b\u037b\u0001\u0000\u0000\u0000\u038b\u0384\u0001\u0000\u0000"+
+ "\u0000\u038c\u00a8\u0001\u0000\u0000\u0000\u038d\u038f\u0003K\u001e\u0000"+
+ "\u038e\u0390\u0003M\u001f\u0000\u038f\u038e\u0001\u0000\u0000\u0000\u0390"+
+ "\u0391\u0001\u0000\u0000\u0000\u0391\u038f\u0001\u0000\u0000\u0000\u0391"+
+ "\u0392\u0001\u0000\u0000\u0000\u0392\u0393\u0001\u0000\u0000\u0000\u0393"+
+ "\u0394\u0003K\u001e\u0000\u0394\u00aa\u0001\u0000\u0000\u0000\u0395\u0396"+
+ "\u0003\u00a9M\u0000\u0396\u00ac\u0001\u0000\u0000\u0000\u0397\u0398\u0003"+
+ "7\u0014\u0000\u0398\u0399\u0001\u0000\u0000\u0000\u0399\u039a\u0006O\n"+
+ "\u0000\u039a\u00ae\u0001\u0000\u0000\u0000\u039b\u039c\u00039\u0015\u0000"+
+ "\u039c\u039d\u0001\u0000\u0000\u0000\u039d\u039e\u0006P\n\u0000\u039e"+
+ "\u00b0\u0001\u0000\u0000\u0000\u039f\u03a0\u0003;\u0016\u0000\u03a0\u03a1"+
+ "\u0001\u0000\u0000\u0000\u03a1\u03a2\u0006Q\n\u0000\u03a2\u00b2\u0001"+
+ "\u0000\u0000\u0000\u03a3\u03a4\u0003\u00a3J\u0000\u03a4\u03a5\u0001\u0000"+
+ "\u0000\u0000\u03a5\u03a6\u0006R\f\u0000\u03a6\u03a7\u0006R\r\u0000\u03a7"+
+ "\u00b4\u0001\u0000\u0000\u0000\u03a8\u03a9\u0003=\u0017\u0000\u03a9\u03aa"+
+ "\u0001\u0000\u0000\u0000\u03aa\u03ab\u0006S\u000e\u0000\u03ab\u03ac\u0006"+
+ "S\u000b\u0000\u03ac\u00b6\u0001\u0000\u0000\u0000\u03ad\u03ae\u0003;\u0016"+
+ "\u0000\u03ae\u03af\u0001\u0000\u0000\u0000\u03af\u03b0\u0006T\n\u0000"+
+ "\u03b0\u00b8\u0001\u0000\u0000\u0000\u03b1\u03b2\u00037\u0014\u0000\u03b2"+
+ "\u03b3\u0001\u0000\u0000\u0000\u03b3\u03b4\u0006U\n\u0000\u03b4\u00ba"+
+ "\u0001\u0000\u0000\u0000\u03b5\u03b6\u00039\u0015\u0000\u03b6\u03b7\u0001"+
+ "\u0000\u0000\u0000\u03b7\u03b8\u0006V\n\u0000\u03b8\u00bc\u0001\u0000"+
+ "\u0000\u0000\u03b9\u03ba\u0003=\u0017\u0000\u03ba\u03bb\u0001\u0000\u0000"+
+ "\u0000\u03bb\u03bc\u0006W\u000e\u0000\u03bc\u03bd\u0006W\u000b\u0000\u03bd"+
+ "\u00be\u0001\u0000\u0000\u0000\u03be\u03bf\u0003\u00a3J\u0000\u03bf\u03c0"+
+ "\u0001\u0000\u0000\u0000\u03c0\u03c1\u0006X\f\u0000\u03c1\u00c0\u0001"+
+ "\u0000\u0000\u0000\u03c2\u03c3\u0003\u00a5K\u0000\u03c3\u03c4\u0001\u0000"+
+ "\u0000\u0000\u03c4\u03c5\u0006Y\u000f\u0000\u03c5\u00c2\u0001\u0000\u0000"+
+ "\u0000\u03c6\u03c7\u0003\u014f\u00a0\u0000\u03c7\u03c8\u0001\u0000\u0000"+
+ "\u0000\u03c8\u03c9\u0006Z\u0010\u0000\u03c9\u00c4\u0001\u0000\u0000\u0000"+
+ "\u03ca\u03cb\u0003c*\u0000\u03cb\u03cc\u0001\u0000\u0000\u0000\u03cc\u03cd"+
+ "\u0006[\u0011\u0000\u03cd\u00c6\u0001\u0000\u0000\u0000\u03ce\u03cf\u0003"+
+ "_(\u0000\u03cf\u03d0\u0001\u0000\u0000\u0000\u03d0\u03d1\u0006\\\u0012"+
+ "\u0000\u03d1\u00c8\u0001\u0000\u0000\u0000\u03d2\u03d3\u0007\u0010\u0000"+
+ "\u0000\u03d3\u03d4\u0007\u0003\u0000\u0000\u03d4\u03d5\u0007\u0005\u0000"+
+ "\u0000\u03d5\u03d6\u0007\f\u0000\u0000\u03d6\u03d7\u0007\u0000\u0000\u0000"+
+ "\u03d7\u03d8\u0007\f\u0000\u0000\u03d8\u03d9\u0007\u0005\u0000\u0000\u03d9"+
+ "\u03da\u0007\f\u0000\u0000\u03da\u00ca\u0001\u0000\u0000\u0000\u03db\u03df"+
+ "\b \u0000\u0000\u03dc\u03dd\u0005/\u0000\u0000\u03dd\u03df\b!\u0000\u0000"+
+ "\u03de\u03db\u0001\u0000\u0000\u0000\u03de\u03dc\u0001\u0000\u0000\u0000"+
+ "\u03df\u00cc\u0001\u0000\u0000\u0000\u03e0\u03e2\u0003\u00cb^\u0000\u03e1"+
+ "\u03e0\u0001\u0000\u0000\u0000\u03e2\u03e3\u0001\u0000\u0000\u0000\u03e3"+
+ "\u03e1\u0001\u0000\u0000\u0000\u03e3\u03e4\u0001\u0000\u0000\u0000\u03e4"+
+ "\u00ce\u0001\u0000\u0000\u0000\u03e5\u03e6\u0003\u00cd_\u0000\u03e6\u03e7"+
+ "\u0001\u0000\u0000\u0000\u03e7\u03e8\u0006`\u0013\u0000\u03e8\u00d0\u0001"+
+ "\u0000\u0000\u0000\u03e9\u03ea\u0003S\"\u0000\u03ea\u03eb\u0001\u0000"+
+ "\u0000\u0000\u03eb\u03ec\u0006a\u0014\u0000\u03ec\u00d2\u0001\u0000\u0000"+
+ "\u0000\u03ed\u03ee\u00037\u0014\u0000\u03ee\u03ef\u0001\u0000\u0000\u0000"+
+ "\u03ef\u03f0\u0006b\n\u0000\u03f0\u00d4\u0001\u0000\u0000\u0000\u03f1"+
+ "\u03f2\u00039\u0015\u0000\u03f2\u03f3\u0001\u0000\u0000\u0000\u03f3\u03f4"+
+ "\u0006c\n\u0000\u03f4\u00d6\u0001\u0000\u0000\u0000\u03f5\u03f6\u0003"+
+ ";\u0016\u0000\u03f6\u03f7\u0001\u0000\u0000\u0000\u03f7\u03f8\u0006d\n"+
+ "\u0000\u03f8\u00d8\u0001\u0000\u0000\u0000\u03f9\u03fa\u0003=\u0017\u0000"+
+ "\u03fa\u03fb\u0001\u0000\u0000\u0000\u03fb\u03fc\u0006e\u000e\u0000\u03fc"+
+ "\u03fd\u0006e\u000b\u0000\u03fd\u00da\u0001\u0000\u0000\u0000\u03fe\u03ff"+
+ "\u0003g,\u0000\u03ff\u0400\u0001\u0000\u0000\u0000\u0400\u0401\u0006f"+
+ "\u0015\u0000\u0401\u00dc\u0001\u0000\u0000\u0000\u0402\u0403\u0003c*\u0000"+
+ "\u0403\u0404\u0001\u0000\u0000\u0000\u0404\u0405\u0006g\u0011\u0000\u0405"+
+ "\u00de\u0001\u0000\u0000\u0000\u0406\u0407\u0003\u007f8\u0000\u0407\u0408"+
+ "\u0001\u0000\u0000\u0000\u0408\u0409\u0006h\u0016\u0000\u0409\u00e0\u0001"+
+ "\u0000\u0000\u0000\u040a\u040b\u0003\u00a1I\u0000\u040b\u040c\u0001\u0000"+
+ "\u0000\u0000\u040c\u040d\u0006i\u0017\u0000\u040d\u00e2\u0001\u0000\u0000"+
+ "\u0000\u040e\u0413\u0003A\u0019\u0000\u040f\u0413\u0003?\u0018\u0000\u0410"+
+ "\u0413\u0003O \u0000\u0411\u0413\u0003\u0099E\u0000\u0412\u040e\u0001"+
+ "\u0000\u0000\u0000\u0412\u040f\u0001\u0000\u0000\u0000\u0412\u0410\u0001"+
+ "\u0000\u0000\u0000\u0412\u0411\u0001\u0000\u0000\u0000\u0413\u00e4\u0001"+
+ "\u0000\u0000\u0000\u0414\u0417\u0003A\u0019\u0000\u0415\u0417\u0003\u0099"+
+ "E\u0000\u0416\u0414\u0001\u0000\u0000\u0000\u0416\u0415\u0001\u0000\u0000"+
+ "\u0000\u0417\u041b\u0001\u0000\u0000\u0000\u0418\u041a\u0003\u00e3j\u0000"+
+ "\u0419\u0418\u0001\u0000\u0000\u0000\u041a\u041d\u0001\u0000\u0000\u0000"+
+ "\u041b\u0419\u0001\u0000\u0000\u0000\u041b\u041c\u0001\u0000\u0000\u0000"+
+ "\u041c\u0428\u0001\u0000\u0000\u0000\u041d\u041b\u0001\u0000\u0000\u0000"+
+ "\u041e\u0421\u0003O \u0000\u041f\u0421\u0003I\u001d\u0000\u0420\u041e"+
+ "\u0001\u0000\u0000\u0000\u0420\u041f\u0001\u0000\u0000\u0000\u0421\u0423"+
+ "\u0001\u0000\u0000\u0000\u0422\u0424\u0003\u00e3j\u0000\u0423\u0422\u0001"+
+ "\u0000\u0000\u0000\u0424\u0425\u0001\u0000\u0000\u0000\u0425\u0423\u0001"+
+ "\u0000\u0000\u0000\u0425\u0426\u0001\u0000\u0000\u0000\u0426\u0428\u0001"+
+ "\u0000\u0000\u0000\u0427\u0416\u0001\u0000\u0000\u0000\u0427\u0420\u0001"+
+ "\u0000\u0000\u0000\u0428\u00e6\u0001\u0000\u0000\u0000\u0429\u042c\u0003"+
+ "\u00e5k\u0000\u042a\u042c\u0003\u00a9M\u0000\u042b\u0429\u0001\u0000\u0000"+
+ "\u0000\u042b\u042a\u0001\u0000\u0000\u0000\u042c\u042d\u0001\u0000\u0000"+
+ "\u0000\u042d\u042b\u0001\u0000\u0000\u0000\u042d\u042e\u0001\u0000\u0000"+
+ "\u0000\u042e\u00e8\u0001\u0000\u0000\u0000\u042f\u0430\u00037\u0014\u0000"+
+ "\u0430\u0431\u0001\u0000\u0000\u0000\u0431\u0432\u0006m\n\u0000\u0432"+
+ "\u00ea\u0001\u0000\u0000\u0000\u0433\u0434\u00039\u0015\u0000\u0434\u0435"+
+ "\u0001\u0000\u0000\u0000\u0435\u0436\u0006n\n\u0000\u0436\u00ec\u0001"+
+ "\u0000\u0000\u0000\u0437\u0438\u0003;\u0016\u0000\u0438\u0439\u0001\u0000"+
+ "\u0000\u0000\u0439\u043a\u0006o\n\u0000\u043a\u00ee\u0001\u0000\u0000"+
+ "\u0000\u043b\u043c\u0003=\u0017\u0000\u043c\u043d\u0001\u0000\u0000\u0000"+
+ "\u043d\u043e\u0006p\u000e\u0000\u043e\u043f\u0006p\u000b\u0000\u043f\u00f0"+
+ "\u0001\u0000\u0000\u0000\u0440\u0441\u0003_(\u0000\u0441\u0442\u0001\u0000"+
+ "\u0000\u0000\u0442\u0443\u0006q\u0012\u0000\u0443\u00f2\u0001\u0000\u0000"+
+ "\u0000\u0444\u0445\u0003c*\u0000\u0445\u0446\u0001\u0000\u0000\u0000\u0446"+
+ "\u0447\u0006r\u0011\u0000\u0447\u00f4\u0001\u0000\u0000\u0000\u0448\u0449"+
+ "\u0003g,\u0000\u0449\u044a\u0001\u0000\u0000\u0000\u044a\u044b\u0006s"+
+ "\u0015\u0000\u044b\u00f6\u0001\u0000\u0000\u0000\u044c\u044d\u0003\u007f"+
+ "8\u0000\u044d\u044e\u0001\u0000\u0000\u0000\u044e\u044f\u0006t\u0016\u0000"+
+ "\u044f\u00f8\u0001\u0000\u0000\u0000\u0450\u0451\u0003\u00a1I\u0000\u0451"+
+ "\u0452\u0001\u0000\u0000\u0000\u0452\u0453\u0006u\u0017\u0000\u0453\u00fa"+
+ "\u0001\u0000\u0000\u0000\u0454\u0455\u0007\f\u0000\u0000\u0455\u0456\u0007"+
+ "\u0002\u0000\u0000\u0456\u00fc\u0001\u0000\u0000\u0000\u0457\u0458\u0003"+
+ "\u00e7l\u0000\u0458\u0459\u0001\u0000\u0000\u0000\u0459\u045a\u0006w\u0018"+
+ "\u0000\u045a\u00fe\u0001\u0000\u0000\u0000\u045b\u045c\u00037\u0014\u0000"+
+ "\u045c\u045d\u0001\u0000\u0000\u0000\u045d\u045e\u0006x\n\u0000\u045e"+
+ "\u0100\u0001\u0000\u0000\u0000\u045f\u0460\u00039\u0015\u0000\u0460\u0461"+
+ "\u0001\u0000\u0000\u0000\u0461\u0462\u0006y\n\u0000\u0462\u0102\u0001"+
+ "\u0000\u0000\u0000\u0463\u0464\u0003;\u0016\u0000\u0464\u0465\u0001\u0000"+
+ "\u0000\u0000\u0465\u0466\u0006z\n\u0000\u0466\u0104\u0001\u0000\u0000"+
+ "\u0000\u0467\u0468\u0003=\u0017\u0000\u0468\u0469\u0001\u0000\u0000\u0000"+
+ "\u0469\u046a\u0006{\u000e\u0000\u046a\u046b\u0006{\u000b\u0000\u046b\u0106"+
+ "\u0001\u0000\u0000\u0000\u046c\u046d\u0003\u00a3J\u0000\u046d\u046e\u0001"+
+ "\u0000\u0000\u0000\u046e\u046f\u0006|\f\u0000\u046f\u0470\u0006|\u0019"+
+ "\u0000\u0470\u0108\u0001\u0000\u0000\u0000\u0471\u0472\u0007\u0007\u0000"+
+ "\u0000\u0472\u0473\u0007\t\u0000\u0000\u0473\u0474\u0001\u0000\u0000\u0000"+
+ "\u0474\u0475\u0006}\u001a\u0000\u0475\u010a\u0001\u0000\u0000\u0000\u0476"+
+ "\u0477\u0007\u0013\u0000\u0000\u0477\u0478\u0007\u0001\u0000\u0000\u0478"+
+ "\u0479\u0007\u0005\u0000\u0000\u0479\u047a\u0007\n\u0000\u0000\u047a\u047b"+
+ "\u0001\u0000\u0000\u0000\u047b\u047c\u0006~\u001a\u0000\u047c\u010c\u0001"+
+ "\u0000\u0000\u0000\u047d\u047e\b\"\u0000\u0000\u047e\u010e\u0001\u0000"+
+ "\u0000\u0000\u047f\u0481\u0003\u010d\u007f\u0000\u0480\u047f\u0001\u0000"+
+ "\u0000\u0000\u0481\u0482\u0001\u0000\u0000\u0000\u0482\u0480\u0001\u0000"+
+ "\u0000\u0000\u0482\u0483\u0001\u0000\u0000\u0000\u0483\u0484\u0001\u0000"+
+ "\u0000\u0000\u0484\u0485\u0003\u014f\u00a0\u0000\u0485\u0487\u0001\u0000"+
+ "\u0000\u0000\u0486\u0480\u0001\u0000\u0000\u0000\u0486\u0487\u0001\u0000"+
+ "\u0000\u0000\u0487\u0489\u0001\u0000\u0000\u0000\u0488\u048a\u0003\u010d"+
+ "\u007f\u0000\u0489\u0488\u0001\u0000\u0000\u0000\u048a\u048b\u0001\u0000"+
+ "\u0000\u0000\u048b\u0489\u0001\u0000\u0000\u0000\u048b\u048c\u0001\u0000"+
+ "\u0000\u0000\u048c\u0110\u0001\u0000\u0000\u0000\u048d\u048e\u0003\u010f"+
+ "\u0080\u0000\u048e\u048f\u0001\u0000\u0000\u0000\u048f\u0490\u0006\u0081"+
+ "\u001b\u0000\u0490\u0112\u0001\u0000\u0000\u0000\u0491\u0492\u00037\u0014"+
+ "\u0000\u0492\u0493\u0001\u0000\u0000\u0000\u0493\u0494\u0006\u0082\n\u0000"+
+ "\u0494\u0114\u0001\u0000\u0000\u0000\u0495\u0496\u00039\u0015\u0000\u0496"+
+ "\u0497\u0001\u0000\u0000\u0000\u0497\u0498\u0006\u0083\n\u0000\u0498\u0116"+
+ "\u0001\u0000\u0000\u0000\u0499\u049a\u0003;\u0016\u0000\u049a\u049b\u0001"+
+ "\u0000\u0000\u0000\u049b\u049c\u0006\u0084\n\u0000\u049c\u0118\u0001\u0000"+
+ "\u0000\u0000\u049d\u049e\u0003=\u0017\u0000\u049e\u049f\u0001\u0000\u0000"+
+ "\u0000\u049f\u04a0\u0006\u0085\u000e\u0000\u04a0\u04a1\u0006\u0085\u000b"+
+ "\u0000\u04a1\u04a2\u0006\u0085\u000b\u0000\u04a2\u011a\u0001\u0000\u0000"+
+ "\u0000\u04a3\u04a4\u0003_(\u0000\u04a4\u04a5\u0001\u0000\u0000\u0000\u04a5"+
+ "\u04a6\u0006\u0086\u0012\u0000\u04a6\u011c\u0001\u0000\u0000\u0000\u04a7"+
+ "\u04a8\u0003c*\u0000\u04a8\u04a9\u0001\u0000\u0000\u0000\u04a9\u04aa\u0006"+
+ "\u0087\u0011\u0000\u04aa\u011e\u0001\u0000\u0000\u0000\u04ab\u04ac\u0003"+
+ "g,\u0000\u04ac\u04ad\u0001\u0000\u0000\u0000\u04ad\u04ae\u0006\u0088\u0015"+
+ "\u0000\u04ae\u0120\u0001\u0000\u0000\u0000\u04af\u04b0\u0003\u010b~\u0000"+
+ "\u04b0\u04b1\u0001\u0000\u0000\u0000\u04b1\u04b2\u0006\u0089\u001c\u0000"+
+ "\u04b2\u0122\u0001\u0000\u0000\u0000\u04b3\u04b4\u0003\u00e7l\u0000\u04b4"+
+ "\u04b5\u0001\u0000\u0000\u0000\u04b5\u04b6\u0006\u008a\u0018\u0000\u04b6"+
+ "\u0124\u0001\u0000\u0000\u0000\u04b7\u04b8\u0003\u00abN\u0000\u04b8\u04b9"+
+ "\u0001\u0000\u0000\u0000\u04b9\u04ba\u0006\u008b\u001d\u0000\u04ba\u0126"+
+ "\u0001\u0000\u0000\u0000\u04bb\u04bc\u0003\u007f8\u0000\u04bc\u04bd\u0001"+
+ "\u0000\u0000\u0000\u04bd\u04be\u0006\u008c\u0016\u0000\u04be\u0128\u0001"+
+ "\u0000\u0000\u0000\u04bf\u04c0\u0003\u00a1I\u0000\u04c0\u04c1\u0001\u0000"+
+ "\u0000\u0000\u04c1\u04c2\u0006\u008d\u0017\u0000\u04c2\u012a\u0001\u0000"+
+ "\u0000\u0000\u04c3\u04c4\u00037\u0014\u0000\u04c4\u04c5\u0001\u0000\u0000"+
+ "\u0000\u04c5\u04c6\u0006\u008e\n\u0000\u04c6\u012c\u0001\u0000\u0000\u0000"+
+ "\u04c7\u04c8\u00039\u0015\u0000\u04c8\u04c9\u0001\u0000\u0000\u0000\u04c9"+
+ "\u04ca\u0006\u008f\n\u0000\u04ca\u012e\u0001\u0000\u0000\u0000\u04cb\u04cc"+
+ "\u0003;\u0016\u0000\u04cc\u04cd\u0001\u0000\u0000\u0000\u04cd\u04ce\u0006"+
+ "\u0090\n\u0000\u04ce\u0130\u0001\u0000\u0000\u0000\u04cf\u04d0\u0003="+
+ "\u0017\u0000\u04d0\u04d1\u0001\u0000\u0000\u0000\u04d1\u04d2\u0006\u0091"+
+ "\u000e\u0000\u04d2\u04d3\u0006\u0091\u000b\u0000\u04d3\u0132\u0001\u0000"+
+ "\u0000\u0000\u04d4\u04d5\u0003g,\u0000\u04d5\u04d6\u0001\u0000\u0000\u0000"+
+ "\u04d6\u04d7\u0006\u0092\u0015\u0000\u04d7\u0134\u0001\u0000\u0000\u0000"+
+ "\u04d8\u04d9\u0003\u007f8\u0000\u04d9\u04da\u0001\u0000\u0000\u0000\u04da"+
+ "\u04db\u0006\u0093\u0016\u0000\u04db\u0136\u0001\u0000\u0000\u0000\u04dc"+
+ "\u04dd\u0003\u00a1I\u0000\u04dd\u04de\u0001\u0000\u0000\u0000\u04de\u04df"+
+ "\u0006\u0094\u0017\u0000\u04df\u0138\u0001\u0000\u0000\u0000\u04e0\u04e1"+
+ "\u0003\u00abN\u0000\u04e1\u04e2\u0001\u0000\u0000\u0000\u04e2\u04e3\u0006"+
+ "\u0095\u001d\u0000\u04e3\u013a\u0001\u0000\u0000\u0000\u04e4\u04e5\u0003"+
+ "\u00a7L\u0000\u04e5\u04e6\u0001\u0000\u0000\u0000\u04e6\u04e7\u0006\u0096"+
+ "\u001e\u0000\u04e7\u013c\u0001\u0000\u0000\u0000\u04e8\u04e9\u00037\u0014"+
+ "\u0000\u04e9\u04ea\u0001\u0000\u0000\u0000\u04ea\u04eb\u0006\u0097\n\u0000"+
+ "\u04eb\u013e\u0001\u0000\u0000\u0000\u04ec\u04ed\u00039\u0015\u0000\u04ed"+
+ "\u04ee\u0001\u0000\u0000\u0000\u04ee\u04ef\u0006\u0098\n\u0000\u04ef\u0140"+
+ "\u0001\u0000\u0000\u0000\u04f0\u04f1\u0003;\u0016\u0000\u04f1\u04f2\u0001"+
+ "\u0000\u0000\u0000\u04f2\u04f3\u0006\u0099\n\u0000\u04f3\u0142\u0001\u0000"+
+ "\u0000\u0000\u04f4\u04f5\u0003=\u0017\u0000\u04f5\u04f6\u0001\u0000\u0000"+
+ "\u0000\u04f6\u04f7\u0006\u009a\u000e\u0000\u04f7\u04f8\u0006\u009a\u000b"+
+ "\u0000\u04f8\u0144\u0001\u0000\u0000\u0000\u04f9\u04fa\u0007\u0001\u0000"+
+ "\u0000\u04fa\u04fb\u0007\t\u0000\u0000\u04fb\u04fc\u0007\u000f\u0000\u0000"+
+ "\u04fc\u04fd\u0007\u0007\u0000\u0000\u04fd\u0146\u0001\u0000\u0000\u0000"+
+ "\u04fe\u04ff\u00037\u0014\u0000\u04ff\u0500\u0001\u0000\u0000\u0000\u0500"+
+ "\u0501\u0006\u009c\n\u0000\u0501\u0148\u0001\u0000\u0000\u0000\u0502\u0503"+
+ "\u00039\u0015\u0000\u0503\u0504\u0001\u0000\u0000\u0000\u0504\u0505\u0006"+
+ "\u009d\n\u0000\u0505\u014a\u0001\u0000\u0000\u0000\u0506\u0507\u0003;"+
+ "\u0016\u0000\u0507\u0508\u0001\u0000\u0000\u0000\u0508\u0509\u0006\u009e"+
+ "\n\u0000\u0509\u014c\u0001\u0000\u0000\u0000\u050a\u050b\u0003\u00a5K"+
+ "\u0000\u050b\u050c\u0001\u0000\u0000\u0000\u050c\u050d\u0006\u009f\u000f"+
+ "\u0000\u050d\u050e\u0006\u009f\u000b\u0000\u050e\u014e\u0001\u0000\u0000"+
+ "\u0000\u050f\u0510\u0005:\u0000\u0000\u0510\u0150\u0001\u0000\u0000\u0000"+
+ "\u0511\u0517\u0003I\u001d\u0000\u0512\u0517\u0003?\u0018\u0000\u0513\u0517"+
+ "\u0003g,\u0000\u0514\u0517\u0003A\u0019\u0000\u0515\u0517\u0003O \u0000"+
+ "\u0516\u0511\u0001\u0000\u0000\u0000\u0516\u0512\u0001\u0000\u0000\u0000"+
+ "\u0516\u0513\u0001\u0000\u0000\u0000\u0516\u0514\u0001\u0000\u0000\u0000"+
+ "\u0516\u0515\u0001\u0000\u0000\u0000\u0517\u0518\u0001\u0000\u0000\u0000"+
+ "\u0518\u0516\u0001\u0000\u0000\u0000\u0518\u0519\u0001\u0000\u0000\u0000"+
+ "\u0519\u0152\u0001\u0000\u0000\u0000\u051a\u051b\u00037\u0014\u0000\u051b"+
+ "\u051c\u0001\u0000\u0000\u0000\u051c\u051d\u0006\u00a2\n\u0000\u051d\u0154"+
+ "\u0001\u0000\u0000\u0000\u051e\u051f\u00039\u0015\u0000\u051f\u0520\u0001"+
+ "\u0000\u0000\u0000\u0520\u0521\u0006\u00a3\n\u0000\u0521\u0156\u0001\u0000"+
+ "\u0000\u0000\u0522\u0523\u0003;\u0016\u0000\u0523\u0524\u0001\u0000\u0000"+
+ "\u0000\u0524\u0525\u0006\u00a4\n\u0000\u0525\u0158\u0001\u0000\u0000\u0000"+
+ "\u0526\u0527\u0003=\u0017\u0000\u0527\u0528\u0001\u0000\u0000\u0000\u0528"+
+ "\u0529\u0006\u00a5\u000e\u0000\u0529\u052a\u0006\u00a5\u000b\u0000\u052a"+
+ "\u015a\u0001\u0000\u0000\u0000\u052b\u052c\u0003\u014f\u00a0\u0000\u052c"+
+ "\u052d\u0001\u0000\u0000\u0000\u052d\u052e\u0006\u00a6\u0010\u0000\u052e"+
+ "\u015c\u0001\u0000\u0000\u0000\u052f\u0530\u0003c*\u0000\u0530\u0531\u0001"+
+ "\u0000\u0000\u0000\u0531\u0532\u0006\u00a7\u0011\u0000\u0532\u015e\u0001"+
+ "\u0000\u0000\u0000\u0533\u0534\u0003g,\u0000\u0534\u0535\u0001\u0000\u0000"+
+ "\u0000\u0535\u0536\u0006\u00a8\u0015\u0000\u0536\u0160\u0001\u0000\u0000"+
+ "\u0000\u0537\u0538\u0003\u0109}\u0000\u0538\u0539\u0001\u0000\u0000\u0000"+
+ "\u0539\u053a\u0006\u00a9\u001f\u0000\u053a\u053b\u0006\u00a9 \u0000\u053b"+
+ "\u0162\u0001\u0000\u0000\u0000\u053c\u053d\u0003\u00cd_\u0000\u053d\u053e"+
+ "\u0001\u0000\u0000\u0000\u053e\u053f\u0006\u00aa\u0013\u0000\u053f\u0164"+
+ "\u0001\u0000\u0000\u0000\u0540\u0541\u0003S\"\u0000\u0541\u0542\u0001"+
+ "\u0000\u0000\u0000\u0542\u0543\u0006\u00ab\u0014\u0000\u0543\u0166\u0001"+
+ "\u0000\u0000\u0000\u0544\u0545\u00037\u0014\u0000\u0545\u0546\u0001\u0000"+
+ "\u0000\u0000\u0546\u0547\u0006\u00ac\n\u0000\u0547\u0168\u0001\u0000\u0000"+
+ "\u0000\u0548\u0549\u00039\u0015\u0000\u0549\u054a\u0001\u0000\u0000\u0000"+
+ "\u054a\u054b\u0006\u00ad\n\u0000\u054b\u016a\u0001\u0000\u0000\u0000\u054c"+
+ "\u054d\u0003;\u0016\u0000\u054d\u054e\u0001\u0000\u0000\u0000\u054e\u054f"+
+ "\u0006\u00ae\n\u0000\u054f\u016c\u0001\u0000\u0000\u0000\u0550\u0551\u0003"+
+ "=\u0017\u0000\u0551\u0552\u0001\u0000\u0000\u0000\u0552\u0553\u0006\u00af"+
+ "\u000e\u0000\u0553\u0554\u0006\u00af\u000b\u0000\u0554\u0555\u0006\u00af"+
+ "\u000b\u0000\u0555\u016e\u0001\u0000\u0000\u0000\u0556\u0557\u0003c*\u0000"+
+ "\u0557\u0558\u0001\u0000\u0000\u0000\u0558\u0559\u0006\u00b0\u0011\u0000"+
+ "\u0559\u0170\u0001\u0000\u0000\u0000\u055a\u055b\u0003g,\u0000\u055b\u055c"+
+ "\u0001\u0000\u0000\u0000\u055c\u055d\u0006\u00b1\u0015\u0000\u055d\u0172"+
+ "\u0001\u0000\u0000\u0000\u055e\u055f\u0003\u00e7l\u0000\u055f\u0560\u0001"+
+ "\u0000\u0000\u0000\u0560\u0561\u0006\u00b2\u0018\u0000\u0561\u0174\u0001"+
+ "\u0000\u0000\u0000\u0562\u0563\u00037\u0014\u0000\u0563\u0564\u0001\u0000"+
+ "\u0000\u0000\u0564\u0565\u0006\u00b3\n\u0000\u0565\u0176\u0001\u0000\u0000"+
+ "\u0000\u0566\u0567\u00039\u0015\u0000\u0567\u0568\u0001\u0000\u0000\u0000"+
+ "\u0568\u0569\u0006\u00b4\n\u0000\u0569\u0178\u0001\u0000\u0000\u0000\u056a"+
+ "\u056b\u0003;\u0016\u0000\u056b\u056c\u0001\u0000\u0000\u0000\u056c\u056d"+
+ "\u0006\u00b5\n\u0000\u056d\u017a\u0001\u0000\u0000\u0000\u056e\u056f\u0003"+
+ "=\u0017\u0000\u056f\u0570\u0001\u0000\u0000\u0000\u0570\u0571\u0006\u00b6"+
+ "\u000e\u0000\u0571\u0572\u0006\u00b6\u000b\u0000\u0572\u017c\u0001\u0000"+
+ "\u0000\u0000\u0573\u0574\u0003\u00cd_\u0000\u0574\u0575\u0001\u0000\u0000"+
+ "\u0000\u0575\u0576\u0006\u00b7\u0013\u0000\u0576\u0577\u0006\u00b7\u000b"+
+ "\u0000\u0577\u0578\u0006\u00b7!\u0000\u0578\u017e\u0001\u0000\u0000\u0000"+
+ "\u0579\u057a\u0003S\"\u0000\u057a\u057b\u0001\u0000\u0000\u0000\u057b"+
+ "\u057c\u0006\u00b8\u0014\u0000\u057c\u057d\u0006\u00b8\u000b\u0000\u057d"+
+ "\u057e\u0006\u00b8!\u0000\u057e\u0180\u0001\u0000\u0000\u0000\u057f\u0580"+
+ "\u00037\u0014\u0000\u0580\u0581\u0001\u0000\u0000\u0000\u0581\u0582\u0006"+
+ "\u00b9\n\u0000\u0582\u0182\u0001\u0000\u0000\u0000\u0583\u0584\u00039"+
+ "\u0015\u0000\u0584\u0585\u0001\u0000\u0000\u0000\u0585\u0586\u0006\u00ba"+
+ "\n\u0000\u0586\u0184\u0001\u0000\u0000\u0000\u0587\u0588\u0003;\u0016"+
+ "\u0000\u0588\u0589\u0001\u0000\u0000\u0000\u0589\u058a\u0006\u00bb\n\u0000"+
+ "\u058a\u0186\u0001\u0000\u0000\u0000\u058b\u058c\u0003\u014f\u00a0\u0000"+
+ "\u058c\u058d\u0001\u0000\u0000\u0000\u058d\u058e\u0006\u00bc\u0010\u0000"+
+ "\u058e\u058f\u0006\u00bc\u000b\u0000\u058f\u0590\u0006\u00bc\t\u0000\u0590"+
+ "\u0188\u0001\u0000\u0000\u0000\u0591\u0592\u0003c*\u0000\u0592\u0593\u0001"+
+ "\u0000\u0000\u0000\u0593\u0594\u0006\u00bd\u0011\u0000\u0594\u0595\u0006"+
+ "\u00bd\u000b\u0000\u0595\u0596\u0006\u00bd\t\u0000\u0596\u018a\u0001\u0000"+
+ "\u0000\u0000\u0597\u0598\u00037\u0014\u0000\u0598\u0599\u0001\u0000\u0000"+
+ "\u0000\u0599\u059a\u0006\u00be\n\u0000\u059a\u018c\u0001\u0000\u0000\u0000"+
+ "\u059b\u059c\u00039\u0015\u0000\u059c\u059d\u0001\u0000\u0000\u0000\u059d"+
+ "\u059e\u0006\u00bf\n\u0000\u059e\u018e\u0001\u0000\u0000\u0000\u059f\u05a0"+
+ "\u0003;\u0016\u0000\u05a0\u05a1\u0001\u0000\u0000\u0000\u05a1\u05a2\u0006"+
+ "\u00c0\n\u0000\u05a2\u0190\u0001\u0000\u0000\u0000\u05a3\u05a4\u0003\u00ab"+
+ "N\u0000\u05a4\u05a5\u0001\u0000\u0000\u0000\u05a5\u05a6\u0006\u00c1\u000b"+
+ "\u0000\u05a6\u05a7\u0006\u00c1\u0000\u0000\u05a7\u05a8\u0006\u00c1\u001d"+
+ "\u0000\u05a8\u0192\u0001\u0000\u0000\u0000\u05a9\u05aa\u0003\u00a7L\u0000"+
+ "\u05aa\u05ab\u0001\u0000\u0000\u0000\u05ab\u05ac\u0006\u00c2\u000b\u0000"+
+ "\u05ac\u05ad\u0006\u00c2\u0000\u0000\u05ad\u05ae\u0006\u00c2\u001e\u0000"+
+ "\u05ae\u0194\u0001\u0000\u0000\u0000\u05af\u05b0\u0003Y%\u0000\u05b0\u05b1"+
+ "\u0001\u0000\u0000\u0000\u05b1\u05b2\u0006\u00c3\u000b\u0000\u05b2\u05b3"+
+ "\u0006\u00c3\u0000\u0000\u05b3\u05b4\u0006\u00c3\"\u0000\u05b4\u0196\u0001"+
+ "\u0000\u0000\u0000\u05b5\u05b6\u0003=\u0017\u0000\u05b6\u05b7\u0001\u0000"+
+ "\u0000\u0000\u05b7\u05b8\u0006\u00c4\u000e\u0000\u05b8\u05b9\u0006\u00c4"+
+ "\u000b\u0000\u05b9\u0198\u0001\u0000\u0000\u0000A\u0000\u0001\u0002\u0003"+
+ "\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u0241\u024b\u024f\u0252"+
+ "\u025b\u025d\u0268\u027b\u0280\u0289\u0290\u0295\u0297\u02a2\u02aa\u02ad"+
+ "\u02af\u02b4\u02b9\u02bf\u02c6\u02cb\u02d1\u02d4\u02dc\u02e0\u0361\u0366"+
+ "\u036d\u036f\u037f\u0384\u0389\u038b\u0391\u03de\u03e3\u0412\u0416\u041b"+
+ "\u0420\u0425\u0427\u042b\u042d\u0482\u0486\u048b\u0516\u0518#\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\u000b\u0000"+
+ "\u0005\r\u0000\u0000\u0001\u0000\u0004\u0000\u0000\u0007A\u0000\u0005"+
+ "\u0000\u0000\u0007\u0018\u0000\u0007B\u0000\u0007h\u0000\u0007!\u0000"+
+ "\u0007\u001f\u0000\u0007L\u0000\u0007\u0019\u0000\u0007#\u0000\u0007/"+
+ "\u0000\u0007@\u0000\u0007P\u0000\u0005\n\u0000\u0005\u0007\u0000\u0007"+
+ "Z\u0000\u0007Y\u0000\u0007D\u0000\u0007C\u0000\u0007X\u0000\u0005\f\u0000"+
+ "\u0005\u000e\u0000\u0007\u001c\u0000";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
index eb3c70385d628..5fdf80f24d9b0 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.interp
@@ -23,7 +23,6 @@ null
null
null
null
-null
'|'
null
null
@@ -65,6 +64,7 @@ null
'%'
null
null
+null
']'
null
null
@@ -141,7 +141,6 @@ STATS
WHERE
DEV_INLINESTATS
DEV_LOOKUP
-DEV_MATCH
DEV_METRICS
UNKNOWN_CMD
LINE_COMMENT
@@ -186,6 +185,7 @@ MINUS
ASTERISK
SLASH
PERCENT
+DEV_MATCH
NAMED_OR_POSITIONAL_PARAM
OPENING_BRACKET
CLOSING_BRACKET
@@ -257,6 +257,7 @@ valueExpression
operatorExpression
primaryExpression
functionExpression
+functionName
dataType
rowCommand
fields
@@ -307,4 +308,4 @@ inlinestatsCommand
atn:
-[4, 1, 120, 580, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 128, 8, 1, 10, 1, 12, 1, 131, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 139, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 157, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 169, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 176, 8, 5, 10, 5, 12, 5, 179, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 186, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 192, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 200, 8, 5, 10, 5, 12, 5, 203, 9, 5, 1, 6, 1, 6, 3, 6, 207, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 214, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 219, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 230, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 236, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 244, 8, 9, 10, 9, 12, 9, 247, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 257, 8, 10, 1, 10, 1, 10, 1, 10, 5, 10, 262, 8, 10, 10, 10, 12, 10, 265, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 273, 8, 11, 10, 11, 12, 11, 276, 9, 11, 3, 11, 278, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 5, 14, 290, 8, 14, 10, 14, 12, 14, 293, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 300, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 306, 8, 16, 10, 16, 12, 16, 309, 9, 16, 1, 16, 3, 16, 312, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 319, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 327, 8, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 333, 8, 21, 10, 21, 12, 21, 336, 9, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 346, 8, 23, 10, 23, 12, 23, 349, 9, 23, 1, 23, 3, 23, 352, 8, 23, 1, 23, 1, 23, 3, 23, 356, 8, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 3, 25, 363, 8, 25, 1, 25, 1, 25, 3, 25, 367, 8, 25, 1, 26, 1, 26, 1, 26, 5, 26, 372, 8, 26, 10, 26, 12, 26, 375, 9, 26, 1, 27, 1, 27, 1, 27, 5, 27, 380, 8, 27, 10, 27, 12, 27, 383, 9, 27, 1, 28, 1, 28, 1, 28, 5, 28, 388, 8, 28, 10, 28, 12, 28, 391, 9, 28, 1, 29, 1, 29, 1, 30, 1, 30, 3, 30, 397, 8, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 412, 8, 31, 10, 31, 12, 31, 415, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 423, 8, 31, 10, 31, 12, 31, 426, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 434, 8, 31, 10, 31, 12, 31, 437, 9, 31, 1, 31, 1, 31, 3, 31, 441, 8, 31, 1, 32, 1, 32, 3, 32, 445, 8, 32, 1, 33, 1, 33, 3, 33, 449, 8, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 458, 8, 35, 10, 35, 12, 35, 461, 9, 35, 1, 36, 1, 36, 3, 36, 465, 8, 36, 1, 36, 1, 36, 3, 36, 469, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 481, 8, 39, 10, 39, 12, 39, 484, 9, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 494, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 5, 44, 506, 8, 44, 10, 44, 12, 44, 509, 9, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 3, 47, 519, 8, 47, 1, 48, 3, 48, 522, 8, 48, 1, 48, 1, 48, 1, 49, 3, 49, 527, 8, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 549, 8, 55, 1, 55, 1, 55, 1, 55, 1, 55, 5, 55, 555, 8, 55, 10, 55, 12, 55, 558, 9, 55, 3, 55, 560, 8, 55, 1, 56, 1, 56, 1, 56, 3, 56, 565, 8, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 578, 8, 58, 1, 58, 0, 4, 2, 10, 18, 20, 59, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 0, 8, 1, 0, 59, 60, 1, 0, 61, 63, 2, 0, 26, 26, 76, 76, 1, 0, 67, 68, 2, 0, 31, 31, 35, 35, 2, 0, 38, 38, 41, 41, 2, 0, 37, 37, 51, 51, 2, 0, 52, 52, 54, 58, 606, 0, 118, 1, 0, 0, 0, 2, 121, 1, 0, 0, 0, 4, 138, 1, 0, 0, 0, 6, 156, 1, 0, 0, 0, 8, 158, 1, 0, 0, 0, 10, 191, 1, 0, 0, 0, 12, 218, 1, 0, 0, 0, 14, 220, 1, 0, 0, 0, 16, 229, 1, 0, 0, 0, 18, 235, 1, 0, 0, 0, 20, 256, 1, 0, 0, 0, 22, 266, 1, 0, 0, 0, 24, 281, 1, 0, 0, 0, 26, 283, 1, 0, 0, 0, 28, 286, 1, 0, 0, 0, 30, 299, 1, 0, 0, 0, 32, 301, 1, 0, 0, 0, 34, 318, 1, 0, 0, 0, 36, 320, 1, 0, 0, 0, 38, 322, 1, 0, 0, 0, 40, 326, 1, 0, 0, 0, 42, 328, 1, 0, 0, 0, 44, 337, 1, 0, 0, 0, 46, 341, 1, 0, 0, 0, 48, 357, 1, 0, 0, 0, 50, 360, 1, 0, 0, 0, 52, 368, 1, 0, 0, 0, 54, 376, 1, 0, 0, 0, 56, 384, 1, 0, 0, 0, 58, 392, 1, 0, 0, 0, 60, 396, 1, 0, 0, 0, 62, 440, 1, 0, 0, 0, 64, 444, 1, 0, 0, 0, 66, 448, 1, 0, 0, 0, 68, 450, 1, 0, 0, 0, 70, 453, 1, 0, 0, 0, 72, 462, 1, 0, 0, 0, 74, 470, 1, 0, 0, 0, 76, 473, 1, 0, 0, 0, 78, 476, 1, 0, 0, 0, 80, 485, 1, 0, 0, 0, 82, 489, 1, 0, 0, 0, 84, 495, 1, 0, 0, 0, 86, 499, 1, 0, 0, 0, 88, 502, 1, 0, 0, 0, 90, 510, 1, 0, 0, 0, 92, 514, 1, 0, 0, 0, 94, 518, 1, 0, 0, 0, 96, 521, 1, 0, 0, 0, 98, 526, 1, 0, 0, 0, 100, 530, 1, 0, 0, 0, 102, 532, 1, 0, 0, 0, 104, 534, 1, 0, 0, 0, 106, 537, 1, 0, 0, 0, 108, 541, 1, 0, 0, 0, 110, 544, 1, 0, 0, 0, 112, 564, 1, 0, 0, 0, 114, 568, 1, 0, 0, 0, 116, 573, 1, 0, 0, 0, 118, 119, 3, 2, 1, 0, 119, 120, 5, 0, 0, 1, 120, 1, 1, 0, 0, 0, 121, 122, 6, 1, -1, 0, 122, 123, 3, 4, 2, 0, 123, 129, 1, 0, 0, 0, 124, 125, 10, 1, 0, 0, 125, 126, 5, 25, 0, 0, 126, 128, 3, 6, 3, 0, 127, 124, 1, 0, 0, 0, 128, 131, 1, 0, 0, 0, 129, 127, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 3, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 132, 139, 3, 104, 52, 0, 133, 139, 3, 32, 16, 0, 134, 139, 3, 26, 13, 0, 135, 139, 3, 108, 54, 0, 136, 137, 4, 2, 1, 0, 137, 139, 3, 46, 23, 0, 138, 132, 1, 0, 0, 0, 138, 133, 1, 0, 0, 0, 138, 134, 1, 0, 0, 0, 138, 135, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 139, 5, 1, 0, 0, 0, 140, 157, 3, 48, 24, 0, 141, 157, 3, 8, 4, 0, 142, 157, 3, 74, 37, 0, 143, 157, 3, 68, 34, 0, 144, 157, 3, 50, 25, 0, 145, 157, 3, 70, 35, 0, 146, 157, 3, 76, 38, 0, 147, 157, 3, 78, 39, 0, 148, 157, 3, 82, 41, 0, 149, 157, 3, 84, 42, 0, 150, 157, 3, 110, 55, 0, 151, 157, 3, 86, 43, 0, 152, 153, 4, 3, 2, 0, 153, 157, 3, 116, 58, 0, 154, 155, 4, 3, 3, 0, 155, 157, 3, 114, 57, 0, 156, 140, 1, 0, 0, 0, 156, 141, 1, 0, 0, 0, 156, 142, 1, 0, 0, 0, 156, 143, 1, 0, 0, 0, 156, 144, 1, 0, 0, 0, 156, 145, 1, 0, 0, 0, 156, 146, 1, 0, 0, 0, 156, 147, 1, 0, 0, 0, 156, 148, 1, 0, 0, 0, 156, 149, 1, 0, 0, 0, 156, 150, 1, 0, 0, 0, 156, 151, 1, 0, 0, 0, 156, 152, 1, 0, 0, 0, 156, 154, 1, 0, 0, 0, 157, 7, 1, 0, 0, 0, 158, 159, 5, 16, 0, 0, 159, 160, 3, 10, 5, 0, 160, 9, 1, 0, 0, 0, 161, 162, 6, 5, -1, 0, 162, 163, 5, 44, 0, 0, 163, 192, 3, 10, 5, 8, 164, 192, 3, 16, 8, 0, 165, 192, 3, 12, 6, 0, 166, 168, 3, 16, 8, 0, 167, 169, 5, 44, 0, 0, 168, 167, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 170, 1, 0, 0, 0, 170, 171, 5, 39, 0, 0, 171, 172, 5, 43, 0, 0, 172, 177, 3, 16, 8, 0, 173, 174, 5, 34, 0, 0, 174, 176, 3, 16, 8, 0, 175, 173, 1, 0, 0, 0, 176, 179, 1, 0, 0, 0, 177, 175, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 180, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 180, 181, 5, 50, 0, 0, 181, 192, 1, 0, 0, 0, 182, 183, 3, 16, 8, 0, 183, 185, 5, 40, 0, 0, 184, 186, 5, 44, 0, 0, 185, 184, 1, 0, 0, 0, 185, 186, 1, 0, 0, 0, 186, 187, 1, 0, 0, 0, 187, 188, 5, 45, 0, 0, 188, 192, 1, 0, 0, 0, 189, 190, 4, 5, 4, 0, 190, 192, 3, 14, 7, 0, 191, 161, 1, 0, 0, 0, 191, 164, 1, 0, 0, 0, 191, 165, 1, 0, 0, 0, 191, 166, 1, 0, 0, 0, 191, 182, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 201, 1, 0, 0, 0, 193, 194, 10, 5, 0, 0, 194, 195, 5, 30, 0, 0, 195, 200, 3, 10, 5, 6, 196, 197, 10, 4, 0, 0, 197, 198, 5, 47, 0, 0, 198, 200, 3, 10, 5, 5, 199, 193, 1, 0, 0, 0, 199, 196, 1, 0, 0, 0, 200, 203, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 11, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 204, 206, 3, 16, 8, 0, 205, 207, 5, 44, 0, 0, 206, 205, 1, 0, 0, 0, 206, 207, 1, 0, 0, 0, 207, 208, 1, 0, 0, 0, 208, 209, 5, 42, 0, 0, 209, 210, 3, 100, 50, 0, 210, 219, 1, 0, 0, 0, 211, 213, 3, 16, 8, 0, 212, 214, 5, 44, 0, 0, 213, 212, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 5, 49, 0, 0, 216, 217, 3, 100, 50, 0, 217, 219, 1, 0, 0, 0, 218, 204, 1, 0, 0, 0, 218, 211, 1, 0, 0, 0, 219, 13, 1, 0, 0, 0, 220, 221, 3, 16, 8, 0, 221, 222, 5, 19, 0, 0, 222, 223, 3, 100, 50, 0, 223, 15, 1, 0, 0, 0, 224, 230, 3, 18, 9, 0, 225, 226, 3, 18, 9, 0, 226, 227, 3, 102, 51, 0, 227, 228, 3, 18, 9, 0, 228, 230, 1, 0, 0, 0, 229, 224, 1, 0, 0, 0, 229, 225, 1, 0, 0, 0, 230, 17, 1, 0, 0, 0, 231, 232, 6, 9, -1, 0, 232, 236, 3, 20, 10, 0, 233, 234, 7, 0, 0, 0, 234, 236, 3, 18, 9, 3, 235, 231, 1, 0, 0, 0, 235, 233, 1, 0, 0, 0, 236, 245, 1, 0, 0, 0, 237, 238, 10, 2, 0, 0, 238, 239, 7, 1, 0, 0, 239, 244, 3, 18, 9, 3, 240, 241, 10, 1, 0, 0, 241, 242, 7, 0, 0, 0, 242, 244, 3, 18, 9, 2, 243, 237, 1, 0, 0, 0, 243, 240, 1, 0, 0, 0, 244, 247, 1, 0, 0, 0, 245, 243, 1, 0, 0, 0, 245, 246, 1, 0, 0, 0, 246, 19, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 248, 249, 6, 10, -1, 0, 249, 257, 3, 62, 31, 0, 250, 257, 3, 52, 26, 0, 251, 257, 3, 22, 11, 0, 252, 253, 5, 43, 0, 0, 253, 254, 3, 10, 5, 0, 254, 255, 5, 50, 0, 0, 255, 257, 1, 0, 0, 0, 256, 248, 1, 0, 0, 0, 256, 250, 1, 0, 0, 0, 256, 251, 1, 0, 0, 0, 256, 252, 1, 0, 0, 0, 257, 263, 1, 0, 0, 0, 258, 259, 10, 1, 0, 0, 259, 260, 5, 33, 0, 0, 260, 262, 3, 24, 12, 0, 261, 258, 1, 0, 0, 0, 262, 265, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 21, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 266, 267, 3, 66, 33, 0, 267, 277, 5, 43, 0, 0, 268, 278, 5, 61, 0, 0, 269, 274, 3, 10, 5, 0, 270, 271, 5, 34, 0, 0, 271, 273, 3, 10, 5, 0, 272, 270, 1, 0, 0, 0, 273, 276, 1, 0, 0, 0, 274, 272, 1, 0, 0, 0, 274, 275, 1, 0, 0, 0, 275, 278, 1, 0, 0, 0, 276, 274, 1, 0, 0, 0, 277, 268, 1, 0, 0, 0, 277, 269, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 280, 5, 50, 0, 0, 280, 23, 1, 0, 0, 0, 281, 282, 3, 58, 29, 0, 282, 25, 1, 0, 0, 0, 283, 284, 5, 12, 0, 0, 284, 285, 3, 28, 14, 0, 285, 27, 1, 0, 0, 0, 286, 291, 3, 30, 15, 0, 287, 288, 5, 34, 0, 0, 288, 290, 3, 30, 15, 0, 289, 287, 1, 0, 0, 0, 290, 293, 1, 0, 0, 0, 291, 289, 1, 0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 29, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 294, 300, 3, 10, 5, 0, 295, 296, 3, 52, 26, 0, 296, 297, 5, 32, 0, 0, 297, 298, 3, 10, 5, 0, 298, 300, 1, 0, 0, 0, 299, 294, 1, 0, 0, 0, 299, 295, 1, 0, 0, 0, 300, 31, 1, 0, 0, 0, 301, 302, 5, 6, 0, 0, 302, 307, 3, 34, 17, 0, 303, 304, 5, 34, 0, 0, 304, 306, 3, 34, 17, 0, 305, 303, 1, 0, 0, 0, 306, 309, 1, 0, 0, 0, 307, 305, 1, 0, 0, 0, 307, 308, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 310, 312, 3, 40, 20, 0, 311, 310, 1, 0, 0, 0, 311, 312, 1, 0, 0, 0, 312, 33, 1, 0, 0, 0, 313, 314, 3, 36, 18, 0, 314, 315, 5, 104, 0, 0, 315, 316, 3, 38, 19, 0, 316, 319, 1, 0, 0, 0, 317, 319, 3, 38, 19, 0, 318, 313, 1, 0, 0, 0, 318, 317, 1, 0, 0, 0, 319, 35, 1, 0, 0, 0, 320, 321, 5, 76, 0, 0, 321, 37, 1, 0, 0, 0, 322, 323, 7, 2, 0, 0, 323, 39, 1, 0, 0, 0, 324, 327, 3, 42, 21, 0, 325, 327, 3, 44, 22, 0, 326, 324, 1, 0, 0, 0, 326, 325, 1, 0, 0, 0, 327, 41, 1, 0, 0, 0, 328, 329, 5, 75, 0, 0, 329, 334, 5, 76, 0, 0, 330, 331, 5, 34, 0, 0, 331, 333, 5, 76, 0, 0, 332, 330, 1, 0, 0, 0, 333, 336, 1, 0, 0, 0, 334, 332, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 43, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 337, 338, 5, 65, 0, 0, 338, 339, 3, 42, 21, 0, 339, 340, 5, 66, 0, 0, 340, 45, 1, 0, 0, 0, 341, 342, 5, 20, 0, 0, 342, 347, 3, 34, 17, 0, 343, 344, 5, 34, 0, 0, 344, 346, 3, 34, 17, 0, 345, 343, 1, 0, 0, 0, 346, 349, 1, 0, 0, 0, 347, 345, 1, 0, 0, 0, 347, 348, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 350, 352, 3, 28, 14, 0, 351, 350, 1, 0, 0, 0, 351, 352, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 354, 5, 29, 0, 0, 354, 356, 3, 28, 14, 0, 355, 353, 1, 0, 0, 0, 355, 356, 1, 0, 0, 0, 356, 47, 1, 0, 0, 0, 357, 358, 5, 4, 0, 0, 358, 359, 3, 28, 14, 0, 359, 49, 1, 0, 0, 0, 360, 362, 5, 15, 0, 0, 361, 363, 3, 28, 14, 0, 362, 361, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 366, 1, 0, 0, 0, 364, 365, 5, 29, 0, 0, 365, 367, 3, 28, 14, 0, 366, 364, 1, 0, 0, 0, 366, 367, 1, 0, 0, 0, 367, 51, 1, 0, 0, 0, 368, 373, 3, 66, 33, 0, 369, 370, 5, 36, 0, 0, 370, 372, 3, 66, 33, 0, 371, 369, 1, 0, 0, 0, 372, 375, 1, 0, 0, 0, 373, 371, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 53, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 376, 381, 3, 60, 30, 0, 377, 378, 5, 36, 0, 0, 378, 380, 3, 60, 30, 0, 379, 377, 1, 0, 0, 0, 380, 383, 1, 0, 0, 0, 381, 379, 1, 0, 0, 0, 381, 382, 1, 0, 0, 0, 382, 55, 1, 0, 0, 0, 383, 381, 1, 0, 0, 0, 384, 389, 3, 54, 27, 0, 385, 386, 5, 34, 0, 0, 386, 388, 3, 54, 27, 0, 387, 385, 1, 0, 0, 0, 388, 391, 1, 0, 0, 0, 389, 387, 1, 0, 0, 0, 389, 390, 1, 0, 0, 0, 390, 57, 1, 0, 0, 0, 391, 389, 1, 0, 0, 0, 392, 393, 7, 3, 0, 0, 393, 59, 1, 0, 0, 0, 394, 397, 5, 80, 0, 0, 395, 397, 3, 64, 32, 0, 396, 394, 1, 0, 0, 0, 396, 395, 1, 0, 0, 0, 397, 61, 1, 0, 0, 0, 398, 441, 5, 45, 0, 0, 399, 400, 3, 98, 49, 0, 400, 401, 5, 67, 0, 0, 401, 441, 1, 0, 0, 0, 402, 441, 3, 96, 48, 0, 403, 441, 3, 98, 49, 0, 404, 441, 3, 92, 46, 0, 405, 441, 3, 64, 32, 0, 406, 441, 3, 100, 50, 0, 407, 408, 5, 65, 0, 0, 408, 413, 3, 94, 47, 0, 409, 410, 5, 34, 0, 0, 410, 412, 3, 94, 47, 0, 411, 409, 1, 0, 0, 0, 412, 415, 1, 0, 0, 0, 413, 411, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 416, 1, 0, 0, 0, 415, 413, 1, 0, 0, 0, 416, 417, 5, 66, 0, 0, 417, 441, 1, 0, 0, 0, 418, 419, 5, 65, 0, 0, 419, 424, 3, 92, 46, 0, 420, 421, 5, 34, 0, 0, 421, 423, 3, 92, 46, 0, 422, 420, 1, 0, 0, 0, 423, 426, 1, 0, 0, 0, 424, 422, 1, 0, 0, 0, 424, 425, 1, 0, 0, 0, 425, 427, 1, 0, 0, 0, 426, 424, 1, 0, 0, 0, 427, 428, 5, 66, 0, 0, 428, 441, 1, 0, 0, 0, 429, 430, 5, 65, 0, 0, 430, 435, 3, 100, 50, 0, 431, 432, 5, 34, 0, 0, 432, 434, 3, 100, 50, 0, 433, 431, 1, 0, 0, 0, 434, 437, 1, 0, 0, 0, 435, 433, 1, 0, 0, 0, 435, 436, 1, 0, 0, 0, 436, 438, 1, 0, 0, 0, 437, 435, 1, 0, 0, 0, 438, 439, 5, 66, 0, 0, 439, 441, 1, 0, 0, 0, 440, 398, 1, 0, 0, 0, 440, 399, 1, 0, 0, 0, 440, 402, 1, 0, 0, 0, 440, 403, 1, 0, 0, 0, 440, 404, 1, 0, 0, 0, 440, 405, 1, 0, 0, 0, 440, 406, 1, 0, 0, 0, 440, 407, 1, 0, 0, 0, 440, 418, 1, 0, 0, 0, 440, 429, 1, 0, 0, 0, 441, 63, 1, 0, 0, 0, 442, 445, 5, 48, 0, 0, 443, 445, 5, 64, 0, 0, 444, 442, 1, 0, 0, 0, 444, 443, 1, 0, 0, 0, 445, 65, 1, 0, 0, 0, 446, 449, 3, 58, 29, 0, 447, 449, 3, 64, 32, 0, 448, 446, 1, 0, 0, 0, 448, 447, 1, 0, 0, 0, 449, 67, 1, 0, 0, 0, 450, 451, 5, 9, 0, 0, 451, 452, 5, 27, 0, 0, 452, 69, 1, 0, 0, 0, 453, 454, 5, 14, 0, 0, 454, 459, 3, 72, 36, 0, 455, 456, 5, 34, 0, 0, 456, 458, 3, 72, 36, 0, 457, 455, 1, 0, 0, 0, 458, 461, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 459, 460, 1, 0, 0, 0, 460, 71, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 462, 464, 3, 10, 5, 0, 463, 465, 7, 4, 0, 0, 464, 463, 1, 0, 0, 0, 464, 465, 1, 0, 0, 0, 465, 468, 1, 0, 0, 0, 466, 467, 5, 46, 0, 0, 467, 469, 7, 5, 0, 0, 468, 466, 1, 0, 0, 0, 468, 469, 1, 0, 0, 0, 469, 73, 1, 0, 0, 0, 470, 471, 5, 8, 0, 0, 471, 472, 3, 56, 28, 0, 472, 75, 1, 0, 0, 0, 473, 474, 5, 2, 0, 0, 474, 475, 3, 56, 28, 0, 475, 77, 1, 0, 0, 0, 476, 477, 5, 11, 0, 0, 477, 482, 3, 80, 40, 0, 478, 479, 5, 34, 0, 0, 479, 481, 3, 80, 40, 0, 480, 478, 1, 0, 0, 0, 481, 484, 1, 0, 0, 0, 482, 480, 1, 0, 0, 0, 482, 483, 1, 0, 0, 0, 483, 79, 1, 0, 0, 0, 484, 482, 1, 0, 0, 0, 485, 486, 3, 54, 27, 0, 486, 487, 5, 84, 0, 0, 487, 488, 3, 54, 27, 0, 488, 81, 1, 0, 0, 0, 489, 490, 5, 1, 0, 0, 490, 491, 3, 20, 10, 0, 491, 493, 3, 100, 50, 0, 492, 494, 3, 88, 44, 0, 493, 492, 1, 0, 0, 0, 493, 494, 1, 0, 0, 0, 494, 83, 1, 0, 0, 0, 495, 496, 5, 7, 0, 0, 496, 497, 3, 20, 10, 0, 497, 498, 3, 100, 50, 0, 498, 85, 1, 0, 0, 0, 499, 500, 5, 10, 0, 0, 500, 501, 3, 52, 26, 0, 501, 87, 1, 0, 0, 0, 502, 507, 3, 90, 45, 0, 503, 504, 5, 34, 0, 0, 504, 506, 3, 90, 45, 0, 505, 503, 1, 0, 0, 0, 506, 509, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 507, 508, 1, 0, 0, 0, 508, 89, 1, 0, 0, 0, 509, 507, 1, 0, 0, 0, 510, 511, 3, 58, 29, 0, 511, 512, 5, 32, 0, 0, 512, 513, 3, 62, 31, 0, 513, 91, 1, 0, 0, 0, 514, 515, 7, 6, 0, 0, 515, 93, 1, 0, 0, 0, 516, 519, 3, 96, 48, 0, 517, 519, 3, 98, 49, 0, 518, 516, 1, 0, 0, 0, 518, 517, 1, 0, 0, 0, 519, 95, 1, 0, 0, 0, 520, 522, 7, 0, 0, 0, 521, 520, 1, 0, 0, 0, 521, 522, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 524, 5, 28, 0, 0, 524, 97, 1, 0, 0, 0, 525, 527, 7, 0, 0, 0, 526, 525, 1, 0, 0, 0, 526, 527, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 529, 5, 27, 0, 0, 529, 99, 1, 0, 0, 0, 530, 531, 5, 26, 0, 0, 531, 101, 1, 0, 0, 0, 532, 533, 7, 7, 0, 0, 533, 103, 1, 0, 0, 0, 534, 535, 5, 5, 0, 0, 535, 536, 3, 106, 53, 0, 536, 105, 1, 0, 0, 0, 537, 538, 5, 65, 0, 0, 538, 539, 3, 2, 1, 0, 539, 540, 5, 66, 0, 0, 540, 107, 1, 0, 0, 0, 541, 542, 5, 13, 0, 0, 542, 543, 5, 100, 0, 0, 543, 109, 1, 0, 0, 0, 544, 545, 5, 3, 0, 0, 545, 548, 5, 90, 0, 0, 546, 547, 5, 88, 0, 0, 547, 549, 3, 54, 27, 0, 548, 546, 1, 0, 0, 0, 548, 549, 1, 0, 0, 0, 549, 559, 1, 0, 0, 0, 550, 551, 5, 89, 0, 0, 551, 556, 3, 112, 56, 0, 552, 553, 5, 34, 0, 0, 553, 555, 3, 112, 56, 0, 554, 552, 1, 0, 0, 0, 555, 558, 1, 0, 0, 0, 556, 554, 1, 0, 0, 0, 556, 557, 1, 0, 0, 0, 557, 560, 1, 0, 0, 0, 558, 556, 1, 0, 0, 0, 559, 550, 1, 0, 0, 0, 559, 560, 1, 0, 0, 0, 560, 111, 1, 0, 0, 0, 561, 562, 3, 54, 27, 0, 562, 563, 5, 32, 0, 0, 563, 565, 1, 0, 0, 0, 564, 561, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 566, 1, 0, 0, 0, 566, 567, 3, 54, 27, 0, 567, 113, 1, 0, 0, 0, 568, 569, 5, 18, 0, 0, 569, 570, 3, 34, 17, 0, 570, 571, 5, 88, 0, 0, 571, 572, 3, 56, 28, 0, 572, 115, 1, 0, 0, 0, 573, 574, 5, 17, 0, 0, 574, 577, 3, 28, 14, 0, 575, 576, 5, 29, 0, 0, 576, 578, 3, 28, 14, 0, 577, 575, 1, 0, 0, 0, 577, 578, 1, 0, 0, 0, 578, 117, 1, 0, 0, 0, 56, 129, 138, 156, 168, 177, 185, 191, 199, 201, 206, 213, 218, 229, 235, 243, 245, 256, 263, 274, 277, 291, 299, 307, 311, 318, 326, 334, 347, 351, 355, 362, 366, 373, 381, 389, 396, 413, 424, 435, 440, 444, 448, 459, 464, 468, 482, 493, 507, 518, 521, 526, 548, 556, 559, 564, 577]
\ No newline at end of file
+[4, 1, 120, 587, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 130, 8, 1, 10, 1, 12, 1, 133, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 141, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 159, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 171, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 178, 8, 5, 10, 5, 12, 5, 181, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 188, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 194, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 202, 8, 5, 10, 5, 12, 5, 205, 9, 5, 1, 6, 1, 6, 3, 6, 209, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 216, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 221, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 232, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 238, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 246, 8, 9, 10, 9, 12, 9, 249, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 259, 8, 10, 1, 10, 1, 10, 1, 10, 5, 10, 264, 8, 10, 10, 10, 12, 10, 267, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 275, 8, 11, 10, 11, 12, 11, 278, 9, 11, 3, 11, 280, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 3, 12, 287, 8, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 5, 15, 297, 8, 15, 10, 15, 12, 15, 300, 9, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 307, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 313, 8, 17, 10, 17, 12, 17, 316, 9, 17, 1, 17, 3, 17, 319, 8, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 3, 18, 326, 8, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 3, 21, 334, 8, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 340, 8, 22, 10, 22, 12, 22, 343, 9, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 5, 24, 353, 8, 24, 10, 24, 12, 24, 356, 9, 24, 1, 24, 3, 24, 359, 8, 24, 1, 24, 1, 24, 3, 24, 363, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 3, 26, 370, 8, 26, 1, 26, 1, 26, 3, 26, 374, 8, 26, 1, 27, 1, 27, 1, 27, 5, 27, 379, 8, 27, 10, 27, 12, 27, 382, 9, 27, 1, 28, 1, 28, 1, 28, 5, 28, 387, 8, 28, 10, 28, 12, 28, 390, 9, 28, 1, 29, 1, 29, 1, 29, 5, 29, 395, 8, 29, 10, 29, 12, 29, 398, 9, 29, 1, 30, 1, 30, 1, 31, 1, 31, 3, 31, 404, 8, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 419, 8, 32, 10, 32, 12, 32, 422, 9, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 430, 8, 32, 10, 32, 12, 32, 433, 9, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 441, 8, 32, 10, 32, 12, 32, 444, 9, 32, 1, 32, 1, 32, 3, 32, 448, 8, 32, 1, 33, 1, 33, 3, 33, 452, 8, 33, 1, 34, 1, 34, 3, 34, 456, 8, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 465, 8, 36, 10, 36, 12, 36, 468, 9, 36, 1, 37, 1, 37, 3, 37, 472, 8, 37, 1, 37, 1, 37, 3, 37, 476, 8, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 488, 8, 40, 10, 40, 12, 40, 491, 9, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 3, 42, 501, 8, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 5, 45, 513, 8, 45, 10, 45, 12, 45, 516, 9, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 3, 48, 526, 8, 48, 1, 49, 3, 49, 529, 8, 49, 1, 49, 1, 49, 1, 50, 3, 50, 534, 8, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 556, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 562, 8, 56, 10, 56, 12, 56, 565, 9, 56, 3, 56, 567, 8, 56, 1, 57, 1, 57, 1, 57, 3, 57, 572, 8, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 3, 59, 585, 8, 59, 1, 59, 0, 4, 2, 10, 18, 20, 60, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 0, 8, 1, 0, 58, 59, 1, 0, 60, 62, 2, 0, 25, 25, 76, 76, 1, 0, 67, 68, 2, 0, 30, 30, 34, 34, 2, 0, 37, 37, 40, 40, 2, 0, 36, 36, 50, 50, 2, 0, 51, 51, 53, 57, 613, 0, 120, 1, 0, 0, 0, 2, 123, 1, 0, 0, 0, 4, 140, 1, 0, 0, 0, 6, 158, 1, 0, 0, 0, 8, 160, 1, 0, 0, 0, 10, 193, 1, 0, 0, 0, 12, 220, 1, 0, 0, 0, 14, 222, 1, 0, 0, 0, 16, 231, 1, 0, 0, 0, 18, 237, 1, 0, 0, 0, 20, 258, 1, 0, 0, 0, 22, 268, 1, 0, 0, 0, 24, 286, 1, 0, 0, 0, 26, 288, 1, 0, 0, 0, 28, 290, 1, 0, 0, 0, 30, 293, 1, 0, 0, 0, 32, 306, 1, 0, 0, 0, 34, 308, 1, 0, 0, 0, 36, 325, 1, 0, 0, 0, 38, 327, 1, 0, 0, 0, 40, 329, 1, 0, 0, 0, 42, 333, 1, 0, 0, 0, 44, 335, 1, 0, 0, 0, 46, 344, 1, 0, 0, 0, 48, 348, 1, 0, 0, 0, 50, 364, 1, 0, 0, 0, 52, 367, 1, 0, 0, 0, 54, 375, 1, 0, 0, 0, 56, 383, 1, 0, 0, 0, 58, 391, 1, 0, 0, 0, 60, 399, 1, 0, 0, 0, 62, 403, 1, 0, 0, 0, 64, 447, 1, 0, 0, 0, 66, 451, 1, 0, 0, 0, 68, 455, 1, 0, 0, 0, 70, 457, 1, 0, 0, 0, 72, 460, 1, 0, 0, 0, 74, 469, 1, 0, 0, 0, 76, 477, 1, 0, 0, 0, 78, 480, 1, 0, 0, 0, 80, 483, 1, 0, 0, 0, 82, 492, 1, 0, 0, 0, 84, 496, 1, 0, 0, 0, 86, 502, 1, 0, 0, 0, 88, 506, 1, 0, 0, 0, 90, 509, 1, 0, 0, 0, 92, 517, 1, 0, 0, 0, 94, 521, 1, 0, 0, 0, 96, 525, 1, 0, 0, 0, 98, 528, 1, 0, 0, 0, 100, 533, 1, 0, 0, 0, 102, 537, 1, 0, 0, 0, 104, 539, 1, 0, 0, 0, 106, 541, 1, 0, 0, 0, 108, 544, 1, 0, 0, 0, 110, 548, 1, 0, 0, 0, 112, 551, 1, 0, 0, 0, 114, 571, 1, 0, 0, 0, 116, 575, 1, 0, 0, 0, 118, 580, 1, 0, 0, 0, 120, 121, 3, 2, 1, 0, 121, 122, 5, 0, 0, 1, 122, 1, 1, 0, 0, 0, 123, 124, 6, 1, -1, 0, 124, 125, 3, 4, 2, 0, 125, 131, 1, 0, 0, 0, 126, 127, 10, 1, 0, 0, 127, 128, 5, 24, 0, 0, 128, 130, 3, 6, 3, 0, 129, 126, 1, 0, 0, 0, 130, 133, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 3, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 134, 141, 3, 106, 53, 0, 135, 141, 3, 34, 17, 0, 136, 141, 3, 28, 14, 0, 137, 141, 3, 110, 55, 0, 138, 139, 4, 2, 1, 0, 139, 141, 3, 48, 24, 0, 140, 134, 1, 0, 0, 0, 140, 135, 1, 0, 0, 0, 140, 136, 1, 0, 0, 0, 140, 137, 1, 0, 0, 0, 140, 138, 1, 0, 0, 0, 141, 5, 1, 0, 0, 0, 142, 159, 3, 50, 25, 0, 143, 159, 3, 8, 4, 0, 144, 159, 3, 76, 38, 0, 145, 159, 3, 70, 35, 0, 146, 159, 3, 52, 26, 0, 147, 159, 3, 72, 36, 0, 148, 159, 3, 78, 39, 0, 149, 159, 3, 80, 40, 0, 150, 159, 3, 84, 42, 0, 151, 159, 3, 86, 43, 0, 152, 159, 3, 112, 56, 0, 153, 159, 3, 88, 44, 0, 154, 155, 4, 3, 2, 0, 155, 159, 3, 118, 59, 0, 156, 157, 4, 3, 3, 0, 157, 159, 3, 116, 58, 0, 158, 142, 1, 0, 0, 0, 158, 143, 1, 0, 0, 0, 158, 144, 1, 0, 0, 0, 158, 145, 1, 0, 0, 0, 158, 146, 1, 0, 0, 0, 158, 147, 1, 0, 0, 0, 158, 148, 1, 0, 0, 0, 158, 149, 1, 0, 0, 0, 158, 150, 1, 0, 0, 0, 158, 151, 1, 0, 0, 0, 158, 152, 1, 0, 0, 0, 158, 153, 1, 0, 0, 0, 158, 154, 1, 0, 0, 0, 158, 156, 1, 0, 0, 0, 159, 7, 1, 0, 0, 0, 160, 161, 5, 16, 0, 0, 161, 162, 3, 10, 5, 0, 162, 9, 1, 0, 0, 0, 163, 164, 6, 5, -1, 0, 164, 165, 5, 43, 0, 0, 165, 194, 3, 10, 5, 8, 166, 194, 3, 16, 8, 0, 167, 194, 3, 12, 6, 0, 168, 170, 3, 16, 8, 0, 169, 171, 5, 43, 0, 0, 170, 169, 1, 0, 0, 0, 170, 171, 1, 0, 0, 0, 171, 172, 1, 0, 0, 0, 172, 173, 5, 38, 0, 0, 173, 174, 5, 42, 0, 0, 174, 179, 3, 16, 8, 0, 175, 176, 5, 33, 0, 0, 176, 178, 3, 16, 8, 0, 177, 175, 1, 0, 0, 0, 178, 181, 1, 0, 0, 0, 179, 177, 1, 0, 0, 0, 179, 180, 1, 0, 0, 0, 180, 182, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 182, 183, 5, 49, 0, 0, 183, 194, 1, 0, 0, 0, 184, 185, 3, 16, 8, 0, 185, 187, 5, 39, 0, 0, 186, 188, 5, 43, 0, 0, 187, 186, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 189, 1, 0, 0, 0, 189, 190, 5, 44, 0, 0, 190, 194, 1, 0, 0, 0, 191, 192, 4, 5, 4, 0, 192, 194, 3, 14, 7, 0, 193, 163, 1, 0, 0, 0, 193, 166, 1, 0, 0, 0, 193, 167, 1, 0, 0, 0, 193, 168, 1, 0, 0, 0, 193, 184, 1, 0, 0, 0, 193, 191, 1, 0, 0, 0, 194, 203, 1, 0, 0, 0, 195, 196, 10, 5, 0, 0, 196, 197, 5, 29, 0, 0, 197, 202, 3, 10, 5, 6, 198, 199, 10, 4, 0, 0, 199, 200, 5, 46, 0, 0, 200, 202, 3, 10, 5, 5, 201, 195, 1, 0, 0, 0, 201, 198, 1, 0, 0, 0, 202, 205, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 203, 204, 1, 0, 0, 0, 204, 11, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 206, 208, 3, 16, 8, 0, 207, 209, 5, 43, 0, 0, 208, 207, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 210, 1, 0, 0, 0, 210, 211, 5, 41, 0, 0, 211, 212, 3, 102, 51, 0, 212, 221, 1, 0, 0, 0, 213, 215, 3, 16, 8, 0, 214, 216, 5, 43, 0, 0, 215, 214, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 218, 5, 48, 0, 0, 218, 219, 3, 102, 51, 0, 219, 221, 1, 0, 0, 0, 220, 206, 1, 0, 0, 0, 220, 213, 1, 0, 0, 0, 221, 13, 1, 0, 0, 0, 222, 223, 3, 16, 8, 0, 223, 224, 5, 63, 0, 0, 224, 225, 3, 102, 51, 0, 225, 15, 1, 0, 0, 0, 226, 232, 3, 18, 9, 0, 227, 228, 3, 18, 9, 0, 228, 229, 3, 104, 52, 0, 229, 230, 3, 18, 9, 0, 230, 232, 1, 0, 0, 0, 231, 226, 1, 0, 0, 0, 231, 227, 1, 0, 0, 0, 232, 17, 1, 0, 0, 0, 233, 234, 6, 9, -1, 0, 234, 238, 3, 20, 10, 0, 235, 236, 7, 0, 0, 0, 236, 238, 3, 18, 9, 3, 237, 233, 1, 0, 0, 0, 237, 235, 1, 0, 0, 0, 238, 247, 1, 0, 0, 0, 239, 240, 10, 2, 0, 0, 240, 241, 7, 1, 0, 0, 241, 246, 3, 18, 9, 3, 242, 243, 10, 1, 0, 0, 243, 244, 7, 0, 0, 0, 244, 246, 3, 18, 9, 2, 245, 239, 1, 0, 0, 0, 245, 242, 1, 0, 0, 0, 246, 249, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 248, 1, 0, 0, 0, 248, 19, 1, 0, 0, 0, 249, 247, 1, 0, 0, 0, 250, 251, 6, 10, -1, 0, 251, 259, 3, 64, 32, 0, 252, 259, 3, 54, 27, 0, 253, 259, 3, 22, 11, 0, 254, 255, 5, 42, 0, 0, 255, 256, 3, 10, 5, 0, 256, 257, 5, 49, 0, 0, 257, 259, 1, 0, 0, 0, 258, 250, 1, 0, 0, 0, 258, 252, 1, 0, 0, 0, 258, 253, 1, 0, 0, 0, 258, 254, 1, 0, 0, 0, 259, 265, 1, 0, 0, 0, 260, 261, 10, 1, 0, 0, 261, 262, 5, 32, 0, 0, 262, 264, 3, 26, 13, 0, 263, 260, 1, 0, 0, 0, 264, 267, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 265, 266, 1, 0, 0, 0, 266, 21, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 268, 269, 3, 24, 12, 0, 269, 279, 5, 42, 0, 0, 270, 280, 5, 60, 0, 0, 271, 276, 3, 10, 5, 0, 272, 273, 5, 33, 0, 0, 273, 275, 3, 10, 5, 0, 274, 272, 1, 0, 0, 0, 275, 278, 1, 0, 0, 0, 276, 274, 1, 0, 0, 0, 276, 277, 1, 0, 0, 0, 277, 280, 1, 0, 0, 0, 278, 276, 1, 0, 0, 0, 279, 270, 1, 0, 0, 0, 279, 271, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 281, 1, 0, 0, 0, 281, 282, 5, 49, 0, 0, 282, 23, 1, 0, 0, 0, 283, 284, 4, 12, 10, 0, 284, 287, 5, 63, 0, 0, 285, 287, 3, 68, 34, 0, 286, 283, 1, 0, 0, 0, 286, 285, 1, 0, 0, 0, 287, 25, 1, 0, 0, 0, 288, 289, 3, 60, 30, 0, 289, 27, 1, 0, 0, 0, 290, 291, 5, 12, 0, 0, 291, 292, 3, 30, 15, 0, 292, 29, 1, 0, 0, 0, 293, 298, 3, 32, 16, 0, 294, 295, 5, 33, 0, 0, 295, 297, 3, 32, 16, 0, 296, 294, 1, 0, 0, 0, 297, 300, 1, 0, 0, 0, 298, 296, 1, 0, 0, 0, 298, 299, 1, 0, 0, 0, 299, 31, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 301, 307, 3, 10, 5, 0, 302, 303, 3, 54, 27, 0, 303, 304, 5, 31, 0, 0, 304, 305, 3, 10, 5, 0, 305, 307, 1, 0, 0, 0, 306, 301, 1, 0, 0, 0, 306, 302, 1, 0, 0, 0, 307, 33, 1, 0, 0, 0, 308, 309, 5, 6, 0, 0, 309, 314, 3, 36, 18, 0, 310, 311, 5, 33, 0, 0, 311, 313, 3, 36, 18, 0, 312, 310, 1, 0, 0, 0, 313, 316, 1, 0, 0, 0, 314, 312, 1, 0, 0, 0, 314, 315, 1, 0, 0, 0, 315, 318, 1, 0, 0, 0, 316, 314, 1, 0, 0, 0, 317, 319, 3, 42, 21, 0, 318, 317, 1, 0, 0, 0, 318, 319, 1, 0, 0, 0, 319, 35, 1, 0, 0, 0, 320, 321, 3, 38, 19, 0, 321, 322, 5, 104, 0, 0, 322, 323, 3, 40, 20, 0, 323, 326, 1, 0, 0, 0, 324, 326, 3, 40, 20, 0, 325, 320, 1, 0, 0, 0, 325, 324, 1, 0, 0, 0, 326, 37, 1, 0, 0, 0, 327, 328, 5, 76, 0, 0, 328, 39, 1, 0, 0, 0, 329, 330, 7, 2, 0, 0, 330, 41, 1, 0, 0, 0, 331, 334, 3, 44, 22, 0, 332, 334, 3, 46, 23, 0, 333, 331, 1, 0, 0, 0, 333, 332, 1, 0, 0, 0, 334, 43, 1, 0, 0, 0, 335, 336, 5, 75, 0, 0, 336, 341, 5, 76, 0, 0, 337, 338, 5, 33, 0, 0, 338, 340, 5, 76, 0, 0, 339, 337, 1, 0, 0, 0, 340, 343, 1, 0, 0, 0, 341, 339, 1, 0, 0, 0, 341, 342, 1, 0, 0, 0, 342, 45, 1, 0, 0, 0, 343, 341, 1, 0, 0, 0, 344, 345, 5, 65, 0, 0, 345, 346, 3, 44, 22, 0, 346, 347, 5, 66, 0, 0, 347, 47, 1, 0, 0, 0, 348, 349, 5, 19, 0, 0, 349, 354, 3, 36, 18, 0, 350, 351, 5, 33, 0, 0, 351, 353, 3, 36, 18, 0, 352, 350, 1, 0, 0, 0, 353, 356, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 354, 355, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 357, 359, 3, 30, 15, 0, 358, 357, 1, 0, 0, 0, 358, 359, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 361, 5, 28, 0, 0, 361, 363, 3, 30, 15, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 49, 1, 0, 0, 0, 364, 365, 5, 4, 0, 0, 365, 366, 3, 30, 15, 0, 366, 51, 1, 0, 0, 0, 367, 369, 5, 15, 0, 0, 368, 370, 3, 30, 15, 0, 369, 368, 1, 0, 0, 0, 369, 370, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 372, 5, 28, 0, 0, 372, 374, 3, 30, 15, 0, 373, 371, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 53, 1, 0, 0, 0, 375, 380, 3, 68, 34, 0, 376, 377, 5, 35, 0, 0, 377, 379, 3, 68, 34, 0, 378, 376, 1, 0, 0, 0, 379, 382, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 380, 381, 1, 0, 0, 0, 381, 55, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 388, 3, 62, 31, 0, 384, 385, 5, 35, 0, 0, 385, 387, 3, 62, 31, 0, 386, 384, 1, 0, 0, 0, 387, 390, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 57, 1, 0, 0, 0, 390, 388, 1, 0, 0, 0, 391, 396, 3, 56, 28, 0, 392, 393, 5, 33, 0, 0, 393, 395, 3, 56, 28, 0, 394, 392, 1, 0, 0, 0, 395, 398, 1, 0, 0, 0, 396, 394, 1, 0, 0, 0, 396, 397, 1, 0, 0, 0, 397, 59, 1, 0, 0, 0, 398, 396, 1, 0, 0, 0, 399, 400, 7, 3, 0, 0, 400, 61, 1, 0, 0, 0, 401, 404, 5, 80, 0, 0, 402, 404, 3, 66, 33, 0, 403, 401, 1, 0, 0, 0, 403, 402, 1, 0, 0, 0, 404, 63, 1, 0, 0, 0, 405, 448, 5, 44, 0, 0, 406, 407, 3, 100, 50, 0, 407, 408, 5, 67, 0, 0, 408, 448, 1, 0, 0, 0, 409, 448, 3, 98, 49, 0, 410, 448, 3, 100, 50, 0, 411, 448, 3, 94, 47, 0, 412, 448, 3, 66, 33, 0, 413, 448, 3, 102, 51, 0, 414, 415, 5, 65, 0, 0, 415, 420, 3, 96, 48, 0, 416, 417, 5, 33, 0, 0, 417, 419, 3, 96, 48, 0, 418, 416, 1, 0, 0, 0, 419, 422, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 423, 1, 0, 0, 0, 422, 420, 1, 0, 0, 0, 423, 424, 5, 66, 0, 0, 424, 448, 1, 0, 0, 0, 425, 426, 5, 65, 0, 0, 426, 431, 3, 94, 47, 0, 427, 428, 5, 33, 0, 0, 428, 430, 3, 94, 47, 0, 429, 427, 1, 0, 0, 0, 430, 433, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 431, 432, 1, 0, 0, 0, 432, 434, 1, 0, 0, 0, 433, 431, 1, 0, 0, 0, 434, 435, 5, 66, 0, 0, 435, 448, 1, 0, 0, 0, 436, 437, 5, 65, 0, 0, 437, 442, 3, 102, 51, 0, 438, 439, 5, 33, 0, 0, 439, 441, 3, 102, 51, 0, 440, 438, 1, 0, 0, 0, 441, 444, 1, 0, 0, 0, 442, 440, 1, 0, 0, 0, 442, 443, 1, 0, 0, 0, 443, 445, 1, 0, 0, 0, 444, 442, 1, 0, 0, 0, 445, 446, 5, 66, 0, 0, 446, 448, 1, 0, 0, 0, 447, 405, 1, 0, 0, 0, 447, 406, 1, 0, 0, 0, 447, 409, 1, 0, 0, 0, 447, 410, 1, 0, 0, 0, 447, 411, 1, 0, 0, 0, 447, 412, 1, 0, 0, 0, 447, 413, 1, 0, 0, 0, 447, 414, 1, 0, 0, 0, 447, 425, 1, 0, 0, 0, 447, 436, 1, 0, 0, 0, 448, 65, 1, 0, 0, 0, 449, 452, 5, 47, 0, 0, 450, 452, 5, 64, 0, 0, 451, 449, 1, 0, 0, 0, 451, 450, 1, 0, 0, 0, 452, 67, 1, 0, 0, 0, 453, 456, 3, 60, 30, 0, 454, 456, 3, 66, 33, 0, 455, 453, 1, 0, 0, 0, 455, 454, 1, 0, 0, 0, 456, 69, 1, 0, 0, 0, 457, 458, 5, 9, 0, 0, 458, 459, 5, 26, 0, 0, 459, 71, 1, 0, 0, 0, 460, 461, 5, 14, 0, 0, 461, 466, 3, 74, 37, 0, 462, 463, 5, 33, 0, 0, 463, 465, 3, 74, 37, 0, 464, 462, 1, 0, 0, 0, 465, 468, 1, 0, 0, 0, 466, 464, 1, 0, 0, 0, 466, 467, 1, 0, 0, 0, 467, 73, 1, 0, 0, 0, 468, 466, 1, 0, 0, 0, 469, 471, 3, 10, 5, 0, 470, 472, 7, 4, 0, 0, 471, 470, 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 472, 475, 1, 0, 0, 0, 473, 474, 5, 45, 0, 0, 474, 476, 7, 5, 0, 0, 475, 473, 1, 0, 0, 0, 475, 476, 1, 0, 0, 0, 476, 75, 1, 0, 0, 0, 477, 478, 5, 8, 0, 0, 478, 479, 3, 58, 29, 0, 479, 77, 1, 0, 0, 0, 480, 481, 5, 2, 0, 0, 481, 482, 3, 58, 29, 0, 482, 79, 1, 0, 0, 0, 483, 484, 5, 11, 0, 0, 484, 489, 3, 82, 41, 0, 485, 486, 5, 33, 0, 0, 486, 488, 3, 82, 41, 0, 487, 485, 1, 0, 0, 0, 488, 491, 1, 0, 0, 0, 489, 487, 1, 0, 0, 0, 489, 490, 1, 0, 0, 0, 490, 81, 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 492, 493, 3, 56, 28, 0, 493, 494, 5, 84, 0, 0, 494, 495, 3, 56, 28, 0, 495, 83, 1, 0, 0, 0, 496, 497, 5, 1, 0, 0, 497, 498, 3, 20, 10, 0, 498, 500, 3, 102, 51, 0, 499, 501, 3, 90, 45, 0, 500, 499, 1, 0, 0, 0, 500, 501, 1, 0, 0, 0, 501, 85, 1, 0, 0, 0, 502, 503, 5, 7, 0, 0, 503, 504, 3, 20, 10, 0, 504, 505, 3, 102, 51, 0, 505, 87, 1, 0, 0, 0, 506, 507, 5, 10, 0, 0, 507, 508, 3, 54, 27, 0, 508, 89, 1, 0, 0, 0, 509, 514, 3, 92, 46, 0, 510, 511, 5, 33, 0, 0, 511, 513, 3, 92, 46, 0, 512, 510, 1, 0, 0, 0, 513, 516, 1, 0, 0, 0, 514, 512, 1, 0, 0, 0, 514, 515, 1, 0, 0, 0, 515, 91, 1, 0, 0, 0, 516, 514, 1, 0, 0, 0, 517, 518, 3, 60, 30, 0, 518, 519, 5, 31, 0, 0, 519, 520, 3, 64, 32, 0, 520, 93, 1, 0, 0, 0, 521, 522, 7, 6, 0, 0, 522, 95, 1, 0, 0, 0, 523, 526, 3, 98, 49, 0, 524, 526, 3, 100, 50, 0, 525, 523, 1, 0, 0, 0, 525, 524, 1, 0, 0, 0, 526, 97, 1, 0, 0, 0, 527, 529, 7, 0, 0, 0, 528, 527, 1, 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 530, 1, 0, 0, 0, 530, 531, 5, 27, 0, 0, 531, 99, 1, 0, 0, 0, 532, 534, 7, 0, 0, 0, 533, 532, 1, 0, 0, 0, 533, 534, 1, 0, 0, 0, 534, 535, 1, 0, 0, 0, 535, 536, 5, 26, 0, 0, 536, 101, 1, 0, 0, 0, 537, 538, 5, 25, 0, 0, 538, 103, 1, 0, 0, 0, 539, 540, 7, 7, 0, 0, 540, 105, 1, 0, 0, 0, 541, 542, 5, 5, 0, 0, 542, 543, 3, 108, 54, 0, 543, 107, 1, 0, 0, 0, 544, 545, 5, 65, 0, 0, 545, 546, 3, 2, 1, 0, 546, 547, 5, 66, 0, 0, 547, 109, 1, 0, 0, 0, 548, 549, 5, 13, 0, 0, 549, 550, 5, 100, 0, 0, 550, 111, 1, 0, 0, 0, 551, 552, 5, 3, 0, 0, 552, 555, 5, 90, 0, 0, 553, 554, 5, 88, 0, 0, 554, 556, 3, 56, 28, 0, 555, 553, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 566, 1, 0, 0, 0, 557, 558, 5, 89, 0, 0, 558, 563, 3, 114, 57, 0, 559, 560, 5, 33, 0, 0, 560, 562, 3, 114, 57, 0, 561, 559, 1, 0, 0, 0, 562, 565, 1, 0, 0, 0, 563, 561, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 567, 1, 0, 0, 0, 565, 563, 1, 0, 0, 0, 566, 557, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 113, 1, 0, 0, 0, 568, 569, 3, 56, 28, 0, 569, 570, 5, 31, 0, 0, 570, 572, 1, 0, 0, 0, 571, 568, 1, 0, 0, 0, 571, 572, 1, 0, 0, 0, 572, 573, 1, 0, 0, 0, 573, 574, 3, 56, 28, 0, 574, 115, 1, 0, 0, 0, 575, 576, 5, 18, 0, 0, 576, 577, 3, 36, 18, 0, 577, 578, 5, 88, 0, 0, 578, 579, 3, 58, 29, 0, 579, 117, 1, 0, 0, 0, 580, 581, 5, 17, 0, 0, 581, 584, 3, 30, 15, 0, 582, 583, 5, 28, 0, 0, 583, 585, 3, 30, 15, 0, 584, 582, 1, 0, 0, 0, 584, 585, 1, 0, 0, 0, 585, 119, 1, 0, 0, 0, 57, 131, 140, 158, 170, 179, 187, 193, 201, 203, 208, 215, 220, 231, 237, 245, 247, 258, 265, 276, 279, 286, 298, 306, 314, 318, 325, 333, 341, 354, 358, 362, 369, 373, 380, 388, 396, 403, 420, 431, 442, 447, 451, 455, 466, 471, 475, 489, 500, 514, 525, 528, 533, 555, 563, 566, 571, 584]
\ No newline at end of file
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
index 14913849d1b51..522393fb42c4b 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParser.java
@@ -8,14 +8,26 @@
* 2.0.
*/
-import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.FailedPredicateException;
+import org.antlr.v4.runtime.NoViableAltException;
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.RuleContext;
+import org.antlr.v4.runtime.RuntimeMetaData;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.Vocabulary;
+import org.antlr.v4.runtime.VocabularyImpl;
+import org.antlr.v4.runtime.atn.ATN;
+import org.antlr.v4.runtime.atn.ATNDeserializer;
+import org.antlr.v4.runtime.atn.ParserATNSimulator;
+import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.misc.*;
-import org.antlr.v4.runtime.tree.*;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
public class EsqlBaseParser extends ParserConfig {
@@ -25,66 +37,66 @@ public class EsqlBaseParser extends ParserConfig {
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
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, DEV_INLINESTATS=17, DEV_LOOKUP=18, DEV_MATCH=19, DEV_METRICS=20,
- UNKNOWN_CMD=21, LINE_COMMENT=22, MULTILINE_COMMENT=23, WS=24, PIPE=25,
- QUOTED_STRING=26, INTEGER_LITERAL=27, DECIMAL_LITERAL=28, BY=29, AND=30,
- ASC=31, ASSIGN=32, CAST_OP=33, COMMA=34, DESC=35, DOT=36, FALSE=37, FIRST=38,
- IN=39, IS=40, LAST=41, LIKE=42, LP=43, NOT=44, NULL=45, NULLS=46, OR=47,
- PARAM=48, RLIKE=49, RP=50, TRUE=51, EQ=52, CIEQ=53, NEQ=54, LT=55, LTE=56,
- GT=57, GTE=58, PLUS=59, MINUS=60, ASTERISK=61, SLASH=62, PERCENT=63, NAMED_OR_POSITIONAL_PARAM=64,
- OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
- EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, EXPLAIN_WS=72,
- EXPLAIN_LINE_COMMENT=73, EXPLAIN_MULTILINE_COMMENT=74, METADATA=75, UNQUOTED_SOURCE=76,
- FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80,
- PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83,
- AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87,
- ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92,
- ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95,
- ENRICH_FIELD_WS=96, MVEXPAND_LINE_COMMENT=97, MVEXPAND_MULTILINE_COMMENT=98,
- MVEXPAND_WS=99, INFO=100, SHOW_LINE_COMMENT=101, SHOW_MULTILINE_COMMENT=102,
- SHOW_WS=103, COLON=104, SETTING=105, SETTING_LINE_COMMENT=106, SETTTING_MULTILINE_COMMENT=107,
- SETTING_WS=108, LOOKUP_LINE_COMMENT=109, LOOKUP_MULTILINE_COMMENT=110,
- LOOKUP_WS=111, LOOKUP_FIELD_LINE_COMMENT=112, LOOKUP_FIELD_MULTILINE_COMMENT=113,
- LOOKUP_FIELD_WS=114, METRICS_LINE_COMMENT=115, METRICS_MULTILINE_COMMENT=116,
- METRICS_WS=117, CLOSING_METRICS_LINE_COMMENT=118, CLOSING_METRICS_MULTILINE_COMMENT=119,
+ 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, DEV_INLINESTATS=17, DEV_LOOKUP=18, DEV_METRICS=19, UNKNOWN_CMD=20,
+ LINE_COMMENT=21, MULTILINE_COMMENT=22, WS=23, PIPE=24, QUOTED_STRING=25,
+ INTEGER_LITERAL=26, DECIMAL_LITERAL=27, BY=28, AND=29, ASC=30, ASSIGN=31,
+ CAST_OP=32, COMMA=33, DESC=34, DOT=35, FALSE=36, FIRST=37, IN=38, IS=39,
+ LAST=40, LIKE=41, LP=42, NOT=43, NULL=44, NULLS=45, OR=46, PARAM=47, RLIKE=48,
+ RP=49, TRUE=50, EQ=51, CIEQ=52, NEQ=53, LT=54, LTE=55, GT=56, GTE=57,
+ PLUS=58, MINUS=59, ASTERISK=60, SLASH=61, PERCENT=62, DEV_MATCH=63, NAMED_OR_POSITIONAL_PARAM=64,
+ OPENING_BRACKET=65, CLOSING_BRACKET=66, UNQUOTED_IDENTIFIER=67, QUOTED_IDENTIFIER=68,
+ EXPR_LINE_COMMENT=69, EXPR_MULTILINE_COMMENT=70, EXPR_WS=71, EXPLAIN_WS=72,
+ EXPLAIN_LINE_COMMENT=73, EXPLAIN_MULTILINE_COMMENT=74, METADATA=75, UNQUOTED_SOURCE=76,
+ FROM_LINE_COMMENT=77, FROM_MULTILINE_COMMENT=78, FROM_WS=79, ID_PATTERN=80,
+ PROJECT_LINE_COMMENT=81, PROJECT_MULTILINE_COMMENT=82, PROJECT_WS=83,
+ AS=84, RENAME_LINE_COMMENT=85, RENAME_MULTILINE_COMMENT=86, RENAME_WS=87,
+ ON=88, WITH=89, ENRICH_POLICY_NAME=90, ENRICH_LINE_COMMENT=91, ENRICH_MULTILINE_COMMENT=92,
+ ENRICH_WS=93, ENRICH_FIELD_LINE_COMMENT=94, ENRICH_FIELD_MULTILINE_COMMENT=95,
+ ENRICH_FIELD_WS=96, MVEXPAND_LINE_COMMENT=97, MVEXPAND_MULTILINE_COMMENT=98,
+ MVEXPAND_WS=99, INFO=100, SHOW_LINE_COMMENT=101, SHOW_MULTILINE_COMMENT=102,
+ SHOW_WS=103, COLON=104, SETTING=105, SETTING_LINE_COMMENT=106, SETTTING_MULTILINE_COMMENT=107,
+ SETTING_WS=108, LOOKUP_LINE_COMMENT=109, LOOKUP_MULTILINE_COMMENT=110,
+ LOOKUP_WS=111, LOOKUP_FIELD_LINE_COMMENT=112, LOOKUP_FIELD_MULTILINE_COMMENT=113,
+ LOOKUP_FIELD_WS=114, METRICS_LINE_COMMENT=115, METRICS_MULTILINE_COMMENT=116,
+ METRICS_WS=117, CLOSING_METRICS_LINE_COMMENT=118, CLOSING_METRICS_MULTILINE_COMMENT=119,
CLOSING_METRICS_WS=120;
public static final int
- RULE_singleStatement = 0, RULE_query = 1, RULE_sourceCommand = 2, RULE_processingCommand = 3,
- RULE_whereCommand = 4, RULE_booleanExpression = 5, RULE_regexBooleanExpression = 6,
- RULE_matchBooleanExpression = 7, RULE_valueExpression = 8, RULE_operatorExpression = 9,
- RULE_primaryExpression = 10, RULE_functionExpression = 11, RULE_dataType = 12,
- RULE_rowCommand = 13, RULE_fields = 14, RULE_field = 15, RULE_fromCommand = 16,
- RULE_indexPattern = 17, RULE_clusterString = 18, RULE_indexString = 19,
- RULE_metadata = 20, RULE_metadataOption = 21, RULE_deprecated_metadata = 22,
- RULE_metricsCommand = 23, RULE_evalCommand = 24, RULE_statsCommand = 25,
- RULE_qualifiedName = 26, RULE_qualifiedNamePattern = 27, RULE_qualifiedNamePatterns = 28,
- RULE_identifier = 29, RULE_identifierPattern = 30, RULE_constant = 31,
- RULE_parameter = 32, RULE_identifierOrParameter = 33, RULE_limitCommand = 34,
- RULE_sortCommand = 35, RULE_orderExpression = 36, RULE_keepCommand = 37,
- RULE_dropCommand = 38, RULE_renameCommand = 39, RULE_renameClause = 40,
- RULE_dissectCommand = 41, RULE_grokCommand = 42, RULE_mvExpandCommand = 43,
- RULE_commandOptions = 44, RULE_commandOption = 45, RULE_booleanValue = 46,
- RULE_numericValue = 47, RULE_decimalValue = 48, RULE_integerValue = 49,
- RULE_string = 50, RULE_comparisonOperator = 51, RULE_explainCommand = 52,
- RULE_subqueryExpression = 53, RULE_showCommand = 54, RULE_enrichCommand = 55,
- RULE_enrichWithClause = 56, RULE_lookupCommand = 57, RULE_inlinestatsCommand = 58;
+ RULE_singleStatement = 0, RULE_query = 1, RULE_sourceCommand = 2, RULE_processingCommand = 3,
+ RULE_whereCommand = 4, RULE_booleanExpression = 5, RULE_regexBooleanExpression = 6,
+ RULE_matchBooleanExpression = 7, RULE_valueExpression = 8, RULE_operatorExpression = 9,
+ RULE_primaryExpression = 10, RULE_functionExpression = 11, RULE_functionName = 12,
+ RULE_dataType = 13, RULE_rowCommand = 14, RULE_fields = 15, RULE_field = 16,
+ RULE_fromCommand = 17, RULE_indexPattern = 18, RULE_clusterString = 19,
+ RULE_indexString = 20, RULE_metadata = 21, RULE_metadataOption = 22, RULE_deprecated_metadata = 23,
+ RULE_metricsCommand = 24, RULE_evalCommand = 25, RULE_statsCommand = 26,
+ RULE_qualifiedName = 27, RULE_qualifiedNamePattern = 28, RULE_qualifiedNamePatterns = 29,
+ RULE_identifier = 30, RULE_identifierPattern = 31, RULE_constant = 32,
+ RULE_parameter = 33, RULE_identifierOrParameter = 34, RULE_limitCommand = 35,
+ RULE_sortCommand = 36, RULE_orderExpression = 37, RULE_keepCommand = 38,
+ RULE_dropCommand = 39, RULE_renameCommand = 40, RULE_renameClause = 41,
+ RULE_dissectCommand = 42, RULE_grokCommand = 43, RULE_mvExpandCommand = 44,
+ RULE_commandOptions = 45, RULE_commandOption = 46, RULE_booleanValue = 47,
+ RULE_numericValue = 48, RULE_decimalValue = 49, RULE_integerValue = 50,
+ RULE_string = 51, RULE_comparisonOperator = 52, RULE_explainCommand = 53,
+ RULE_subqueryExpression = 54, RULE_showCommand = 55, RULE_enrichCommand = 56,
+ RULE_enrichWithClause = 57, RULE_lookupCommand = 58, RULE_inlinestatsCommand = 59;
private static String[] makeRuleNames() {
return new String[] {
- "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand",
- "booleanExpression", "regexBooleanExpression", "matchBooleanExpression",
- "valueExpression", "operatorExpression", "primaryExpression", "functionExpression",
- "dataType", "rowCommand", "fields", "field", "fromCommand", "indexPattern",
- "clusterString", "indexString", "metadata", "metadataOption", "deprecated_metadata",
- "metricsCommand", "evalCommand", "statsCommand", "qualifiedName", "qualifiedNamePattern",
- "qualifiedNamePatterns", "identifier", "identifierPattern", "constant",
- "parameter", "identifierOrParameter", "limitCommand", "sortCommand",
- "orderExpression", "keepCommand", "dropCommand", "renameCommand", "renameClause",
- "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions",
- "commandOption", "booleanValue", "numericValue", "decimalValue", "integerValue",
- "string", "comparisonOperator", "explainCommand", "subqueryExpression",
- "showCommand", "enrichCommand", "enrichWithClause", "lookupCommand",
+ "singleStatement", "query", "sourceCommand", "processingCommand", "whereCommand",
+ "booleanExpression", "regexBooleanExpression", "matchBooleanExpression",
+ "valueExpression", "operatorExpression", "primaryExpression", "functionExpression",
+ "functionName", "dataType", "rowCommand", "fields", "field", "fromCommand",
+ "indexPattern", "clusterString", "indexString", "metadata", "metadataOption",
+ "deprecated_metadata", "metricsCommand", "evalCommand", "statsCommand",
+ "qualifiedName", "qualifiedNamePattern", "qualifiedNamePatterns", "identifier",
+ "identifierPattern", "constant", "parameter", "identifierOrParameter",
+ "limitCommand", "sortCommand", "orderExpression", "keepCommand", "dropCommand",
+ "renameCommand", "renameClause", "dissectCommand", "grokCommand", "mvExpandCommand",
+ "commandOptions", "commandOption", "booleanValue", "numericValue", "decimalValue",
+ "integerValue", "string", "comparisonOperator", "explainCommand", "subqueryExpression",
+ "showCommand", "enrichCommand", "enrichWithClause", "lookupCommand",
"inlinestatsCommand"
};
}
@@ -92,46 +104,46 @@ private static String[] makeRuleNames() {
private static String[] makeLiteralNames() {
return new String[] {
- null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'",
- "'grok'", "'keep'", "'limit'", "'mv_expand'", "'rename'", "'row'", "'show'",
- "'sort'", "'stats'", "'where'", null, 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'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='",
- "'+'", "'-'", "'*'", "'/'", "'%'", null, null, "']'", null, null, null,
- null, null, null, null, null, "'metadata'", null, null, null, null, null,
- null, null, null, "'as'", null, null, null, "'on'", "'with'", null, null,
- null, null, null, null, null, null, null, null, "'info'", null, null,
+ null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'",
+ "'grok'", "'keep'", "'limit'", "'mv_expand'", "'rename'", "'row'", "'show'",
+ "'sort'", "'stats'", "'where'", 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'", "'=='", "'=~'", "'!='", "'<'", "'<='", "'>'", "'>='", "'+'",
+ "'-'", "'*'", "'/'", "'%'", null, null, null, "']'", null, null, null,
+ null, null, null, null, null, "'metadata'", null, null, null, null, null,
+ null, null, null, "'as'", null, null, null, "'on'", "'with'", null, null,
+ null, null, null, null, null, null, null, null, "'info'", null, null,
null, "':'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
- null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK",
- "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS",
- "WHERE", "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_MATCH", "DEV_METRICS",
- "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING",
- "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP",
- "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", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET", "CLOSING_BRACKET",
- "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", "EXPR_MULTILINE_COMMENT",
- "EXPR_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", "EXPLAIN_MULTILINE_COMMENT",
- "METADATA", "UNQUOTED_SOURCE", "FROM_LINE_COMMENT", "FROM_MULTILINE_COMMENT",
- "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT",
- "PROJECT_WS", "AS", "RENAME_LINE_COMMENT", "RENAME_MULTILINE_COMMENT",
- "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME", "ENRICH_LINE_COMMENT",
- "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT",
- "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT",
- "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT",
- "SHOW_MULTILINE_COMMENT", "SHOW_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT",
- "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT",
- "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT",
- "LOOKUP_FIELD_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT",
- "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
+ null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK",
+ "KEEP", "LIMIT", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS",
+ "WHERE", "DEV_INLINESTATS", "DEV_LOOKUP", "DEV_METRICS", "UNKNOWN_CMD",
+ "LINE_COMMENT", "MULTILINE_COMMENT", "WS", "PIPE", "QUOTED_STRING", "INTEGER_LITERAL",
+ "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", "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", "DEV_MATCH", "NAMED_OR_POSITIONAL_PARAM", "OPENING_BRACKET",
+ "CLOSING_BRACKET", "UNQUOTED_IDENTIFIER", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT",
+ "EXPR_MULTILINE_COMMENT", "EXPR_WS", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT",
+ "EXPLAIN_MULTILINE_COMMENT", "METADATA", "UNQUOTED_SOURCE", "FROM_LINE_COMMENT",
+ "FROM_MULTILINE_COMMENT", "FROM_WS", "ID_PATTERN", "PROJECT_LINE_COMMENT",
+ "PROJECT_MULTILINE_COMMENT", "PROJECT_WS", "AS", "RENAME_LINE_COMMENT",
+ "RENAME_MULTILINE_COMMENT", "RENAME_WS", "ON", "WITH", "ENRICH_POLICY_NAME",
+ "ENRICH_LINE_COMMENT", "ENRICH_MULTILINE_COMMENT", "ENRICH_WS", "ENRICH_FIELD_LINE_COMMENT",
+ "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", "MVEXPAND_LINE_COMMENT",
+ "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", "INFO", "SHOW_LINE_COMMENT",
+ "SHOW_MULTILINE_COMMENT", "SHOW_WS", "COLON", "SETTING", "SETTING_LINE_COMMENT",
+ "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "LOOKUP_LINE_COMMENT", "LOOKUP_MULTILINE_COMMENT",
+ "LOOKUP_WS", "LOOKUP_FIELD_LINE_COMMENT", "LOOKUP_FIELD_MULTILINE_COMMENT",
+ "LOOKUP_FIELD_WS", "METRICS_LINE_COMMENT", "METRICS_MULTILINE_COMMENT",
+ "METRICS_WS", "CLOSING_METRICS_LINE_COMMENT", "CLOSING_METRICS_MULTILINE_COMMENT",
"CLOSING_METRICS_WS"
};
}
@@ -219,9 +231,9 @@ public final SingleStatementContext singleStatement() throws RecognitionExceptio
try {
enterOuterAlt(_localctx, 1);
{
- setState(118);
+ setState(120);
query(0);
- setState(119);
+ setState(121);
match(EOF);
}
}
@@ -243,7 +255,7 @@ public QueryContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_query; }
-
+
@SuppressWarnings("this-escape")
public QueryContext() { }
public void copyFrom(QueryContext ctx) {
@@ -317,11 +329,11 @@ private QueryContext query(int _p) throws RecognitionException {
_ctx = _localctx;
_prevctx = _localctx;
- setState(122);
+ setState(124);
sourceCommand();
}
_ctx.stop = _input.LT(-1);
- setState(129);
+ setState(131);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,0,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -332,16 +344,16 @@ private QueryContext query(int _p) throws RecognitionException {
{
_localctx = new CompositeQueryContext(new QueryContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_query);
- setState(124);
+ setState(126);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(125);
+ setState(127);
match(PIPE);
- setState(126);
+ setState(128);
processingCommand();
}
- }
+ }
}
- setState(131);
+ setState(133);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,0,_ctx);
}
@@ -399,43 +411,43 @@ public final SourceCommandContext sourceCommand() throws RecognitionException {
SourceCommandContext _localctx = new SourceCommandContext(_ctx, getState());
enterRule(_localctx, 4, RULE_sourceCommand);
try {
- setState(138);
+ setState(140);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(132);
+ setState(134);
explainCommand();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(133);
+ setState(135);
fromCommand();
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
- setState(134);
+ setState(136);
rowCommand();
}
break;
case 4:
enterOuterAlt(_localctx, 4);
{
- setState(135);
+ setState(137);
showCommand();
}
break;
case 5:
enterOuterAlt(_localctx, 5);
{
- setState(136);
+ setState(138);
if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()");
- setState(137);
+ setState(139);
metricsCommand();
}
break;
@@ -520,108 +532,108 @@ public final ProcessingCommandContext processingCommand() throws RecognitionExce
ProcessingCommandContext _localctx = new ProcessingCommandContext(_ctx, getState());
enterRule(_localctx, 6, RULE_processingCommand);
try {
- setState(156);
+ setState(158);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(140);
+ setState(142);
evalCommand();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(141);
+ setState(143);
whereCommand();
}
break;
case 3:
enterOuterAlt(_localctx, 3);
{
- setState(142);
+ setState(144);
keepCommand();
}
break;
case 4:
enterOuterAlt(_localctx, 4);
{
- setState(143);
+ setState(145);
limitCommand();
}
break;
case 5:
enterOuterAlt(_localctx, 5);
{
- setState(144);
+ setState(146);
statsCommand();
}
break;
case 6:
enterOuterAlt(_localctx, 6);
{
- setState(145);
+ setState(147);
sortCommand();
}
break;
case 7:
enterOuterAlt(_localctx, 7);
{
- setState(146);
+ setState(148);
dropCommand();
}
break;
case 8:
enterOuterAlt(_localctx, 8);
{
- setState(147);
+ setState(149);
renameCommand();
}
break;
case 9:
enterOuterAlt(_localctx, 9);
{
- setState(148);
+ setState(150);
dissectCommand();
}
break;
case 10:
enterOuterAlt(_localctx, 10);
{
- setState(149);
+ setState(151);
grokCommand();
}
break;
case 11:
enterOuterAlt(_localctx, 11);
{
- setState(150);
+ setState(152);
enrichCommand();
}
break;
case 12:
enterOuterAlt(_localctx, 12);
{
- setState(151);
+ setState(153);
mvExpandCommand();
}
break;
case 13:
enterOuterAlt(_localctx, 13);
{
- setState(152);
+ setState(154);
if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()");
- setState(153);
+ setState(155);
inlinestatsCommand();
}
break;
case 14:
enterOuterAlt(_localctx, 14);
{
- setState(154);
+ setState(156);
if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()");
- setState(155);
+ setState(157);
lookupCommand();
}
break;
@@ -670,9 +682,9 @@ public final WhereCommandContext whereCommand() throws RecognitionException {
try {
enterOuterAlt(_localctx, 1);
{
- setState(158);
+ setState(160);
match(WHERE);
- setState(159);
+ setState(161);
booleanExpression(0);
}
}
@@ -694,7 +706,7 @@ public BooleanExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_booleanExpression; }
-
+
@SuppressWarnings("this-escape")
public BooleanExpressionContext() { }
public void copyFrom(BooleanExpressionContext ctx) {
@@ -888,7 +900,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(191);
+ setState(193);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
case 1:
@@ -897,9 +909,9 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_ctx = _localctx;
_prevctx = _localctx;
- setState(162);
+ setState(164);
match(NOT);
- setState(163);
+ setState(165);
booleanExpression(8);
}
break;
@@ -908,7 +920,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new BooleanDefaultContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(164);
+ setState(166);
valueExpression();
}
break;
@@ -917,7 +929,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new RegexExpressionContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(165);
+ setState(167);
regexBooleanExpression();
}
break;
@@ -926,41 +938,41 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new LogicalInContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(166);
- valueExpression();
setState(168);
+ valueExpression();
+ setState(170);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(167);
+ setState(169);
match(NOT);
}
}
- setState(170);
+ setState(172);
match(IN);
- setState(171);
+ setState(173);
match(LP);
- setState(172);
+ setState(174);
valueExpression();
- setState(177);
+ setState(179);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(173);
+ setState(175);
match(COMMA);
- setState(174);
+ setState(176);
valueExpression();
}
}
- setState(179);
+ setState(181);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(180);
+ setState(182);
match(RP);
}
break;
@@ -969,21 +981,21 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new IsNullContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(182);
+ setState(184);
valueExpression();
- setState(183);
- match(IS);
setState(185);
+ match(IS);
+ setState(187);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(184);
+ setState(186);
match(NOT);
}
}
- setState(187);
+ setState(189);
match(NULL);
}
break;
@@ -992,15 +1004,15 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new MatchExpressionContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(189);
+ setState(191);
if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()");
- setState(190);
+ setState(192);
matchBooleanExpression();
}
break;
}
_ctx.stop = _input.LT(-1);
- setState(201);
+ setState(203);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,8,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1008,7 +1020,7 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(199);
+ setState(201);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
case 1:
@@ -1016,11 +1028,11 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState));
((LogicalBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression);
- setState(193);
+ setState(195);
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
- setState(194);
+ setState(196);
((LogicalBinaryContext)_localctx).operator = match(AND);
- setState(195);
+ setState(197);
((LogicalBinaryContext)_localctx).right = booleanExpression(6);
}
break;
@@ -1029,18 +1041,18 @@ private BooleanExpressionContext booleanExpression(int _p) throws RecognitionExc
_localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState));
((LogicalBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression);
- setState(196);
+ setState(198);
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
- setState(197);
+ setState(199);
((LogicalBinaryContext)_localctx).operator = match(OR);
- setState(198);
+ setState(200);
((LogicalBinaryContext)_localctx).right = booleanExpression(5);
}
break;
}
- }
+ }
}
- setState(203);
+ setState(205);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,8,_ctx);
}
@@ -1095,48 +1107,48 @@ public final RegexBooleanExpressionContext regexBooleanExpression() throws Recog
enterRule(_localctx, 12, RULE_regexBooleanExpression);
int _la;
try {
- setState(218);
+ setState(220);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(204);
- valueExpression();
setState(206);
+ valueExpression();
+ setState(208);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(205);
+ setState(207);
match(NOT);
}
}
- setState(208);
+ setState(210);
((RegexBooleanExpressionContext)_localctx).kind = match(LIKE);
- setState(209);
+ setState(211);
((RegexBooleanExpressionContext)_localctx).pattern = string();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(211);
- valueExpression();
setState(213);
+ valueExpression();
+ setState(215);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==NOT) {
{
- setState(212);
+ setState(214);
match(NOT);
}
}
- setState(215);
+ setState(217);
((RegexBooleanExpressionContext)_localctx).kind = match(RLIKE);
- setState(216);
+ setState(218);
((RegexBooleanExpressionContext)_localctx).pattern = string();
}
break;
@@ -1189,11 +1201,11 @@ public final MatchBooleanExpressionContext matchBooleanExpression() throws Recog
try {
enterOuterAlt(_localctx, 1);
{
- setState(220);
+ setState(222);
valueExpression();
- setState(221);
+ setState(223);
match(DEV_MATCH);
- setState(222);
+ setState(224);
((MatchBooleanExpressionContext)_localctx).queryString = string();
}
}
@@ -1215,7 +1227,7 @@ public ValueExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_valueExpression; }
-
+
@SuppressWarnings("this-escape")
public ValueExpressionContext() { }
public void copyFrom(ValueExpressionContext ctx) {
@@ -1277,14 +1289,14 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio
ValueExpressionContext _localctx = new ValueExpressionContext(_ctx, getState());
enterRule(_localctx, 16, RULE_valueExpression);
try {
- setState(229);
+ setState(231);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,12,_ctx) ) {
case 1:
_localctx = new ValueExpressionDefaultContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(224);
+ setState(226);
operatorExpression(0);
}
break;
@@ -1292,11 +1304,11 @@ public final ValueExpressionContext valueExpression() throws RecognitionExceptio
_localctx = new ComparisonContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(225);
+ setState(227);
((ComparisonContext)_localctx).left = operatorExpression(0);
- setState(226);
+ setState(228);
comparisonOperator();
- setState(227);
+ setState(229);
((ComparisonContext)_localctx).right = operatorExpression(0);
}
break;
@@ -1320,7 +1332,7 @@ public OperatorExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_operatorExpression; }
-
+
@SuppressWarnings("this-escape")
public OperatorExpressionContext() { }
public void copyFrom(OperatorExpressionContext ctx) {
@@ -1421,7 +1433,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(235);
+ setState(237);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,13,_ctx) ) {
case 1:
@@ -1430,7 +1442,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_ctx = _localctx;
_prevctx = _localctx;
- setState(232);
+ setState(234);
primaryExpression(0);
}
break;
@@ -1439,7 +1451,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_localctx = new ArithmeticUnaryContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(233);
+ setState(235);
((ArithmeticUnaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
@@ -1450,13 +1462,13 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(234);
+ setState(236);
operatorExpression(3);
}
break;
}
_ctx.stop = _input.LT(-1);
- setState(245);
+ setState(247);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1464,7 +1476,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
- setState(243);
+ setState(245);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,14,_ctx) ) {
case 1:
@@ -1472,12 +1484,12 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState));
((ArithmeticBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression);
- setState(237);
+ setState(239);
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
- setState(238);
+ setState(240);
((ArithmeticBinaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & -2305843009213693952L) != 0)) ) {
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 8070450532247928832L) != 0)) ) {
((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this);
}
else {
@@ -1485,7 +1497,7 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(239);
+ setState(241);
((ArithmeticBinaryContext)_localctx).right = operatorExpression(3);
}
break;
@@ -1494,9 +1506,9 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_localctx = new ArithmeticBinaryContext(new OperatorExpressionContext(_parentctx, _parentState));
((ArithmeticBinaryContext)_localctx).left = _prevctx;
pushNewRecursionContext(_localctx, _startState, RULE_operatorExpression);
- setState(240);
+ setState(242);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(241);
+ setState(243);
((ArithmeticBinaryContext)_localctx).operator = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
@@ -1507,14 +1519,14 @@ private OperatorExpressionContext operatorExpression(int _p) throws RecognitionE
_errHandler.reportMatch(this);
consume();
}
- setState(242);
+ setState(244);
((ArithmeticBinaryContext)_localctx).right = operatorExpression(2);
}
break;
}
- }
+ }
}
- setState(247);
+ setState(249);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,15,_ctx);
}
@@ -1538,7 +1550,7 @@ public PrimaryExpressionContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_primaryExpression; }
-
+
@SuppressWarnings("this-escape")
public PrimaryExpressionContext() { }
public void copyFrom(PrimaryExpressionContext ctx) {
@@ -1672,7 +1684,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(256);
+ setState(258);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) {
case 1:
@@ -1681,7 +1693,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
_ctx = _localctx;
_prevctx = _localctx;
- setState(249);
+ setState(251);
constant();
}
break;
@@ -1690,7 +1702,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
_localctx = new DereferenceContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(250);
+ setState(252);
qualifiedName();
}
break;
@@ -1699,7 +1711,7 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
_localctx = new FunctionContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(251);
+ setState(253);
functionExpression();
}
break;
@@ -1708,17 +1720,17 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
_localctx = new ParenthesizedExpressionContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
- setState(252);
+ setState(254);
match(LP);
- setState(253);
+ setState(255);
booleanExpression(0);
- setState(254);
+ setState(256);
match(RP);
}
break;
}
_ctx.stop = _input.LT(-1);
- setState(263);
+ setState(265);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
@@ -1729,16 +1741,16 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
{
_localctx = new InlineCastContext(new PrimaryExpressionContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_primaryExpression);
- setState(258);
+ setState(260);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
- setState(259);
+ setState(261);
match(CAST_OP);
- setState(260);
+ setState(262);
dataType();
}
- }
+ }
}
- setState(265);
+ setState(267);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,17,_ctx);
}
@@ -1757,8 +1769,8 @@ private PrimaryExpressionContext primaryExpression(int _p) throws RecognitionExc
@SuppressWarnings("CheckReturnValue")
public static class FunctionExpressionContext extends ParserRuleContext {
- public IdentifierOrParameterContext identifierOrParameter() {
- return getRuleContext(IdentifierOrParameterContext.class,0);
+ public FunctionNameContext functionName() {
+ return getRuleContext(FunctionNameContext.class,0);
}
public TerminalNode LP() { return getToken(EsqlBaseParser.LP, 0); }
public TerminalNode RP() { return getToken(EsqlBaseParser.RP, 0); }
@@ -1800,37 +1812,37 @@ public final FunctionExpressionContext functionExpression() throws RecognitionEx
try {
enterOuterAlt(_localctx, 1);
{
- setState(266);
- identifierOrParameter();
- setState(267);
+ setState(268);
+ functionName();
+ setState(269);
match(LP);
- setState(277);
+ setState(279);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) {
case 1:
{
- setState(268);
+ setState(270);
match(ASTERISK);
}
break;
case 2:
{
{
- setState(269);
+ setState(271);
booleanExpression(0);
- setState(274);
+ setState(276);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(270);
+ setState(272);
match(COMMA);
- setState(271);
+ setState(273);
booleanExpression(0);
}
}
- setState(276);
+ setState(278);
_errHandler.sync(this);
_la = _input.LA(1);
}
@@ -1838,7 +1850,7 @@ public final FunctionExpressionContext functionExpression() throws RecognitionEx
}
break;
}
- setState(279);
+ setState(281);
match(RP);
}
}
@@ -1853,6 +1865,68 @@ public final FunctionExpressionContext functionExpression() throws RecognitionEx
return _localctx;
}
+ @SuppressWarnings("CheckReturnValue")
+ public static class FunctionNameContext extends ParserRuleContext {
+ public TerminalNode DEV_MATCH() { return getToken(EsqlBaseParser.DEV_MATCH, 0); }
+ public IdentifierOrParameterContext identifierOrParameter() {
+ return getRuleContext(IdentifierOrParameterContext.class,0);
+ }
+ @SuppressWarnings("this-escape")
+ public FunctionNameContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_functionName; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).enterFunctionName(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof EsqlBaseParserListener ) ((EsqlBaseParserListener)listener).exitFunctionName(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof EsqlBaseParserVisitor ) return ((EsqlBaseParserVisitor extends T>)visitor).visitFunctionName(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final FunctionNameContext functionName() throws RecognitionException {
+ FunctionNameContext _localctx = new FunctionNameContext(_ctx, getState());
+ enterRule(_localctx, 24, RULE_functionName);
+ try {
+ setState(286);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,20,_ctx) ) {
+ case 1:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(283);
+ if (!(this.isDevVersion())) throw new FailedPredicateException(this, "this.isDevVersion()");
+ setState(284);
+ match(DEV_MATCH);
+ }
+ break;
+ case 2:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(285);
+ identifierOrParameter();
+ }
+ break;
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
@SuppressWarnings("CheckReturnValue")
public static class DataTypeContext extends ParserRuleContext {
@SuppressWarnings("this-escape")
@@ -1860,7 +1934,7 @@ public DataTypeContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_dataType; }
-
+
@SuppressWarnings("this-escape")
public DataTypeContext() { }
public void copyFrom(DataTypeContext ctx) {
@@ -1891,12 +1965,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DataTypeContext dataType() throws RecognitionException {
DataTypeContext _localctx = new DataTypeContext(_ctx, getState());
- enterRule(_localctx, 24, RULE_dataType);
+ enterRule(_localctx, 26, RULE_dataType);
try {
_localctx = new ToDataTypeContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(281);
+ setState(288);
identifier();
}
}
@@ -1939,13 +2013,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final RowCommandContext rowCommand() throws RecognitionException {
RowCommandContext _localctx = new RowCommandContext(_ctx, getState());
- enterRule(_localctx, 26, RULE_rowCommand);
+ enterRule(_localctx, 28, RULE_rowCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(283);
+ setState(290);
match(ROW);
- setState(284);
+ setState(291);
fields();
}
}
@@ -1994,30 +2068,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final FieldsContext fields() throws RecognitionException {
FieldsContext _localctx = new FieldsContext(_ctx, getState());
- enterRule(_localctx, 28, RULE_fields);
+ enterRule(_localctx, 30, RULE_fields);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(286);
+ setState(293);
field();
- setState(291);
+ setState(298);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(287);
+ setState(294);
match(COMMA);
- setState(288);
+ setState(295);
field();
}
- }
+ }
}
- setState(293);
+ setState(300);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,20,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,21,_ctx);
}
}
}
@@ -2063,26 +2137,26 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final FieldContext field() throws RecognitionException {
FieldContext _localctx = new FieldContext(_ctx, getState());
- enterRule(_localctx, 30, RULE_field);
+ enterRule(_localctx, 32, RULE_field);
try {
- setState(299);
+ setState(306);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,21,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(294);
+ setState(301);
booleanExpression(0);
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(295);
+ setState(302);
qualifiedName();
- setState(296);
+ setState(303);
match(ASSIGN);
- setState(297);
+ setState(304);
booleanExpression(0);
}
break;
@@ -2137,39 +2211,39 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final FromCommandContext fromCommand() throws RecognitionException {
FromCommandContext _localctx = new FromCommandContext(_ctx, getState());
- enterRule(_localctx, 32, RULE_fromCommand);
+ enterRule(_localctx, 34, RULE_fromCommand);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(301);
+ setState(308);
match(FROM);
- setState(302);
+ setState(309);
indexPattern();
- setState(307);
+ setState(314);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,22,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,23,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(303);
+ setState(310);
match(COMMA);
- setState(304);
+ setState(311);
indexPattern();
}
- }
+ }
}
- setState(309);
+ setState(316);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,22,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,23,_ctx);
}
- setState(311);
+ setState(318);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
case 1:
{
- setState(310);
+ setState(317);
metadata();
}
break;
@@ -2218,26 +2292,26 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IndexPatternContext indexPattern() throws RecognitionException {
IndexPatternContext _localctx = new IndexPatternContext(_ctx, getState());
- enterRule(_localctx, 34, RULE_indexPattern);
+ enterRule(_localctx, 36, RULE_indexPattern);
try {
- setState(318);
+ setState(325);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,24,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(313);
+ setState(320);
clusterString();
- setState(314);
+ setState(321);
match(COLON);
- setState(315);
+ setState(322);
indexString();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(317);
+ setState(324);
indexString();
}
break;
@@ -2279,11 +2353,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ClusterStringContext clusterString() throws RecognitionException {
ClusterStringContext _localctx = new ClusterStringContext(_ctx, getState());
- enterRule(_localctx, 36, RULE_clusterString);
+ enterRule(_localctx, 38, RULE_clusterString);
try {
enterOuterAlt(_localctx, 1);
{
- setState(320);
+ setState(327);
match(UNQUOTED_SOURCE);
}
}
@@ -2324,12 +2398,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IndexStringContext indexString() throws RecognitionException {
IndexStringContext _localctx = new IndexStringContext(_ctx, getState());
- enterRule(_localctx, 38, RULE_indexString);
+ enterRule(_localctx, 40, RULE_indexString);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(322);
+ setState(329);
_la = _input.LA(1);
if ( !(_la==QUOTED_STRING || _la==UNQUOTED_SOURCE) ) {
_errHandler.recoverInline(this);
@@ -2382,22 +2456,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MetadataContext metadata() throws RecognitionException {
MetadataContext _localctx = new MetadataContext(_ctx, getState());
- enterRule(_localctx, 40, RULE_metadata);
+ enterRule(_localctx, 42, RULE_metadata);
try {
- setState(326);
+ setState(333);
_errHandler.sync(this);
switch (_input.LA(1)) {
case METADATA:
enterOuterAlt(_localctx, 1);
{
- setState(324);
+ setState(331);
metadataOption();
}
break;
case OPENING_BRACKET:
enterOuterAlt(_localctx, 2);
{
- setState(325);
+ setState(332);
deprecated_metadata();
}
break;
@@ -2449,32 +2523,32 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MetadataOptionContext metadataOption() throws RecognitionException {
MetadataOptionContext _localctx = new MetadataOptionContext(_ctx, getState());
- enterRule(_localctx, 42, RULE_metadataOption);
+ enterRule(_localctx, 44, RULE_metadataOption);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(328);
+ setState(335);
match(METADATA);
- setState(329);
+ setState(336);
match(UNQUOTED_SOURCE);
- setState(334);
+ setState(341);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(330);
+ setState(337);
match(COMMA);
- setState(331);
+ setState(338);
match(UNQUOTED_SOURCE);
}
- }
+ }
}
- setState(336);
+ setState(343);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,26,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
}
}
}
@@ -2517,15 +2591,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final Deprecated_metadataContext deprecated_metadata() throws RecognitionException {
Deprecated_metadataContext _localctx = new Deprecated_metadataContext(_ctx, getState());
- enterRule(_localctx, 44, RULE_deprecated_metadata);
+ enterRule(_localctx, 46, RULE_deprecated_metadata);
try {
enterOuterAlt(_localctx, 1);
{
- setState(337);
+ setState(344);
match(OPENING_BRACKET);
- setState(338);
+ setState(345);
metadataOption();
- setState(339);
+ setState(346);
match(CLOSING_BRACKET);
}
}
@@ -2584,51 +2658,51 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MetricsCommandContext metricsCommand() throws RecognitionException {
MetricsCommandContext _localctx = new MetricsCommandContext(_ctx, getState());
- enterRule(_localctx, 46, RULE_metricsCommand);
+ enterRule(_localctx, 48, RULE_metricsCommand);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(341);
+ setState(348);
match(DEV_METRICS);
- setState(342);
+ setState(349);
indexPattern();
- setState(347);
+ setState(354);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(343);
+ setState(350);
match(COMMA);
- setState(344);
+ setState(351);
indexPattern();
}
- }
+ }
}
- setState(349);
+ setState(356);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,27,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,28,_ctx);
}
- setState(351);
+ setState(358);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) {
case 1:
{
- setState(350);
+ setState(357);
((MetricsCommandContext)_localctx).aggregates = fields();
}
break;
}
- setState(355);
+ setState(362);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,29,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
case 1:
{
- setState(353);
+ setState(360);
match(BY);
- setState(354);
+ setState(361);
((MetricsCommandContext)_localctx).grouping = fields();
}
break;
@@ -2674,13 +2748,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final EvalCommandContext evalCommand() throws RecognitionException {
EvalCommandContext _localctx = new EvalCommandContext(_ctx, getState());
- enterRule(_localctx, 48, RULE_evalCommand);
+ enterRule(_localctx, 50, RULE_evalCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(357);
+ setState(364);
match(EVAL);
- setState(358);
+ setState(365);
fields();
}
}
@@ -2729,30 +2803,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final StatsCommandContext statsCommand() throws RecognitionException {
StatsCommandContext _localctx = new StatsCommandContext(_ctx, getState());
- enterRule(_localctx, 50, RULE_statsCommand);
+ enterRule(_localctx, 52, RULE_statsCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(360);
+ setState(367);
match(STATS);
- setState(362);
+ setState(369);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
case 1:
{
- setState(361);
+ setState(368);
((StatsCommandContext)_localctx).stats = fields();
}
break;
}
- setState(366);
+ setState(373);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,32,_ctx) ) {
case 1:
{
- setState(364);
+ setState(371);
match(BY);
- setState(365);
+ setState(372);
((StatsCommandContext)_localctx).grouping = fields();
}
break;
@@ -2804,30 +2878,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final QualifiedNameContext qualifiedName() throws RecognitionException {
QualifiedNameContext _localctx = new QualifiedNameContext(_ctx, getState());
- enterRule(_localctx, 52, RULE_qualifiedName);
+ enterRule(_localctx, 54, RULE_qualifiedName);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(368);
+ setState(375);
identifierOrParameter();
- setState(373);
+ setState(380);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(369);
+ setState(376);
match(DOT);
- setState(370);
+ setState(377);
identifierOrParameter();
}
- }
+ }
}
- setState(375);
+ setState(382);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,32,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
}
}
}
@@ -2876,30 +2950,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final QualifiedNamePatternContext qualifiedNamePattern() throws RecognitionException {
QualifiedNamePatternContext _localctx = new QualifiedNamePatternContext(_ctx, getState());
- enterRule(_localctx, 54, RULE_qualifiedNamePattern);
+ enterRule(_localctx, 56, RULE_qualifiedNamePattern);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(376);
+ setState(383);
identifierPattern();
- setState(381);
+ setState(388);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,34,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(377);
+ setState(384);
match(DOT);
- setState(378);
+ setState(385);
identifierPattern();
}
- }
+ }
}
- setState(383);
+ setState(390);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,33,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,34,_ctx);
}
}
}
@@ -2948,30 +3022,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final QualifiedNamePatternsContext qualifiedNamePatterns() throws RecognitionException {
QualifiedNamePatternsContext _localctx = new QualifiedNamePatternsContext(_ctx, getState());
- enterRule(_localctx, 56, RULE_qualifiedNamePatterns);
+ enterRule(_localctx, 58, RULE_qualifiedNamePatterns);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(384);
+ setState(391);
qualifiedNamePattern();
- setState(389);
+ setState(396);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,34,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,35,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(385);
+ setState(392);
match(COMMA);
- setState(386);
+ setState(393);
qualifiedNamePattern();
}
- }
+ }
}
- setState(391);
+ setState(398);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,34,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,35,_ctx);
}
}
}
@@ -3012,12 +3086,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IdentifierContext identifier() throws RecognitionException {
IdentifierContext _localctx = new IdentifierContext(_ctx, getState());
- enterRule(_localctx, 58, RULE_identifier);
+ enterRule(_localctx, 60, RULE_identifier);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(392);
+ setState(399);
_la = _input.LA(1);
if ( !(_la==UNQUOTED_IDENTIFIER || _la==QUOTED_IDENTIFIER) ) {
_errHandler.recoverInline(this);
@@ -3068,15 +3142,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IdentifierPatternContext identifierPattern() throws RecognitionException {
IdentifierPatternContext _localctx = new IdentifierPatternContext(_ctx, getState());
- enterRule(_localctx, 60, RULE_identifierPattern);
+ enterRule(_localctx, 62, RULE_identifierPattern);
try {
- setState(396);
+ setState(403);
_errHandler.sync(this);
switch (_input.LA(1)) {
case ID_PATTERN:
enterOuterAlt(_localctx, 1);
{
- setState(394);
+ setState(401);
match(ID_PATTERN);
}
break;
@@ -3084,7 +3158,7 @@ public final IdentifierPatternContext identifierPattern() throws RecognitionExce
case NAMED_OR_POSITIONAL_PARAM:
enterOuterAlt(_localctx, 2);
{
- setState(395);
+ setState(402);
parameter();
}
break;
@@ -3110,7 +3184,7 @@ public ConstantContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_constant; }
-
+
@SuppressWarnings("this-escape")
public ConstantContext() { }
public void copyFrom(ConstantContext ctx) {
@@ -3356,17 +3430,17 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ConstantContext constant() throws RecognitionException {
ConstantContext _localctx = new ConstantContext(_ctx, getState());
- enterRule(_localctx, 62, RULE_constant);
+ enterRule(_localctx, 64, RULE_constant);
int _la;
try {
- setState(440);
+ setState(447);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) {
case 1:
_localctx = new NullLiteralContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(398);
+ setState(405);
match(NULL);
}
break;
@@ -3374,9 +3448,9 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new QualifiedIntegerLiteralContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(399);
+ setState(406);
integerValue();
- setState(400);
+ setState(407);
match(UNQUOTED_IDENTIFIER);
}
break;
@@ -3384,7 +3458,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new DecimalLiteralContext(_localctx);
enterOuterAlt(_localctx, 3);
{
- setState(402);
+ setState(409);
decimalValue();
}
break;
@@ -3392,7 +3466,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new IntegerLiteralContext(_localctx);
enterOuterAlt(_localctx, 4);
{
- setState(403);
+ setState(410);
integerValue();
}
break;
@@ -3400,7 +3474,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new BooleanLiteralContext(_localctx);
enterOuterAlt(_localctx, 5);
{
- setState(404);
+ setState(411);
booleanValue();
}
break;
@@ -3408,7 +3482,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new InputParameterContext(_localctx);
enterOuterAlt(_localctx, 6);
{
- setState(405);
+ setState(412);
parameter();
}
break;
@@ -3416,7 +3490,7 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new StringLiteralContext(_localctx);
enterOuterAlt(_localctx, 7);
{
- setState(406);
+ setState(413);
string();
}
break;
@@ -3424,27 +3498,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new NumericArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 8);
{
- setState(407);
+ setState(414);
match(OPENING_BRACKET);
- setState(408);
+ setState(415);
numericValue();
- setState(413);
+ setState(420);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(409);
+ setState(416);
match(COMMA);
- setState(410);
+ setState(417);
numericValue();
}
}
- setState(415);
+ setState(422);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(416);
+ setState(423);
match(CLOSING_BRACKET);
}
break;
@@ -3452,27 +3526,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new BooleanArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 9);
{
- setState(418);
+ setState(425);
match(OPENING_BRACKET);
- setState(419);
+ setState(426);
booleanValue();
- setState(424);
+ setState(431);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(420);
+ setState(427);
match(COMMA);
- setState(421);
+ setState(428);
booleanValue();
}
}
- setState(426);
+ setState(433);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(427);
+ setState(434);
match(CLOSING_BRACKET);
}
break;
@@ -3480,27 +3554,27 @@ public final ConstantContext constant() throws RecognitionException {
_localctx = new StringArrayLiteralContext(_localctx);
enterOuterAlt(_localctx, 10);
{
- setState(429);
+ setState(436);
match(OPENING_BRACKET);
- setState(430);
+ setState(437);
string();
- setState(435);
+ setState(442);
_errHandler.sync(this);
_la = _input.LA(1);
while (_la==COMMA) {
{
{
- setState(431);
+ setState(438);
match(COMMA);
- setState(432);
+ setState(439);
string();
}
}
- setState(437);
+ setState(444);
_errHandler.sync(this);
_la = _input.LA(1);
}
- setState(438);
+ setState(445);
match(CLOSING_BRACKET);
}
break;
@@ -3524,7 +3598,7 @@ public ParameterContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_parameter; }
-
+
@SuppressWarnings("this-escape")
public ParameterContext() { }
public void copyFrom(ParameterContext ctx) {
@@ -3572,16 +3646,16 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ParameterContext parameter() throws RecognitionException {
ParameterContext _localctx = new ParameterContext(_ctx, getState());
- enterRule(_localctx, 64, RULE_parameter);
+ enterRule(_localctx, 66, RULE_parameter);
try {
- setState(444);
+ setState(451);
_errHandler.sync(this);
switch (_input.LA(1)) {
case PARAM:
_localctx = new InputParamContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(442);
+ setState(449);
match(PARAM);
}
break;
@@ -3589,7 +3663,7 @@ public final ParameterContext parameter() throws RecognitionException {
_localctx = new InputNamedOrPositionalParamContext(_localctx);
enterOuterAlt(_localctx, 2);
{
- setState(443);
+ setState(450);
match(NAMED_OR_POSITIONAL_PARAM);
}
break;
@@ -3638,16 +3712,16 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IdentifierOrParameterContext identifierOrParameter() throws RecognitionException {
IdentifierOrParameterContext _localctx = new IdentifierOrParameterContext(_ctx, getState());
- enterRule(_localctx, 66, RULE_identifierOrParameter);
+ enterRule(_localctx, 68, RULE_identifierOrParameter);
try {
- setState(448);
+ setState(455);
_errHandler.sync(this);
switch (_input.LA(1)) {
case UNQUOTED_IDENTIFIER:
case QUOTED_IDENTIFIER:
enterOuterAlt(_localctx, 1);
{
- setState(446);
+ setState(453);
identifier();
}
break;
@@ -3655,7 +3729,7 @@ public final IdentifierOrParameterContext identifierOrParameter() throws Recogni
case NAMED_OR_POSITIONAL_PARAM:
enterOuterAlt(_localctx, 2);
{
- setState(447);
+ setState(454);
parameter();
}
break;
@@ -3700,13 +3774,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final LimitCommandContext limitCommand() throws RecognitionException {
LimitCommandContext _localctx = new LimitCommandContext(_ctx, getState());
- enterRule(_localctx, 68, RULE_limitCommand);
+ enterRule(_localctx, 70, RULE_limitCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(450);
+ setState(457);
match(LIMIT);
- setState(451);
+ setState(458);
match(INTEGER_LITERAL);
}
}
@@ -3756,32 +3830,32 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final SortCommandContext sortCommand() throws RecognitionException {
SortCommandContext _localctx = new SortCommandContext(_ctx, getState());
- enterRule(_localctx, 70, RULE_sortCommand);
+ enterRule(_localctx, 72, RULE_sortCommand);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(453);
+ setState(460);
match(SORT);
- setState(454);
+ setState(461);
orderExpression();
- setState(459);
+ setState(466);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,42,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,43,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(455);
+ setState(462);
match(COMMA);
- setState(456);
+ setState(463);
orderExpression();
}
- }
+ }
}
- setState(461);
+ setState(468);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,42,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,43,_ctx);
}
}
}
@@ -3830,19 +3904,19 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final OrderExpressionContext orderExpression() throws RecognitionException {
OrderExpressionContext _localctx = new OrderExpressionContext(_ctx, getState());
- enterRule(_localctx, 72, RULE_orderExpression);
+ enterRule(_localctx, 74, RULE_orderExpression);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(462);
+ setState(469);
booleanExpression(0);
- setState(464);
+ setState(471);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,44,_ctx) ) {
case 1:
{
- setState(463);
+ setState(470);
((OrderExpressionContext)_localctx).ordering = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==ASC || _la==DESC) ) {
@@ -3856,14 +3930,14 @@ public final OrderExpressionContext orderExpression() throws RecognitionExceptio
}
break;
}
- setState(468);
+ setState(475);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,44,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,45,_ctx) ) {
case 1:
{
- setState(466);
+ setState(473);
match(NULLS);
- setState(467);
+ setState(474);
((OrderExpressionContext)_localctx).nullOrdering = _input.LT(1);
_la = _input.LA(1);
if ( !(_la==FIRST || _la==LAST) ) {
@@ -3918,13 +3992,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final KeepCommandContext keepCommand() throws RecognitionException {
KeepCommandContext _localctx = new KeepCommandContext(_ctx, getState());
- enterRule(_localctx, 74, RULE_keepCommand);
+ enterRule(_localctx, 76, RULE_keepCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(470);
+ setState(477);
match(KEEP);
- setState(471);
+ setState(478);
qualifiedNamePatterns();
}
}
@@ -3967,13 +4041,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DropCommandContext dropCommand() throws RecognitionException {
DropCommandContext _localctx = new DropCommandContext(_ctx, getState());
- enterRule(_localctx, 76, RULE_dropCommand);
+ enterRule(_localctx, 78, RULE_dropCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(473);
+ setState(480);
match(DROP);
- setState(474);
+ setState(481);
qualifiedNamePatterns();
}
}
@@ -4023,32 +4097,32 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final RenameCommandContext renameCommand() throws RecognitionException {
RenameCommandContext _localctx = new RenameCommandContext(_ctx, getState());
- enterRule(_localctx, 78, RULE_renameCommand);
+ enterRule(_localctx, 80, RULE_renameCommand);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(476);
+ setState(483);
match(RENAME);
- setState(477);
+ setState(484);
renameClause();
- setState(482);
+ setState(489);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,45,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,46,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(478);
+ setState(485);
match(COMMA);
- setState(479);
+ setState(486);
renameClause();
}
- }
+ }
}
- setState(484);
+ setState(491);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,45,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,46,_ctx);
}
}
}
@@ -4096,15 +4170,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final RenameClauseContext renameClause() throws RecognitionException {
RenameClauseContext _localctx = new RenameClauseContext(_ctx, getState());
- enterRule(_localctx, 80, RULE_renameClause);
+ enterRule(_localctx, 82, RULE_renameClause);
try {
enterOuterAlt(_localctx, 1);
{
- setState(485);
+ setState(492);
((RenameClauseContext)_localctx).oldName = qualifiedNamePattern();
- setState(486);
+ setState(493);
match(AS);
- setState(487);
+ setState(494);
((RenameClauseContext)_localctx).newName = qualifiedNamePattern();
}
}
@@ -4153,22 +4227,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DissectCommandContext dissectCommand() throws RecognitionException {
DissectCommandContext _localctx = new DissectCommandContext(_ctx, getState());
- enterRule(_localctx, 82, RULE_dissectCommand);
+ enterRule(_localctx, 84, RULE_dissectCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(489);
+ setState(496);
match(DISSECT);
- setState(490);
+ setState(497);
primaryExpression(0);
- setState(491);
+ setState(498);
string();
- setState(493);
+ setState(500);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,46,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) {
case 1:
{
- setState(492);
+ setState(499);
commandOptions();
}
break;
@@ -4217,15 +4291,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final GrokCommandContext grokCommand() throws RecognitionException {
GrokCommandContext _localctx = new GrokCommandContext(_ctx, getState());
- enterRule(_localctx, 84, RULE_grokCommand);
+ enterRule(_localctx, 86, RULE_grokCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(495);
+ setState(502);
match(GROK);
- setState(496);
+ setState(503);
primaryExpression(0);
- setState(497);
+ setState(504);
string();
}
}
@@ -4268,13 +4342,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final MvExpandCommandContext mvExpandCommand() throws RecognitionException {
MvExpandCommandContext _localctx = new MvExpandCommandContext(_ctx, getState());
- enterRule(_localctx, 86, RULE_mvExpandCommand);
+ enterRule(_localctx, 88, RULE_mvExpandCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(499);
+ setState(506);
match(MV_EXPAND);
- setState(500);
+ setState(507);
qualifiedName();
}
}
@@ -4323,30 +4397,30 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final CommandOptionsContext commandOptions() throws RecognitionException {
CommandOptionsContext _localctx = new CommandOptionsContext(_ctx, getState());
- enterRule(_localctx, 88, RULE_commandOptions);
+ enterRule(_localctx, 90, RULE_commandOptions);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(502);
+ setState(509);
commandOption();
- setState(507);
+ setState(514);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,47,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,48,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(503);
+ setState(510);
match(COMMA);
- setState(504);
+ setState(511);
commandOption();
}
- }
+ }
}
- setState(509);
+ setState(516);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,47,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,48,_ctx);
}
}
}
@@ -4392,15 +4466,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final CommandOptionContext commandOption() throws RecognitionException {
CommandOptionContext _localctx = new CommandOptionContext(_ctx, getState());
- enterRule(_localctx, 90, RULE_commandOption);
+ enterRule(_localctx, 92, RULE_commandOption);
try {
enterOuterAlt(_localctx, 1);
{
- setState(510);
+ setState(517);
identifier();
- setState(511);
+ setState(518);
match(ASSIGN);
- setState(512);
+ setState(519);
constant();
}
}
@@ -4441,12 +4515,12 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final BooleanValueContext booleanValue() throws RecognitionException {
BooleanValueContext _localctx = new BooleanValueContext(_ctx, getState());
- enterRule(_localctx, 92, RULE_booleanValue);
+ enterRule(_localctx, 94, RULE_booleanValue);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(514);
+ setState(521);
_la = _input.LA(1);
if ( !(_la==FALSE || _la==TRUE) ) {
_errHandler.recoverInline(this);
@@ -4499,22 +4573,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final NumericValueContext numericValue() throws RecognitionException {
NumericValueContext _localctx = new NumericValueContext(_ctx, getState());
- enterRule(_localctx, 94, RULE_numericValue);
+ enterRule(_localctx, 96, RULE_numericValue);
try {
- setState(518);
+ setState(525);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,48,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) {
case 1:
enterOuterAlt(_localctx, 1);
{
- setState(516);
+ setState(523);
decimalValue();
}
break;
case 2:
enterOuterAlt(_localctx, 2);
{
- setState(517);
+ setState(524);
integerValue();
}
break;
@@ -4558,17 +4632,17 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final DecimalValueContext decimalValue() throws RecognitionException {
DecimalValueContext _localctx = new DecimalValueContext(_ctx, getState());
- enterRule(_localctx, 96, RULE_decimalValue);
+ enterRule(_localctx, 98, RULE_decimalValue);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(521);
+ setState(528);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==PLUS || _la==MINUS) {
{
- setState(520);
+ setState(527);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
_errHandler.recoverInline(this);
@@ -4581,7 +4655,7 @@ public final DecimalValueContext decimalValue() throws RecognitionException {
}
}
- setState(523);
+ setState(530);
match(DECIMAL_LITERAL);
}
}
@@ -4623,17 +4697,17 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final IntegerValueContext integerValue() throws RecognitionException {
IntegerValueContext _localctx = new IntegerValueContext(_ctx, getState());
- enterRule(_localctx, 98, RULE_integerValue);
+ enterRule(_localctx, 100, RULE_integerValue);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(526);
+ setState(533);
_errHandler.sync(this);
_la = _input.LA(1);
if (_la==PLUS || _la==MINUS) {
{
- setState(525);
+ setState(532);
_la = _input.LA(1);
if ( !(_la==PLUS || _la==MINUS) ) {
_errHandler.recoverInline(this);
@@ -4646,7 +4720,7 @@ public final IntegerValueContext integerValue() throws RecognitionException {
}
}
- setState(528);
+ setState(535);
match(INTEGER_LITERAL);
}
}
@@ -4686,11 +4760,11 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final StringContext string() throws RecognitionException {
StringContext _localctx = new StringContext(_ctx, getState());
- enterRule(_localctx, 100, RULE_string);
+ enterRule(_localctx, 102, RULE_string);
try {
enterOuterAlt(_localctx, 1);
{
- setState(530);
+ setState(537);
match(QUOTED_STRING);
}
}
@@ -4735,14 +4809,14 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ComparisonOperatorContext comparisonOperator() throws RecognitionException {
ComparisonOperatorContext _localctx = new ComparisonOperatorContext(_ctx, getState());
- enterRule(_localctx, 102, RULE_comparisonOperator);
+ enterRule(_localctx, 104, RULE_comparisonOperator);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
- setState(532);
+ setState(539);
_la = _input.LA(1);
- if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 562949953421312000L) != 0)) ) {
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 281474976710656000L) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@@ -4791,13 +4865,13 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ExplainCommandContext explainCommand() throws RecognitionException {
ExplainCommandContext _localctx = new ExplainCommandContext(_ctx, getState());
- enterRule(_localctx, 104, RULE_explainCommand);
+ enterRule(_localctx, 106, RULE_explainCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(534);
+ setState(541);
match(EXPLAIN);
- setState(535);
+ setState(542);
subqueryExpression();
}
}
@@ -4841,15 +4915,15 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final SubqueryExpressionContext subqueryExpression() throws RecognitionException {
SubqueryExpressionContext _localctx = new SubqueryExpressionContext(_ctx, getState());
- enterRule(_localctx, 106, RULE_subqueryExpression);
+ enterRule(_localctx, 108, RULE_subqueryExpression);
try {
enterOuterAlt(_localctx, 1);
{
- setState(537);
+ setState(544);
match(OPENING_BRACKET);
- setState(538);
+ setState(545);
query(0);
- setState(539);
+ setState(546);
match(CLOSING_BRACKET);
}
}
@@ -4871,7 +4945,7 @@ public ShowCommandContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_showCommand; }
-
+
@SuppressWarnings("this-escape")
public ShowCommandContext() { }
public void copyFrom(ShowCommandContext ctx) {
@@ -4901,14 +4975,14 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final ShowCommandContext showCommand() throws RecognitionException {
ShowCommandContext _localctx = new ShowCommandContext(_ctx, getState());
- enterRule(_localctx, 108, RULE_showCommand);
+ enterRule(_localctx, 110, RULE_showCommand);
try {
_localctx = new ShowInfoContext(_localctx);
enterOuterAlt(_localctx, 1);
{
- setState(541);
+ setState(548);
match(SHOW);
- setState(542);
+ setState(549);
match(INFO);
}
}
@@ -4966,53 +5040,53 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final EnrichCommandContext enrichCommand() throws RecognitionException {
EnrichCommandContext _localctx = new EnrichCommandContext(_ctx, getState());
- enterRule(_localctx, 110, RULE_enrichCommand);
+ enterRule(_localctx, 112, RULE_enrichCommand);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
- setState(544);
+ setState(551);
match(ENRICH);
- setState(545);
+ setState(552);
((EnrichCommandContext)_localctx).policyName = match(ENRICH_POLICY_NAME);
- setState(548);
+ setState(555);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,52,_ctx) ) {
case 1:
{
- setState(546);
+ setState(553);
match(ON);
- setState(547);
+ setState(554);
((EnrichCommandContext)_localctx).matchField = qualifiedNamePattern();
}
break;
}
- setState(559);
+ setState(566);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,53,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) {
case 1:
{
- setState(550);
+ setState(557);
match(WITH);
- setState(551);
+ setState(558);
enrichWithClause();
- setState(556);
+ setState(563);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,52,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,53,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
{
{
- setState(552);
+ setState(559);
match(COMMA);
- setState(553);
+ setState(560);
enrichWithClause();
}
- }
+ }
}
- setState(558);
+ setState(565);
_errHandler.sync(this);
- _alt = getInterpreter().adaptivePredict(_input,52,_ctx);
+ _alt = getInterpreter().adaptivePredict(_input,53,_ctx);
}
}
break;
@@ -5063,23 +5137,23 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final EnrichWithClauseContext enrichWithClause() throws RecognitionException {
EnrichWithClauseContext _localctx = new EnrichWithClauseContext(_ctx, getState());
- enterRule(_localctx, 112, RULE_enrichWithClause);
+ enterRule(_localctx, 114, RULE_enrichWithClause);
try {
enterOuterAlt(_localctx, 1);
{
- setState(564);
+ setState(571);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,55,_ctx) ) {
case 1:
{
- setState(561);
+ setState(568);
((EnrichWithClauseContext)_localctx).newName = qualifiedNamePattern();
- setState(562);
+ setState(569);
match(ASSIGN);
}
break;
}
- setState(566);
+ setState(573);
((EnrichWithClauseContext)_localctx).enrichField = qualifiedNamePattern();
}
}
@@ -5128,17 +5202,17 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final LookupCommandContext lookupCommand() throws RecognitionException {
LookupCommandContext _localctx = new LookupCommandContext(_ctx, getState());
- enterRule(_localctx, 114, RULE_lookupCommand);
+ enterRule(_localctx, 116, RULE_lookupCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(568);
+ setState(575);
match(DEV_LOOKUP);
- setState(569);
+ setState(576);
((LookupCommandContext)_localctx).tableName = indexPattern();
- setState(570);
+ setState(577);
match(ON);
- setState(571);
+ setState(578);
((LookupCommandContext)_localctx).matchFields = qualifiedNamePatterns();
}
}
@@ -5187,22 +5261,22 @@ public T accept(ParseTreeVisitor extends T> visitor) {
public final InlinestatsCommandContext inlinestatsCommand() throws RecognitionException {
InlinestatsCommandContext _localctx = new InlinestatsCommandContext(_ctx, getState());
- enterRule(_localctx, 116, RULE_inlinestatsCommand);
+ enterRule(_localctx, 118, RULE_inlinestatsCommand);
try {
enterOuterAlt(_localctx, 1);
{
- setState(573);
+ setState(580);
match(DEV_INLINESTATS);
- setState(574);
+ setState(581);
((InlinestatsCommandContext)_localctx).stats = fields();
- setState(577);
+ setState(584);
_errHandler.sync(this);
- switch ( getInterpreter().adaptivePredict(_input,55,_ctx) ) {
+ switch ( getInterpreter().adaptivePredict(_input,56,_ctx) ) {
case 1:
{
- setState(575);
+ setState(582);
match(BY);
- setState(576);
+ setState(583);
((InlinestatsCommandContext)_localctx).grouping = fields();
}
break;
@@ -5234,6 +5308,8 @@ public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
return operatorExpression_sempred((OperatorExpressionContext)_localctx, predIndex);
case 10:
return primaryExpression_sempred((PrimaryExpressionContext)_localctx, predIndex);
+ case 12:
+ return functionName_sempred((FunctionNameContext)_localctx, predIndex);
}
return true;
}
@@ -5287,9 +5363,16 @@ private boolean primaryExpression_sempred(PrimaryExpressionContext _localctx, in
}
return true;
}
+ private boolean functionName_sempred(FunctionNameContext _localctx, int predIndex) {
+ switch (predIndex) {
+ case 10:
+ return this.isDevVersion();
+ }
+ return true;
+ }
public static final String _serializedATN =
- "\u0004\u0001x\u0244\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
+ "\u0004\u0001x\u024b\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"+
@@ -5304,360 +5387,361 @@ private boolean primaryExpression_sempred(PrimaryExpressionContext _localctx, in
"(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007+\u0002,\u0007,\u0002"+
"-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u00070\u00021\u00071\u0002"+
"2\u00072\u00023\u00073\u00024\u00074\u00025\u00075\u00026\u00076\u0002"+
- "7\u00077\u00028\u00078\u00029\u00079\u0002:\u0007:\u0001\u0000\u0001\u0000"+
- "\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
- "\u0001\u0001\u0005\u0001\u0080\b\u0001\n\u0001\f\u0001\u0083\t\u0001\u0001"+
- "\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0003"+
- "\u0002\u008b\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+
- "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+
- "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003"+
- "\u0003\u009d\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0005\u0001"+
- "\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003"+
- "\u0005\u00a9\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
- "\u0005\u0005\u0005\u00b0\b\u0005\n\u0005\f\u0005\u00b3\t\u0005\u0001\u0005"+
- "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00ba\b\u0005"+
- "\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003\u0005\u00c0\b\u0005"+
+ "7\u00077\u00028\u00078\u00029\u00079\u0002:\u0007:\u0002;\u0007;\u0001"+
+ "\u0000\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
+ "\u0001\u0001\u0001\u0001\u0001\u0005\u0001\u0082\b\u0001\n\u0001\f\u0001"+
+ "\u0085\t\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002"+
+ "\u0001\u0002\u0003\u0002\u008d\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+
+ "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
+ "\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+
+ "\u0001\u0003\u0003\u0003\u009f\b\u0003\u0001\u0004\u0001\u0004\u0001\u0004"+
"\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
- "\u0005\u0005\u00c8\b\u0005\n\u0005\f\u0005\u00cb\t\u0005\u0001\u0006\u0001"+
- "\u0006\u0003\u0006\u00cf\b\u0006\u0001\u0006\u0001\u0006\u0001\u0006\u0001"+
- "\u0006\u0001\u0006\u0003\u0006\u00d6\b\u0006\u0001\u0006\u0001\u0006\u0001"+
- "\u0006\u0003\u0006\u00db\b\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001"+
- "\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0003\b\u00e6\b\b\u0001"+
- "\t\u0001\t\u0001\t\u0001\t\u0003\t\u00ec\b\t\u0001\t\u0001\t\u0001\t\u0001"+
- "\t\u0001\t\u0001\t\u0005\t\u00f4\b\t\n\t\f\t\u00f7\t\t\u0001\n\u0001\n"+
- "\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003\n\u0101\b\n\u0001"+
- "\n\u0001\n\u0001\n\u0005\n\u0106\b\n\n\n\f\n\u0109\t\n\u0001\u000b\u0001"+
- "\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0005\u000b\u0111"+
- "\b\u000b\n\u000b\f\u000b\u0114\t\u000b\u0003\u000b\u0116\b\u000b\u0001"+
- "\u000b\u0001\u000b\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\u000e"+
- "\u0001\u000e\u0001\u000e\u0005\u000e\u0122\b\u000e\n\u000e\f\u000e\u0125"+
- "\t\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u000f\u0003"+
- "\u000f\u012c\b\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0005"+
- "\u0010\u0132\b\u0010\n\u0010\f\u0010\u0135\t\u0010\u0001\u0010\u0003\u0010"+
- "\u0138\b\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011"+
- "\u0003\u0011\u013f\b\u0011\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013"+
- "\u0001\u0014\u0001\u0014\u0003\u0014\u0147\b\u0014\u0001\u0015\u0001\u0015"+
- "\u0001\u0015\u0001\u0015\u0005\u0015\u014d\b\u0015\n\u0015\f\u0015\u0150"+
- "\t\u0015\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0016\u0001\u0017\u0001"+
- "\u0017\u0001\u0017\u0001\u0017\u0005\u0017\u015a\b\u0017\n\u0017\f\u0017"+
- "\u015d\t\u0017\u0001\u0017\u0003\u0017\u0160\b\u0017\u0001\u0017\u0001"+
- "\u0017\u0003\u0017\u0164\b\u0017\u0001\u0018\u0001\u0018\u0001\u0018\u0001"+
- "\u0019\u0001\u0019\u0003\u0019\u016b\b\u0019\u0001\u0019\u0001\u0019\u0003"+
- "\u0019\u016f\b\u0019\u0001\u001a\u0001\u001a\u0001\u001a\u0005\u001a\u0174"+
- "\b\u001a\n\u001a\f\u001a\u0177\t\u001a\u0001\u001b\u0001\u001b\u0001\u001b"+
- "\u0005\u001b\u017c\b\u001b\n\u001b\f\u001b\u017f\t\u001b\u0001\u001c\u0001"+
- "\u001c\u0001\u001c\u0005\u001c\u0184\b\u001c\n\u001c\f\u001c\u0187\t\u001c"+
- "\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0003\u001e\u018d\b\u001e"+
- "\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f"+
- "\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f"+
- "\u0001\u001f\u0005\u001f\u019c\b\u001f\n\u001f\f\u001f\u019f\t\u001f\u0001"+
- "\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0005"+
- "\u001f\u01a7\b\u001f\n\u001f\f\u001f\u01aa\t\u001f\u0001\u001f\u0001\u001f"+
- "\u0001\u001f\u0001\u001f\u0001\u001f\u0001\u001f\u0005\u001f\u01b2\b\u001f"+
- "\n\u001f\f\u001f\u01b5\t\u001f\u0001\u001f\u0001\u001f\u0003\u001f\u01b9"+
- "\b\u001f\u0001 \u0001 \u0003 \u01bd\b \u0001!\u0001!\u0003!\u01c1\b!\u0001"+
- "\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001#\u0005#\u01ca\b#\n#\f#\u01cd"+
- "\t#\u0001$\u0001$\u0003$\u01d1\b$\u0001$\u0001$\u0003$\u01d5\b$\u0001"+
- "%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001\'\u0005"+
- "\'\u01e1\b\'\n\'\f\'\u01e4\t\'\u0001(\u0001(\u0001(\u0001(\u0001)\u0001"+
- ")\u0001)\u0001)\u0003)\u01ee\b)\u0001*\u0001*\u0001*\u0001*\u0001+\u0001"+
- "+\u0001+\u0001,\u0001,\u0001,\u0005,\u01fa\b,\n,\f,\u01fd\t,\u0001-\u0001"+
- "-\u0001-\u0001-\u0001.\u0001.\u0001/\u0001/\u0003/\u0207\b/\u00010\u0003"+
- "0\u020a\b0\u00010\u00010\u00011\u00031\u020f\b1\u00011\u00011\u00012\u0001"+
- "2\u00013\u00013\u00014\u00014\u00014\u00015\u00015\u00015\u00015\u0001"+
- "6\u00016\u00016\u00017\u00017\u00017\u00017\u00037\u0225\b7\u00017\u0001"+
- "7\u00017\u00017\u00057\u022b\b7\n7\f7\u022e\t7\u00037\u0230\b7\u00018"+
- "\u00018\u00018\u00038\u0235\b8\u00018\u00018\u00019\u00019\u00019\u0001"+
- "9\u00019\u0001:\u0001:\u0001:\u0001:\u0003:\u0242\b:\u0001:\u0000\u0004"+
- "\u0002\n\u0012\u0014;\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012"+
- "\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJLNPRTVXZ\\"+
- "^`bdfhjlnprt\u0000\b\u0001\u0000;<\u0001\u0000=?\u0002\u0000\u001a\u001a"+
- "LL\u0001\u0000CD\u0002\u0000\u001f\u001f##\u0002\u0000&&))\u0002\u0000"+
- "%%33\u0002\u0000446:\u025e\u0000v\u0001\u0000\u0000\u0000\u0002y\u0001"+
- "\u0000\u0000\u0000\u0004\u008a\u0001\u0000\u0000\u0000\u0006\u009c\u0001"+
- "\u0000\u0000\u0000\b\u009e\u0001\u0000\u0000\u0000\n\u00bf\u0001\u0000"+
- "\u0000\u0000\f\u00da\u0001\u0000\u0000\u0000\u000e\u00dc\u0001\u0000\u0000"+
- "\u0000\u0010\u00e5\u0001\u0000\u0000\u0000\u0012\u00eb\u0001\u0000\u0000"+
- "\u0000\u0014\u0100\u0001\u0000\u0000\u0000\u0016\u010a\u0001\u0000\u0000"+
- "\u0000\u0018\u0119\u0001\u0000\u0000\u0000\u001a\u011b\u0001\u0000\u0000"+
- "\u0000\u001c\u011e\u0001\u0000\u0000\u0000\u001e\u012b\u0001\u0000\u0000"+
- "\u0000 \u012d\u0001\u0000\u0000\u0000\"\u013e\u0001\u0000\u0000\u0000"+
- "$\u0140\u0001\u0000\u0000\u0000&\u0142\u0001\u0000\u0000\u0000(\u0146"+
- "\u0001\u0000\u0000\u0000*\u0148\u0001\u0000\u0000\u0000,\u0151\u0001\u0000"+
- "\u0000\u0000.\u0155\u0001\u0000\u0000\u00000\u0165\u0001\u0000\u0000\u0000"+
- "2\u0168\u0001\u0000\u0000\u00004\u0170\u0001\u0000\u0000\u00006\u0178"+
- "\u0001\u0000\u0000\u00008\u0180\u0001\u0000\u0000\u0000:\u0188\u0001\u0000"+
- "\u0000\u0000<\u018c\u0001\u0000\u0000\u0000>\u01b8\u0001\u0000\u0000\u0000"+
- "@\u01bc\u0001\u0000\u0000\u0000B\u01c0\u0001\u0000\u0000\u0000D\u01c2"+
- "\u0001\u0000\u0000\u0000F\u01c5\u0001\u0000\u0000\u0000H\u01ce\u0001\u0000"+
- "\u0000\u0000J\u01d6\u0001\u0000\u0000\u0000L\u01d9\u0001\u0000\u0000\u0000"+
- "N\u01dc\u0001\u0000\u0000\u0000P\u01e5\u0001\u0000\u0000\u0000R\u01e9"+
- "\u0001\u0000\u0000\u0000T\u01ef\u0001\u0000\u0000\u0000V\u01f3\u0001\u0000"+
- "\u0000\u0000X\u01f6\u0001\u0000\u0000\u0000Z\u01fe\u0001\u0000\u0000\u0000"+
- "\\\u0202\u0001\u0000\u0000\u0000^\u0206\u0001\u0000\u0000\u0000`\u0209"+
- "\u0001\u0000\u0000\u0000b\u020e\u0001\u0000\u0000\u0000d\u0212\u0001\u0000"+
- "\u0000\u0000f\u0214\u0001\u0000\u0000\u0000h\u0216\u0001\u0000\u0000\u0000"+
- "j\u0219\u0001\u0000\u0000\u0000l\u021d\u0001\u0000\u0000\u0000n\u0220"+
- "\u0001\u0000\u0000\u0000p\u0234\u0001\u0000\u0000\u0000r\u0238\u0001\u0000"+
- "\u0000\u0000t\u023d\u0001\u0000\u0000\u0000vw\u0003\u0002\u0001\u0000"+
- "wx\u0005\u0000\u0000\u0001x\u0001\u0001\u0000\u0000\u0000yz\u0006\u0001"+
- "\uffff\uffff\u0000z{\u0003\u0004\u0002\u0000{\u0081\u0001\u0000\u0000"+
- "\u0000|}\n\u0001\u0000\u0000}~\u0005\u0019\u0000\u0000~\u0080\u0003\u0006"+
- "\u0003\u0000\u007f|\u0001\u0000\u0000\u0000\u0080\u0083\u0001\u0000\u0000"+
- "\u0000\u0081\u007f\u0001\u0000\u0000\u0000\u0081\u0082\u0001\u0000\u0000"+
- "\u0000\u0082\u0003\u0001\u0000\u0000\u0000\u0083\u0081\u0001\u0000\u0000"+
- "\u0000\u0084\u008b\u0003h4\u0000\u0085\u008b\u0003 \u0010\u0000\u0086"+
- "\u008b\u0003\u001a\r\u0000\u0087\u008b\u0003l6\u0000\u0088\u0089\u0004"+
- "\u0002\u0001\u0000\u0089\u008b\u0003.\u0017\u0000\u008a\u0084\u0001\u0000"+
- "\u0000\u0000\u008a\u0085\u0001\u0000\u0000\u0000\u008a\u0086\u0001\u0000"+
- "\u0000\u0000\u008a\u0087\u0001\u0000\u0000\u0000\u008a\u0088\u0001\u0000"+
- "\u0000\u0000\u008b\u0005\u0001\u0000\u0000\u0000\u008c\u009d\u00030\u0018"+
- "\u0000\u008d\u009d\u0003\b\u0004\u0000\u008e\u009d\u0003J%\u0000\u008f"+
- "\u009d\u0003D\"\u0000\u0090\u009d\u00032\u0019\u0000\u0091\u009d\u0003"+
- "F#\u0000\u0092\u009d\u0003L&\u0000\u0093\u009d\u0003N\'\u0000\u0094\u009d"+
- "\u0003R)\u0000\u0095\u009d\u0003T*\u0000\u0096\u009d\u0003n7\u0000\u0097"+
- "\u009d\u0003V+\u0000\u0098\u0099\u0004\u0003\u0002\u0000\u0099\u009d\u0003"+
- "t:\u0000\u009a\u009b\u0004\u0003\u0003\u0000\u009b\u009d\u0003r9\u0000"+
- "\u009c\u008c\u0001\u0000\u0000\u0000\u009c\u008d\u0001\u0000\u0000\u0000"+
- "\u009c\u008e\u0001\u0000\u0000\u0000\u009c\u008f\u0001\u0000\u0000\u0000"+
- "\u009c\u0090\u0001\u0000\u0000\u0000\u009c\u0091\u0001\u0000\u0000\u0000"+
- "\u009c\u0092\u0001\u0000\u0000\u0000\u009c\u0093\u0001\u0000\u0000\u0000"+
- "\u009c\u0094\u0001\u0000\u0000\u0000\u009c\u0095\u0001\u0000\u0000\u0000"+
- "\u009c\u0096\u0001\u0000\u0000\u0000\u009c\u0097\u0001\u0000\u0000\u0000"+
- "\u009c\u0098\u0001\u0000\u0000\u0000\u009c\u009a\u0001\u0000\u0000\u0000"+
- "\u009d\u0007\u0001\u0000\u0000\u0000\u009e\u009f\u0005\u0010\u0000\u0000"+
- "\u009f\u00a0\u0003\n\u0005\u0000\u00a0\t\u0001\u0000\u0000\u0000\u00a1"+
- "\u00a2\u0006\u0005\uffff\uffff\u0000\u00a2\u00a3\u0005,\u0000\u0000\u00a3"+
- "\u00c0\u0003\n\u0005\b\u00a4\u00c0\u0003\u0010\b\u0000\u00a5\u00c0\u0003"+
- "\f\u0006\u0000\u00a6\u00a8\u0003\u0010\b\u0000\u00a7\u00a9\u0005,\u0000"+
- "\u0000\u00a8\u00a7\u0001\u0000\u0000\u0000\u00a8\u00a9\u0001\u0000\u0000"+
- "\u0000\u00a9\u00aa\u0001\u0000\u0000\u0000\u00aa\u00ab\u0005\'\u0000\u0000"+
- "\u00ab\u00ac\u0005+\u0000\u0000\u00ac\u00b1\u0003\u0010\b\u0000\u00ad"+
- "\u00ae\u0005\"\u0000\u0000\u00ae\u00b0\u0003\u0010\b\u0000\u00af\u00ad"+
- "\u0001\u0000\u0000\u0000\u00b0\u00b3\u0001\u0000\u0000\u0000\u00b1\u00af"+
- "\u0001\u0000\u0000\u0000\u00b1\u00b2\u0001\u0000\u0000\u0000\u00b2\u00b4"+
- "\u0001\u0000\u0000\u0000\u00b3\u00b1\u0001\u0000\u0000\u0000\u00b4\u00b5"+
- "\u00052\u0000\u0000\u00b5\u00c0\u0001\u0000\u0000\u0000\u00b6\u00b7\u0003"+
- "\u0010\b\u0000\u00b7\u00b9\u0005(\u0000\u0000\u00b8\u00ba\u0005,\u0000"+
- "\u0000\u00b9\u00b8\u0001\u0000\u0000\u0000\u00b9\u00ba\u0001\u0000\u0000"+
- "\u0000\u00ba\u00bb\u0001\u0000\u0000\u0000\u00bb\u00bc\u0005-\u0000\u0000"+
- "\u00bc\u00c0\u0001\u0000\u0000\u0000\u00bd\u00be\u0004\u0005\u0004\u0000"+
- "\u00be\u00c0\u0003\u000e\u0007\u0000\u00bf\u00a1\u0001\u0000\u0000\u0000"+
- "\u00bf\u00a4\u0001\u0000\u0000\u0000\u00bf\u00a5\u0001\u0000\u0000\u0000"+
- "\u00bf\u00a6\u0001\u0000\u0000\u0000\u00bf\u00b6\u0001\u0000\u0000\u0000"+
- "\u00bf\u00bd\u0001\u0000\u0000\u0000\u00c0\u00c9\u0001\u0000\u0000\u0000"+
- "\u00c1\u00c2\n\u0005\u0000\u0000\u00c2\u00c3\u0005\u001e\u0000\u0000\u00c3"+
- "\u00c8\u0003\n\u0005\u0006\u00c4\u00c5\n\u0004\u0000\u0000\u00c5\u00c6"+
- "\u0005/\u0000\u0000\u00c6\u00c8\u0003\n\u0005\u0005\u00c7\u00c1\u0001"+
- "\u0000\u0000\u0000\u00c7\u00c4\u0001\u0000\u0000\u0000\u00c8\u00cb\u0001"+
- "\u0000\u0000\u0000\u00c9\u00c7\u0001\u0000\u0000\u0000\u00c9\u00ca\u0001"+
- "\u0000\u0000\u0000\u00ca\u000b\u0001\u0000\u0000\u0000\u00cb\u00c9\u0001"+
- "\u0000\u0000\u0000\u00cc\u00ce\u0003\u0010\b\u0000\u00cd\u00cf\u0005,"+
- "\u0000\u0000\u00ce\u00cd\u0001\u0000\u0000\u0000\u00ce\u00cf\u0001\u0000"+
- "\u0000\u0000\u00cf\u00d0\u0001\u0000\u0000\u0000\u00d0\u00d1\u0005*\u0000"+
- "\u0000\u00d1\u00d2\u0003d2\u0000\u00d2\u00db\u0001\u0000\u0000\u0000\u00d3"+
- "\u00d5\u0003\u0010\b\u0000\u00d4\u00d6\u0005,\u0000\u0000\u00d5\u00d4"+
- "\u0001\u0000\u0000\u0000\u00d5\u00d6\u0001\u0000\u0000\u0000\u00d6\u00d7"+
- "\u0001\u0000\u0000\u0000\u00d7\u00d8\u00051\u0000\u0000\u00d8\u00d9\u0003"+
- "d2\u0000\u00d9\u00db\u0001\u0000\u0000\u0000\u00da\u00cc\u0001\u0000\u0000"+
- "\u0000\u00da\u00d3\u0001\u0000\u0000\u0000\u00db\r\u0001\u0000\u0000\u0000"+
- "\u00dc\u00dd\u0003\u0010\b\u0000\u00dd\u00de\u0005\u0013\u0000\u0000\u00de"+
- "\u00df\u0003d2\u0000\u00df\u000f\u0001\u0000\u0000\u0000\u00e0\u00e6\u0003"+
- "\u0012\t\u0000\u00e1\u00e2\u0003\u0012\t\u0000\u00e2\u00e3\u0003f3\u0000"+
- "\u00e3\u00e4\u0003\u0012\t\u0000\u00e4\u00e6\u0001\u0000\u0000\u0000\u00e5"+
- "\u00e0\u0001\u0000\u0000\u0000\u00e5\u00e1\u0001\u0000\u0000\u0000\u00e6"+
- "\u0011\u0001\u0000\u0000\u0000\u00e7\u00e8\u0006\t\uffff\uffff\u0000\u00e8"+
- "\u00ec\u0003\u0014\n\u0000\u00e9\u00ea\u0007\u0000\u0000\u0000\u00ea\u00ec"+
- "\u0003\u0012\t\u0003\u00eb\u00e7\u0001\u0000\u0000\u0000\u00eb\u00e9\u0001"+
- "\u0000\u0000\u0000\u00ec\u00f5\u0001\u0000\u0000\u0000\u00ed\u00ee\n\u0002"+
- "\u0000\u0000\u00ee\u00ef\u0007\u0001\u0000\u0000\u00ef\u00f4\u0003\u0012"+
- "\t\u0003\u00f0\u00f1\n\u0001\u0000\u0000\u00f1\u00f2\u0007\u0000\u0000"+
- "\u0000\u00f2\u00f4\u0003\u0012\t\u0002\u00f3\u00ed\u0001\u0000\u0000\u0000"+
- "\u00f3\u00f0\u0001\u0000\u0000\u0000\u00f4\u00f7\u0001\u0000\u0000\u0000"+
- "\u00f5\u00f3\u0001\u0000\u0000\u0000\u00f5\u00f6\u0001\u0000\u0000\u0000"+
- "\u00f6\u0013\u0001\u0000\u0000\u0000\u00f7\u00f5\u0001\u0000\u0000\u0000"+
- "\u00f8\u00f9\u0006\n\uffff\uffff\u0000\u00f9\u0101\u0003>\u001f\u0000"+
- "\u00fa\u0101\u00034\u001a\u0000\u00fb\u0101\u0003\u0016\u000b\u0000\u00fc"+
- "\u00fd\u0005+\u0000\u0000\u00fd\u00fe\u0003\n\u0005\u0000\u00fe\u00ff"+
- "\u00052\u0000\u0000\u00ff\u0101\u0001\u0000\u0000\u0000\u0100\u00f8\u0001"+
- "\u0000\u0000\u0000\u0100\u00fa\u0001\u0000\u0000\u0000\u0100\u00fb\u0001"+
- "\u0000\u0000\u0000\u0100\u00fc\u0001\u0000\u0000\u0000\u0101\u0107\u0001"+
- "\u0000\u0000\u0000\u0102\u0103\n\u0001\u0000\u0000\u0103\u0104\u0005!"+
- "\u0000\u0000\u0104\u0106\u0003\u0018\f\u0000\u0105\u0102\u0001\u0000\u0000"+
- "\u0000\u0106\u0109\u0001\u0000\u0000\u0000\u0107\u0105\u0001\u0000\u0000"+
- "\u0000\u0107\u0108\u0001\u0000\u0000\u0000\u0108\u0015\u0001\u0000\u0000"+
- "\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u010a\u010b\u0003B!\u0000\u010b"+
- "\u0115\u0005+\u0000\u0000\u010c\u0116\u0005=\u0000\u0000\u010d\u0112\u0003"+
- "\n\u0005\u0000\u010e\u010f\u0005\"\u0000\u0000\u010f\u0111\u0003\n\u0005"+
- "\u0000\u0110\u010e\u0001\u0000\u0000\u0000\u0111\u0114\u0001\u0000\u0000"+
- "\u0000\u0112\u0110\u0001\u0000\u0000\u0000\u0112\u0113\u0001\u0000\u0000"+
- "\u0000\u0113\u0116\u0001\u0000\u0000\u0000\u0114\u0112\u0001\u0000\u0000"+
- "\u0000\u0115\u010c\u0001\u0000\u0000\u0000\u0115\u010d\u0001\u0000\u0000"+
- "\u0000\u0115\u0116\u0001\u0000\u0000\u0000\u0116\u0117\u0001\u0000\u0000"+
- "\u0000\u0117\u0118\u00052\u0000\u0000\u0118\u0017\u0001\u0000\u0000\u0000"+
- "\u0119\u011a\u0003:\u001d\u0000\u011a\u0019\u0001\u0000\u0000\u0000\u011b"+
- "\u011c\u0005\f\u0000\u0000\u011c\u011d\u0003\u001c\u000e\u0000\u011d\u001b"+
- "\u0001\u0000\u0000\u0000\u011e\u0123\u0003\u001e\u000f\u0000\u011f\u0120"+
- "\u0005\"\u0000\u0000\u0120\u0122\u0003\u001e\u000f\u0000\u0121\u011f\u0001"+
- "\u0000\u0000\u0000\u0122\u0125\u0001\u0000\u0000\u0000\u0123\u0121\u0001"+
- "\u0000\u0000\u0000\u0123\u0124\u0001\u0000\u0000\u0000\u0124\u001d\u0001"+
- "\u0000\u0000\u0000\u0125\u0123\u0001\u0000\u0000\u0000\u0126\u012c\u0003"+
- "\n\u0005\u0000\u0127\u0128\u00034\u001a\u0000\u0128\u0129\u0005 \u0000"+
- "\u0000\u0129\u012a\u0003\n\u0005\u0000\u012a\u012c\u0001\u0000\u0000\u0000"+
- "\u012b\u0126\u0001\u0000\u0000\u0000\u012b\u0127\u0001\u0000\u0000\u0000"+
- "\u012c\u001f\u0001\u0000\u0000\u0000\u012d\u012e\u0005\u0006\u0000\u0000"+
- "\u012e\u0133\u0003\"\u0011\u0000\u012f\u0130\u0005\"\u0000\u0000\u0130"+
- "\u0132\u0003\"\u0011\u0000\u0131\u012f\u0001\u0000\u0000\u0000\u0132\u0135"+
- "\u0001\u0000\u0000\u0000\u0133\u0131\u0001\u0000\u0000\u0000\u0133\u0134"+
- "\u0001\u0000\u0000\u0000\u0134\u0137\u0001\u0000\u0000\u0000\u0135\u0133"+
- "\u0001\u0000\u0000\u0000\u0136\u0138\u0003(\u0014\u0000\u0137\u0136\u0001"+
- "\u0000\u0000\u0000\u0137\u0138\u0001\u0000\u0000\u0000\u0138!\u0001\u0000"+
- "\u0000\u0000\u0139\u013a\u0003$\u0012\u0000\u013a\u013b\u0005h\u0000\u0000"+
- "\u013b\u013c\u0003&\u0013\u0000\u013c\u013f\u0001\u0000\u0000\u0000\u013d"+
- "\u013f\u0003&\u0013\u0000\u013e\u0139\u0001\u0000\u0000\u0000\u013e\u013d"+
- "\u0001\u0000\u0000\u0000\u013f#\u0001\u0000\u0000\u0000\u0140\u0141\u0005"+
- "L\u0000\u0000\u0141%\u0001\u0000\u0000\u0000\u0142\u0143\u0007\u0002\u0000"+
- "\u0000\u0143\'\u0001\u0000\u0000\u0000\u0144\u0147\u0003*\u0015\u0000"+
- "\u0145\u0147\u0003,\u0016\u0000\u0146\u0144\u0001\u0000\u0000\u0000\u0146"+
- "\u0145\u0001\u0000\u0000\u0000\u0147)\u0001\u0000\u0000\u0000\u0148\u0149"+
- "\u0005K\u0000\u0000\u0149\u014e\u0005L\u0000\u0000\u014a\u014b\u0005\""+
- "\u0000\u0000\u014b\u014d\u0005L\u0000\u0000\u014c\u014a\u0001\u0000\u0000"+
- "\u0000\u014d\u0150\u0001\u0000\u0000\u0000\u014e\u014c\u0001\u0000\u0000"+
- "\u0000\u014e\u014f\u0001\u0000\u0000\u0000\u014f+\u0001\u0000\u0000\u0000"+
- "\u0150\u014e\u0001\u0000\u0000\u0000\u0151\u0152\u0005A\u0000\u0000\u0152"+
- "\u0153\u0003*\u0015\u0000\u0153\u0154\u0005B\u0000\u0000\u0154-\u0001"+
- "\u0000\u0000\u0000\u0155\u0156\u0005\u0014\u0000\u0000\u0156\u015b\u0003"+
- "\"\u0011\u0000\u0157\u0158\u0005\"\u0000\u0000\u0158\u015a\u0003\"\u0011"+
- "\u0000\u0159\u0157\u0001\u0000\u0000\u0000\u015a\u015d\u0001\u0000\u0000"+
- "\u0000\u015b\u0159\u0001\u0000\u0000\u0000\u015b\u015c\u0001\u0000\u0000"+
- "\u0000\u015c\u015f\u0001\u0000\u0000\u0000\u015d\u015b\u0001\u0000\u0000"+
- "\u0000\u015e\u0160\u0003\u001c\u000e\u0000\u015f\u015e\u0001\u0000\u0000"+
- "\u0000\u015f\u0160\u0001\u0000\u0000\u0000\u0160\u0163\u0001\u0000\u0000"+
- "\u0000\u0161\u0162\u0005\u001d\u0000\u0000\u0162\u0164\u0003\u001c\u000e"+
- "\u0000\u0163\u0161\u0001\u0000\u0000\u0000\u0163\u0164\u0001\u0000\u0000"+
- "\u0000\u0164/\u0001\u0000\u0000\u0000\u0165\u0166\u0005\u0004\u0000\u0000"+
- "\u0166\u0167\u0003\u001c\u000e\u0000\u01671\u0001\u0000\u0000\u0000\u0168"+
- "\u016a\u0005\u000f\u0000\u0000\u0169\u016b\u0003\u001c\u000e\u0000\u016a"+
- "\u0169\u0001\u0000\u0000\u0000\u016a\u016b\u0001\u0000\u0000\u0000\u016b"+
- "\u016e\u0001\u0000\u0000\u0000\u016c\u016d\u0005\u001d\u0000\u0000\u016d"+
- "\u016f\u0003\u001c\u000e\u0000\u016e\u016c\u0001\u0000\u0000\u0000\u016e"+
- "\u016f\u0001\u0000\u0000\u0000\u016f3\u0001\u0000\u0000\u0000\u0170\u0175"+
- "\u0003B!\u0000\u0171\u0172\u0005$\u0000\u0000\u0172\u0174\u0003B!\u0000"+
- "\u0173\u0171\u0001\u0000\u0000\u0000\u0174\u0177\u0001\u0000\u0000\u0000"+
- "\u0175\u0173\u0001\u0000\u0000\u0000\u0175\u0176\u0001\u0000\u0000\u0000"+
- "\u01765\u0001\u0000\u0000\u0000\u0177\u0175\u0001\u0000\u0000\u0000\u0178"+
- "\u017d\u0003<\u001e\u0000\u0179\u017a\u0005$\u0000\u0000\u017a\u017c\u0003"+
- "<\u001e\u0000\u017b\u0179\u0001\u0000\u0000\u0000\u017c\u017f\u0001\u0000"+
- "\u0000\u0000\u017d\u017b\u0001\u0000\u0000\u0000\u017d\u017e\u0001\u0000"+
- "\u0000\u0000\u017e7\u0001\u0000\u0000\u0000\u017f\u017d\u0001\u0000\u0000"+
- "\u0000\u0180\u0185\u00036\u001b\u0000\u0181\u0182\u0005\"\u0000\u0000"+
- "\u0182\u0184\u00036\u001b\u0000\u0183\u0181\u0001\u0000\u0000\u0000\u0184"+
- "\u0187\u0001\u0000\u0000\u0000\u0185\u0183\u0001\u0000\u0000\u0000\u0185"+
- "\u0186\u0001\u0000\u0000\u0000\u01869\u0001\u0000\u0000\u0000\u0187\u0185"+
- "\u0001\u0000\u0000\u0000\u0188\u0189\u0007\u0003\u0000\u0000\u0189;\u0001"+
- "\u0000\u0000\u0000\u018a\u018d\u0005P\u0000\u0000\u018b\u018d\u0003@ "+
- "\u0000\u018c\u018a\u0001\u0000\u0000\u0000\u018c\u018b\u0001\u0000\u0000"+
- "\u0000\u018d=\u0001\u0000\u0000\u0000\u018e\u01b9\u0005-\u0000\u0000\u018f"+
- "\u0190\u0003b1\u0000\u0190\u0191\u0005C\u0000\u0000\u0191\u01b9\u0001"+
- "\u0000\u0000\u0000\u0192\u01b9\u0003`0\u0000\u0193\u01b9\u0003b1\u0000"+
- "\u0194\u01b9\u0003\\.\u0000\u0195\u01b9\u0003@ \u0000\u0196\u01b9\u0003"+
- "d2\u0000\u0197\u0198\u0005A\u0000\u0000\u0198\u019d\u0003^/\u0000\u0199"+
- "\u019a\u0005\"\u0000\u0000\u019a\u019c\u0003^/\u0000\u019b\u0199\u0001"+
- "\u0000\u0000\u0000\u019c\u019f\u0001\u0000\u0000\u0000\u019d\u019b\u0001"+
- "\u0000\u0000\u0000\u019d\u019e\u0001\u0000\u0000\u0000\u019e\u01a0\u0001"+
- "\u0000\u0000\u0000\u019f\u019d\u0001\u0000\u0000\u0000\u01a0\u01a1\u0005"+
- "B\u0000\u0000\u01a1\u01b9\u0001\u0000\u0000\u0000\u01a2\u01a3\u0005A\u0000"+
- "\u0000\u01a3\u01a8\u0003\\.\u0000\u01a4\u01a5\u0005\"\u0000\u0000\u01a5"+
- "\u01a7\u0003\\.\u0000\u01a6\u01a4\u0001\u0000\u0000\u0000\u01a7\u01aa"+
- "\u0001\u0000\u0000\u0000\u01a8\u01a6\u0001\u0000\u0000\u0000\u01a8\u01a9"+
- "\u0001\u0000\u0000\u0000\u01a9\u01ab\u0001\u0000\u0000\u0000\u01aa\u01a8"+
- "\u0001\u0000\u0000\u0000\u01ab\u01ac\u0005B\u0000\u0000\u01ac\u01b9\u0001"+
- "\u0000\u0000\u0000\u01ad\u01ae\u0005A\u0000\u0000\u01ae\u01b3\u0003d2"+
- "\u0000\u01af\u01b0\u0005\"\u0000\u0000\u01b0\u01b2\u0003d2\u0000\u01b1"+
- "\u01af\u0001\u0000\u0000\u0000\u01b2\u01b5\u0001\u0000\u0000\u0000\u01b3"+
- "\u01b1\u0001\u0000\u0000\u0000\u01b3\u01b4\u0001\u0000\u0000\u0000\u01b4"+
- "\u01b6\u0001\u0000\u0000\u0000\u01b5\u01b3\u0001\u0000\u0000\u0000\u01b6"+
- "\u01b7\u0005B\u0000\u0000\u01b7\u01b9\u0001\u0000\u0000\u0000\u01b8\u018e"+
- "\u0001\u0000\u0000\u0000\u01b8\u018f\u0001\u0000\u0000\u0000\u01b8\u0192"+
- "\u0001\u0000\u0000\u0000\u01b8\u0193\u0001\u0000\u0000\u0000\u01b8\u0194"+
- "\u0001\u0000\u0000\u0000\u01b8\u0195\u0001\u0000\u0000\u0000\u01b8\u0196"+
- "\u0001\u0000\u0000\u0000\u01b8\u0197\u0001\u0000\u0000\u0000\u01b8\u01a2"+
- "\u0001\u0000\u0000\u0000\u01b8\u01ad\u0001\u0000\u0000\u0000\u01b9?\u0001"+
- "\u0000\u0000\u0000\u01ba\u01bd\u00050\u0000\u0000\u01bb\u01bd\u0005@\u0000"+
- "\u0000\u01bc\u01ba\u0001\u0000\u0000\u0000\u01bc\u01bb\u0001\u0000\u0000"+
- "\u0000\u01bdA\u0001\u0000\u0000\u0000\u01be\u01c1\u0003:\u001d\u0000\u01bf"+
- "\u01c1\u0003@ \u0000\u01c0\u01be\u0001\u0000\u0000\u0000\u01c0\u01bf\u0001"+
- "\u0000\u0000\u0000\u01c1C\u0001\u0000\u0000\u0000\u01c2\u01c3\u0005\t"+
- "\u0000\u0000\u01c3\u01c4\u0005\u001b\u0000\u0000\u01c4E\u0001\u0000\u0000"+
- "\u0000\u01c5\u01c6\u0005\u000e\u0000\u0000\u01c6\u01cb\u0003H$\u0000\u01c7"+
- "\u01c8\u0005\"\u0000\u0000\u01c8\u01ca\u0003H$\u0000\u01c9\u01c7\u0001"+
- "\u0000\u0000\u0000\u01ca\u01cd\u0001\u0000\u0000\u0000\u01cb\u01c9\u0001"+
- "\u0000\u0000\u0000\u01cb\u01cc\u0001\u0000\u0000\u0000\u01ccG\u0001\u0000"+
- "\u0000\u0000\u01cd\u01cb\u0001\u0000\u0000\u0000\u01ce\u01d0\u0003\n\u0005"+
- "\u0000\u01cf\u01d1\u0007\u0004\u0000\u0000\u01d0\u01cf\u0001\u0000\u0000"+
- "\u0000\u01d0\u01d1\u0001\u0000\u0000\u0000\u01d1\u01d4\u0001\u0000\u0000"+
- "\u0000\u01d2\u01d3\u0005.\u0000\u0000\u01d3\u01d5\u0007\u0005\u0000\u0000"+
- "\u01d4\u01d2\u0001\u0000\u0000\u0000\u01d4\u01d5\u0001\u0000\u0000\u0000"+
- "\u01d5I\u0001\u0000\u0000\u0000\u01d6\u01d7\u0005\b\u0000\u0000\u01d7"+
- "\u01d8\u00038\u001c\u0000\u01d8K\u0001\u0000\u0000\u0000\u01d9\u01da\u0005"+
- "\u0002\u0000\u0000\u01da\u01db\u00038\u001c\u0000\u01dbM\u0001\u0000\u0000"+
- "\u0000\u01dc\u01dd\u0005\u000b\u0000\u0000\u01dd\u01e2\u0003P(\u0000\u01de"+
- "\u01df\u0005\"\u0000\u0000\u01df\u01e1\u0003P(\u0000\u01e0\u01de\u0001"+
- "\u0000\u0000\u0000\u01e1\u01e4\u0001\u0000\u0000\u0000\u01e2\u01e0\u0001"+
- "\u0000\u0000\u0000\u01e2\u01e3\u0001\u0000\u0000\u0000\u01e3O\u0001\u0000"+
- "\u0000\u0000\u01e4\u01e2\u0001\u0000\u0000\u0000\u01e5\u01e6\u00036\u001b"+
- "\u0000\u01e6\u01e7\u0005T\u0000\u0000\u01e7\u01e8\u00036\u001b\u0000\u01e8"+
- "Q\u0001\u0000\u0000\u0000\u01e9\u01ea\u0005\u0001\u0000\u0000\u01ea\u01eb"+
- "\u0003\u0014\n\u0000\u01eb\u01ed\u0003d2\u0000\u01ec\u01ee\u0003X,\u0000"+
- "\u01ed\u01ec\u0001\u0000\u0000\u0000\u01ed\u01ee\u0001\u0000\u0000\u0000"+
- "\u01eeS\u0001\u0000\u0000\u0000\u01ef\u01f0\u0005\u0007\u0000\u0000\u01f0"+
- "\u01f1\u0003\u0014\n\u0000\u01f1\u01f2\u0003d2\u0000\u01f2U\u0001\u0000"+
- "\u0000\u0000\u01f3\u01f4\u0005\n\u0000\u0000\u01f4\u01f5\u00034\u001a"+
- "\u0000\u01f5W\u0001\u0000\u0000\u0000\u01f6\u01fb\u0003Z-\u0000\u01f7"+
- "\u01f8\u0005\"\u0000\u0000\u01f8\u01fa\u0003Z-\u0000\u01f9\u01f7\u0001"+
- "\u0000\u0000\u0000\u01fa\u01fd\u0001\u0000\u0000\u0000\u01fb\u01f9\u0001"+
- "\u0000\u0000\u0000\u01fb\u01fc\u0001\u0000\u0000\u0000\u01fcY\u0001\u0000"+
- "\u0000\u0000\u01fd\u01fb\u0001\u0000\u0000\u0000\u01fe\u01ff\u0003:\u001d"+
- "\u0000\u01ff\u0200\u0005 \u0000\u0000\u0200\u0201\u0003>\u001f\u0000\u0201"+
- "[\u0001\u0000\u0000\u0000\u0202\u0203\u0007\u0006\u0000\u0000\u0203]\u0001"+
- "\u0000\u0000\u0000\u0204\u0207\u0003`0\u0000\u0205\u0207\u0003b1\u0000"+
- "\u0206\u0204\u0001\u0000\u0000\u0000\u0206\u0205\u0001\u0000\u0000\u0000"+
- "\u0207_\u0001\u0000\u0000\u0000\u0208\u020a\u0007\u0000\u0000\u0000\u0209"+
- "\u0208\u0001\u0000\u0000\u0000\u0209\u020a\u0001\u0000\u0000\u0000\u020a"+
- "\u020b\u0001\u0000\u0000\u0000\u020b\u020c\u0005\u001c\u0000\u0000\u020c"+
- "a\u0001\u0000\u0000\u0000\u020d\u020f\u0007\u0000\u0000\u0000\u020e\u020d"+
- "\u0001\u0000\u0000\u0000\u020e\u020f\u0001\u0000\u0000\u0000\u020f\u0210"+
- "\u0001\u0000\u0000\u0000\u0210\u0211\u0005\u001b\u0000\u0000\u0211c\u0001"+
- "\u0000\u0000\u0000\u0212\u0213\u0005\u001a\u0000\u0000\u0213e\u0001\u0000"+
- "\u0000\u0000\u0214\u0215\u0007\u0007\u0000\u0000\u0215g\u0001\u0000\u0000"+
- "\u0000\u0216\u0217\u0005\u0005\u0000\u0000\u0217\u0218\u0003j5\u0000\u0218"+
- "i\u0001\u0000\u0000\u0000\u0219\u021a\u0005A\u0000\u0000\u021a\u021b\u0003"+
- "\u0002\u0001\u0000\u021b\u021c\u0005B\u0000\u0000\u021ck\u0001\u0000\u0000"+
- "\u0000\u021d\u021e\u0005\r\u0000\u0000\u021e\u021f\u0005d\u0000\u0000"+
- "\u021fm\u0001\u0000\u0000\u0000\u0220\u0221\u0005\u0003\u0000\u0000\u0221"+
- "\u0224\u0005Z\u0000\u0000\u0222\u0223\u0005X\u0000\u0000\u0223\u0225\u0003"+
- "6\u001b\u0000\u0224\u0222\u0001\u0000\u0000\u0000\u0224\u0225\u0001\u0000"+
- "\u0000\u0000\u0225\u022f\u0001\u0000\u0000\u0000\u0226\u0227\u0005Y\u0000"+
- "\u0000\u0227\u022c\u0003p8\u0000\u0228\u0229\u0005\"\u0000\u0000\u0229"+
- "\u022b\u0003p8\u0000\u022a\u0228\u0001\u0000\u0000\u0000\u022b\u022e\u0001"+
- "\u0000\u0000\u0000\u022c\u022a\u0001\u0000\u0000\u0000\u022c\u022d\u0001"+
- "\u0000\u0000\u0000\u022d\u0230\u0001\u0000\u0000\u0000\u022e\u022c\u0001"+
- "\u0000\u0000\u0000\u022f\u0226\u0001\u0000\u0000\u0000\u022f\u0230\u0001"+
- "\u0000\u0000\u0000\u0230o\u0001\u0000\u0000\u0000\u0231\u0232\u00036\u001b"+
- "\u0000\u0232\u0233\u0005 \u0000\u0000\u0233\u0235\u0001\u0000\u0000\u0000"+
- "\u0234\u0231\u0001\u0000\u0000\u0000\u0234\u0235\u0001\u0000\u0000\u0000"+
- "\u0235\u0236\u0001\u0000\u0000\u0000\u0236\u0237\u00036\u001b\u0000\u0237"+
- "q\u0001\u0000\u0000\u0000\u0238\u0239\u0005\u0012\u0000\u0000\u0239\u023a"+
- "\u0003\"\u0011\u0000\u023a\u023b\u0005X\u0000\u0000\u023b\u023c\u0003"+
- "8\u001c\u0000\u023cs\u0001\u0000\u0000\u0000\u023d\u023e\u0005\u0011\u0000"+
- "\u0000\u023e\u0241\u0003\u001c\u000e\u0000\u023f\u0240\u0005\u001d\u0000"+
- "\u0000\u0240\u0242\u0003\u001c\u000e\u0000\u0241\u023f\u0001\u0000\u0000"+
- "\u0000\u0241\u0242\u0001\u0000\u0000\u0000\u0242u\u0001\u0000\u0000\u0000"+
- "8\u0081\u008a\u009c\u00a8\u00b1\u00b9\u00bf\u00c7\u00c9\u00ce\u00d5\u00da"+
- "\u00e5\u00eb\u00f3\u00f5\u0100\u0107\u0112\u0115\u0123\u012b\u0133\u0137"+
- "\u013e\u0146\u014e\u015b\u015f\u0163\u016a\u016e\u0175\u017d\u0185\u018c"+
- "\u019d\u01a8\u01b3\u01b8\u01bc\u01c0\u01cb\u01d0\u01d4\u01e2\u01ed\u01fb"+
- "\u0206\u0209\u020e\u0224\u022c\u022f\u0234\u0241";
+ "\u0001\u0005\u0003\u0005\u00ab\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
+ "\u0001\u0005\u0001\u0005\u0005\u0005\u00b2\b\u0005\n\u0005\f\u0005\u00b5"+
+ "\t\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003"+
+ "\u0005\u00bc\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0003"+
+ "\u0005\u00c2\b\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005\u0001"+
+ "\u0005\u0001\u0005\u0005\u0005\u00ca\b\u0005\n\u0005\f\u0005\u00cd\t\u0005"+
+ "\u0001\u0006\u0001\u0006\u0003\u0006\u00d1\b\u0006\u0001\u0006\u0001\u0006"+
+ "\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006\u00d8\b\u0006\u0001\u0006"+
+ "\u0001\u0006\u0001\u0006\u0003\u0006\u00dd\b\u0006\u0001\u0007\u0001\u0007"+
+ "\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\b\u0001\b\u0003"+
+ "\b\u00e8\b\b\u0001\t\u0001\t\u0001\t\u0001\t\u0003\t\u00ee\b\t\u0001\t"+
+ "\u0001\t\u0001\t\u0001\t\u0001\t\u0001\t\u0005\t\u00f6\b\t\n\t\f\t\u00f9"+
+ "\t\t\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0001\n\u0003"+
+ "\n\u0103\b\n\u0001\n\u0001\n\u0001\n\u0005\n\u0108\b\n\n\n\f\n\u010b\t"+
+ "\n\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b\u0001\u000b"+
+ "\u0005\u000b\u0113\b\u000b\n\u000b\f\u000b\u0116\t\u000b\u0003\u000b\u0118"+
+ "\b\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0003\f\u011f"+
+ "\b\f\u0001\r\u0001\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0001"+
+ "\u000f\u0001\u000f\u0005\u000f\u0129\b\u000f\n\u000f\f\u000f\u012c\t\u000f"+
+ "\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0001\u0010\u0003\u0010"+
+ "\u0133\b\u0010\u0001\u0011\u0001\u0011\u0001\u0011\u0001\u0011\u0005\u0011"+
+ "\u0139\b\u0011\n\u0011\f\u0011\u013c\t\u0011\u0001\u0011\u0003\u0011\u013f"+
+ "\b\u0011\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0001\u0012\u0003"+
+ "\u0012\u0146\b\u0012\u0001\u0013\u0001\u0013\u0001\u0014\u0001\u0014\u0001"+
+ "\u0015\u0001\u0015\u0003\u0015\u014e\b\u0015\u0001\u0016\u0001\u0016\u0001"+
+ "\u0016\u0001\u0016\u0005\u0016\u0154\b\u0016\n\u0016\f\u0016\u0157\t\u0016"+
+ "\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018"+
+ "\u0001\u0018\u0001\u0018\u0005\u0018\u0161\b\u0018\n\u0018\f\u0018\u0164"+
+ "\t\u0018\u0001\u0018\u0003\u0018\u0167\b\u0018\u0001\u0018\u0001\u0018"+
+ "\u0003\u0018\u016b\b\u0018\u0001\u0019\u0001\u0019\u0001\u0019\u0001\u001a"+
+ "\u0001\u001a\u0003\u001a\u0172\b\u001a\u0001\u001a\u0001\u001a\u0003\u001a"+
+ "\u0176\b\u001a\u0001\u001b\u0001\u001b\u0001\u001b\u0005\u001b\u017b\b"+
+ "\u001b\n\u001b\f\u001b\u017e\t\u001b\u0001\u001c\u0001\u001c\u0001\u001c"+
+ "\u0005\u001c\u0183\b\u001c\n\u001c\f\u001c\u0186\t\u001c\u0001\u001d\u0001"+
+ "\u001d\u0001\u001d\u0005\u001d\u018b\b\u001d\n\u001d\f\u001d\u018e\t\u001d"+
+ "\u0001\u001e\u0001\u001e\u0001\u001f\u0001\u001f\u0003\u001f\u0194\b\u001f"+
+ "\u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001 \u0001"+
+ " \u0001 \u0001 \u0001 \u0005 \u01a3\b \n \f \u01a6\t \u0001 \u0001 \u0001"+
+ " \u0001 \u0001 \u0001 \u0005 \u01ae\b \n \f \u01b1\t \u0001 \u0001 \u0001"+
+ " \u0001 \u0001 \u0001 \u0005 \u01b9\b \n \f \u01bc\t \u0001 \u0001 \u0003"+
+ " \u01c0\b \u0001!\u0001!\u0003!\u01c4\b!\u0001\"\u0001\"\u0003\"\u01c8"+
+ "\b\"\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001$\u0005$\u01d1\b$"+
+ "\n$\f$\u01d4\t$\u0001%\u0001%\u0003%\u01d8\b%\u0001%\u0001%\u0003%\u01dc"+
+ "\b%\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001\'\u0001(\u0001(\u0001("+
+ "\u0001(\u0005(\u01e8\b(\n(\f(\u01eb\t(\u0001)\u0001)\u0001)\u0001)\u0001"+
+ "*\u0001*\u0001*\u0001*\u0003*\u01f5\b*\u0001+\u0001+\u0001+\u0001+\u0001"+
+ ",\u0001,\u0001,\u0001-\u0001-\u0001-\u0005-\u0201\b-\n-\f-\u0204\t-\u0001"+
+ ".\u0001.\u0001.\u0001.\u0001/\u0001/\u00010\u00010\u00030\u020e\b0\u0001"+
+ "1\u00031\u0211\b1\u00011\u00011\u00012\u00032\u0216\b2\u00012\u00012\u0001"+
+ "3\u00013\u00014\u00014\u00015\u00015\u00015\u00016\u00016\u00016\u0001"+
+ "6\u00017\u00017\u00017\u00018\u00018\u00018\u00018\u00038\u022c\b8\u0001"+
+ "8\u00018\u00018\u00018\u00058\u0232\b8\n8\f8\u0235\t8\u00038\u0237\b8"+
+ "\u00019\u00019\u00019\u00039\u023c\b9\u00019\u00019\u0001:\u0001:\u0001"+
+ ":\u0001:\u0001:\u0001;\u0001;\u0001;\u0001;\u0003;\u0249\b;\u0001;\u0000"+
+ "\u0004\u0002\n\u0012\u0014<\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010"+
+ "\u0012\u0014\u0016\u0018\u001a\u001c\u001e \"$&(*,.02468:<>@BDFHJLNPR"+
+ "TVXZ\\^`bdfhjlnprtv\u0000\b\u0001\u0000:;\u0001\u0000<>\u0002\u0000\u0019"+
+ "\u0019LL\u0001\u0000CD\u0002\u0000\u001e\u001e\"\"\u0002\u0000%%((\u0002"+
+ "\u0000$$22\u0002\u00003359\u0265\u0000x\u0001\u0000\u0000\u0000\u0002"+
+ "{\u0001\u0000\u0000\u0000\u0004\u008c\u0001\u0000\u0000\u0000\u0006\u009e"+
+ "\u0001\u0000\u0000\u0000\b\u00a0\u0001\u0000\u0000\u0000\n\u00c1\u0001"+
+ "\u0000\u0000\u0000\f\u00dc\u0001\u0000\u0000\u0000\u000e\u00de\u0001\u0000"+
+ "\u0000\u0000\u0010\u00e7\u0001\u0000\u0000\u0000\u0012\u00ed\u0001\u0000"+
+ "\u0000\u0000\u0014\u0102\u0001\u0000\u0000\u0000\u0016\u010c\u0001\u0000"+
+ "\u0000\u0000\u0018\u011e\u0001\u0000\u0000\u0000\u001a\u0120\u0001\u0000"+
+ "\u0000\u0000\u001c\u0122\u0001\u0000\u0000\u0000\u001e\u0125\u0001\u0000"+
+ "\u0000\u0000 \u0132\u0001\u0000\u0000\u0000\"\u0134\u0001\u0000\u0000"+
+ "\u0000$\u0145\u0001\u0000\u0000\u0000&\u0147\u0001\u0000\u0000\u0000("+
+ "\u0149\u0001\u0000\u0000\u0000*\u014d\u0001\u0000\u0000\u0000,\u014f\u0001"+
+ "\u0000\u0000\u0000.\u0158\u0001\u0000\u0000\u00000\u015c\u0001\u0000\u0000"+
+ "\u00002\u016c\u0001\u0000\u0000\u00004\u016f\u0001\u0000\u0000\u00006"+
+ "\u0177\u0001\u0000\u0000\u00008\u017f\u0001\u0000\u0000\u0000:\u0187\u0001"+
+ "\u0000\u0000\u0000<\u018f\u0001\u0000\u0000\u0000>\u0193\u0001\u0000\u0000"+
+ "\u0000@\u01bf\u0001\u0000\u0000\u0000B\u01c3\u0001\u0000\u0000\u0000D"+
+ "\u01c7\u0001\u0000\u0000\u0000F\u01c9\u0001\u0000\u0000\u0000H\u01cc\u0001"+
+ "\u0000\u0000\u0000J\u01d5\u0001\u0000\u0000\u0000L\u01dd\u0001\u0000\u0000"+
+ "\u0000N\u01e0\u0001\u0000\u0000\u0000P\u01e3\u0001\u0000\u0000\u0000R"+
+ "\u01ec\u0001\u0000\u0000\u0000T\u01f0\u0001\u0000\u0000\u0000V\u01f6\u0001"+
+ "\u0000\u0000\u0000X\u01fa\u0001\u0000\u0000\u0000Z\u01fd\u0001\u0000\u0000"+
+ "\u0000\\\u0205\u0001\u0000\u0000\u0000^\u0209\u0001\u0000\u0000\u0000"+
+ "`\u020d\u0001\u0000\u0000\u0000b\u0210\u0001\u0000\u0000\u0000d\u0215"+
+ "\u0001\u0000\u0000\u0000f\u0219\u0001\u0000\u0000\u0000h\u021b\u0001\u0000"+
+ "\u0000\u0000j\u021d\u0001\u0000\u0000\u0000l\u0220\u0001\u0000\u0000\u0000"+
+ "n\u0224\u0001\u0000\u0000\u0000p\u0227\u0001\u0000\u0000\u0000r\u023b"+
+ "\u0001\u0000\u0000\u0000t\u023f\u0001\u0000\u0000\u0000v\u0244\u0001\u0000"+
+ "\u0000\u0000xy\u0003\u0002\u0001\u0000yz\u0005\u0000\u0000\u0001z\u0001"+
+ "\u0001\u0000\u0000\u0000{|\u0006\u0001\uffff\uffff\u0000|}\u0003\u0004"+
+ "\u0002\u0000}\u0083\u0001\u0000\u0000\u0000~\u007f\n\u0001\u0000\u0000"+
+ "\u007f\u0080\u0005\u0018\u0000\u0000\u0080\u0082\u0003\u0006\u0003\u0000"+
+ "\u0081~\u0001\u0000\u0000\u0000\u0082\u0085\u0001\u0000\u0000\u0000\u0083"+
+ "\u0081\u0001\u0000\u0000\u0000\u0083\u0084\u0001\u0000\u0000\u0000\u0084"+
+ "\u0003\u0001\u0000\u0000\u0000\u0085\u0083\u0001\u0000\u0000\u0000\u0086"+
+ "\u008d\u0003j5\u0000\u0087\u008d\u0003\"\u0011\u0000\u0088\u008d\u0003"+
+ "\u001c\u000e\u0000\u0089\u008d\u0003n7\u0000\u008a\u008b\u0004\u0002\u0001"+
+ "\u0000\u008b\u008d\u00030\u0018\u0000\u008c\u0086\u0001\u0000\u0000\u0000"+
+ "\u008c\u0087\u0001\u0000\u0000\u0000\u008c\u0088\u0001\u0000\u0000\u0000"+
+ "\u008c\u0089\u0001\u0000\u0000\u0000\u008c\u008a\u0001\u0000\u0000\u0000"+
+ "\u008d\u0005\u0001\u0000\u0000\u0000\u008e\u009f\u00032\u0019\u0000\u008f"+
+ "\u009f\u0003\b\u0004\u0000\u0090\u009f\u0003L&\u0000\u0091\u009f\u0003"+
+ "F#\u0000\u0092\u009f\u00034\u001a\u0000\u0093\u009f\u0003H$\u0000\u0094"+
+ "\u009f\u0003N\'\u0000\u0095\u009f\u0003P(\u0000\u0096\u009f\u0003T*\u0000"+
+ "\u0097\u009f\u0003V+\u0000\u0098\u009f\u0003p8\u0000\u0099\u009f\u0003"+
+ "X,\u0000\u009a\u009b\u0004\u0003\u0002\u0000\u009b\u009f\u0003v;\u0000"+
+ "\u009c\u009d\u0004\u0003\u0003\u0000\u009d\u009f\u0003t:\u0000\u009e\u008e"+
+ "\u0001\u0000\u0000\u0000\u009e\u008f\u0001\u0000\u0000\u0000\u009e\u0090"+
+ "\u0001\u0000\u0000\u0000\u009e\u0091\u0001\u0000\u0000\u0000\u009e\u0092"+
+ "\u0001\u0000\u0000\u0000\u009e\u0093\u0001\u0000\u0000\u0000\u009e\u0094"+
+ "\u0001\u0000\u0000\u0000\u009e\u0095\u0001\u0000\u0000\u0000\u009e\u0096"+
+ "\u0001\u0000\u0000\u0000\u009e\u0097\u0001\u0000\u0000\u0000\u009e\u0098"+
+ "\u0001\u0000\u0000\u0000\u009e\u0099\u0001\u0000\u0000\u0000\u009e\u009a"+
+ "\u0001\u0000\u0000\u0000\u009e\u009c\u0001\u0000\u0000\u0000\u009f\u0007"+
+ "\u0001\u0000\u0000\u0000\u00a0\u00a1\u0005\u0010\u0000\u0000\u00a1\u00a2"+
+ "\u0003\n\u0005\u0000\u00a2\t\u0001\u0000\u0000\u0000\u00a3\u00a4\u0006"+
+ "\u0005\uffff\uffff\u0000\u00a4\u00a5\u0005+\u0000\u0000\u00a5\u00c2\u0003"+
+ "\n\u0005\b\u00a6\u00c2\u0003\u0010\b\u0000\u00a7\u00c2\u0003\f\u0006\u0000"+
+ "\u00a8\u00aa\u0003\u0010\b\u0000\u00a9\u00ab\u0005+\u0000\u0000\u00aa"+
+ "\u00a9\u0001\u0000\u0000\u0000\u00aa\u00ab\u0001\u0000\u0000\u0000\u00ab"+
+ "\u00ac\u0001\u0000\u0000\u0000\u00ac\u00ad\u0005&\u0000\u0000\u00ad\u00ae"+
+ "\u0005*\u0000\u0000\u00ae\u00b3\u0003\u0010\b\u0000\u00af\u00b0\u0005"+
+ "!\u0000\u0000\u00b0\u00b2\u0003\u0010\b\u0000\u00b1\u00af\u0001\u0000"+
+ "\u0000\u0000\u00b2\u00b5\u0001\u0000\u0000\u0000\u00b3\u00b1\u0001\u0000"+
+ "\u0000\u0000\u00b3\u00b4\u0001\u0000\u0000\u0000\u00b4\u00b6\u0001\u0000"+
+ "\u0000\u0000\u00b5\u00b3\u0001\u0000\u0000\u0000\u00b6\u00b7\u00051\u0000"+
+ "\u0000\u00b7\u00c2\u0001\u0000\u0000\u0000\u00b8\u00b9\u0003\u0010\b\u0000"+
+ "\u00b9\u00bb\u0005\'\u0000\u0000\u00ba\u00bc\u0005+\u0000\u0000\u00bb"+
+ "\u00ba\u0001\u0000\u0000\u0000\u00bb\u00bc\u0001\u0000\u0000\u0000\u00bc"+
+ "\u00bd\u0001\u0000\u0000\u0000\u00bd\u00be\u0005,\u0000\u0000\u00be\u00c2"+
+ "\u0001\u0000\u0000\u0000\u00bf\u00c0\u0004\u0005\u0004\u0000\u00c0\u00c2"+
+ "\u0003\u000e\u0007\u0000\u00c1\u00a3\u0001\u0000\u0000\u0000\u00c1\u00a6"+
+ "\u0001\u0000\u0000\u0000\u00c1\u00a7\u0001\u0000\u0000\u0000\u00c1\u00a8"+
+ "\u0001\u0000\u0000\u0000\u00c1\u00b8\u0001\u0000\u0000\u0000\u00c1\u00bf"+
+ "\u0001\u0000\u0000\u0000\u00c2\u00cb\u0001\u0000\u0000\u0000\u00c3\u00c4"+
+ "\n\u0005\u0000\u0000\u00c4\u00c5\u0005\u001d\u0000\u0000\u00c5\u00ca\u0003"+
+ "\n\u0005\u0006\u00c6\u00c7\n\u0004\u0000\u0000\u00c7\u00c8\u0005.\u0000"+
+ "\u0000\u00c8\u00ca\u0003\n\u0005\u0005\u00c9\u00c3\u0001\u0000\u0000\u0000"+
+ "\u00c9\u00c6\u0001\u0000\u0000\u0000\u00ca\u00cd\u0001\u0000\u0000\u0000"+
+ "\u00cb\u00c9\u0001\u0000\u0000\u0000\u00cb\u00cc\u0001\u0000\u0000\u0000"+
+ "\u00cc\u000b\u0001\u0000\u0000\u0000\u00cd\u00cb\u0001\u0000\u0000\u0000"+
+ "\u00ce\u00d0\u0003\u0010\b\u0000\u00cf\u00d1\u0005+\u0000\u0000\u00d0"+
+ "\u00cf\u0001\u0000\u0000\u0000\u00d0\u00d1\u0001\u0000\u0000\u0000\u00d1"+
+ "\u00d2\u0001\u0000\u0000\u0000\u00d2\u00d3\u0005)\u0000\u0000\u00d3\u00d4"+
+ "\u0003f3\u0000\u00d4\u00dd\u0001\u0000\u0000\u0000\u00d5\u00d7\u0003\u0010"+
+ "\b\u0000\u00d6\u00d8\u0005+\u0000\u0000\u00d7\u00d6\u0001\u0000\u0000"+
+ "\u0000\u00d7\u00d8\u0001\u0000\u0000\u0000\u00d8\u00d9\u0001\u0000\u0000"+
+ "\u0000\u00d9\u00da\u00050\u0000\u0000\u00da\u00db\u0003f3\u0000\u00db"+
+ "\u00dd\u0001\u0000\u0000\u0000\u00dc\u00ce\u0001\u0000\u0000\u0000\u00dc"+
+ "\u00d5\u0001\u0000\u0000\u0000\u00dd\r\u0001\u0000\u0000\u0000\u00de\u00df"+
+ "\u0003\u0010\b\u0000\u00df\u00e0\u0005?\u0000\u0000\u00e0\u00e1\u0003"+
+ "f3\u0000\u00e1\u000f\u0001\u0000\u0000\u0000\u00e2\u00e8\u0003\u0012\t"+
+ "\u0000\u00e3\u00e4\u0003\u0012\t\u0000\u00e4\u00e5\u0003h4\u0000\u00e5"+
+ "\u00e6\u0003\u0012\t\u0000\u00e6\u00e8\u0001\u0000\u0000\u0000\u00e7\u00e2"+
+ "\u0001\u0000\u0000\u0000\u00e7\u00e3\u0001\u0000\u0000\u0000\u00e8\u0011"+
+ "\u0001\u0000\u0000\u0000\u00e9\u00ea\u0006\t\uffff\uffff\u0000\u00ea\u00ee"+
+ "\u0003\u0014\n\u0000\u00eb\u00ec\u0007\u0000\u0000\u0000\u00ec\u00ee\u0003"+
+ "\u0012\t\u0003\u00ed\u00e9\u0001\u0000\u0000\u0000\u00ed\u00eb\u0001\u0000"+
+ "\u0000\u0000\u00ee\u00f7\u0001\u0000\u0000\u0000\u00ef\u00f0\n\u0002\u0000"+
+ "\u0000\u00f0\u00f1\u0007\u0001\u0000\u0000\u00f1\u00f6\u0003\u0012\t\u0003"+
+ "\u00f2\u00f3\n\u0001\u0000\u0000\u00f3\u00f4\u0007\u0000\u0000\u0000\u00f4"+
+ "\u00f6\u0003\u0012\t\u0002\u00f5\u00ef\u0001\u0000\u0000\u0000\u00f5\u00f2"+
+ "\u0001\u0000\u0000\u0000\u00f6\u00f9\u0001\u0000\u0000\u0000\u00f7\u00f5"+
+ "\u0001\u0000\u0000\u0000\u00f7\u00f8\u0001\u0000\u0000\u0000\u00f8\u0013"+
+ "\u0001\u0000\u0000\u0000\u00f9\u00f7\u0001\u0000\u0000\u0000\u00fa\u00fb"+
+ "\u0006\n\uffff\uffff\u0000\u00fb\u0103\u0003@ \u0000\u00fc\u0103\u0003"+
+ "6\u001b\u0000\u00fd\u0103\u0003\u0016\u000b\u0000\u00fe\u00ff\u0005*\u0000"+
+ "\u0000\u00ff\u0100\u0003\n\u0005\u0000\u0100\u0101\u00051\u0000\u0000"+
+ "\u0101\u0103\u0001\u0000\u0000\u0000\u0102\u00fa\u0001\u0000\u0000\u0000"+
+ "\u0102\u00fc\u0001\u0000\u0000\u0000\u0102\u00fd\u0001\u0000\u0000\u0000"+
+ "\u0102\u00fe\u0001\u0000\u0000\u0000\u0103\u0109\u0001\u0000\u0000\u0000"+
+ "\u0104\u0105\n\u0001\u0000\u0000\u0105\u0106\u0005 \u0000\u0000\u0106"+
+ "\u0108\u0003\u001a\r\u0000\u0107\u0104\u0001\u0000\u0000\u0000\u0108\u010b"+
+ "\u0001\u0000\u0000\u0000\u0109\u0107\u0001\u0000\u0000\u0000\u0109\u010a"+
+ "\u0001\u0000\u0000\u0000\u010a\u0015\u0001\u0000\u0000\u0000\u010b\u0109"+
+ "\u0001\u0000\u0000\u0000\u010c\u010d\u0003\u0018\f\u0000\u010d\u0117\u0005"+
+ "*\u0000\u0000\u010e\u0118\u0005<\u0000\u0000\u010f\u0114\u0003\n\u0005"+
+ "\u0000\u0110\u0111\u0005!\u0000\u0000\u0111\u0113\u0003\n\u0005\u0000"+
+ "\u0112\u0110\u0001\u0000\u0000\u0000\u0113\u0116\u0001\u0000\u0000\u0000"+
+ "\u0114\u0112\u0001\u0000\u0000\u0000\u0114\u0115\u0001\u0000\u0000\u0000"+
+ "\u0115\u0118\u0001\u0000\u0000\u0000\u0116\u0114\u0001\u0000\u0000\u0000"+
+ "\u0117\u010e\u0001\u0000\u0000\u0000\u0117\u010f\u0001\u0000\u0000\u0000"+
+ "\u0117\u0118\u0001\u0000\u0000\u0000\u0118\u0119\u0001\u0000\u0000\u0000"+
+ "\u0119\u011a\u00051\u0000\u0000\u011a\u0017\u0001\u0000\u0000\u0000\u011b"+
+ "\u011c\u0004\f\n\u0000\u011c\u011f\u0005?\u0000\u0000\u011d\u011f\u0003"+
+ "D\"\u0000\u011e\u011b\u0001\u0000\u0000\u0000\u011e\u011d\u0001\u0000"+
+ "\u0000\u0000\u011f\u0019\u0001\u0000\u0000\u0000\u0120\u0121\u0003<\u001e"+
+ "\u0000\u0121\u001b\u0001\u0000\u0000\u0000\u0122\u0123\u0005\f\u0000\u0000"+
+ "\u0123\u0124\u0003\u001e\u000f\u0000\u0124\u001d\u0001\u0000\u0000\u0000"+
+ "\u0125\u012a\u0003 \u0010\u0000\u0126\u0127\u0005!\u0000\u0000\u0127\u0129"+
+ "\u0003 \u0010\u0000\u0128\u0126\u0001\u0000\u0000\u0000\u0129\u012c\u0001"+
+ "\u0000\u0000\u0000\u012a\u0128\u0001\u0000\u0000\u0000\u012a\u012b\u0001"+
+ "\u0000\u0000\u0000\u012b\u001f\u0001\u0000\u0000\u0000\u012c\u012a\u0001"+
+ "\u0000\u0000\u0000\u012d\u0133\u0003\n\u0005\u0000\u012e\u012f\u00036"+
+ "\u001b\u0000\u012f\u0130\u0005\u001f\u0000\u0000\u0130\u0131\u0003\n\u0005"+
+ "\u0000\u0131\u0133\u0001\u0000\u0000\u0000\u0132\u012d\u0001\u0000\u0000"+
+ "\u0000\u0132\u012e\u0001\u0000\u0000\u0000\u0133!\u0001\u0000\u0000\u0000"+
+ "\u0134\u0135\u0005\u0006\u0000\u0000\u0135\u013a\u0003$\u0012\u0000\u0136"+
+ "\u0137\u0005!\u0000\u0000\u0137\u0139\u0003$\u0012\u0000\u0138\u0136\u0001"+
+ "\u0000\u0000\u0000\u0139\u013c\u0001\u0000\u0000\u0000\u013a\u0138\u0001"+
+ "\u0000\u0000\u0000\u013a\u013b\u0001\u0000\u0000\u0000\u013b\u013e\u0001"+
+ "\u0000\u0000\u0000\u013c\u013a\u0001\u0000\u0000\u0000\u013d\u013f\u0003"+
+ "*\u0015\u0000\u013e\u013d\u0001\u0000\u0000\u0000\u013e\u013f\u0001\u0000"+
+ "\u0000\u0000\u013f#\u0001\u0000\u0000\u0000\u0140\u0141\u0003&\u0013\u0000"+
+ "\u0141\u0142\u0005h\u0000\u0000\u0142\u0143\u0003(\u0014\u0000\u0143\u0146"+
+ "\u0001\u0000\u0000\u0000\u0144\u0146\u0003(\u0014\u0000\u0145\u0140\u0001"+
+ "\u0000\u0000\u0000\u0145\u0144\u0001\u0000\u0000\u0000\u0146%\u0001\u0000"+
+ "\u0000\u0000\u0147\u0148\u0005L\u0000\u0000\u0148\'\u0001\u0000\u0000"+
+ "\u0000\u0149\u014a\u0007\u0002\u0000\u0000\u014a)\u0001\u0000\u0000\u0000"+
+ "\u014b\u014e\u0003,\u0016\u0000\u014c\u014e\u0003.\u0017\u0000\u014d\u014b"+
+ "\u0001\u0000\u0000\u0000\u014d\u014c\u0001\u0000\u0000\u0000\u014e+\u0001"+
+ "\u0000\u0000\u0000\u014f\u0150\u0005K\u0000\u0000\u0150\u0155\u0005L\u0000"+
+ "\u0000\u0151\u0152\u0005!\u0000\u0000\u0152\u0154\u0005L\u0000\u0000\u0153"+
+ "\u0151\u0001\u0000\u0000\u0000\u0154\u0157\u0001\u0000\u0000\u0000\u0155"+
+ "\u0153\u0001\u0000\u0000\u0000\u0155\u0156\u0001\u0000\u0000\u0000\u0156"+
+ "-\u0001\u0000\u0000\u0000\u0157\u0155\u0001\u0000\u0000\u0000\u0158\u0159"+
+ "\u0005A\u0000\u0000\u0159\u015a\u0003,\u0016\u0000\u015a\u015b\u0005B"+
+ "\u0000\u0000\u015b/\u0001\u0000\u0000\u0000\u015c\u015d\u0005\u0013\u0000"+
+ "\u0000\u015d\u0162\u0003$\u0012\u0000\u015e\u015f\u0005!\u0000\u0000\u015f"+
+ "\u0161\u0003$\u0012\u0000\u0160\u015e\u0001\u0000\u0000\u0000\u0161\u0164"+
+ "\u0001\u0000\u0000\u0000\u0162\u0160\u0001\u0000\u0000\u0000\u0162\u0163"+
+ "\u0001\u0000\u0000\u0000\u0163\u0166\u0001\u0000\u0000\u0000\u0164\u0162"+
+ "\u0001\u0000\u0000\u0000\u0165\u0167\u0003\u001e\u000f\u0000\u0166\u0165"+
+ "\u0001\u0000\u0000\u0000\u0166\u0167\u0001\u0000\u0000\u0000\u0167\u016a"+
+ "\u0001\u0000\u0000\u0000\u0168\u0169\u0005\u001c\u0000\u0000\u0169\u016b"+
+ "\u0003\u001e\u000f\u0000\u016a\u0168\u0001\u0000\u0000\u0000\u016a\u016b"+
+ "\u0001\u0000\u0000\u0000\u016b1\u0001\u0000\u0000\u0000\u016c\u016d\u0005"+
+ "\u0004\u0000\u0000\u016d\u016e\u0003\u001e\u000f\u0000\u016e3\u0001\u0000"+
+ "\u0000\u0000\u016f\u0171\u0005\u000f\u0000\u0000\u0170\u0172\u0003\u001e"+
+ "\u000f\u0000\u0171\u0170\u0001\u0000\u0000\u0000\u0171\u0172\u0001\u0000"+
+ "\u0000\u0000\u0172\u0175\u0001\u0000\u0000\u0000\u0173\u0174\u0005\u001c"+
+ "\u0000\u0000\u0174\u0176\u0003\u001e\u000f\u0000\u0175\u0173\u0001\u0000"+
+ "\u0000\u0000\u0175\u0176\u0001\u0000\u0000\u0000\u01765\u0001\u0000\u0000"+
+ "\u0000\u0177\u017c\u0003D\"\u0000\u0178\u0179\u0005#\u0000\u0000\u0179"+
+ "\u017b\u0003D\"\u0000\u017a\u0178\u0001\u0000\u0000\u0000\u017b\u017e"+
+ "\u0001\u0000\u0000\u0000\u017c\u017a\u0001\u0000\u0000\u0000\u017c\u017d"+
+ "\u0001\u0000\u0000\u0000\u017d7\u0001\u0000\u0000\u0000\u017e\u017c\u0001"+
+ "\u0000\u0000\u0000\u017f\u0184\u0003>\u001f\u0000\u0180\u0181\u0005#\u0000"+
+ "\u0000\u0181\u0183\u0003>\u001f\u0000\u0182\u0180\u0001\u0000\u0000\u0000"+
+ "\u0183\u0186\u0001\u0000\u0000\u0000\u0184\u0182\u0001\u0000\u0000\u0000"+
+ "\u0184\u0185\u0001\u0000\u0000\u0000\u01859\u0001\u0000\u0000\u0000\u0186"+
+ "\u0184\u0001\u0000\u0000\u0000\u0187\u018c\u00038\u001c\u0000\u0188\u0189"+
+ "\u0005!\u0000\u0000\u0189\u018b\u00038\u001c\u0000\u018a\u0188\u0001\u0000"+
+ "\u0000\u0000\u018b\u018e\u0001\u0000\u0000\u0000\u018c\u018a\u0001\u0000"+
+ "\u0000\u0000\u018c\u018d\u0001\u0000\u0000\u0000\u018d;\u0001\u0000\u0000"+
+ "\u0000\u018e\u018c\u0001\u0000\u0000\u0000\u018f\u0190\u0007\u0003\u0000"+
+ "\u0000\u0190=\u0001\u0000\u0000\u0000\u0191\u0194\u0005P\u0000\u0000\u0192"+
+ "\u0194\u0003B!\u0000\u0193\u0191\u0001\u0000\u0000\u0000\u0193\u0192\u0001"+
+ "\u0000\u0000\u0000\u0194?\u0001\u0000\u0000\u0000\u0195\u01c0\u0005,\u0000"+
+ "\u0000\u0196\u0197\u0003d2\u0000\u0197\u0198\u0005C\u0000\u0000\u0198"+
+ "\u01c0\u0001\u0000\u0000\u0000\u0199\u01c0\u0003b1\u0000\u019a\u01c0\u0003"+
+ "d2\u0000\u019b\u01c0\u0003^/\u0000\u019c\u01c0\u0003B!\u0000\u019d\u01c0"+
+ "\u0003f3\u0000\u019e\u019f\u0005A\u0000\u0000\u019f\u01a4\u0003`0\u0000"+
+ "\u01a0\u01a1\u0005!\u0000\u0000\u01a1\u01a3\u0003`0\u0000\u01a2\u01a0"+
+ "\u0001\u0000\u0000\u0000\u01a3\u01a6\u0001\u0000\u0000\u0000\u01a4\u01a2"+
+ "\u0001\u0000\u0000\u0000\u01a4\u01a5\u0001\u0000\u0000\u0000\u01a5\u01a7"+
+ "\u0001\u0000\u0000\u0000\u01a6\u01a4\u0001\u0000\u0000\u0000\u01a7\u01a8"+
+ "\u0005B\u0000\u0000\u01a8\u01c0\u0001\u0000\u0000\u0000\u01a9\u01aa\u0005"+
+ "A\u0000\u0000\u01aa\u01af\u0003^/\u0000\u01ab\u01ac\u0005!\u0000\u0000"+
+ "\u01ac\u01ae\u0003^/\u0000\u01ad\u01ab\u0001\u0000\u0000\u0000\u01ae\u01b1"+
+ "\u0001\u0000\u0000\u0000\u01af\u01ad\u0001\u0000\u0000\u0000\u01af\u01b0"+
+ "\u0001\u0000\u0000\u0000\u01b0\u01b2\u0001\u0000\u0000\u0000\u01b1\u01af"+
+ "\u0001\u0000\u0000\u0000\u01b2\u01b3\u0005B\u0000\u0000\u01b3\u01c0\u0001"+
+ "\u0000\u0000\u0000\u01b4\u01b5\u0005A\u0000\u0000\u01b5\u01ba\u0003f3"+
+ "\u0000\u01b6\u01b7\u0005!\u0000\u0000\u01b7\u01b9\u0003f3\u0000\u01b8"+
+ "\u01b6\u0001\u0000\u0000\u0000\u01b9\u01bc\u0001\u0000\u0000\u0000\u01ba"+
+ "\u01b8\u0001\u0000\u0000\u0000\u01ba\u01bb\u0001\u0000\u0000\u0000\u01bb"+
+ "\u01bd\u0001\u0000\u0000\u0000\u01bc\u01ba\u0001\u0000\u0000\u0000\u01bd"+
+ "\u01be\u0005B\u0000\u0000\u01be\u01c0\u0001\u0000\u0000\u0000\u01bf\u0195"+
+ "\u0001\u0000\u0000\u0000\u01bf\u0196\u0001\u0000\u0000\u0000\u01bf\u0199"+
+ "\u0001\u0000\u0000\u0000\u01bf\u019a\u0001\u0000\u0000\u0000\u01bf\u019b"+
+ "\u0001\u0000\u0000\u0000\u01bf\u019c\u0001\u0000\u0000\u0000\u01bf\u019d"+
+ "\u0001\u0000\u0000\u0000\u01bf\u019e\u0001\u0000\u0000\u0000\u01bf\u01a9"+
+ "\u0001\u0000\u0000\u0000\u01bf\u01b4\u0001\u0000\u0000\u0000\u01c0A\u0001"+
+ "\u0000\u0000\u0000\u01c1\u01c4\u0005/\u0000\u0000\u01c2\u01c4\u0005@\u0000"+
+ "\u0000\u01c3\u01c1\u0001\u0000\u0000\u0000\u01c3\u01c2\u0001\u0000\u0000"+
+ "\u0000\u01c4C\u0001\u0000\u0000\u0000\u01c5\u01c8\u0003<\u001e\u0000\u01c6"+
+ "\u01c8\u0003B!\u0000\u01c7\u01c5\u0001\u0000\u0000\u0000\u01c7\u01c6\u0001"+
+ "\u0000\u0000\u0000\u01c8E\u0001\u0000\u0000\u0000\u01c9\u01ca\u0005\t"+
+ "\u0000\u0000\u01ca\u01cb\u0005\u001a\u0000\u0000\u01cbG\u0001\u0000\u0000"+
+ "\u0000\u01cc\u01cd\u0005\u000e\u0000\u0000\u01cd\u01d2\u0003J%\u0000\u01ce"+
+ "\u01cf\u0005!\u0000\u0000\u01cf\u01d1\u0003J%\u0000\u01d0\u01ce\u0001"+
+ "\u0000\u0000\u0000\u01d1\u01d4\u0001\u0000\u0000\u0000\u01d2\u01d0\u0001"+
+ "\u0000\u0000\u0000\u01d2\u01d3\u0001\u0000\u0000\u0000\u01d3I\u0001\u0000"+
+ "\u0000\u0000\u01d4\u01d2\u0001\u0000\u0000\u0000\u01d5\u01d7\u0003\n\u0005"+
+ "\u0000\u01d6\u01d8\u0007\u0004\u0000\u0000\u01d7\u01d6\u0001\u0000\u0000"+
+ "\u0000\u01d7\u01d8\u0001\u0000\u0000\u0000\u01d8\u01db\u0001\u0000\u0000"+
+ "\u0000\u01d9\u01da\u0005-\u0000\u0000\u01da\u01dc\u0007\u0005\u0000\u0000"+
+ "\u01db\u01d9\u0001\u0000\u0000\u0000\u01db\u01dc\u0001\u0000\u0000\u0000"+
+ "\u01dcK\u0001\u0000\u0000\u0000\u01dd\u01de\u0005\b\u0000\u0000\u01de"+
+ "\u01df\u0003:\u001d\u0000\u01dfM\u0001\u0000\u0000\u0000\u01e0\u01e1\u0005"+
+ "\u0002\u0000\u0000\u01e1\u01e2\u0003:\u001d\u0000\u01e2O\u0001\u0000\u0000"+
+ "\u0000\u01e3\u01e4\u0005\u000b\u0000\u0000\u01e4\u01e9\u0003R)\u0000\u01e5"+
+ "\u01e6\u0005!\u0000\u0000\u01e6\u01e8\u0003R)\u0000\u01e7\u01e5\u0001"+
+ "\u0000\u0000\u0000\u01e8\u01eb\u0001\u0000\u0000\u0000\u01e9\u01e7\u0001"+
+ "\u0000\u0000\u0000\u01e9\u01ea\u0001\u0000\u0000\u0000\u01eaQ\u0001\u0000"+
+ "\u0000\u0000\u01eb\u01e9\u0001\u0000\u0000\u0000\u01ec\u01ed\u00038\u001c"+
+ "\u0000\u01ed\u01ee\u0005T\u0000\u0000\u01ee\u01ef\u00038\u001c\u0000\u01ef"+
+ "S\u0001\u0000\u0000\u0000\u01f0\u01f1\u0005\u0001\u0000\u0000\u01f1\u01f2"+
+ "\u0003\u0014\n\u0000\u01f2\u01f4\u0003f3\u0000\u01f3\u01f5\u0003Z-\u0000"+
+ "\u01f4\u01f3\u0001\u0000\u0000\u0000\u01f4\u01f5\u0001\u0000\u0000\u0000"+
+ "\u01f5U\u0001\u0000\u0000\u0000\u01f6\u01f7\u0005\u0007\u0000\u0000\u01f7"+
+ "\u01f8\u0003\u0014\n\u0000\u01f8\u01f9\u0003f3\u0000\u01f9W\u0001\u0000"+
+ "\u0000\u0000\u01fa\u01fb\u0005\n\u0000\u0000\u01fb\u01fc\u00036\u001b"+
+ "\u0000\u01fcY\u0001\u0000\u0000\u0000\u01fd\u0202\u0003\\.\u0000\u01fe"+
+ "\u01ff\u0005!\u0000\u0000\u01ff\u0201\u0003\\.\u0000\u0200\u01fe\u0001"+
+ "\u0000\u0000\u0000\u0201\u0204\u0001\u0000\u0000\u0000\u0202\u0200\u0001"+
+ "\u0000\u0000\u0000\u0202\u0203\u0001\u0000\u0000\u0000\u0203[\u0001\u0000"+
+ "\u0000\u0000\u0204\u0202\u0001\u0000\u0000\u0000\u0205\u0206\u0003<\u001e"+
+ "\u0000\u0206\u0207\u0005\u001f\u0000\u0000\u0207\u0208\u0003@ \u0000\u0208"+
+ "]\u0001\u0000\u0000\u0000\u0209\u020a\u0007\u0006\u0000\u0000\u020a_\u0001"+
+ "\u0000\u0000\u0000\u020b\u020e\u0003b1\u0000\u020c\u020e\u0003d2\u0000"+
+ "\u020d\u020b\u0001\u0000\u0000\u0000\u020d\u020c\u0001\u0000\u0000\u0000"+
+ "\u020ea\u0001\u0000\u0000\u0000\u020f\u0211\u0007\u0000\u0000\u0000\u0210"+
+ "\u020f\u0001\u0000\u0000\u0000\u0210\u0211\u0001\u0000\u0000\u0000\u0211"+
+ "\u0212\u0001\u0000\u0000\u0000\u0212\u0213\u0005\u001b\u0000\u0000\u0213"+
+ "c\u0001\u0000\u0000\u0000\u0214\u0216\u0007\u0000\u0000\u0000\u0215\u0214"+
+ "\u0001\u0000\u0000\u0000\u0215\u0216\u0001\u0000\u0000\u0000\u0216\u0217"+
+ "\u0001\u0000\u0000\u0000\u0217\u0218\u0005\u001a\u0000\u0000\u0218e\u0001"+
+ "\u0000\u0000\u0000\u0219\u021a\u0005\u0019\u0000\u0000\u021ag\u0001\u0000"+
+ "\u0000\u0000\u021b\u021c\u0007\u0007\u0000\u0000\u021ci\u0001\u0000\u0000"+
+ "\u0000\u021d\u021e\u0005\u0005\u0000\u0000\u021e\u021f\u0003l6\u0000\u021f"+
+ "k\u0001\u0000\u0000\u0000\u0220\u0221\u0005A\u0000\u0000\u0221\u0222\u0003"+
+ "\u0002\u0001\u0000\u0222\u0223\u0005B\u0000\u0000\u0223m\u0001\u0000\u0000"+
+ "\u0000\u0224\u0225\u0005\r\u0000\u0000\u0225\u0226\u0005d\u0000\u0000"+
+ "\u0226o\u0001\u0000\u0000\u0000\u0227\u0228\u0005\u0003\u0000\u0000\u0228"+
+ "\u022b\u0005Z\u0000\u0000\u0229\u022a\u0005X\u0000\u0000\u022a\u022c\u0003"+
+ "8\u001c\u0000\u022b\u0229\u0001\u0000\u0000\u0000\u022b\u022c\u0001\u0000"+
+ "\u0000\u0000\u022c\u0236\u0001\u0000\u0000\u0000\u022d\u022e\u0005Y\u0000"+
+ "\u0000\u022e\u0233\u0003r9\u0000\u022f\u0230\u0005!\u0000\u0000\u0230"+
+ "\u0232\u0003r9\u0000\u0231\u022f\u0001\u0000\u0000\u0000\u0232\u0235\u0001"+
+ "\u0000\u0000\u0000\u0233\u0231\u0001\u0000\u0000\u0000\u0233\u0234\u0001"+
+ "\u0000\u0000\u0000\u0234\u0237\u0001\u0000\u0000\u0000\u0235\u0233\u0001"+
+ "\u0000\u0000\u0000\u0236\u022d\u0001\u0000\u0000\u0000\u0236\u0237\u0001"+
+ "\u0000\u0000\u0000\u0237q\u0001\u0000\u0000\u0000\u0238\u0239\u00038\u001c"+
+ "\u0000\u0239\u023a\u0005\u001f\u0000\u0000\u023a\u023c\u0001\u0000\u0000"+
+ "\u0000\u023b\u0238\u0001\u0000\u0000\u0000\u023b\u023c\u0001\u0000\u0000"+
+ "\u0000\u023c\u023d\u0001\u0000\u0000\u0000\u023d\u023e\u00038\u001c\u0000"+
+ "\u023es\u0001\u0000\u0000\u0000\u023f\u0240\u0005\u0012\u0000\u0000\u0240"+
+ "\u0241\u0003$\u0012\u0000\u0241\u0242\u0005X\u0000\u0000\u0242\u0243\u0003"+
+ ":\u001d\u0000\u0243u\u0001\u0000\u0000\u0000\u0244\u0245\u0005\u0011\u0000"+
+ "\u0000\u0245\u0248\u0003\u001e\u000f\u0000\u0246\u0247\u0005\u001c\u0000"+
+ "\u0000\u0247\u0249\u0003\u001e\u000f\u0000\u0248\u0246\u0001\u0000\u0000"+
+ "\u0000\u0248\u0249\u0001\u0000\u0000\u0000\u0249w\u0001\u0000\u0000\u0000"+
+ "9\u0083\u008c\u009e\u00aa\u00b3\u00bb\u00c1\u00c9\u00cb\u00d0\u00d7\u00dc"+
+ "\u00e7\u00ed\u00f5\u00f7\u0102\u0109\u0114\u0117\u011e\u012a\u0132\u013a"+
+ "\u013e\u0145\u014d\u0155\u0162\u0166\u016a\u0171\u0175\u017c\u0184\u018c"+
+ "\u0193\u01a4\u01af\u01ba\u01bf\u01c3\u01c7\u01d2\u01d7\u01db\u01e9\u01f4"+
+ "\u0202\u020d\u0210\u0215\u022b\u0233\u0236\u023b\u0248";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
index 027281d44b2dc..e2340df954674 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseListener.java
@@ -332,6 +332,18 @@ public class EsqlBaseParserBaseListener implements EsqlBaseParserListener {
* The default implementation does nothing.
*/
@Override public void exitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterFunctionName(EsqlBaseParser.FunctionNameContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitFunctionName(EsqlBaseParser.FunctionNameContext ctx) { }
/**
* {@inheritDoc}
*
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
index 463414ab67ea2..99f038b14b5e0 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserBaseVisitor.java
@@ -202,6 +202,13 @@ public class EsqlBaseParserBaseVisitor extends AbstractParseTreeVisitor im
* {@link #visitChildren} on {@code ctx}.
*/
@Override public T visitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitFunctionName(EsqlBaseParser.FunctionNameContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
index 1747ff001e162..c6dcaca736e1f 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserListener.java
@@ -313,6 +313,16 @@ public interface EsqlBaseParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link EsqlBaseParser#functionName}.
+ * @param ctx the parse tree
+ */
+ void enterFunctionName(EsqlBaseParser.FunctionNameContext ctx);
+ /**
+ * Exit a parse tree produced by {@link EsqlBaseParser#functionName}.
+ * @param ctx the parse tree
+ */
+ void exitFunctionName(EsqlBaseParser.FunctionNameContext ctx);
/**
* Enter a parse tree produced by the {@code toDataType}
* labeled alternative in {@link EsqlBaseParser#dataType}.
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
index b7411d0f99c09..310d3dc76dd6d 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlBaseParserVisitor.java
@@ -193,6 +193,12 @@ public interface EsqlBaseParserVisitor extends ParseTreeVisitor {
* @return the visitor result
*/
T visitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link EsqlBaseParser#functionName}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitFunctionName(EsqlBaseParser.FunctionNameContext ctx);
/**
* Visit a parse tree produced by the {@code toDataType}
* labeled alternative in {@link EsqlBaseParser#dataType}.
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
index 5696ccea188b1..620a25e0170ea 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/EsqlParser.java
@@ -98,10 +98,8 @@ private class PostProcessor extends EsqlBaseParserBaseListener {
@Override
public void exitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx) {
// TODO remove this at some point
- EsqlBaseParser.IdentifierOrParameterContext identifierOrParameter = ctx.identifierOrParameter();
- EsqlBaseParser.IdentifierContext idCtx = identifierOrParameter.identifier();
- String functionName = idCtx != null ? idCtx.getText() : identifierOrParameter.parameter().getText();
- if ("is_null".equalsIgnoreCase(functionName)) {
+ EsqlBaseParser.FunctionNameContext identifier = ctx.functionName();
+ if (identifier.getText().equalsIgnoreCase("is_null")) {
throw new ParsingException(
source(ctx),
"is_null function is not supported anymore, please use 'is null'/'is not null' predicates instead"
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
index 50cf4bc998679..39f1758b78733 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/ExpressionBuilder.java
@@ -593,13 +593,7 @@ public UnresolvedAttribute visitDereference(EsqlBaseParser.DereferenceContext ct
@Override
public Expression visitFunctionExpression(EsqlBaseParser.FunctionExpressionContext ctx) {
- EsqlBaseParser.IdentifierOrParameterContext identifierOrParameter = ctx.identifierOrParameter();
- String name;
- if (identifierOrParameter.identifier() != null) {
- name = visitIdentifier(identifierOrParameter.identifier());
- } else {
- name = unresolvedAttributeNameInParam(identifierOrParameter.parameter(), expression(identifierOrParameter.parameter()));
- }
+ String name = visitFunctionName(ctx.functionName());
List args = expressions(ctx.booleanExpression());
if ("is_null".equals(EsqlFunctionRegistry.normalizeName(name))) {
throw new ParsingException(
@@ -616,6 +610,23 @@ public Expression visitFunctionExpression(EsqlBaseParser.FunctionExpressionConte
return new UnresolvedFunction(source(ctx), name, FunctionResolutionStrategy.DEFAULT, args);
}
+ @Override
+ public String visitFunctionName(EsqlBaseParser.FunctionNameContext ctx) {
+ if (ctx.DEV_MATCH() != null) {
+ return ctx.DEV_MATCH().getText();
+ }
+ return visitIdentifierOrParameter(ctx.identifierOrParameter());
+ }
+
+ @Override
+ public String visitIdentifierOrParameter(EsqlBaseParser.IdentifierOrParameterContext ctx) {
+ if (ctx.identifier() != null) {
+ return visitIdentifier(ctx.identifier());
+ }
+
+ return unresolvedAttributeNameInParam(ctx.parameter(), expression(ctx.parameter()));
+ }
+
@Override
public Expression visitInlineCast(EsqlBaseParser.InlineCastContext ctx) {
Source source = source(ctx);
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsqlExpressionTranslators.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsqlExpressionTranslators.java
index 18aa2628fdc7c..2c8604a7c4a80 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsqlExpressionTranslators.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/EsqlExpressionTranslators.java
@@ -24,15 +24,18 @@
import org.elasticsearch.xpack.esql.core.planner.ExpressionTranslators;
import org.elasticsearch.xpack.esql.core.planner.TranslatorHandler;
import org.elasticsearch.xpack.esql.core.querydsl.query.MatchAll;
+import org.elasticsearch.xpack.esql.core.querydsl.query.MatchQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.NotQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.Query;
+import org.elasticsearch.xpack.esql.core.querydsl.query.QueryStringQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.RangeQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.TermQuery;
import org.elasticsearch.xpack.esql.core.querydsl.query.TermsQuery;
import org.elasticsearch.xpack.esql.core.tree.Source;
import org.elasticsearch.xpack.esql.core.type.DataType;
import org.elasticsearch.xpack.esql.core.util.Check;
-import org.elasticsearch.xpack.esql.expression.function.fulltext.FullTextFunction;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.Match;
+import org.elasticsearch.xpack.esql.expression.function.fulltext.QueryString;
import org.elasticsearch.xpack.esql.expression.function.scalar.ip.CIDRMatch;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesFunction;
import org.elasticsearch.xpack.esql.expression.function.scalar.spatial.SpatialRelatesUtils;
@@ -55,6 +58,7 @@
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import static org.elasticsearch.xpack.esql.core.expression.Foldables.valueOf;
@@ -85,17 +89,11 @@ public final class EsqlExpressionTranslators {
new ExpressionTranslators.StringQueries(),
new ExpressionTranslators.Matches(),
new ExpressionTranslators.MultiMatches(),
- new FullTextFunctions(),
+ new MatchFunctionTranslator(),
+ new QueryStringFunctionTranslator(),
new Scalars()
);
- public static class FullTextFunctions extends ExpressionTranslator {
- @Override
- protected Query asQuery(FullTextFunction fullTextFunction, TranslatorHandler handler) {
- return fullTextFunction.asQuery();
- }
- }
-
public static Query toQuery(Expression e, TranslatorHandler handler) {
Query translation = null;
for (ExpressionTranslator> translator : QUERY_TRANSLATORS) {
@@ -528,4 +526,18 @@ private static RangeQuery translate(Range r, TranslatorHandler handler) {
);
}
}
+
+ public static class MatchFunctionTranslator extends ExpressionTranslator {
+ @Override
+ protected Query asQuery(Match match, TranslatorHandler handler) {
+ return new MatchQuery(match.source(), ((FieldAttribute) match.field()).name(), match.queryAsText());
+ }
+ }
+
+ public static class QueryStringFunctionTranslator extends ExpressionTranslator {
+ @Override
+ protected Query asQuery(QueryString queryString, TranslatorHandler handler) {
+ return new QueryStringQuery(queryString.source(), queryString.queryAsText(), Map.of(), null);
+ }
+ }
}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java
index 965358c0c3f8c..f881c0e1a9bba 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java
@@ -252,6 +252,10 @@ public final void test() throws Throwable {
"can't use QSTR function in csv tests",
testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.QSTR_FUNCTION.capabilityName())
);
+ assumeFalse(
+ "can't use MATCH function in csv tests",
+ testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.MATCH_FUNCTION.capabilityName())
+ );
if (Build.current().isSnapshot()) {
assertThat(
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
index 83b3e88c57964..612f2870fe8bc 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
@@ -8,6 +8,7 @@
package org.elasticsearch.xpack.esql.analysis;
import org.elasticsearch.Build;
+import org.elasticsearch.common.logging.LoggerMessageFormat;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.esql.VerificationException;
import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
@@ -1086,6 +1087,15 @@ public void testMatchFilter() throws Exception {
);
}
+ public void testMatchFunctionNotAllowedAfterCommands() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ assertEquals(
+ "1:24: [MATCH] function cannot be used after LIMIT",
+ error("from test | limit 10 | where match(first_name, \"Anna\")")
+ );
+ }
+
public void testQueryStringFunctionsNotAllowedAfterCommands() throws Exception {
assumeTrue("skipping because QSTR is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
@@ -1146,26 +1156,167 @@ public void testQueryStringFunctionsNotAllowedAfterCommands() throws Exception {
);
}
- public void testQueryStringFunctionsOnlyAllowedInWhere() throws Exception {
+ public void testQueryStringFunctionOnlyAllowedInWhere() throws Exception {
assumeTrue("skipping because QSTR is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
- assertEquals("1:22: [QSTR] function is only supported in WHERE commands", error("from test | eval y = qstr(\"Anna\")"));
- assertEquals("1:18: [QSTR] function is only supported in WHERE commands", error("from test | sort qstr(\"Connection\") asc"));
- assertEquals("1:5: [QSTR] function is only supported in WHERE commands", error("row qstr(\"Connection\")"));
+ assertEquals("1:9: [QSTR] function is only supported in WHERE commands", error("row a = qstr(\"Anna\")"));
+ checkFullTextFunctionsOnlyAllowedInWhere("QSTR", "qstr(\"Anna\")");
+ }
+
+ public void testMatchFunctionOnlyAllowedInWhere() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ checkFullTextFunctionsOnlyAllowedInWhere("MATCH", "match(first_name, \"Anna\")");
+ }
+
+ private void checkFullTextFunctionsOnlyAllowedInWhere(String functionName, String functionInvocation) throws Exception {
+ assertEquals(
+ "1:22: [" + functionName + "] function is only supported in WHERE commands",
+ error("from test | eval y = " + functionInvocation)
+ );
+ assertEquals(
+ "1:18: [" + functionName + "] function is only supported in WHERE commands",
+ error("from test | sort " + functionInvocation + " asc")
+ );
assertEquals(
- "1:23: [QSTR] function is only supported in WHERE commands",
- error("from test | STATS c = qstr(\"foo\") BY languages")
+ "1:23: [" + functionName + "] function is only supported in WHERE commands",
+ error("from test | STATS c = " + functionInvocation + " BY first_name")
);
}
public void testQueryStringFunctionArgNotNullOrConstant() throws Exception {
assumeTrue("skipping because QSTR is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
- assertEquals("1:19: argument of [QSTR] must be a constant, received [first_name]", error("from test | where qstr(first_name)"));
- assertEquals("1:19: argument of [QSTR] cannot be null, received [null]", error("from test | where qstr(null)"));
+ assertEquals(
+ "1:19: argument of [qstr(first_name)] must be a constant, received [first_name]",
+ error("from test | where qstr(first_name)")
+ );
+ assertEquals("1:19: argument of [qstr(null)] cannot be null, received [null]", error("from test | where qstr(null)"));
// Other value types are tested in QueryStringFunctionTests
}
+ public void testQueryStringWithDisjunctions() {
+ assumeTrue("skipping because QSTR is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
+
+ checkWithDisjunctions("QSTR", "qstr(\"first_name: Anna\")");
+ }
+
+ public void testMatchWithDisjunctions() {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ checkWithDisjunctions("MATCH", "match(first_name, \"Anna\")");
+ }
+
+ private void checkWithDisjunctions(String functionName, String functionInvocation) {
+ assertEquals(
+ LoggerMessageFormat.format(
+ null,
+ "1:19: Invalid condition [{} or length(first_name) > 12]. " + "Function {} can't be used as part of an or condition",
+ functionInvocation,
+ functionName
+ ),
+ error("from test | where " + functionInvocation + " or length(first_name) > 12")
+ );
+ assertEquals(
+ LoggerMessageFormat.format(
+ null,
+ "1:19: Invalid condition [({} and first_name is not null) or (length(first_name) > 12 and first_name is null)]. "
+ + "Function {} can't be used as part of an or condition",
+ functionInvocation,
+ functionName
+ ),
+ error(
+ "from test | where ("
+ + functionInvocation
+ + " and first_name is not null) or (length(first_name) > 12 and first_name is null)"
+ )
+ );
+ assertEquals(
+ LoggerMessageFormat.format(
+ null,
+ "1:19: Invalid condition [({} and first_name is not null) or first_name is null]. "
+ + "Function {} can't be used as part of an or condition",
+ functionInvocation,
+ functionName
+ ),
+ error("from test | where (" + functionInvocation + " and first_name is not null) or first_name is null")
+ );
+ }
+
+ public void testQueryStringFunctionWithNonBooleanFunctions() {
+ assumeTrue("skipping because QSTR is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
+
+ checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"first_name: Anna\")");
+ }
+
+ public void testMatchFunctionWithNonBooleanFunctions() {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ checkFullTextFunctionsWithNonBooleanFunctions("MATCH", "match(first_name, \"Anna\")");
+ }
+
+ private void checkFullTextFunctionsWithNonBooleanFunctions(String functionName, String functionInvocation) {
+ assertEquals(
+ "1:19: Invalid condition [" + functionInvocation + " is not null]. Function " + functionName + " can't be used with ISNOTNULL",
+ error("from test | where " + functionInvocation + " is not null")
+ );
+ assertEquals(
+ "1:19: Invalid condition [" + functionInvocation + " is null]. Function " + functionName + " can't be used with ISNULL",
+ error("from test | where " + functionInvocation + " is null")
+ );
+ assertEquals(
+ "1:19: Invalid condition ["
+ + functionInvocation
+ + " in (\"hello\", \"world\")]. Function "
+ + functionName
+ + " can't be used with IN",
+ error("from test | where " + functionInvocation + " in (\"hello\", \"world\")")
+ );
+ }
+
+ public void testMatchFunctionArgNotConstant() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ assertEquals(
+ "1:19: second argument of [match(first_name, first_name)] must be a constant, received [first_name]",
+ error("from test | where match(first_name, first_name)")
+ );
+ assertEquals(
+ "1:59: second argument of [match(first_name, query)] must be a constant, received [query]",
+ error("from test | eval query = concat(\"first\", \" name\") | where match(first_name, query)")
+ );
+ // Other value types are tested in QueryStringFunctionTests
+ }
+
+ // These should pass eventually once we lift some restrictions on match function
+ public void testMatchFunctionCurrentlyUnsupportedBehaviour() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ assertEquals(
+ "1:68: Unknown column [first_name]",
+ error("from test | stats max_salary = max(salary) by emp_no | where match(first_name, \"Anna\")")
+ );
+ }
+
+ public void testMatchFunctionNullArgs() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ assertEquals(
+ "1:19: first argument of [match(null, \"query\")] cannot be null, received [null]",
+ error("from test | where match(null, \"query\")")
+ );
+ assertEquals(
+ "1:19: second argument of [match(first_name, null)] cannot be null, received [null]",
+ error("from test | where match(first_name, null)")
+ );
+ }
+
+ public void testMatchFunctionTargetsExistingField() throws Exception {
+ assumeTrue("skipping because MATCH is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ assertEquals("1:39: Unknown column [first_name]", error("from test | keep emp_no | where match(first_name, \"Anna\")"));
+ }
+
public void testCoalesceWithMixedNumericTypes() {
assertEquals(
"1:22: second argument of [coalesce(languages, height)] must be [integer], found value [height] type [double]",
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchTests.java
new file mode 100644
index 0000000000000..f04e9bd495a49
--- /dev/null
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/MatchTests.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+package org.elasticsearch.xpack.esql.expression.function.fulltext;
+
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+
+import org.apache.lucene.util.BytesRef;
+import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression;
+import org.elasticsearch.xpack.esql.core.expression.Expression;
+import org.elasticsearch.xpack.esql.core.tree.Source;
+import org.elasticsearch.xpack.esql.core.type.DataType;
+import org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase;
+import org.elasticsearch.xpack.esql.expression.function.FunctionName;
+import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier;
+import org.hamcrest.Matcher;
+import org.junit.BeforeClass;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.MATCH_FUNCTION;
+import static org.hamcrest.Matchers.equalTo;
+
+@FunctionName("match")
+public class MatchTests extends AbstractFunctionTestCase {
+
+ @BeforeClass
+ public static void checkFunctionEnabled() {
+ assumeTrue("MATCH function should be enabled ", MATCH_FUNCTION.isEnabled());
+ }
+
+ public MatchTests(@Name("TestCase") Supplier testCaseSupplier) {
+ this.testCase = testCaseSupplier.get();
+ }
+
+ @ParametersFactory
+ public static Iterable parameters() {
+ Set supported = Set.of(DataType.KEYWORD, DataType.TEXT);
+ List> supportedPerPosition = List.of(supported, supported);
+ List suppliers = new LinkedList<>();
+ for (DataType fieldType : validStringDataTypes()) {
+ for (DataType queryType : validStringDataTypes()) {
+ suppliers.add(
+ new TestCaseSupplier(
+ "<" + fieldType + "-ES field, " + queryType + ">",
+ List.of(fieldType, queryType),
+ () -> testCase(fieldType, randomIdentifier(), queryType, randomAlphaOfLengthBetween(1, 10), equalTo(true))
+ )
+ );
+ suppliers.add(
+ new TestCaseSupplier(
+ "<" + fieldType + "-non ES field, " + queryType + ">",
+ List.of(fieldType, queryType),
+ typeErrorSupplier(true, supportedPerPosition, List.of(fieldType, queryType), MatchTests::matchTypeErrorSupplier)
+ )
+ );
+ }
+ }
+ List errorsSuppliers = errorsForCasesWithoutExamples(suppliers, (v, p) -> "string");
+ // Don't test null, as it is not allowed but the expected message is not a type error - so we check it separately in VerifierTests
+ return parameterSuppliersFromTypedData(errorsSuppliers.stream().filter(s -> s.types().contains(DataType.NULL) == false).toList());
+ }
+
+ private static String matchTypeErrorSupplier(boolean includeOrdinal, List> validPerPosition, List types) {
+ return "[] cannot operate on [" + types.getFirst().typeName() + "], which is not a field from an index mapping";
+ }
+
+ private static List validStringDataTypes() {
+ return Arrays.stream(DataType.values()).filter(DataType::isString).toList();
+ }
+
+ private static TestCaseSupplier.TestCase testCase(
+ DataType fieldType,
+ String field,
+ DataType queryType,
+ String query,
+ Matcher matcher
+ ) {
+ return new TestCaseSupplier.TestCase(
+ List.of(
+ new TestCaseSupplier.TypedData(
+ new FieldExpression(field, List.of(new FieldExpression.FieldValue(field))),
+ fieldType,
+ "field"
+ ),
+ new TestCaseSupplier.TypedData(new BytesRef(query), queryType, "query")
+ ),
+ "EndsWithEvaluator[str=Attribute[channel=0], suffix=Attribute[channel=1]]",
+ DataType.BOOLEAN,
+ matcher
+ );
+ }
+
+ @Override
+ protected Expression build(Source source, List args) {
+ return new Match(source, args.get(0), args.get(1));
+ }
+}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunctionTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringTests.java
similarity index 92%
rename from x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunctionTests.java
rename to x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringTests.java
index 37e16a2499cd9..8b0e4f10b8d54 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringFunctionTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/fulltext/QueryStringTests.java
@@ -29,14 +29,14 @@
import static org.hamcrest.Matchers.equalTo;
@FunctionName("qstr")
-public class QueryStringFunctionTests extends AbstractFunctionTestCase {
+public class QueryStringTests extends AbstractFunctionTestCase {
@BeforeClass
public static void checkFunctionEnabled() {
assumeTrue("QSTR capability should be enabled ", QSTR_FUNCTION.isEnabled());
}
- public QueryStringFunctionTests(@Name("TestCase") Supplier testCaseSupplier) {
+ public QueryStringTests(@Name("TestCase") Supplier testCaseSupplier) {
this.testCase = testCaseSupplier.get();
}
@@ -77,6 +77,6 @@ private static TestCaseSupplier.TestCase testCase(DataType strType, String str,
@Override
protected Expression build(Source source, List args) {
- return new QueryStringFunction(source, args.get(0));
+ return new QueryString(source, args.get(0));
}
}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java
index c2779b7dbc46d..3dd0828b82eed 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java
@@ -50,7 +50,6 @@
import org.elasticsearch.xpack.esql.plan.physical.EvalExec;
import org.elasticsearch.xpack.esql.plan.physical.ExchangeExec;
import org.elasticsearch.xpack.esql.plan.physical.FieldExtractExec;
-import org.elasticsearch.xpack.esql.plan.physical.FilterExec;
import org.elasticsearch.xpack.esql.plan.physical.LimitExec;
import org.elasticsearch.xpack.esql.plan.physical.LocalSourceExec;
import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan;
@@ -438,22 +437,24 @@ public void testQueryStringFunctionConjunctionWhereOperands() {
/**
* Expecting
* LimitExec[1000[INTEGER]]
- * \_ExchangeExec[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, job{f}#10, job.raw{f}#11, languages{f}#6, last_n
- * ame{f}#7, long_noidx{f}#12, salary{f}#8],false]
- * \_ProjectExec[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, job{f}#10, job.raw{f}#11, languages{f}#6, last_n
- * ame{f}#7, long_noidx{f}#12, salary{f}#8]]
- * \_FieldExtractExec[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gen]
- * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"should":[{"query_string":{"query":"last_name: Smith","fields":[]}},
- * {"esql_single_value":{"field":"emp_no","next":{"range":{"emp_no":{"gt":10010,"boost":1.0}}},"source":"emp_no > 10010@2:37"}}],
- * "boost":1.0}}][_doc{f}#13], limit[1000], sort[] estimatedRowSize[324]
+ * \_ExchangeExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
+ * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16],
+ * false]
+ * \_ProjectExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
+ * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16]
+ * \_FieldExtractExec[!alias_integer, boolean{f}#4, byte{f}#5, constant_k..]
+ * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},{
+ * "esql_single_value":{"field":"ip","next":{"terms":{"ip":["127.0.0.1/32"],"boost":1.0}},
+ * "source":"cidr_match(ip, \"127.0.0.1/32\")@2:38"}}],"boost":1.0}}][_doc{f}#21], limit[1000], sort[] estimatedRowSize[354]
*/
- public void testQueryStringFunctionDisjunctionWhereClauses() {
+ public void testQueryStringFunctionWithFunctionsPushedToLucene() {
assumeTrue("skipping because QSTR_FUNCTION is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
String queryText = """
from test
- | where qstr("last_name: Smith") or emp_no > 10010
+ | where qstr("last_name: Smith") and cidr_match(ip, "127.0.0.1/32")
""";
- var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
+ var analyzer = makeAnalyzer("mapping-all-types.json", new EnrichResolution());
+ var plan = plannerOptimizer.plan(queryText, IS_SV_STATS, analyzer);
var limit = as(plan, LimitExec.class);
var exchange = as(limit.child(), ExchangeExec.class);
@@ -462,34 +463,34 @@ public void testQueryStringFunctionDisjunctionWhereClauses() {
var query = as(field.child(), EsQueryExec.class);
assertThat(query.limit().fold(), is(1000));
- Source filterSource = new Source(2, 36, "emp_no > 10000");
- var range = wrapWithSingleQuery(queryText, QueryBuilders.rangeQuery("emp_no").gt(10010), "emp_no", filterSource);
+ Source filterSource = new Source(2, 37, "cidr_match(ip, \"127.0.0.1/32\")");
+ var terms = wrapWithSingleQuery(queryText, QueryBuilders.termsQuery("ip", "127.0.0.1/32"), "ip", filterSource);
var queryString = QueryBuilders.queryStringQuery("last_name: Smith");
- var expected = QueryBuilders.boolQuery().should(queryString).should(range);
+ var expected = QueryBuilders.boolQuery().must(queryString).must(terms);
assertThat(query.query().toString(), is(expected.toString()));
}
/**
* Expecting
* LimitExec[1000[INTEGER]]
- * \_ExchangeExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
- * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16],
- * false]
- * \_ProjectExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
- * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16]
- * \_FieldExtractExec[!alias_integer, boolean{f}#4, byte{f}#5, constant_k..]
- * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},{
- * "esql_single_value":{"field":"ip","next":{"terms":{"ip":["127.0.0.1/32"],"boost":1.0}},
- * "source":"cidr_match(ip, \"127.0.0.1/32\")@2:38"}}],"boost":1.0}}][_doc{f}#21], limit[1000], sort[] estimatedRowSize[354]
+ * \_ExchangeExec[[_meta_field{f}#1163, emp_no{f}#1157, first_name{f}#1158, gender{f}#1159, job{f}#1164, job.raw{f}#1165, langua
+ * ges{f}#1160, last_name{f}#1161, long_noidx{f}#1166, salary{f}#1162],false]
+ * \_ProjectExec[[_meta_field{f}#1163, emp_no{f}#1157, first_name{f}#1158, gender{f}#1159, job{f}#1164, job.raw{f}#1165, langua
+ * ges{f}#1160, last_name{f}#1161, long_noidx{f}#1166, salary{f}#1162]]
+ * \_FieldExtractExec[_meta_field{f}#1163, emp_no{f}#1157, first_name{f}#]
+ * \_EsQueryExec[test], indexMode[standard],
+ * query[{"bool":{"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},
+ * {"esql_single_value":{"field":"emp_no","next":{"range":{"emp_no":{"gt":10010,"boost":1.0}}},"source":"emp_no > 10010@3:9"}}],
+ * "boost":1.0}}][_doc{f}#1167], limit[1000], sort[] estimatedRowSize[324]
*/
- public void testQueryStringFunctionWithFunctionsPushedToLucene() {
+ public void testQueryStringFunctionMultipleWhereClauses() {
assumeTrue("skipping because QSTR_FUNCTION is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
String queryText = """
from test
- | where qstr("last_name: Smith") and cidr_match(ip, "127.0.0.1/32")
+ | where qstr("last_name: Smith")
+ | where emp_no > 10010
""";
- var analyzer = makeAnalyzer("mapping-all-types.json", new EnrichResolution());
- var plan = plannerOptimizer.plan(queryText, IS_SV_STATS, analyzer);
+ var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
var limit = as(plan, LimitExec.class);
var exchange = as(limit.child(), ExchangeExec.class);
@@ -498,45 +499,140 @@ public void testQueryStringFunctionWithFunctionsPushedToLucene() {
var query = as(field.child(), EsQueryExec.class);
assertThat(query.limit().fold(), is(1000));
- Source filterSource = new Source(2, 37, "cidr_match(ip, \"127.0.0.1/32\")");
- var terms = wrapWithSingleQuery(queryText, QueryBuilders.termsQuery("ip", "127.0.0.1/32"), "ip", filterSource);
+ Source filterSource = new Source(3, 8, "emp_no > 10000");
+ var range = wrapWithSingleQuery(queryText, QueryBuilders.rangeQuery("emp_no").gt(10010), "emp_no", filterSource);
var queryString = QueryBuilders.queryStringQuery("last_name: Smith");
- var expected = QueryBuilders.boolQuery().must(queryString).must(terms);
+ var expected = QueryBuilders.boolQuery().must(queryString).must(range);
assertThat(query.query().toString(), is(expected.toString()));
}
/**
* Expecting
- *LimitExec[1000[INTEGER]]
- * \_ExchangeExec[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, job{f}#10, job.raw{f}#11, languages{f}#6, last_n
- * ame{f}#7, long_noidx{f}#12, salary{f}#8],false]
- * \_ProjectExec[[_meta_field{f}#9, emp_no{f}#3, first_name{f}#4, gender{f}#5, job{f}#10, job.raw{f}#11, languages{f}#6, last_n
- * ame{f}#7, long_noidx{f}#12, salary{f}#8]]
- * \_FieldExtractExec[_meta_field{f}#9, emp_no{f}#3, gender{f}#5, job{f}#]
- * \_LimitExec[1000[INTEGER]]
- * \_FilterExec[LENGTH(first_name{f}#4) > 10[INTEGER]]
- * \_FieldExtractExec[first_name{f}#4]
- * \_EsQueryExec[test], indexMode[standard],
- * query[{"query_string":{"query":"last_name: Smith","fields":[]}}][_doc{f}#13], limit[], sort[] estimatedRowSize[324]
+ * LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gender{f}#4, job{f}#9, job.raw{f}#10, languages{f}#5, last_na
+ * me{f}#6, long_noidx{f}#11, salary{f}#7],false]
+ * \_ProjectExec[[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gender{f}#4, job{f}#9, job.raw{f}#10, languages{f}#5, last_na
+ * me{f}#6, long_noidx{f}#11, salary{f}#7]]
+ * \_FieldExtractExec[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gen]
+ * \_EsQueryExec[test], indexMode[standard], query[{"bool":
+ * {"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},
+ * {"query_string":{"query":"emp_no: [10010 TO *]","fields":[]}}],"boost":1.0}}]
*/
- public void testQueryStringFunctionWithFunctionNotPushedDown() {
+ public void testQueryStringFunctionMultipleQstrClauses() {
assumeTrue("skipping because QSTR_FUNCTION is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
String queryText = """
from test
- | where qstr("last_name: Smith") and length(first_name) > 10
+ | where qstr("last_name: Smith") and qstr("emp_no: [10010 TO *]")
""";
var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
- var firstLimit = as(plan, LimitExec.class);
- var exchange = as(firstLimit.child(), ExchangeExec.class);
+ var limit = as(plan, LimitExec.class);
+ var exchange = as(limit.child(), ExchangeExec.class);
var project = as(exchange.child(), ProjectExec.class);
var field = as(project.child(), FieldExtractExec.class);
- var secondLimit = as(field.child(), LimitExec.class);
- var filter = as(secondLimit.child(), FilterExec.class);
- var fieldExtract = as(filter.child(), FieldExtractExec.class);
- var query = as(fieldExtract.child(), EsQueryExec.class);
+ var query = as(field.child(), EsQueryExec.class);
+ assertThat(query.limit().fold(), is(1000));
- var expected = QueryBuilders.queryStringQuery("last_name: Smith");
+ var queryStringLeft = QueryBuilders.queryStringQuery("last_name: Smith");
+ var queryStringRight = QueryBuilders.queryStringQuery("emp_no: [10010 TO *]");
+ var expected = QueryBuilders.boolQuery().must(queryStringLeft).must(queryStringRight);
+ assertThat(query.query().toString(), is(expected.toString()));
+ }
+
+ /**
+ * Expecting
+ * LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gender{f}#4, job{f}#9, job.raw{f}#10, languages{f}#5, last_na
+ * me{f}#6, long_noidx{f}#11, salary{f}#7],false]
+ * \_ProjectExec[[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gender{f}#4, job{f}#9, job.raw{f}#10, languages{f}#5, last_na
+ * me{f}#6, long_noidx{f}#11, salary{f}#7]]
+ * \_FieldExtractExec[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gen]
+ * \_EsQueryExec[test], indexMode[standard], query[{"match":{"last_name":{"query":"Smith"}}}]
+ */
+ public void testMatchFunction() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+ var plan = plannerOptimizer.plan("""
+ from test
+ | where match(last_name, "Smith")
+ """, IS_SV_STATS);
+
+ var limit = as(plan, LimitExec.class);
+ var exchange = as(limit.child(), ExchangeExec.class);
+ var project = as(exchange.child(), ProjectExec.class);
+ var field = as(project.child(), FieldExtractExec.class);
+ var query = as(field.child(), EsQueryExec.class);
+ assertThat(query.limit().fold(), is(1000));
+ var expected = QueryBuilders.matchQuery("last_name", "Smith");
+ assertThat(query.query().toString(), is(expected.toString()));
+ }
+
+ /**
+ * Expecting
+ * LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[_meta_field{f}#1419, emp_no{f}#1413, first_name{f}#1414, gender{f}#1415, job{f}#1420, job.raw{f}#1421, langua
+ * ges{f}#1416, last_name{f}#1417, long_noidx{f}#1422, salary{f}#1418],false]
+ * \_ProjectExec[[_meta_field{f}#1419, emp_no{f}#1413, first_name{f}#1414, gender{f}#1415, job{f}#1420, job.raw{f}#1421, langua
+ * ges{f}#1416, last_name{f}#1417, long_noidx{f}#1422, salary{f}#1418]]
+ * \_FieldExtractExec[_meta_field{f}#1419, emp_no{f}#1413, first_name{f}#]
+ * \EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"match":{"last_name":{"query":"Smith"}}},
+ * {"esql_single_value":{"field":"emp_no","next":{"range":{"emp_no":{"gt":10010,"boost":1.0}}},
+ * "source":"emp_no > 10010@2:39"}}],"boost":1.0}}][_doc{f}#14], limit[1000], sort[] estimatedRowSize[324]
+ */
+ public void testMatchFunctionConjunctionWhereOperands() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+ String queryText = """
+ from test
+ | where match(last_name, "Smith") and emp_no > 10010
+ """;
+ var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
+
+ var limit = as(plan, LimitExec.class);
+ var exchange = as(limit.child(), ExchangeExec.class);
+ var project = as(exchange.child(), ProjectExec.class);
+ var field = as(project.child(), FieldExtractExec.class);
+ var query = as(field.child(), EsQueryExec.class);
+ assertThat(query.limit().fold(), is(1000));
+
+ Source filterSource = new Source(2, 38, "emp_no > 10000");
+ var range = wrapWithSingleQuery(queryText, QueryBuilders.rangeQuery("emp_no").gt(10010), "emp_no", filterSource);
+ var queryString = QueryBuilders.matchQuery("last_name", "Smith");
+ var expected = QueryBuilders.boolQuery().must(queryString).must(range);
+ assertThat(query.query().toString(), is(expected.toString()));
+ }
+
+ /**
+ * Expecting
+ * LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
+ * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16],
+ * false]
+ * \_ProjectExec[[!alias_integer, boolean{f}#4, byte{f}#5, constant_keyword-foo{f}#6, date{f}#7, double{f}#8, float{f}#9, half_
+ * float{f}#10, integer{f}#12, ip{f}#13, keyword{f}#14, long{f}#15, scaled_float{f}#11, short{f}#17, text{f}#18, unsigned_long{f}#16]
+ * \_FieldExtractExec[!alias_integer, boolean{f}#4, byte{f}#5, constant_k..]
+ * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"match":{"text":{"query":"beta"}}},
+ * {"esql_single_value":{"field":"ip","next":{"terms":{"ip":["127.0.0.1/32"],"boost":1.0}},
+ * "source":"cidr_match(ip, \"127.0.0.1/32\")@2:33"}}],"boost":1.0}}][_doc{f}#22], limit[1000], sort[] estimatedRowSize[354]
+ */
+ public void testMatchFunctionWithFunctionsPushedToLucene() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+ String queryText = """
+ from test
+ | where match(text, "beta") and cidr_match(ip, "127.0.0.1/32")
+ """;
+ var analyzer = makeAnalyzer("mapping-all-types.json", new EnrichResolution());
+ var plan = plannerOptimizer.plan(queryText, IS_SV_STATS, analyzer);
+
+ var limit = as(plan, LimitExec.class);
+ var exchange = as(limit.child(), ExchangeExec.class);
+ var project = as(exchange.child(), ProjectExec.class);
+ var field = as(project.child(), FieldExtractExec.class);
+ var query = as(field.child(), EsQueryExec.class);
+ assertThat(query.limit().fold(), is(1000));
+
+ Source filterSource = new Source(2, 32, "cidr_match(ip, \"127.0.0.1/32\")");
+ var terms = wrapWithSingleQuery(queryText, QueryBuilders.termsQuery("ip", "127.0.0.1/32"), "ip", filterSource);
+ var queryString = QueryBuilders.matchQuery("text", "beta");
+ var expected = QueryBuilders.boolQuery().must(queryString).must(terms);
assertThat(query.query().toString(), is(expected.toString()));
}
@@ -548,16 +644,15 @@ public void testQueryStringFunctionWithFunctionNotPushedDown() {
* \_ProjectExec[[_meta_field{f}#1163, emp_no{f}#1157, first_name{f}#1158, gender{f}#1159, job{f}#1164, job.raw{f}#1165, langua
* ges{f}#1160, last_name{f}#1161, long_noidx{f}#1166, salary{f}#1162]]
* \_FieldExtractExec[_meta_field{f}#1163, emp_no{f}#1157, first_name{f}#]
- * \_EsQueryExec[test], indexMode[standard],
- * query[{"bool":{"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},
- * {"esql_single_value":{"field":"emp_no","next":{"range":{"emp_no":{"gt":10010,"boost":1.0}}},"source":"emp_no > 10010@3:9"}}],
- * "boost":1.0}}][_doc{f}#1167], limit[1000], sort[] estimatedRowSize[324]
+ * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"match":{"last_name":{"query":"Smith"}}},
+ * {"esql_single_value":{"field":"emp_no","next":{"range":{"emp_no":{"gt":10010,"boost":1.0}}},
+ * "source":"emp_no > 10010@3:9"}}],"boost":1.0}}][_doc{f}#14], limit[1000], sort[] estimatedRowSize[324]
*/
- public void testQueryStringFunctionMultipleWhereClauses() {
- assumeTrue("skipping because QSTR_FUNCTION is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
+ public void testMatchFunctionMultipleWhereClauses() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
String queryText = """
from test
- | where qstr("last_name: Smith")
+ | where match(last_name, "Smith")
| where emp_no > 10010
""";
var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
@@ -571,7 +666,7 @@ public void testQueryStringFunctionMultipleWhereClauses() {
Source filterSource = new Source(3, 8, "emp_no > 10000");
var range = wrapWithSingleQuery(queryText, QueryBuilders.rangeQuery("emp_no").gt(10010), "emp_no", filterSource);
- var queryString = QueryBuilders.queryStringQuery("last_name: Smith");
+ var queryString = QueryBuilders.matchQuery("last_name", "Smith");
var expected = QueryBuilders.boolQuery().must(queryString).must(range);
assertThat(query.query().toString(), is(expected.toString()));
}
@@ -584,15 +679,14 @@ public void testQueryStringFunctionMultipleWhereClauses() {
* \_ProjectExec[[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gender{f}#4, job{f}#9, job.raw{f}#10, languages{f}#5, last_na
* me{f}#6, long_noidx{f}#11, salary{f}#7]]
* \_FieldExtractExec[_meta_field{f}#8, emp_no{f}#2, first_name{f}#3, gen]
- * \_EsQueryExec[test], indexMode[standard], query[{"bool":
- * {"must":[{"query_string":{"query":"last_name: Smith","fields":[]}},
- * {"query_string":{"query":"emp_no: [10010 TO *]","fields":[]}}],"boost":1.0}}]
+ * \_EsQueryExec[test], indexMode[standard], query[{"bool":{"must":[{"match":{"last_name":{"query":"Smith"}}},
+ * {"match":{"first_name":{"query":"John"}}}],"boost":1.0}}][_doc{f}#14], limit[1000], sort[] estimatedRowSize[324]
*/
- public void testQueryStringFunctionMultipleQstrClauses() {
- assumeTrue("skipping because QSTR_FUNCTION is not enabled", EsqlCapabilities.Cap.QSTR_FUNCTION.isEnabled());
+ public void testMatchFunctionMultipleQstrClauses() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
String queryText = """
from test
- | where qstr("last_name: Smith") and qstr("emp_no: [10010 TO *]")
+ | where match(last_name, "Smith") and match(first_name, "John")
""";
var plan = plannerOptimizer.plan(queryText, IS_SV_STATS);
@@ -603,8 +697,8 @@ public void testQueryStringFunctionMultipleQstrClauses() {
var query = as(field.child(), EsQueryExec.class);
assertThat(query.limit().fold(), is(1000));
- var queryStringLeft = QueryBuilders.queryStringQuery("last_name: Smith");
- var queryStringRight = QueryBuilders.queryStringQuery("emp_no: [10010 TO *]");
+ var queryStringLeft = QueryBuilders.matchQuery("last_name", "Smith");
+ var queryStringRight = QueryBuilders.matchQuery("first_name", "John");
var expected = QueryBuilders.boolQuery().must(queryStringLeft).must(queryStringRight);
assertThat(query.query().toString(), is(expected.toString()));
}
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
index 6ff541de1854a..e8980c99a61f9 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java
@@ -18,6 +18,7 @@
import org.elasticsearch.xpack.esql.EsqlTestUtils;
import org.elasticsearch.xpack.esql.TestBlockFactory;
import org.elasticsearch.xpack.esql.VerificationException;
+import org.elasticsearch.xpack.esql.action.EsqlCapabilities;
import org.elasticsearch.xpack.esql.analysis.Analyzer;
import org.elasticsearch.xpack.esql.analysis.AnalyzerContext;
import org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils;
@@ -5565,6 +5566,42 @@ public void testToDatePeriodToTimeDurationWithField() {
assertEquals("1:60: argument of [to_timeduration(x)] must be a constant, received [x]", e.getMessage().substring(header.length()));
}
+ // These should pass eventually once we lift some restrictions on match function
+ public void testMatchWithNonIndexedColumnCurrentlyUnsupported() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ final String header = "Found 1 problem\nline ";
+ VerificationException e = expectThrows(VerificationException.class, () -> plan("""
+ from test | eval initial = substring(first_name, 1) | where match(initial, "A")"""));
+ assertTrue(e.getMessage().startsWith("Found "));
+ assertEquals(
+ "1:67: [MATCH] cannot operate on [initial], which is not a field from an index mapping",
+ e.getMessage().substring(header.length())
+ );
+
+ e = expectThrows(VerificationException.class, () -> plan("""
+ from test | eval text=concat(first_name, last_name) | where match(text, "cat")"""));
+ assertTrue(e.getMessage().startsWith("Found "));
+ assertEquals(
+ "1:67: [MATCH] cannot operate on [text], which is not a field from an index mapping",
+ e.getMessage().substring(header.length())
+ );
+ }
+
+ public void testMatchFunctionIsNotNullable() {
+ assumeTrue("skipping because MATCH function is not enabled", EsqlCapabilities.Cap.MATCH_FUNCTION.isEnabled());
+
+ String queryText = """
+ row n = null | eval text = n + 5 | where match(text::keyword, "Anna")
+ """;
+
+ VerificationException ve = expectThrows(VerificationException.class, () -> plan(queryText));
+ assertThat(
+ ve.getMessage(),
+ containsString("[MATCH] cannot operate on [text::keyword], which is not a field from an index mapping")
+ );
+ }
+
private Literal nullOf(DataType dataType) {
return new Literal(Source.EMPTY, null, dataType);
}
From d94fbcb01a0004445787f356aeecce5338be02c3 Mon Sep 17 00:00:00 2001
From: Gergely Kalapos
Date: Mon, 14 Oct 2024 10:33:36 +0200
Subject: [PATCH 06/77] Add alias event.dataset -> data_stream.dataset
(#114642)
---
.../component-templates/otel@mappings.yaml | 3 +++
.../rest-api-spec/test/20_logs_tests.yml | 18 ++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/x-pack/plugin/otel-data/src/main/resources/component-templates/otel@mappings.yaml b/x-pack/plugin/otel-data/src/main/resources/component-templates/otel@mappings.yaml
index 513e1a857787e..4a039886ecc4e 100644
--- a/x-pack/plugin/otel-data/src/main/resources/component-templates/otel@mappings.yaml
+++ b/x-pack/plugin/otel-data/src/main/resources/component-templates/otel@mappings.yaml
@@ -17,6 +17,9 @@ template:
type: constant_keyword
data_stream.namespace:
type: constant_keyword
+ event.dataset:
+ type: alias
+ path: data_stream.dataset
attributes:
type: passthrough
dynamic: true
diff --git a/x-pack/plugin/otel-data/src/yamlRestTest/resources/rest-api-spec/test/20_logs_tests.yml b/x-pack/plugin/otel-data/src/yamlRestTest/resources/rest-api-spec/test/20_logs_tests.yml
index 0957a79552ad3..be4de6dca6c76 100644
--- a/x-pack/plugin/otel-data/src/yamlRestTest/resources/rest-api-spec/test/20_logs_tests.yml
+++ b/x-pack/plugin/otel-data/src/yamlRestTest/resources/rest-api-spec/test/20_logs_tests.yml
@@ -145,3 +145,21 @@ Structured log body:
index: $datastream-backing-index
- is_true: $datastream-backing-index
- match: { .$datastream-backing-index.mappings.properties.body.properties.flattened.type: "flattened" }
+---
+"event.dataset alias must point to data_stream.dataset":
+ - do:
+ bulk:
+ index: logs-generic.otel-default
+ refresh: true
+ body:
+ - create: {}
+ - '{"@timestamp":"2024-07-18T14:49:33.467654000Z","data_stream":{"dataset":"generic.otel","namespace":"default"}, "body_text":"error1"}'
+ - is_false: errors
+ - is_false: errors
+ - do:
+ search:
+ index: logs-generic.otel-default
+ body:
+ fields: ["event.dataset"]
+ - length: { hits.hits: 1 }
+ - match: { hits.hits.0.fields.event\.dataset: ["generic.otel"] }
From bdce88a190efe7c3586119a476458896bd87ffd6 Mon Sep 17 00:00:00 2001
From: David Kyle
Date: Mon, 14 Oct 2024 09:34:35 +0100
Subject: [PATCH 07/77] [ML] Feature flag default configs (#114660)
---
.../org/elasticsearch/xpack/inference/InferencePlugin.java | 6 ++++--
.../rest-api-spec/test/inference/inference_crud.yml | 4 ++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java
index d251120980e0b..d361ce0837b93 100644
--- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java
+++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java
@@ -217,8 +217,10 @@ public Collection> createComponents(PluginServices services) {
// reference correctly
var registry = new InferenceServiceRegistry(inferenceServices, factoryContext);
registry.init(services.client());
- for (var service : registry.getServices().values()) {
- service.defaultConfigs().forEach(modelRegistry::addDefaultConfiguration);
+ if (DefaultElserFeatureFlag.isEnabled()) {
+ for (var service : registry.getServices().values()) {
+ service.defaultConfigs().forEach(modelRegistry::addDefaultConfiguration);
+ }
}
inferenceServiceRegistry.set(registry);
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/inference/inference_crud.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/inference/inference_crud.yml
index 11be68cc764e2..b1f640a40b34e 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/inference/inference_crud.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/inference/inference_crud.yml
@@ -41,6 +41,10 @@
---
"Test get all":
+ - requires:
+ cluster_features: "semantic_text.default_elser_2"
+ reason: semantic_text default ELSER 2 inference ID introduced in 8.16.0
+
- do:
inference.get:
inference_id: "*"
From 1d037811fd9e0d407b34bf96635cf118a5f11d46 Mon Sep 17 00:00:00 2001
From: Rene Groeschke
Date: Mon, 14 Oct 2024 10:47:24 +0200
Subject: [PATCH 08/77] Renovate Bot PRs should run ci checks (#114699)
---
.buildkite/pull-requests.json | 1 +
1 file changed, 1 insertion(+)
diff --git a/.buildkite/pull-requests.json b/.buildkite/pull-requests.json
index 235a4b2dbb4ad..ea4f34bcbe11e 100644
--- a/.buildkite/pull-requests.json
+++ b/.buildkite/pull-requests.json
@@ -8,6 +8,7 @@
"admin",
"write"
],
+ "allowed_list": ["elastic-renovate-prod[bot]"],
"set_commit_status": false,
"build_on_commit": true,
"build_on_comment": true,
From 08bad488cfabeb5c158eda8f385da9563792fb40 Mon Sep 17 00:00:00 2001
From: Ievgen Degtiarenko
Date: Mon, 14 Oct 2024 10:56:30 +0200
Subject: [PATCH 09/77] Simplify NodeShutdownShardsIT (#114583)
We no longer need to manually reroute after registering node shutdown in test
since https://github.com/elastic/elasticsearch/pull/103251
---
.../xpack/shutdown/NodeShutdownShardsIT.java | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
index d12d093dd5b8d..0e162238e96c8 100644
--- a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
+++ b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
@@ -327,11 +327,8 @@ public void testAutoExpandDuringRestart() throws Exception {
ensureGreen("myindex");
putNodeShutdown(primaryNodeId, SingleNodeShutdownMetadata.Type.RESTART, null);
- // registering node shutdown entry does not perform reroute, neither should it.
- // we provoke it here in the test to ensure that auto-expansion has run.
- updateIndexSettings(Settings.builder().put("index.routing.allocation.exclude.name", "non-existent"), "myindex");
- assertBusy(() -> assertIndexSetting("myindex", "index.number_of_replicas", "1"));
+ assertIndexSetting("myindex", "index.number_of_replicas", "1");
indexRandomData("myindex");
internalCluster().restartNode(primaryNode, new InternalTestCluster.RestartCallback() {
@@ -361,9 +358,6 @@ public void testAutoExpandDuringReplace() throws Exception {
var replacementNodeName = "node_t2";
putNodeShutdown(nodeIdToReplace, SingleNodeShutdownMetadata.Type.REPLACE, replacementNodeName);
- // registering node shutdown entry does not perform reroute, neither should it.
- // we provoke it here in the test to ensure that auto-expansion has run.
- updateIndexSettings(Settings.builder().put("index.routing.allocation.exclude.name", "non-existent"), "index");
ensureGreen("index");
assertIndexSetting("index", "index.number_of_replicas", "1");
From 30ff4741c674532c832c53a3bd31aa307dce8a95 Mon Sep 17 00:00:00 2001
From: Ioana Tagirta
Date: Mon, 14 Oct 2024 11:05:35 +0200
Subject: [PATCH 10/77] Add generated code changes for HypotEvaluator (#114697)
---
.../function/scalar/math/HypotEvaluator.java | 24 +++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/math/HypotEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/math/HypotEvaluator.java
index f5684bcb4be18..22094f7e623e6 100644
--- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/math/HypotEvaluator.java
+++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/math/HypotEvaluator.java
@@ -13,16 +13,16 @@
import org.elasticsearch.compute.data.Page;
import org.elasticsearch.compute.operator.DriverContext;
import org.elasticsearch.compute.operator.EvalOperator;
+import org.elasticsearch.compute.operator.Warnings;
import org.elasticsearch.core.Releasables;
import org.elasticsearch.xpack.esql.core.tree.Source;
-import org.elasticsearch.xpack.esql.expression.function.Warnings;
/**
* {@link EvalOperator.ExpressionEvaluator} implementation for {@link Hypot}.
* This class is generated. Do not edit it.
*/
public final class HypotEvaluator implements EvalOperator.ExpressionEvaluator {
- private final Warnings warnings;
+ private final Source source;
private final EvalOperator.ExpressionEvaluator n1;
@@ -30,12 +30,14 @@ public final class HypotEvaluator implements EvalOperator.ExpressionEvaluator {
private final DriverContext driverContext;
+ private Warnings warnings;
+
public HypotEvaluator(Source source, EvalOperator.ExpressionEvaluator n1,
EvalOperator.ExpressionEvaluator n2, DriverContext driverContext) {
+ this.source = source;
this.n1 = n1;
this.n2 = n2;
this.driverContext = driverContext;
- this.warnings = Warnings.createWarnings(driverContext.warningsMode(), source);
}
@Override
@@ -64,7 +66,7 @@ public DoubleBlock eval(int positionCount, DoubleBlock n1Block, DoubleBlock n2Bl
}
if (n1Block.getValueCount(p) != 1) {
if (n1Block.getValueCount(p) > 1) {
- warnings.registerException(new IllegalArgumentException("single-value function encountered multi-value"));
+ warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value"));
}
result.appendNull();
continue position;
@@ -75,7 +77,7 @@ public DoubleBlock eval(int positionCount, DoubleBlock n1Block, DoubleBlock n2Bl
}
if (n2Block.getValueCount(p) != 1) {
if (n2Block.getValueCount(p) > 1) {
- warnings.registerException(new IllegalArgumentException("single-value function encountered multi-value"));
+ warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value"));
}
result.appendNull();
continue position;
@@ -105,6 +107,18 @@ public void close() {
Releasables.closeExpectNoException(n1, n2);
}
+ private Warnings warnings() {
+ if (warnings == null) {
+ this.warnings = Warnings.createWarnings(
+ driverContext.warningsMode(),
+ source.source().getLineNumber(),
+ source.source().getColumnNumber(),
+ source.text()
+ );
+ }
+ return warnings;
+ }
+
static class Factory implements EvalOperator.ExpressionEvaluator.Factory {
private final Source source;
From 2af19d87b08565b2b3960bee8b7e797b4ef27190 Mon Sep 17 00:00:00 2001
From: Andrei Stefan
Date: Mon, 14 Oct 2024 12:24:40 +0300
Subject: [PATCH 11/77] ES|QL: Restrict sorting for _source and counter field
types (#114638)
---
docs/changelog/114638.yaml | 7 ++++++
.../xpack/esql/core/type/DataType.java | 8 +++++++
.../src/main/resources/tsdb-mapping.json | 4 ++++
.../xpack/esql/action/EsqlCapabilities.java | 7 +++++-
.../xpack/esql/analysis/Verifier.java | 8 +++----
.../expression/function/aggregate/Rate.java | 2 +-
.../xpack/esql/analysis/AnalyzerTests.java | 2 +-
.../xpack/esql/analysis/VerifierTests.java | 23 +++++++++++++++++++
.../rest-api-spec/test/esql/140_metadata.yml | 16 +++++++++++++
.../rest-api-spec/test/esql/40_tsdb.yml | 12 ++++++++--
10 files changed, 80 insertions(+), 9 deletions(-)
create mode 100644 docs/changelog/114638.yaml
diff --git a/docs/changelog/114638.yaml b/docs/changelog/114638.yaml
new file mode 100644
index 0000000000000..0386aacfe3e18
--- /dev/null
+++ b/docs/changelog/114638.yaml
@@ -0,0 +1,7 @@
+pr: 114638
+summary: "ES|QL: Restrict sorting for `_source` and counter field types"
+area: ES|QL
+type: bug
+issues:
+ - 114423
+ - 111976
diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java
index c0092caeb9d5d..b23703c6d8b66 100644
--- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java
+++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java
@@ -425,6 +425,10 @@ public static boolean isRepresentable(DataType t) {
&& t.isCounter() == false;
}
+ public static boolean isCounter(DataType t) {
+ return t == COUNTER_DOUBLE || t == COUNTER_INTEGER || t == COUNTER_LONG;
+ }
+
public static boolean isSpatialPoint(DataType t) {
return t == GEO_POINT || t == CARTESIAN_POINT;
}
@@ -437,6 +441,10 @@ public static boolean isSpatial(DataType t) {
return t == GEO_POINT || t == CARTESIAN_POINT || t == GEO_SHAPE || t == CARTESIAN_SHAPE;
}
+ public static boolean isSortable(DataType t) {
+ return false == (t == SOURCE || isCounter(t) || isSpatial(t));
+ }
+
public String nameUpper() {
return name;
}
diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/tsdb-mapping.json b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/tsdb-mapping.json
index dd4073d5dc7cf..39b1b10edd916 100644
--- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/tsdb-mapping.json
+++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/tsdb-mapping.json
@@ -27,6 +27,10 @@
"message_in": {
"type": "float",
"time_series_metric": "counter"
+ },
+ "message_out": {
+ "type": "integer",
+ "time_series_metric": "counter"
}
}
}
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
index 2e979dcce1758..1d6d81077b9be 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java
@@ -365,7 +365,12 @@ public enum Cap {
/**
* Support named parameters for field names.
*/
- NAMED_PARAMETER_FOR_FIELD_AND_FUNCTION_NAMES;
+ NAMED_PARAMETER_FOR_FIELD_AND_FUNCTION_NAMES,
+
+ /**
+ * Fix sorting not allowed on _source and counters.
+ */
+ SORTING_ON_SOURCE_AND_COUNTERS_FORBIDDEN;
private final boolean snapshotOnly;
private final FeatureFlag featureFlag;
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
index e45db0c02be7e..dd2b72b4d35d9 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java
@@ -190,7 +190,7 @@ else if (p instanceof Lookup lookup) {
checkOperationsOnUnsignedLong(p, failures);
checkBinaryComparison(p, failures);
- checkForSortOnSpatialTypes(p, failures);
+ checkForSortableDataTypes(p, failures);
checkFilterMatchConditions(p, failures);
checkFullTextQueryFunctions(p, failures);
@@ -555,12 +555,12 @@ private static Failure validateUnsignedLongNegation(Neg neg) {
}
/**
- * Makes sure that spatial types do not appear in sorting contexts.
+ * Some datatypes are not sortable
*/
- private static void checkForSortOnSpatialTypes(LogicalPlan p, Set localFailures) {
+ private static void checkForSortableDataTypes(LogicalPlan p, Set localFailures) {
if (p instanceof OrderBy ob) {
ob.order().forEach(order -> {
- if (DataType.isSpatial(order.dataType())) {
+ if (DataType.isSortable(order.dataType()) == false) {
localFailures.add(fail(order, "cannot sort on " + order.dataType().typeName()));
}
});
diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Rate.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Rate.java
index f5597b7d64e81..135264c448f10 100644
--- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Rate.java
+++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/aggregate/Rate.java
@@ -115,7 +115,7 @@ public DataType dataType() {
protected TypeResolution resolveType() {
TypeResolution resolution = isType(
field(),
- dt -> dt == DataType.COUNTER_LONG || dt == DataType.COUNTER_INTEGER || dt == DataType.COUNTER_DOUBLE,
+ dt -> DataType.isCounter(dt),
sourceText(),
FIRST,
"counter_long",
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
index 5d75549893512..6644f9b17055e 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java
@@ -1638,7 +1638,7 @@ public void testCounterTypes() {
var attributes = limit.output().stream().collect(Collectors.toMap(NamedExpression::name, a -> a));
assertThat(
attributes.keySet(),
- equalTo(Set.of("network.connections", "network.bytes_in", "network.bytes_out", "network.message_in"))
+ equalTo(Set.of("network.connections", "network.bytes_in", "network.bytes_out", "network.message_in", "network.message_out"))
);
assertThat(attributes.get("network.connections").dataType(), equalTo(DataType.LONG));
assertThat(attributes.get("network.bytes_in").dataType(), equalTo(DataType.COUNTER_LONG));
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
index 612f2870fe8bc..01c020b16ecad 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java
@@ -26,12 +26,16 @@
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static org.elasticsearch.xpack.esql.EsqlTestUtils.paramAsConstant;
import static org.elasticsearch.xpack.esql.EsqlTestUtils.withDefaultLimitWarning;
import static org.elasticsearch.xpack.esql.analysis.AnalyzerTestUtils.loadMapping;
+import static org.elasticsearch.xpack.esql.core.type.DataType.COUNTER_DOUBLE;
+import static org.elasticsearch.xpack.esql.core.type.DataType.COUNTER_INTEGER;
+import static org.elasticsearch.xpack.esql.core.type.DataType.COUNTER_LONG;
import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
@@ -909,6 +913,25 @@ public void testSpatialSort() {
assertEquals("1:42: cannot sort on cartesian_shape", error("FROM countries_bbox_web | LIMIT 5 | sort shape", countriesBboxWeb));
}
+ public void testSourceSorting() {
+ assertEquals("1:35: cannot sort on _source", error("from test metadata _source | sort _source"));
+ }
+
+ public void testCountersSorting() {
+ Map counterDataTypes = Map.of(
+ COUNTER_DOUBLE,
+ "network.message_in",
+ COUNTER_INTEGER,
+ "network.message_out",
+ COUNTER_LONG,
+ "network.bytes_out"
+ );
+ for (DataType counterDT : counterDataTypes.keySet()) {
+ var fieldName = counterDataTypes.get(counterDT);
+ assertEquals("1:18: cannot sort on " + counterDT.name().toLowerCase(Locale.ROOT), error("from test | sort " + fieldName, tsdb));
+ }
+ }
+
public void testInlineImpossibleConvert() {
assertEquals("1:5: argument of [false::ip] must be [ip or string], found value [false] type [boolean]", error("ROW false::ip"));
}
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/140_metadata.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/140_metadata.yml
index 33c9cc7558672..83234901ae8f2 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/140_metadata.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/140_metadata.yml
@@ -155,3 +155,19 @@ setup:
esql.query:
body:
query: 'FROM test [metadata _source] | STATS COUNT_DISTINCT(_source)'
+
+---
+"sort on _source not allowed":
+ - requires:
+ test_runner_features: [capabilities]
+ capabilities:
+ - method: POST
+ path: /_query
+ parameters: []
+ capabilities: [sorting_on_source_and_counters_forbidden]
+ reason: "Sorting on _source shouldn't have been possible"
+ - do:
+ catch: /cannot sort on _source/
+ esql.query:
+ body:
+ query: 'FROM test metadata _source | sort _source'
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml
index 642407ac6d45b..ebf464ba667db 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/40_tsdb.yml
@@ -178,11 +178,19 @@ cast counter then filter:
---
sort on counter without cast:
+ - requires:
+ test_runner_features: [capabilities]
+ capabilities:
+ - method: POST
+ path: /_query
+ parameters: []
+ capabilities: [sorting_on_source_and_counters_forbidden]
+ reason: "Sorting on counters shouldn't have been possible"
- do:
- catch: bad_request
+ catch: /cannot sort on counter_long/
esql.query:
body:
- query: 'from test | KEEP k8s.pod.network.tx | sort @k8s.pod.network.tx | limit 1'
+ query: 'from test | KEEP k8s.pod.network.tx | sort k8s.pod.network.tx | limit 1'
---
cast then sort on counter:
From 2f09fb66e95b327048156d2ef970ebd6c0e2fe23 Mon Sep 17 00:00:00 2001
From: Pooya Salehi
Date: Mon, 14 Oct 2024 11:59:44 +0200
Subject: [PATCH 12/77] Preserve thread context when waiting for segment
generation in RTG (#114623)
Closes ES-9778
---
docs/changelog/114623.yaml | 5 +++++
.../org/elasticsearch/action/get/TransportGetAction.java | 9 +++++----
2 files changed, 10 insertions(+), 4 deletions(-)
create mode 100644 docs/changelog/114623.yaml
diff --git a/docs/changelog/114623.yaml b/docs/changelog/114623.yaml
new file mode 100644
index 0000000000000..817a8e874bcc0
--- /dev/null
+++ b/docs/changelog/114623.yaml
@@ -0,0 +1,5 @@
+pr: 114623
+summary: Preserve thread context when waiting for segment generation in RTG
+area: CRUD
+type: bug
+issues: []
diff --git a/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java b/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java
index 99eac250641ae..fb4b3907d2bfd 100644
--- a/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java
+++ b/server/src/main/java/org/elasticsearch/action/get/TransportGetAction.java
@@ -20,6 +20,7 @@
import org.elasticsearch.action.NoShardAvailableActionException;
import org.elasticsearch.action.admin.indices.refresh.TransportShardRefreshAction;
import org.elasticsearch.action.support.ActionFilters;
+import org.elasticsearch.action.support.ContextPreservingActionListener;
import org.elasticsearch.action.support.replication.BasicReplicationRequest;
import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
import org.elasticsearch.client.internal.node.NodeClient;
@@ -284,11 +285,11 @@ private void tryGetFromTranslog(GetRequest request, IndexShard indexShard, Disco
} else {
assert r.segmentGeneration() > -1L;
assert r.primaryTerm() > Engine.UNKNOWN_PRIMARY_TERM;
- indexShard.waitForPrimaryTermAndGeneration(
- r.primaryTerm(),
- r.segmentGeneration(),
- listener.delegateFailureAndWrap((ll, aLong) -> super.asyncShardOperation(request, shardId, ll))
+ final ActionListener termAndGenerationListener = ContextPreservingActionListener.wrapPreservingContext(
+ listener.delegateFailureAndWrap((ll, aLong) -> super.asyncShardOperation(request, shardId, ll)),
+ threadPool.getThreadContext()
);
+ indexShard.waitForPrimaryTermAndGeneration(r.primaryTerm(), r.segmentGeneration(), termAndGenerationListener);
}
}
}), TransportGetFromTranslogAction.Response::new, getExecutor(request, shardId))
From 4ab2e6157db6ea02c2abd824ce4c9c03b560cd88 Mon Sep 17 00:00:00 2001
From: Craig Taverner
Date: Mon, 14 Oct 2024 12:01:53 +0200
Subject: [PATCH 13/77] Fix failing tests after PR clash (#114625)
Two PRs conflicted without github or CI noticing. The first added these
tests, and the second modified their behaviour. Both went green in CI
and both were merged within an hour of each other.
* PR that added the tests:
* https://github.com/elastic/elasticsearch/pull/112938
* merged 14:13CET
* PR that changed the behaviour of these tests:
* https://github.com/elastic/elasticsearch/pull/114411
* merged 14:48CET
---
muted-tests.yml | 6 --
.../optimizer/PhysicalPlanOptimizerTests.java | 58 +++++++++----------
2 files changed, 28 insertions(+), 36 deletions(-)
diff --git a/muted-tests.yml b/muted-tests.yml
index d0fc50de31bd1..975eb0c434054 100644
--- a/muted-tests.yml
+++ b/muted-tests.yml
@@ -363,12 +363,6 @@ tests:
- class: org.elasticsearch.backwards.MixedClusterClientYamlTestSuiteIT
method: test {p0=synonyms/60_synonym_rule_get/Synonym rule not found}
issue: https://github.com/elastic/elasticsearch/issues/114444
-- class: org.elasticsearch.xpack.esql.optimizer.PhysicalPlanOptimizerTests
- method: testPushSpatialIntersectsEvalToSource {default}
- issue: https://github.com/elastic/elasticsearch/issues/114627
-- class: org.elasticsearch.xpack.esql.optimizer.PhysicalPlanOptimizerTests
- method: testPushWhereEvalToSource {default}
- issue: https://github.com/elastic/elasticsearch/issues/114628
- class: org.elasticsearch.xpack.inference.integration.ModelRegistryIT
method: testGetModel
issue: https://github.com/elastic/elasticsearch/issues/114657
diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
index 6746b8ff61268..114aed68761fe 100644
--- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
+++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java
@@ -3211,28 +3211,28 @@ public void testPushSpatialIntersectsStringToSource() {
/**
* Plan:
*
- * LimitExec[1000[INTEGER]]
- * \_ExchangeExec[[],false]
- * \_FragmentExec[filter=null, estimatedRowSize=0, reducer=[], fragment=[
+ * EvalExec[[scalerank{f}#8 AS rank]]
+ * \_LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[],false]
+ * \_FragmentExec[filter=null, estimatedRowSize=0, reducer=[], fragment=[
* Limit[1000[INTEGER]]
- * \_Filter[rank{r}#4 lt 4[INTEGER]]
- * \_Eval[[scalerank{f}#8 AS rank]]
- * \_EsRelation[airports][abbrev{f}#6, city{f}#12, city_location{f}#13, count..]]]
+ * \_Filter[scalerank{f}#8 < 4[INTEGER]]
+ * \_EsRelation[airports][abbrev{f}#6, city{f}#12, city_location{f}#13, count..]]]
*
* Optimized:
*
- * LimitExec[1000[INTEGER]]
- * \_ExchangeExec[[abbrev{f}#6, city{f}#12, city_location{f}#13, country{f}#11, location{f}#10, name{f}#7, scalerank{f}#8,
- * type{f}#9, rank{r}#4],false]
- * \_ProjectExec[[abbrev{f}#6, city{f}#12, city_location{f}#13, country{f}#11, location{f}#10, name{f}#7, scalerank{f}#8,
- * type{f}#9, rank{r}#4]]
- * \_FieldExtractExec[abbrev{f}#6, city{f}#12, city_location{f}#13, count..][]
- * \_LimitExec[1000[INTEGER]]
- * \_EvalExec[[scalerank{f}#8 AS rank]]
- * \_FieldExtractExec[scalerank{f}#8][]
- * \_EsQueryExec[airports], indexMode[standard], query[{"
- * esql_single_value":{"field":"scalerank","next":{"range":{"scalerank":{"lt":4,"boost":1.0}}},"source":"rank < 4@3:9"}
- * }][_doc{f}#23], limit[], sort[] estimatedRowSize[304]
+ * EvalExec[[scalerank{f}#8 AS rank]]
+ * \_LimitExec[1000[INTEGER]]
+ * \_ExchangeExec[[abbrev{f}#6, city{f}#12, city_location{f}#13, country{f}#11, location{f}#10, name{f}#7, scalerank{f}#8,
+ * type{f}#9],false
+ * ]
+ * \_ProjectExec[[abbrev{f}#6, city{f}#12, city_location{f}#13, country{f}#11, location{f}#10, name{f}#7, scalerank{f}#8,
+ * type{f}#9]
+ * ]
+ * \_FieldExtractExec[abbrev{f}#6, city{f}#12, city_location{f}#13, count..][]
+ * \_EsQueryExec[airports], indexMode[standard], query[{
+ * "esql_single_value":{"field":"scalerank","next":{"range":{"scalerank":{"lt":4,"boost":1.0}}},"source":"rank < 4@3:9"}
+ * ][_doc{f}#23], limit[1000], sort[] estimatedRowSize[304]
*
*/
public void testPushWhereEvalToSource() {
@@ -3243,7 +3243,8 @@ public void testPushWhereEvalToSource() {
""";
var plan = this.physicalPlan(query, airports);
- var limit = as(plan, LimitExec.class);
+ var eval = as(plan, EvalExec.class);
+ var limit = as(eval.child(), LimitExec.class);
var exchange = as(limit.child(), ExchangeExec.class);
var fragment = as(exchange.child(), FragmentExec.class);
var limit2 = as(fragment.fragment(), Limit.class);
@@ -3251,16 +3252,14 @@ public void testPushWhereEvalToSource() {
assertThat("filter contains LessThan", filter.condition(), instanceOf(LessThan.class));
var optimized = optimizedPlan(plan);
- var topLimit = as(optimized, LimitExec.class);
+ eval = as(optimized, EvalExec.class);
+ var topLimit = as(eval.child(), LimitExec.class);
exchange = as(topLimit.child(), ExchangeExec.class);
var project = as(exchange.child(), ProjectExec.class);
var fieldExtract = as(project.child(), FieldExtractExec.class);
assertThat(fieldExtract.attributesToExtract().size(), greaterThan(5));
- limit = as(fieldExtract.child(), LimitExec.class);
- var eval = as(limit.child(), EvalExec.class);
- fieldExtract = as(eval.child(), FieldExtractExec.class);
- assertThat(fieldExtract.attributesToExtract().stream().map(Attribute::name).collect(Collectors.toList()), contains("scalerank"));
var source = source(fieldExtract.child());
+ assertThat(source.limit(), is(topLimit.limit()));
var condition = as(source.query(), SingleValueQuery.Builder.class);
assertThat("Expected predicate to be passed to Lucene query", condition.source().text(), equalTo("rank < 4"));
assertThat("Expected field to be passed to Lucene query", condition.field(), equalTo("scalerank"));
@@ -3281,7 +3280,8 @@ public void testPushSpatialIntersectsEvalToSource() {
""" }) {
var plan = this.physicalPlan(query, airports);
- var limit = as(plan, LimitExec.class);
+ var eval = as(plan, EvalExec.class);
+ var limit = as(eval.child(), LimitExec.class);
var exchange = as(limit.child(), ExchangeExec.class);
var fragment = as(exchange.child(), FragmentExec.class);
var limit2 = as(fragment.fragment(), Limit.class);
@@ -3289,16 +3289,14 @@ public void testPushSpatialIntersectsEvalToSource() {
assertThat("filter contains ST_INTERSECTS", filter.condition(), instanceOf(SpatialIntersects.class));
var optimized = optimizedPlan(plan);
- var topLimit = as(optimized, LimitExec.class);
+ eval = as(optimized, EvalExec.class);
+ var topLimit = as(eval.child(), LimitExec.class);
exchange = as(topLimit.child(), ExchangeExec.class);
var project = as(exchange.child(), ProjectExec.class);
var fieldExtract = as(project.child(), FieldExtractExec.class);
assertThat(fieldExtract.attributesToExtract().size(), greaterThan(5));
- limit = as(fieldExtract.child(), LimitExec.class);
- var eval = as(limit.child(), EvalExec.class);
- fieldExtract = as(eval.child(), FieldExtractExec.class);
- assertThat(fieldExtract.attributesToExtract().stream().map(Attribute::name).collect(Collectors.toList()), contains("location"));
var source = source(fieldExtract.child());
+ assertThat(source.limit(), is(topLimit.limit()));
var condition = as(source.query(), SpatialRelatesQuery.ShapeQueryBuilder.class);
assertThat("Geometry field name", condition.fieldName(), equalTo("location"));
assertThat("Spatial relationship", condition.relation(), equalTo(ShapeRelation.INTERSECTS));
From 98e0a4e953d339402c87ed426a70e6cc8320c17f Mon Sep 17 00:00:00 2001
From: Kostas Krikellas <131142368+kkrik-es@users.noreply.github.com>
Date: Mon, 14 Oct 2024 13:03:02 +0300
Subject: [PATCH 14/77] Guard second doc parsing pass with index setting
(#114649)
* Guard second doc parsing pass with index setting
* add test
* updates
* updates
* merge
---
.../21_synthetic_source_stored.yml | 49 +++++++++++++++++++
.../common/settings/IndexScopedSettings.java | 1 +
.../elasticsearch/index/IndexSettings.java | 21 ++++++++
.../index/mapper/DocumentParserContext.java | 7 ++-
.../TransportResumeFollowActionTests.java | 1 +
5 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/21_synthetic_source_stored.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/21_synthetic_source_stored.yml
index dfe6c9820a16a..eab51427876aa 100644
--- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/21_synthetic_source_stored.yml
+++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/21_synthetic_source_stored.yml
@@ -411,6 +411,55 @@ index param - nested array within array:
- match: { hits.hits.0._source.path.to.some.3.id: [ 1000, 2000 ] }
+---
+index param - nested array within array - disabled second pass:
+ - requires:
+ cluster_features: ["mapper.synthetic_source_keep", "mapper.bwc_workaround_9_0"]
+ reason: requires tracking ignored source
+
+ - do:
+ indices.create:
+ index: test
+ body:
+ settings:
+ index:
+ synthetic_source:
+ enable_second_doc_parsing_pass: false
+ mappings:
+ _source:
+ mode: synthetic
+ properties:
+ name:
+ type: keyword
+ path:
+ properties:
+ to:
+ properties:
+ some:
+ synthetic_source_keep: arrays
+ properties:
+ id:
+ type: integer
+
+ - do:
+ bulk:
+ index: test
+ refresh: true
+ body:
+ - '{ "create": { } }'
+ - '{ "name": "A", "path": [ { "to": [ { "some" : [ { "id": 10 }, { "id": [1, 3, 2] } ] }, { "some": { "id": 100 } } ] }, { "to": { "some": { "id": [1000, 2000] } } } ] }'
+ - match: { errors: false }
+
+ - do:
+ search:
+ index: test
+ sort: name
+ - match: { hits.hits.0._source.name: A }
+ - length: { hits.hits.0._source.path.to.some: 2}
+ - match: { hits.hits.0._source.path.to.some.0.id: 10 }
+ - match: { hits.hits.0._source.path.to.some.1.id: [ 1, 3, 2] }
+
+
---
# 112156
stored field under object with store_array_source:
diff --git a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
index 884ce38fba391..f5276bbe49b63 100644
--- a/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
+++ b/server/src/main/java/org/elasticsearch/common/settings/IndexScopedSettings.java
@@ -187,6 +187,7 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
FieldMapper.SYNTHETIC_SOURCE_KEEP_INDEX_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING,
IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING,
+ IndexSettings.SYNTHETIC_SOURCE_SECOND_DOC_PARSING_PASS_SETTING,
SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING,
// validate that built-in similarities don't get redefined
diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java
index f3f8ce4b8e7e4..347b44a22e7c0 100644
--- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java
+++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java
@@ -652,6 +652,13 @@ public Iterator> settings() {
Property.Final
);
+ public static final Setting SYNTHETIC_SOURCE_SECOND_DOC_PARSING_PASS_SETTING = Setting.boolSetting(
+ "index.synthetic_source.enable_second_doc_parsing_pass",
+ true,
+ Property.IndexScope,
+ Property.Dynamic
+ );
+
/**
* Returns true
if TSDB encoding is enabled. The default is true
*/
@@ -821,6 +828,7 @@ private void setRetentionLeaseMillis(final TimeValue retentionLease) {
private volatile long mappingDimensionFieldsLimit;
private volatile boolean skipIgnoredSourceWrite;
private volatile boolean skipIgnoredSourceRead;
+ private volatile boolean syntheticSourceSecondDocParsingPassEnabled;
private final SourceFieldMapper.Mode indexMappingSourceMode;
/**
@@ -982,6 +990,7 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
es87TSDBCodecEnabled = scopedSettings.get(TIME_SERIES_ES87TSDB_CODEC_ENABLED_SETTING);
skipIgnoredSourceWrite = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING);
skipIgnoredSourceRead = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
+ syntheticSourceSecondDocParsingPassEnabled = scopedSettings.get(SYNTHETIC_SOURCE_SECOND_DOC_PARSING_PASS_SETTING);
indexMappingSourceMode = scopedSettings.get(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING);
scopedSettings.addSettingsUpdateConsumer(
@@ -1070,6 +1079,10 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
this::setSkipIgnoredSourceWrite
);
scopedSettings.addSettingsUpdateConsumer(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING, this::setSkipIgnoredSourceRead);
+ scopedSettings.addSettingsUpdateConsumer(
+ SYNTHETIC_SOURCE_SECOND_DOC_PARSING_PASS_SETTING,
+ this::setSyntheticSourceSecondDocParsingPassEnabled
+ );
}
private void setSearchIdleAfter(TimeValue searchIdleAfter) {
@@ -1662,6 +1675,14 @@ private void setSkipIgnoredSourceRead(boolean value) {
this.skipIgnoredSourceRead = value;
}
+ private void setSyntheticSourceSecondDocParsingPassEnabled(boolean syntheticSourceSecondDocParsingPassEnabled) {
+ this.syntheticSourceSecondDocParsingPassEnabled = syntheticSourceSecondDocParsingPassEnabled;
+ }
+
+ public boolean isSyntheticSourceSecondDocParsingPassEnabled() {
+ return syntheticSourceSecondDocParsingPassEnabled;
+ }
+
public SourceFieldMapper.Mode getIndexMappingSourceMode() {
return indexMappingSourceMode;
}
diff --git a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java
index ac236e5a7e5fd..2eec14bd1a8d6 100644
--- a/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java
+++ b/server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java
@@ -111,6 +111,7 @@ public int get() {
private final Set ignoredFields;
private final List ignoredFieldValues;
private final List ignoredFieldsMissingValues;
+ private final boolean inArrayScopeEnabled;
private boolean inArrayScope;
private final Map> dynamicMappers;
@@ -143,6 +144,7 @@ private DocumentParserContext(
Set ignoreFields,
List ignoredFieldValues,
List ignoredFieldsWithNoSource,
+ boolean inArrayScopeEnabled,
boolean inArrayScope,
Map> dynamicMappers,
Map dynamicObjectMappers,
@@ -164,6 +166,7 @@ private DocumentParserContext(
this.ignoredFields = ignoreFields;
this.ignoredFieldValues = ignoredFieldValues;
this.ignoredFieldsMissingValues = ignoredFieldsWithNoSource;
+ this.inArrayScopeEnabled = inArrayScopeEnabled;
this.inArrayScope = inArrayScope;
this.dynamicMappers = dynamicMappers;
this.dynamicObjectMappers = dynamicObjectMappers;
@@ -188,6 +191,7 @@ private DocumentParserContext(ObjectMapper parent, ObjectMapper.Dynamic dynamic,
in.ignoredFields,
in.ignoredFieldValues,
in.ignoredFieldsMissingValues,
+ in.inArrayScopeEnabled,
in.inArrayScope,
in.dynamicMappers,
in.dynamicObjectMappers,
@@ -219,6 +223,7 @@ protected DocumentParserContext(
new HashSet<>(),
new ArrayList<>(),
new ArrayList<>(),
+ mappingParserContext.getIndexSettings().isSyntheticSourceSecondDocParsingPassEnabled(),
false,
new HashMap<>(),
new HashMap<>(),
@@ -371,7 +376,7 @@ public final Collection getIgnoredFieldsMiss
* Applies to synthetic source only.
*/
public final DocumentParserContext maybeCloneForArray(Mapper mapper) throws IOException {
- if (canAddIgnoredField() && mapper instanceof ObjectMapper) {
+ if (canAddIgnoredField() && mapper instanceof ObjectMapper && inArrayScopeEnabled) {
boolean isNested = mapper instanceof NestedObjectMapper;
if ((inArrayScope == false && isNested == false) || (inArrayScope && isNested)) {
DocumentParserContext subcontext = switchParser(parser());
diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
index 357e1bca38e8f..ef03fd0ba6f0e 100644
--- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
+++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/action/TransportResumeFollowActionTests.java
@@ -333,6 +333,7 @@ public void testDynamicIndexSettingsAreClassified() {
replicatedSettings.add(IndexSettings.MAX_SHINGLE_DIFF_SETTING);
replicatedSettings.add(IndexSettings.TIME_SERIES_END_TIME);
replicatedSettings.add(IndexSettings.PREFER_ILM_SETTING);
+ replicatedSettings.add(IndexSettings.SYNTHETIC_SOURCE_SECOND_DOC_PARSING_PASS_SETTING);
replicatedSettings.add(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
replicatedSettings.add(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_WRITE_SETTING);
replicatedSettings.add(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING);
From c4118c639f11ae111cea6992376e1b046883d15f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aur=C3=A9lien=20FOUCRET?=
Date: Mon, 14 Oct 2024 12:50:00 +0200
Subject: [PATCH 15/77] Fix termStats posting usage (#114644)
---
.../elasticsearch/script/ScriptTermStats.java | 59 +++++++++----------
.../script/ScriptTermStatsTests.java | 18 +++---
2 files changed, 36 insertions(+), 41 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/script/ScriptTermStats.java b/server/src/main/java/org/elasticsearch/script/ScriptTermStats.java
index 9dde32cc75e6a..b27019765e33b 100644
--- a/server/src/main/java/org/elasticsearch/script/ScriptTermStats.java
+++ b/server/src/main/java/org/elasticsearch/script/ScriptTermStats.java
@@ -12,9 +12,8 @@
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermState;
import org.apache.lucene.index.TermStates;
-import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.elasticsearch.common.util.CachedSupplier;
import org.elasticsearch.features.NodeFeature;
@@ -71,17 +70,15 @@ public int uniqueTermsCount() {
public int matchedTermsCount() {
final int docId = docIdSupplier.getAsInt();
int matchedTerms = 0;
+ advancePostings(docId);
- try {
- for (PostingsEnum postingsEnum : postingsSupplier.get()) {
- if (postingsEnum != null && postingsEnum.advance(docId) == docId && postingsEnum.freq() > 0) {
- matchedTerms++;
- }
+ for (PostingsEnum postingsEnum : postingsSupplier.get()) {
+ if (postingsEnum != null && postingsEnum.docID() == docId) {
+ matchedTerms++;
}
- return matchedTerms;
- } catch (IOException e) {
- throw new UncheckedIOException(e);
}
+
+ return matchedTerms;
}
/**
@@ -150,8 +147,9 @@ public StatsSummary termFreq() {
final int docId = docIdSupplier.getAsInt();
try {
+ advancePostings(docId);
for (PostingsEnum postingsEnum : postingsSupplier.get()) {
- if (postingsEnum == null || postingsEnum.advance(docId) != docId) {
+ if (postingsEnum == null || postingsEnum.docID() != docId) {
statsSummary.accept(0);
} else {
statsSummary.accept(postingsEnum.freq());
@@ -170,12 +168,13 @@ public StatsSummary termFreq() {
* @return statistics on termPositions for the terms of the query in the current dac
*/
public StatsSummary termPositions() {
- try {
- statsSummary.reset();
- int docId = docIdSupplier.getAsInt();
+ statsSummary.reset();
+ int docId = docIdSupplier.getAsInt();
+ try {
+ advancePostings(docId);
for (PostingsEnum postingsEnum : postingsSupplier.get()) {
- if (postingsEnum == null || postingsEnum.advance(docId) != docId) {
+ if (postingsEnum == null || postingsEnum.docID() != docId) {
continue;
}
for (int i = 0; i < postingsEnum.freq(); i++) {
@@ -206,25 +205,9 @@ private TermStates[] loadTermContexts() {
private PostingsEnum[] loadPostings() {
try {
PostingsEnum[] postings = new PostingsEnum[terms.length];
- TermStates[] contexts = termContextsSupplier.get();
for (int i = 0; i < terms.length; i++) {
- TermStates termStates = contexts[i];
- if (termStates.docFreq() == 0) {
- postings[i] = null;
- continue;
- }
-
- TermState state = termStates.get(leafReaderContext);
- if (state == null) {
- postings[i] = null;
- continue;
- }
-
- TermsEnum termsEnum = leafReaderContext.reader().terms(terms[i].field()).iterator();
- termsEnum.seekExact(terms[i].bytes(), state);
-
- postings[i] = termsEnum.postings(null, PostingsEnum.ALL);
+ postings[i] = leafReaderContext.reader().postings(terms[i], PostingsEnum.POSITIONS);
}
return postings;
@@ -232,4 +215,16 @@ private PostingsEnum[] loadPostings() {
throw new UncheckedIOException(e);
}
}
+
+ private void advancePostings(int targetDocId) {
+ try {
+ for (PostingsEnum posting : postingsSupplier.get()) {
+ if (posting != null && posting.docID() < targetDocId && posting.docID() != DocIdSetIterator.NO_MORE_DOCS) {
+ posting.advance(targetDocId);
+ }
+ }
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
}
diff --git a/server/src/test/java/org/elasticsearch/script/ScriptTermStatsTests.java b/server/src/test/java/org/elasticsearch/script/ScriptTermStatsTests.java
index b1b6a11764120..239c90bdee2fd 100644
--- a/server/src/test/java/org/elasticsearch/script/ScriptTermStatsTests.java
+++ b/server/src/test/java/org/elasticsearch/script/ScriptTermStatsTests.java
@@ -48,9 +48,9 @@ public void testMatchedTermsCount() throws IOException {
// Partial match
assertAllDocs(
- Set.of(new Term("field", "foo"), new Term("field", "baz")),
+ Set.of(new Term("field", "foo"), new Term("field", "qux"), new Term("field", "baz")),
ScriptTermStats::matchedTermsCount,
- Map.of("doc-1", equalTo(1), "doc-2", equalTo(1), "doc-3", equalTo(0))
+ Map.of("doc-1", equalTo(2), "doc-2", equalTo(1), "doc-3", equalTo(0))
);
// Always returns 0 when no term is provided.
@@ -211,12 +211,12 @@ public void testTermFreq() throws IOException {
// With missing terms
{
assertAllDocs(
- Set.of(new Term("field", "foo"), new Term("field", "baz")),
+ Set.of(new Term("field", "foo"), new Term("field", "qux"), new Term("field", "baz")),
ScriptTermStats::termFreq,
Map.ofEntries(
- Map.entry("doc-1", equalTo(new StatsSummary(2, 1, 0, 1))),
- Map.entry("doc-2", equalTo(new StatsSummary(2, 2, 0, 2))),
- Map.entry("doc-3", equalTo(new StatsSummary(2, 0, 0, 0)))
+ Map.entry("doc-1", equalTo(new StatsSummary(3, 2, 0, 1))),
+ Map.entry("doc-2", equalTo(new StatsSummary(3, 2, 0, 2))),
+ Map.entry("doc-3", equalTo(new StatsSummary(3, 0, 0, 0)))
)
);
}
@@ -274,10 +274,10 @@ public void testTermPositions() throws IOException {
// With missing terms
{
assertAllDocs(
- Set.of(new Term("field", "foo"), new Term("field", "baz")),
+ Set.of(new Term("field", "foo"), new Term("field", "qux"), new Term("field", "baz")),
ScriptTermStats::termPositions,
Map.ofEntries(
- Map.entry("doc-1", equalTo(new StatsSummary(1, 1, 1, 1))),
+ Map.entry("doc-1", equalTo(new StatsSummary(2, 4, 1, 3))),
Map.entry("doc-2", equalTo(new StatsSummary(2, 3, 1, 2))),
Map.entry("doc-3", equalTo(new StatsSummary()))
)
@@ -311,7 +311,7 @@ private void withIndexSearcher(CheckedConsumer consu
Document doc = new Document();
doc.add(new TextField("id", "doc-1", Field.Store.YES));
- doc.add(new TextField("field", "foo bar", Field.Store.YES));
+ doc.add(new TextField("field", "foo bar qux", Field.Store.YES));
w.addDocument(doc);
doc = new Document();
From 8c31d80ae5f73df3d989ffbb4c29e73c44a526a2 Mon Sep 17 00:00:00 2001
From: Ievgen Degtiarenko
Date: Mon, 14 Oct 2024 13:03:47 +0200
Subject: [PATCH 16/77] Node shutdown test integration test (#114582)
This change adds a test case that verifies that the node
can be shutdown while hosting an index with 0-1 or 0-all
auto-expand configuration.
---
.../xpack/shutdown/NodeShutdownShardsIT.java | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
index 0e162238e96c8..ee7438dfca428 100644
--- a/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
+++ b/x-pack/plugin/shutdown/src/internalClusterTest/java/org/elasticsearch/xpack/shutdown/NodeShutdownShardsIT.java
@@ -375,6 +375,32 @@ public void testAutoExpandDuringReplace() throws Exception {
assertIndexSetting("index", "index.number_of_replicas", "1");
}
+ public void testAutoExpandDuringShutdown() throws Exception {
+
+ var node1 = internalCluster().startNode();
+ var node2 = internalCluster().startNode();
+
+ createIndex("index", indexSettings(1, 0).put("index.auto_expand_replicas", randomFrom("0-all", "0-1")).build());
+ indexRandomData("index");
+
+ ensureGreen("index");
+ assertIndexSetting("index", "index.number_of_replicas", "1");
+
+ var nodeNameToShutdown = randomFrom(node1, node2);
+ var nodeIdToShutdown = getNodeId(nodeNameToShutdown);
+
+ putNodeShutdown(nodeIdToShutdown, SingleNodeShutdownMetadata.Type.REMOVE, null);
+
+ ensureGreen("index");
+ assertIndexSetting("index", "index.number_of_replicas", "0");
+
+ assertBusy(() -> assertNodeShutdownStatus(nodeIdToShutdown, COMPLETE));
+ internalCluster().stopNode(nodeIdToShutdown);
+
+ ensureGreen("index");
+ assertIndexSetting("index", "index.number_of_replicas", "0");
+ }
+
public void testNodeShutdownWithUnassignedShards() throws Exception {
final String nodeA = internalCluster().startNode();
final String nodeAId = getNodeId(nodeA);
From 7157c0a4c4a3638c2d264b42b234491d27ca7557 Mon Sep 17 00:00:00 2001
From: "elastic-renovate-prod[bot]"
<174716857+elastic-renovate-prod[bot]@users.noreply.github.com>
Date: Mon, 14 Oct 2024 14:01:59 +0200
Subject: [PATCH 17/77] Update docker.elastic.co/wolfi/chainguard-base:latest
Docker digest to 277ebb4 (main) (#114409)
* Update docker.elastic.co/wolfi/chainguard-base:latest Docker digest to 277ebb4
* Tweak renovate replace pattern
---------
Co-authored-by: elastic-renovate-prod[bot] <174716857+elastic-renovate-prod[bot]@users.noreply.github.com>
Co-authored-by: Rene Groeschke
---
.../main/java/org/elasticsearch/gradle/internal/DockerBase.java | 2 +-
renovate.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java
index 9d78d3229edc1..d80256ee36a17 100644
--- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java
+++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java
@@ -27,7 +27,7 @@ public enum DockerBase {
// Chainguard based wolfi image with latest jdk
// This is usually updated via renovatebot
// spotless:off
- WOLFI("docker.elastic.co/wolfi/chainguard-base:latest@sha256:90888b190da54062f67f3fef1372eb0ae7d81ea55f5a1f56d748b13e4853d984",
+ WOLFI("docker.elastic.co/wolfi/chainguard-base:latest@sha256:277ebb42c458ef39cb4028f9204f0b3d51d8cd628ea737a65696a1143c3e42fe",
"-wolfi",
"apk"
),
diff --git a/renovate.json b/renovate.json
index 0a1d588e6332c..293a2bb262375 100644
--- a/renovate.json
+++ b/renovate.json
@@ -30,7 +30,7 @@
"\\s*\"?(?[^\\s:@\"]+)(?::(?[-a-zA-Z0-9.]+))?(?:@(?sha256:[a-zA-Z0-9]+))?\"?"
],
"currentValueTemplate": "{{#if currentValue}}{{{currentValue}}}{{else}}latest{{/if}}",
- "autoReplaceStringTemplate": "\"{{{depName}}}{{#if newValue}}:{{{newValue}}}{{/if}}{{#if newDigest}}@{{{newDigest}}}{{/if}}\"",
+ "autoReplaceStringTemplate": "{{{depName}}}{{#if newValue}}:{{{newValue}}}{{/if}}{{#if newDigest}}@{{{newDigest}}}{{/if}}\"",
"datasourceTemplate": "docker"
}
]
From af35cada9251eb81aff7563c8012cfb93103c18d Mon Sep 17 00:00:00 2001
From: elasticsearchmachine
<58790826+elasticsearchmachine@users.noreply.github.com>
Date: Mon, 14 Oct 2024 23:53:26 +1100
Subject: [PATCH 18/77] Mute
org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT test
{yaml=reference/rest-api/usage/line_38} #113694
---
muted-tests.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/muted-tests.yml b/muted-tests.yml
index 975eb0c434054..2e6fd10c6ef65 100644
--- a/muted-tests.yml
+++ b/muted-tests.yml
@@ -366,6 +366,9 @@ tests:
- class: org.elasticsearch.xpack.inference.integration.ModelRegistryIT
method: testGetModel
issue: https://github.com/elastic/elasticsearch/issues/114657
+- class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT
+ method: test {yaml=reference/rest-api/usage/line_38}
+ issue: https://github.com/elastic/elasticsearch/issues/113694
# Examples:
#
From 51ea024eda1336a300e2836d1659a42691880b00 Mon Sep 17 00:00:00 2001
From: Mary Gouseti
Date: Mon, 14 Oct 2024 16:02:24 +0300
Subject: [PATCH 19/77] Introduce CRUD APIs for data stream options (#113945)
In this PR we introduce two endpoint PUT and GET to manage the data
stream options and consequently the failure store configuration on the
data stream level. This means that we can manage the failure store of
existing data streams.
The APIs look like:
```
# Enable/disable
PUT _data_stream/my-data-stream/_options
{
"failure_store": {
"enabled": true
}
}
# Remove existing configuration
DELETE _data_stream/my-data-stream/_options
# Retrieve
GET _data_stream/my-data-stream/_options
{
"failure_store": {
"enabled": true
}
}
```
Future work:
- Document the new APIs
- Convert `DataStreamOptionsIT.java` to a yaml test.
---
.../datastreams/DataStreamOptionsIT.java | 144 +++++++++++
.../src/main/java/module-info.java | 1 +
.../datastreams/DataStreamsPlugin.java | 20 ++
.../action/DeleteDataStreamOptionsAction.java | 108 +++++++++
.../action/GetDataStreamOptionsAction.java | 223 ++++++++++++++++++
.../action/PutDataStreamOptionsAction.java | 165 +++++++++++++
...ransportDeleteDataStreamOptionsAction.java | 86 +++++++
.../TransportGetDataStreamOptionsAction.java | 104 ++++++++
.../TransportPutDataStreamOptionsAction.java | 92 ++++++++
.../RestDeleteDataStreamOptionsAction.java | 54 +++++
.../rest/RestGetDataStreamOptionsAction.java | 58 +++++
.../rest/RestPutDataStreamOptionsAction.java | 58 +++++
.../metadata/MetadataDataStreamsService.java | 94 ++++++++
.../metadata/DataStreamOptionsTests.java | 11 +-
.../MetadataDataStreamsServiceTests.java | 33 +++
.../xpack/security/operator/Constants.java | 3 +
16 files changed, 1253 insertions(+), 1 deletion(-)
create mode 100644 modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DataStreamOptionsIT.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/DeleteDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/GetDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/PutDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportDeleteDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportGetDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportPutDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestDeleteDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestGetDataStreamOptionsAction.java
create mode 100644 modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestPutDataStreamOptionsAction.java
diff --git a/modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DataStreamOptionsIT.java b/modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DataStreamOptionsIT.java
new file mode 100644
index 0000000000000..980cc32a12c68
--- /dev/null
+++ b/modules/data-streams/src/javaRestTest/java/org/elasticsearch/datastreams/DataStreamOptionsIT.java
@@ -0,0 +1,144 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+package org.elasticsearch.datastreams;
+
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.Response;
+import org.junit.Before;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+
+/**
+ * This should be a yaml test, but in order to write one we would need to expose the new APIs in the rest-api-spec.
+ * We do not want to do that until the feature flag is removed. For this reason, we temporarily, test the new APIs here.
+ * Please convert this to a yaml test when the feature flag is removed.
+ */
+public class DataStreamOptionsIT extends DisabledSecurityDataStreamTestCase {
+
+ private static final String DATA_STREAM_NAME = "failure-data-stream";
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setup() throws IOException {
+ Request putComposableIndexTemplateRequest = new Request("POST", "/_index_template/ds-template");
+ putComposableIndexTemplateRequest.setJsonEntity("""
+ {
+ "index_patterns": ["failure-data-stream"],
+ "template": {
+ "settings": {
+ "number_of_replicas": 0
+ }
+ },
+ "data_stream": {
+ "failure_store": true
+ }
+ }
+ """);
+ assertOK(client().performRequest(putComposableIndexTemplateRequest));
+
+ assertOK(client().performRequest(new Request("PUT", "/_data_stream/" + DATA_STREAM_NAME)));
+ // Initialize the failure store.
+ assertOK(client().performRequest(new Request("POST", DATA_STREAM_NAME + "/_rollover?target_failure_store")));
+ ensureGreen(DATA_STREAM_NAME);
+
+ final Response dataStreamResponse = client().performRequest(new Request("GET", "/_data_stream/" + DATA_STREAM_NAME));
+ List dataStreams = (List) entityAsMap(dataStreamResponse).get("data_streams");
+ assertThat(dataStreams.size(), is(1));
+ Map dataStream = (Map) dataStreams.get(0);
+ assertThat(dataStream.get("name"), equalTo(DATA_STREAM_NAME));
+ List backingIndices = getIndices(dataStream);
+ assertThat(backingIndices.size(), is(1));
+ List failureStore = getFailureStore(dataStream);
+ assertThat(failureStore.size(), is(1));
+ }
+
+ public void testEnableDisableFailureStore() throws IOException {
+ {
+ assertAcknowledged(client().performRequest(new Request("DELETE", "/_data_stream/" + DATA_STREAM_NAME + "/_options")));
+ assertFailureStore(false, 1);
+ assertDataStreamOptions(null);
+ }
+ {
+ Request enableRequest = new Request("PUT", "/_data_stream/" + DATA_STREAM_NAME + "/_options");
+ enableRequest.setJsonEntity("""
+ {
+ "failure_store": {
+ "enabled": true
+ }
+ }""");
+ assertAcknowledged(client().performRequest(enableRequest));
+ assertFailureStore(true, 1);
+ assertDataStreamOptions(true);
+ }
+
+ {
+ Request disableRequest = new Request("PUT", "/_data_stream/" + DATA_STREAM_NAME + "/_options");
+ disableRequest.setJsonEntity("""
+ {
+ "failure_store": {
+ "enabled": false
+ }
+ }""");
+ assertAcknowledged(client().performRequest(disableRequest));
+ assertFailureStore(false, 1);
+ assertDataStreamOptions(false);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void assertFailureStore(boolean failureStoreEnabled, int failureStoreSize) throws IOException {
+ final Response dataStreamResponse = client().performRequest(new Request("GET", "/_data_stream/" + DATA_STREAM_NAME));
+ List dataStreams = (List) entityAsMap(dataStreamResponse).get("data_streams");
+ assertThat(dataStreams.size(), is(1));
+ Map dataStream = (Map) dataStreams.get(0);
+ assertThat(dataStream.get("name"), equalTo(DATA_STREAM_NAME));
+ assertThat(dataStream.containsKey("failure_store"), is(true));
+ // Ensure the failure store is set to the provided value
+ assertThat(((Map) dataStream.get("failure_store")).get("enabled"), equalTo(failureStoreEnabled));
+ // And the failure indices preserved
+ List failureStore = getFailureStore(dataStream);
+ assertThat(failureStore.size(), is(failureStoreSize));
+ }
+
+ @SuppressWarnings("unchecked")
+ private void assertDataStreamOptions(Boolean failureStoreEnabled) throws IOException {
+ final Response dataStreamResponse = client().performRequest(new Request("GET", "/_data_stream/" + DATA_STREAM_NAME + "/_options"));
+ List dataStreams = (List) entityAsMap(dataStreamResponse).get("data_streams");
+ assertThat(dataStreams.size(), is(1));
+ Map dataStream = (Map) dataStreams.get(0);
+ assertThat(dataStream.get("name"), equalTo(DATA_STREAM_NAME));
+ Map> options = (Map>) dataStream.get("options");
+ if (failureStoreEnabled == null) {
+ assertThat(options, nullValue());
+ } else {
+ assertThat(options.containsKey("failure_store"), is(true));
+ assertThat(options.get("failure_store").get("enabled"), equalTo(failureStoreEnabled));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private List getFailureStore(Map response) {
+ var failureStore = (Map) response.get("failure_store");
+ return getIndices(failureStore);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ private List getIndices(Map response) {
+ List> indices = (List>) response.get("indices");
+ return indices.stream().map(index -> index.get("index_name")).toList();
+ }
+}
diff --git a/modules/data-streams/src/main/java/module-info.java b/modules/data-streams/src/main/java/module-info.java
index 16229f9eb2394..2d49029c1023c 100644
--- a/modules/data-streams/src/main/java/module-info.java
+++ b/modules/data-streams/src/main/java/module-info.java
@@ -17,6 +17,7 @@
exports org.elasticsearch.datastreams.action to org.elasticsearch.server;
exports org.elasticsearch.datastreams.lifecycle.action to org.elasticsearch.server;
exports org.elasticsearch.datastreams.lifecycle;
+ exports org.elasticsearch.datastreams.options.action to org.elasticsearch.server;
provides org.elasticsearch.features.FeatureSpecification with org.elasticsearch.datastreams.DataStreamFeatures;
}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java
index 1a6465a251021..cb7445705537a 100644
--- a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamsPlugin.java
@@ -23,6 +23,7 @@
import org.elasticsearch.action.datastreams.lifecycle.GetDataStreamLifecycleAction;
import org.elasticsearch.action.datastreams.lifecycle.PutDataStreamLifecycleAction;
import org.elasticsearch.client.internal.OriginSettingClient;
+import org.elasticsearch.cluster.metadata.DataStream;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
@@ -56,6 +57,15 @@
import org.elasticsearch.datastreams.lifecycle.rest.RestExplainDataStreamLifecycleAction;
import org.elasticsearch.datastreams.lifecycle.rest.RestGetDataStreamLifecycleAction;
import org.elasticsearch.datastreams.lifecycle.rest.RestPutDataStreamLifecycleAction;
+import org.elasticsearch.datastreams.options.action.DeleteDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.action.GetDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.action.PutDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.action.TransportDeleteDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.action.TransportGetDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.action.TransportPutDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.rest.RestDeleteDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.rest.RestGetDataStreamOptionsAction;
+import org.elasticsearch.datastreams.options.rest.RestPutDataStreamOptionsAction;
import org.elasticsearch.datastreams.rest.RestCreateDataStreamAction;
import org.elasticsearch.datastreams.rest.RestDataStreamsStatsAction;
import org.elasticsearch.datastreams.rest.RestDeleteDataStreamAction;
@@ -229,6 +239,11 @@ public Collection> createComponents(PluginServices services) {
actions.add(new ActionHandler<>(DeleteDataStreamLifecycleAction.INSTANCE, TransportDeleteDataStreamLifecycleAction.class));
actions.add(new ActionHandler<>(ExplainDataStreamLifecycleAction.INSTANCE, TransportExplainDataStreamLifecycleAction.class));
actions.add(new ActionHandler<>(GetDataStreamLifecycleStatsAction.INSTANCE, TransportGetDataStreamLifecycleStatsAction.class));
+ if (DataStream.isFailureStoreFeatureFlagEnabled()) {
+ actions.add(new ActionHandler<>(GetDataStreamOptionsAction.INSTANCE, TransportGetDataStreamOptionsAction.class));
+ actions.add(new ActionHandler<>(PutDataStreamOptionsAction.INSTANCE, TransportPutDataStreamOptionsAction.class));
+ actions.add(new ActionHandler<>(DeleteDataStreamOptionsAction.INSTANCE, TransportDeleteDataStreamOptionsAction.class));
+ }
return actions;
}
@@ -261,6 +276,11 @@ public List getRestHandlers(
handlers.add(new RestDeleteDataStreamLifecycleAction());
handlers.add(new RestExplainDataStreamLifecycleAction());
handlers.add(new RestDataStreamLifecycleStatsAction());
+ if (DataStream.isFailureStoreFeatureFlagEnabled()) {
+ handlers.add(new RestGetDataStreamOptionsAction());
+ handlers.add(new RestPutDataStreamOptionsAction());
+ handlers.add(new RestDeleteDataStreamOptionsAction());
+ }
return handlers;
}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/DeleteDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/DeleteDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..98a29dd636ddf
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/DeleteDataStreamOptionsAction.java
@@ -0,0 +1,108 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionType;
+import org.elasticsearch.action.IndicesRequest;
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.action.support.master.AcknowledgedRequest;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.core.TimeValue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Removes the data stream options configuration from the requested data streams.
+ */
+public class DeleteDataStreamOptionsAction {
+
+ public static final ActionType INSTANCE = new ActionType<>("indices:admin/data_stream/options/delete");
+
+ private DeleteDataStreamOptionsAction() {/* no instances */}
+
+ public static final class Request extends AcknowledgedRequest implements IndicesRequest.Replaceable {
+
+ private String[] names;
+ private IndicesOptions indicesOptions = IndicesOptions.builder()
+ .concreteTargetOptions(IndicesOptions.ConcreteTargetOptions.ERROR_WHEN_UNAVAILABLE_TARGETS)
+ .wildcardOptions(
+ IndicesOptions.WildcardOptions.builder().matchOpen(true).matchClosed(true).allowEmptyExpressions(true).resolveAliases(false)
+ )
+ .gatekeeperOptions(IndicesOptions.GatekeeperOptions.builder().allowAliasToMultipleIndices(false).allowClosedIndices(true))
+ .build();
+
+ public Request(StreamInput in) throws IOException {
+ super(in);
+ this.names = in.readOptionalStringArray();
+ this.indicesOptions = IndicesOptions.readIndicesOptions(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeOptionalStringArray(names);
+ indicesOptions.writeIndicesOptions(out);
+ }
+
+ public Request(TimeValue masterNodeTimeout, TimeValue ackTimeout, String[] names) {
+ super(masterNodeTimeout, ackTimeout);
+ this.names = names;
+ }
+
+ public String[] getNames() {
+ return names;
+ }
+
+ @Override
+ public String[] indices() {
+ return names;
+ }
+
+ @Override
+ public IndicesOptions indicesOptions() {
+ return indicesOptions;
+ }
+
+ public Request indicesOptions(IndicesOptions indicesOptions) {
+ this.indicesOptions = indicesOptions;
+ return this;
+ }
+
+ @Override
+ public boolean includeDataStreams() {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Request request = (Request) o;
+ return Arrays.equals(names, request.names) && Objects.equals(indicesOptions, request.indicesOptions);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(indicesOptions);
+ result = 31 * result + Arrays.hashCode(names);
+ return result;
+ }
+
+ @Override
+ public IndicesRequest indices(String... indices) {
+ this.names = indices;
+ return this;
+ }
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/GetDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/GetDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..c1354da1129ca
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/GetDataStreamOptionsAction.java
@@ -0,0 +1,223 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.action.ActionType;
+import org.elasticsearch.action.IndicesRequest;
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.action.support.master.MasterNodeReadRequest;
+import org.elasticsearch.cluster.metadata.DataStreamOptions;
+import org.elasticsearch.common.collect.Iterators;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.io.stream.Writeable;
+import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
+import org.elasticsearch.core.TimeValue;
+import org.elasticsearch.xcontent.ParseField;
+import org.elasticsearch.xcontent.ToXContent;
+import org.elasticsearch.xcontent.ToXContentObject;
+import org.elasticsearch.xcontent.XContentBuilder;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This action retrieves the data stream options from every data stream. Currently, data stream options only support
+ * failure store.
+ */
+public class GetDataStreamOptionsAction {
+
+ public static final ActionType INSTANCE = new ActionType<>("indices:admin/data_stream/options/get");
+
+ private GetDataStreamOptionsAction() {/* no instances */}
+
+ public static class Request extends MasterNodeReadRequest implements IndicesRequest.Replaceable {
+
+ private String[] names;
+ private IndicesOptions indicesOptions = IndicesOptions.builder()
+ .concreteTargetOptions(IndicesOptions.ConcreteTargetOptions.ERROR_WHEN_UNAVAILABLE_TARGETS)
+ .wildcardOptions(
+ IndicesOptions.WildcardOptions.builder().matchOpen(true).matchClosed(true).allowEmptyExpressions(true).resolveAliases(false)
+ )
+ .gatekeeperOptions(IndicesOptions.GatekeeperOptions.builder().allowAliasToMultipleIndices(false).allowClosedIndices(true))
+ .build();
+ private boolean includeDefaults = false;
+
+ public Request(TimeValue masterNodeTimeout, String[] names) {
+ super(masterNodeTimeout);
+ this.names = names;
+ }
+
+ public Request(TimeValue masterNodeTimeout, String[] names, boolean includeDefaults) {
+ super(masterNodeTimeout);
+ this.names = names;
+ this.includeDefaults = includeDefaults;
+ }
+
+ public String[] getNames() {
+ return names;
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ return null;
+ }
+
+ public Request(StreamInput in) throws IOException {
+ super(in);
+ this.names = in.readOptionalStringArray();
+ this.indicesOptions = IndicesOptions.readIndicesOptions(in);
+ this.includeDefaults = in.readBoolean();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeOptionalStringArray(names);
+ indicesOptions.writeIndicesOptions(out);
+ out.writeBoolean(includeDefaults);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Request request = (Request) o;
+ return Arrays.equals(names, request.names)
+ && indicesOptions.equals(request.indicesOptions)
+ && includeDefaults == request.includeDefaults;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(indicesOptions, includeDefaults);
+ result = 31 * result + Arrays.hashCode(names);
+ return result;
+ }
+
+ @Override
+ public String[] indices() {
+ return names;
+ }
+
+ @Override
+ public IndicesOptions indicesOptions() {
+ return indicesOptions;
+ }
+
+ public boolean includeDefaults() {
+ return includeDefaults;
+ }
+
+ public Request indicesOptions(IndicesOptions indicesOptions) {
+ this.indicesOptions = indicesOptions;
+ return this;
+ }
+
+ @Override
+ public boolean includeDataStreams() {
+ return true;
+ }
+
+ @Override
+ public IndicesRequest indices(String... indices) {
+ this.names = indices;
+ return this;
+ }
+
+ public Request includeDefaults(boolean includeDefaults) {
+ this.includeDefaults = includeDefaults;
+ return this;
+ }
+ }
+
+ public static class Response extends ActionResponse implements ChunkedToXContentObject {
+ public static final ParseField DATA_STREAMS_FIELD = new ParseField("data_streams");
+
+ public record DataStreamEntry(String dataStreamName, DataStreamOptions dataStreamOptions) implements Writeable, ToXContentObject {
+
+ public static final ParseField NAME_FIELD = new ParseField("name");
+ public static final ParseField OPTIONS_FIELD = new ParseField("options");
+
+ DataStreamEntry(StreamInput in) throws IOException {
+ this(in.readString(), in.readOptionalWriteable(DataStreamOptions::read));
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeString(dataStreamName);
+ out.writeOptionalWriteable(dataStreamOptions);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+ builder.field(NAME_FIELD.getPreferredName(), dataStreamName);
+ if (dataStreamOptions != null && dataStreamOptions.isEmpty() == false) {
+ builder.field(OPTIONS_FIELD.getPreferredName(), dataStreamOptions);
+ }
+ builder.endObject();
+ return builder;
+ }
+ }
+
+ private final List dataStreams;
+
+ public Response(List dataStreams) {
+ this.dataStreams = dataStreams;
+ }
+
+ public Response(StreamInput in) throws IOException {
+ this(in.readCollectionAsList(DataStreamEntry::new));
+ }
+
+ public List getDataStreams() {
+ return dataStreams;
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeCollection(dataStreams);
+ }
+
+ @Override
+ public Iterator toXContentChunked(ToXContent.Params outerParams) {
+ return Iterators.concat(Iterators.single((builder, params) -> {
+ builder.startObject();
+ builder.startArray(DATA_STREAMS_FIELD.getPreferredName());
+ return builder;
+ }),
+ Iterators.map(dataStreams.iterator(), entry -> (builder, params) -> entry.toXContent(builder, outerParams)),
+ Iterators.single((builder, params) -> {
+ builder.endArray();
+ builder.endObject();
+ return builder;
+ })
+ );
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Response response = (Response) o;
+ return dataStreams.equals(response.dataStreams);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(dataStreams);
+ }
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/PutDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/PutDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..d055a6972312a
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/PutDataStreamOptionsAction.java
@@ -0,0 +1,165 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.ActionType;
+import org.elasticsearch.action.IndicesRequest;
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.action.support.master.AcknowledgedRequest;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.cluster.metadata.DataStreamFailureStore;
+import org.elasticsearch.cluster.metadata.DataStreamOptions;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.core.Nullable;
+import org.elasticsearch.core.TimeValue;
+import org.elasticsearch.xcontent.ConstructingObjectParser;
+import org.elasticsearch.xcontent.ParseField;
+import org.elasticsearch.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Objects;
+
+import static org.elasticsearch.action.ValidateActions.addValidationError;
+
+/**
+ * Sets the data stream options that was provided in the request to the requested data streams.
+ */
+public class PutDataStreamOptionsAction {
+
+ public static final ActionType INSTANCE = new ActionType<>("indices:admin/data_stream/options/put");
+
+ private PutDataStreamOptionsAction() {/* no instances */}
+
+ public static final class Request extends AcknowledgedRequest implements IndicesRequest.Replaceable {
+
+ public interface Factory {
+ Request create(@Nullable DataStreamFailureStore dataStreamFailureStore);
+ }
+
+ public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
+ "put_data_stream_options_request",
+ false,
+ (args, factory) -> factory.create((DataStreamFailureStore) args[0])
+ );
+
+ static {
+ PARSER.declareObjectOrNull(
+ ConstructingObjectParser.optionalConstructorArg(),
+ (p, c) -> DataStreamFailureStore.PARSER.parse(p, null),
+ null,
+ new ParseField("failure_store")
+ );
+ }
+
+ public static Request parseRequest(XContentParser parser, Factory factory) {
+ return PARSER.apply(parser, factory);
+ }
+
+ private String[] names;
+ private IndicesOptions indicesOptions = IndicesOptions.builder()
+ .concreteTargetOptions(IndicesOptions.ConcreteTargetOptions.ERROR_WHEN_UNAVAILABLE_TARGETS)
+ .wildcardOptions(
+ IndicesOptions.WildcardOptions.builder().matchOpen(true).matchClosed(true).allowEmptyExpressions(true).resolveAliases(false)
+ )
+ .gatekeeperOptions(IndicesOptions.GatekeeperOptions.builder().allowAliasToMultipleIndices(false).allowClosedIndices(true))
+ .build();
+ private final DataStreamOptions options;
+
+ public Request(StreamInput in) throws IOException {
+ super(in);
+ this.names = in.readStringArray();
+ this.indicesOptions = IndicesOptions.readIndicesOptions(in);
+ options = DataStreamOptions.read(in);
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeStringArray(names);
+ indicesOptions.writeIndicesOptions(out);
+ out.writeWriteable(options);
+ }
+
+ public Request(TimeValue masterNodeTimeout, TimeValue ackTimeout, String[] names, DataStreamOptions options) {
+ super(masterNodeTimeout, ackTimeout);
+ this.names = names;
+ this.options = options;
+ }
+
+ public Request(TimeValue masterNodeTimeout, TimeValue ackTimeout, String[] names, @Nullable DataStreamFailureStore failureStore) {
+ super(masterNodeTimeout, ackTimeout);
+ this.names = names;
+ this.options = new DataStreamOptions(failureStore);
+ }
+
+ @Override
+ public ActionRequestValidationException validate() {
+ ActionRequestValidationException validationException = null;
+ if (options.failureStore() == null) {
+ validationException = addValidationError("At least one option needs to be provided", validationException);
+ }
+ return validationException;
+ }
+
+ public String[] getNames() {
+ return names;
+ }
+
+ public DataStreamOptions getOptions() {
+ return options;
+ }
+
+ @Override
+ public String[] indices() {
+ return names;
+ }
+
+ @Override
+ public IndicesOptions indicesOptions() {
+ return indicesOptions;
+ }
+
+ public Request indicesOptions(IndicesOptions indicesOptions) {
+ this.indicesOptions = indicesOptions;
+ return this;
+ }
+
+ @Override
+ public boolean includeDataStreams() {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Request request = (Request) o;
+ return Arrays.equals(names, request.names)
+ && Objects.equals(indicesOptions, request.indicesOptions)
+ && options.equals(request.options);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(indicesOptions, options);
+ result = 31 * result + Arrays.hashCode(names);
+ return result;
+ }
+
+ @Override
+ public IndicesRequest indices(String... names) {
+ this.names = names;
+ return this;
+ }
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportDeleteDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportDeleteDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..ead23ed78222b
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportDeleteDataStreamOptionsAction.java
@@ -0,0 +1,86 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.datastreams.DataStreamsActionUtil;
+import org.elasticsearch.action.support.ActionFilters;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.action.support.master.AcknowledgedTransportMasterNodeAction;
+import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.block.ClusterBlockException;
+import org.elasticsearch.cluster.block.ClusterBlockLevel;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.MetadataDataStreamsService;
+import org.elasticsearch.cluster.service.ClusterService;
+import org.elasticsearch.common.util.concurrent.EsExecutors;
+import org.elasticsearch.indices.SystemIndices;
+import org.elasticsearch.injection.guice.Inject;
+import org.elasticsearch.tasks.Task;
+import org.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.transport.TransportService;
+
+import java.util.List;
+
+/**
+ * Transport action that resolves the data stream names from the request and removes any configured data stream options from them.
+ */
+public class TransportDeleteDataStreamOptionsAction extends AcknowledgedTransportMasterNodeAction {
+
+ private final MetadataDataStreamsService metadataDataStreamsService;
+ private final SystemIndices systemIndices;
+
+ @Inject
+ public TransportDeleteDataStreamOptionsAction(
+ TransportService transportService,
+ ClusterService clusterService,
+ ThreadPool threadPool,
+ ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver,
+ MetadataDataStreamsService metadataDataStreamsService,
+ SystemIndices systemIndices
+ ) {
+ super(
+ DeleteDataStreamOptionsAction.INSTANCE.name(),
+ transportService,
+ clusterService,
+ threadPool,
+ actionFilters,
+ DeleteDataStreamOptionsAction.Request::new,
+ indexNameExpressionResolver,
+ EsExecutors.DIRECT_EXECUTOR_SERVICE
+ );
+ this.metadataDataStreamsService = metadataDataStreamsService;
+ this.systemIndices = systemIndices;
+ }
+
+ @Override
+ protected void masterOperation(
+ Task task,
+ DeleteDataStreamOptionsAction.Request request,
+ ClusterState state,
+ ActionListener listener
+ ) {
+ List dataStreamNames = DataStreamsActionUtil.getDataStreamNames(
+ indexNameExpressionResolver,
+ state,
+ request.getNames(),
+ request.indicesOptions()
+ );
+ for (String name : dataStreamNames) {
+ systemIndices.validateDataStreamAccess(name, threadPool.getThreadContext());
+ }
+ metadataDataStreamsService.removeDataStreamOptions(dataStreamNames, request.ackTimeout(), request.masterNodeTimeout(), listener);
+ }
+
+ @Override
+ protected ClusterBlockException checkBlock(DeleteDataStreamOptionsAction.Request request, ClusterState state) {
+ return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportGetDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportGetDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..b032b35c943c0
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportGetDataStreamOptionsAction.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.datastreams.DataStreamsActionUtil;
+import org.elasticsearch.action.support.ActionFilters;
+import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
+import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.block.ClusterBlockException;
+import org.elasticsearch.cluster.block.ClusterBlockLevel;
+import org.elasticsearch.cluster.metadata.DataStream;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.service.ClusterService;
+import org.elasticsearch.common.util.concurrent.EsExecutors;
+import org.elasticsearch.indices.SystemIndices;
+import org.elasticsearch.injection.guice.Inject;
+import org.elasticsearch.tasks.Task;
+import org.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.transport.TransportService;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Collects the data streams from the cluster state and then returns for each data stream its name and its
+ * data stream options. Currently, data stream options include only the failure store configuration.
+ */
+public class TransportGetDataStreamOptionsAction extends TransportMasterNodeReadAction<
+ GetDataStreamOptionsAction.Request,
+ GetDataStreamOptionsAction.Response> {
+
+ private final SystemIndices systemIndices;
+
+ @Inject
+ public TransportGetDataStreamOptionsAction(
+ TransportService transportService,
+ ClusterService clusterService,
+ ThreadPool threadPool,
+ ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver,
+ SystemIndices systemIndices
+ ) {
+ super(
+ GetDataStreamOptionsAction.INSTANCE.name(),
+ transportService,
+ clusterService,
+ threadPool,
+ actionFilters,
+ GetDataStreamOptionsAction.Request::new,
+ indexNameExpressionResolver,
+ GetDataStreamOptionsAction.Response::new,
+ EsExecutors.DIRECT_EXECUTOR_SERVICE
+ );
+ this.systemIndices = systemIndices;
+ }
+
+ @Override
+ protected void masterOperation(
+ Task task,
+ GetDataStreamOptionsAction.Request request,
+ ClusterState state,
+ ActionListener listener
+ ) {
+ List requestedDataStreams = DataStreamsActionUtil.getDataStreamNames(
+ indexNameExpressionResolver,
+ state,
+ request.getNames(),
+ request.indicesOptions()
+ );
+ Map dataStreams = state.metadata().dataStreams();
+ for (String name : requestedDataStreams) {
+ systemIndices.validateDataStreamAccess(name, threadPool.getThreadContext());
+ }
+ listener.onResponse(
+ new GetDataStreamOptionsAction.Response(
+ requestedDataStreams.stream()
+ .map(dataStreams::get)
+ .filter(Objects::nonNull)
+ .map(
+ dataStream -> new GetDataStreamOptionsAction.Response.DataStreamEntry(
+ dataStream.getName(),
+ dataStream.getDataStreamOptions()
+ )
+ )
+ .sorted(Comparator.comparing(GetDataStreamOptionsAction.Response.DataStreamEntry::dataStreamName))
+ .toList()
+ )
+ );
+ }
+
+ @Override
+ protected ClusterBlockException checkBlock(GetDataStreamOptionsAction.Request request, ClusterState state) {
+ return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportPutDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportPutDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..b1386232c44f9
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/action/TransportPutDataStreamOptionsAction.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the "Elastic License
+ * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.action;
+
+import org.elasticsearch.action.ActionListener;
+import org.elasticsearch.action.datastreams.DataStreamsActionUtil;
+import org.elasticsearch.action.support.ActionFilters;
+import org.elasticsearch.action.support.master.AcknowledgedResponse;
+import org.elasticsearch.action.support.master.AcknowledgedTransportMasterNodeAction;
+import org.elasticsearch.cluster.ClusterState;
+import org.elasticsearch.cluster.block.ClusterBlockException;
+import org.elasticsearch.cluster.block.ClusterBlockLevel;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.MetadataDataStreamsService;
+import org.elasticsearch.cluster.service.ClusterService;
+import org.elasticsearch.common.util.concurrent.EsExecutors;
+import org.elasticsearch.indices.SystemIndices;
+import org.elasticsearch.injection.guice.Inject;
+import org.elasticsearch.tasks.Task;
+import org.elasticsearch.threadpool.ThreadPool;
+import org.elasticsearch.transport.TransportService;
+
+import java.util.List;
+
+/**
+ * Transport action that resolves the data stream names from the request and sets the data stream lifecycle provided in the request.
+ */
+public class TransportPutDataStreamOptionsAction extends AcknowledgedTransportMasterNodeAction {
+
+ private final MetadataDataStreamsService metadataDataStreamsService;
+ private final SystemIndices systemIndices;
+
+ @Inject
+ public TransportPutDataStreamOptionsAction(
+ TransportService transportService,
+ ClusterService clusterService,
+ ThreadPool threadPool,
+ ActionFilters actionFilters,
+ IndexNameExpressionResolver indexNameExpressionResolver,
+ MetadataDataStreamsService metadataDataStreamsService,
+ SystemIndices systemIndices
+ ) {
+ super(
+ PutDataStreamOptionsAction.INSTANCE.name(),
+ transportService,
+ clusterService,
+ threadPool,
+ actionFilters,
+ PutDataStreamOptionsAction.Request::new,
+ indexNameExpressionResolver,
+ EsExecutors.DIRECT_EXECUTOR_SERVICE
+ );
+ this.metadataDataStreamsService = metadataDataStreamsService;
+ this.systemIndices = systemIndices;
+ }
+
+ @Override
+ protected void masterOperation(
+ Task task,
+ PutDataStreamOptionsAction.Request request,
+ ClusterState state,
+ ActionListener listener
+ ) {
+ List dataStreamNames = DataStreamsActionUtil.getDataStreamNames(
+ indexNameExpressionResolver,
+ state,
+ request.getNames(),
+ request.indicesOptions()
+ );
+ for (String name : dataStreamNames) {
+ systemIndices.validateDataStreamAccess(name, threadPool.getThreadContext());
+ }
+ metadataDataStreamsService.setDataStreamOptions(
+ dataStreamNames,
+ request.getOptions(),
+ request.ackTimeout(),
+ request.masterNodeTimeout(),
+ listener
+ );
+ }
+
+ @Override
+ protected ClusterBlockException checkBlock(PutDataStreamOptionsAction.Request request, ClusterState state) {
+ return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestDeleteDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestDeleteDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..96460632ff443
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestDeleteDataStreamOptionsAction.java
@@ -0,0 +1,54 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.rest;
+
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.action.support.master.AcknowledgedRequest;
+import org.elasticsearch.client.internal.node.NodeClient;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.datastreams.options.action.DeleteDataStreamOptionsAction;
+import org.elasticsearch.rest.BaseRestHandler;
+import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
+import org.elasticsearch.rest.action.RestToXContentListener;
+
+import java.util.List;
+
+import static org.elasticsearch.rest.RestRequest.Method.DELETE;
+import static org.elasticsearch.rest.RestUtils.getMasterNodeTimeout;
+
+@ServerlessScope(Scope.INTERNAL)
+public class RestDeleteDataStreamOptionsAction extends BaseRestHandler {
+
+ @Override
+ public String getName() {
+ return "delete_data_stream_options_action";
+ }
+
+ @Override
+ public List routes() {
+ return List.of(new Route(DELETE, "/_data_stream/{name}/_options"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) {
+ final var deleteDataOptionsRequest = new DeleteDataStreamOptionsAction.Request(
+ getMasterNodeTimeout(request),
+ request.paramAsTime("timeout", AcknowledgedRequest.DEFAULT_ACK_TIMEOUT),
+ Strings.splitStringByCommaToArray(request.param("name"))
+ );
+ deleteDataOptionsRequest.indicesOptions(IndicesOptions.fromRequest(request, deleteDataOptionsRequest.indicesOptions()));
+ return channel -> client.execute(
+ DeleteDataStreamOptionsAction.INSTANCE,
+ deleteDataOptionsRequest,
+ new RestToXContentListener<>(channel)
+ );
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestGetDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestGetDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..6d6530efce1b9
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestGetDataStreamOptionsAction.java
@@ -0,0 +1,58 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.rest;
+
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.client.internal.node.NodeClient;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.datastreams.options.action.GetDataStreamOptionsAction;
+import org.elasticsearch.rest.BaseRestHandler;
+import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.RestUtils;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
+import org.elasticsearch.rest.action.RestRefCountedChunkedToXContentListener;
+
+import java.util.List;
+
+import static org.elasticsearch.rest.RestRequest.Method.GET;
+
+@ServerlessScope(Scope.PUBLIC)
+public class RestGetDataStreamOptionsAction extends BaseRestHandler {
+
+ @Override
+ public String getName() {
+ return "get_data_stream_options_action";
+ }
+
+ @Override
+ public List routes() {
+ return List.of(new Route(GET, "/_data_stream/{name}/_options"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) {
+ GetDataStreamOptionsAction.Request getDataStreamOptionsRequest = new GetDataStreamOptionsAction.Request(
+ RestUtils.getMasterNodeTimeout(request),
+ Strings.splitStringByCommaToArray(request.param("name"))
+ );
+ getDataStreamOptionsRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));
+ getDataStreamOptionsRequest.indicesOptions(IndicesOptions.fromRequest(request, getDataStreamOptionsRequest.indicesOptions()));
+ return channel -> client.execute(
+ GetDataStreamOptionsAction.INSTANCE,
+ getDataStreamOptionsRequest,
+ new RestRefCountedChunkedToXContentListener<>(channel)
+ );
+ }
+
+ @Override
+ public boolean allowSystemIndexAccessByDefault() {
+ return true;
+ }
+}
diff --git a/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestPutDataStreamOptionsAction.java b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestPutDataStreamOptionsAction.java
new file mode 100644
index 0000000000000..9191b96b6039e
--- /dev/null
+++ b/modules/data-streams/src/main/java/org/elasticsearch/datastreams/options/rest/RestPutDataStreamOptionsAction.java
@@ -0,0 +1,58 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side
+ * Public License v 1"; you may not use this file except in compliance with, at
+ * your election, the "Elastic License 2.0", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+package org.elasticsearch.datastreams.options.rest;
+
+import org.elasticsearch.action.support.IndicesOptions;
+import org.elasticsearch.client.internal.node.NodeClient;
+import org.elasticsearch.common.Strings;
+import org.elasticsearch.datastreams.options.action.PutDataStreamOptionsAction;
+import org.elasticsearch.rest.BaseRestHandler;
+import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
+import org.elasticsearch.rest.action.RestToXContentListener;
+import org.elasticsearch.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.elasticsearch.rest.RestRequest.Method.PUT;
+import static org.elasticsearch.rest.RestUtils.getAckTimeout;
+import static org.elasticsearch.rest.RestUtils.getMasterNodeTimeout;
+
+@ServerlessScope(Scope.PUBLIC)
+public class RestPutDataStreamOptionsAction extends BaseRestHandler {
+
+ @Override
+ public String getName() {
+ return "put_data_stream_options_action";
+ }
+
+ @Override
+ public List routes() {
+ return List.of(new Route(PUT, "/_data_stream/{name}/_options"));
+ }
+
+ @Override
+ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
+ try (XContentParser parser = request.contentParser()) {
+ PutDataStreamOptionsAction.Request putOptionsRequest = PutDataStreamOptionsAction.Request.parseRequest(
+ parser,
+ (failureStore) -> new PutDataStreamOptionsAction.Request(
+ getMasterNodeTimeout(request),
+ getAckTimeout(request),
+ Strings.splitStringByCommaToArray(request.param("name")),
+ failureStore
+ )
+ );
+ putOptionsRequest.indicesOptions(IndicesOptions.fromRequest(request, putOptionsRequest.indicesOptions()));
+ return channel -> client.execute(PutDataStreamOptionsAction.INSTANCE, putOptionsRequest, new RestToXContentListener<>(channel));
+ }
+ }
+}
diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsService.java
index 8a46550f8a689..db3973c1a15a8 100644
--- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsService.java
+++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsService.java
@@ -45,6 +45,7 @@ public class MetadataDataStreamsService {
private final DataStreamGlobalRetentionSettings globalRetentionSettings;
private final MasterServiceTaskQueue updateLifecycleTaskQueue;
private final MasterServiceTaskQueue setRolloverOnWriteTaskQueue;
+ private final MasterServiceTaskQueue updateOptionsTaskQueue;
public MetadataDataStreamsService(
ClusterService clusterService,
@@ -93,6 +94,20 @@ public Tuple executeTask(
Priority.NORMAL,
rolloverOnWriteExecutor
);
+ ClusterStateTaskExecutor updateOptionsExecutor = new SimpleBatchedAckListenerTaskExecutor<>() {
+
+ @Override
+ public Tuple executeTask(
+ UpdateOptionsTask modifyOptionsTask,
+ ClusterState clusterState
+ ) {
+ return new Tuple<>(
+ updateDataStreamOptions(clusterState, modifyOptionsTask.getDataStreamNames(), modifyOptionsTask.getOptions()),
+ modifyOptionsTask
+ );
+ }
+ };
+ this.updateOptionsTaskQueue = clusterService.createTaskQueue("modify-data-stream-options", Priority.NORMAL, updateOptionsExecutor);
}
public void modifyDataStream(final ModifyDataStreamsAction.Request request, final ActionListener listener) {
@@ -147,6 +162,39 @@ public void removeLifecycle(
);
}
+ /**
+ * Submits the task to set the provided data stream options to the requested data streams.
+ */
+ public void setDataStreamOptions(
+ final List dataStreamNames,
+ DataStreamOptions options,
+ TimeValue ackTimeout,
+ TimeValue masterTimeout,
+ final ActionListener listener
+ ) {
+ updateOptionsTaskQueue.submitTask(
+ "set-data-stream-options",
+ new UpdateOptionsTask(dataStreamNames, options, ackTimeout, listener),
+ masterTimeout
+ );
+ }
+
+ /**
+ * Submits the task to remove the data stream options from the requested data streams.
+ */
+ public void removeDataStreamOptions(
+ List dataStreamNames,
+ TimeValue ackTimeout,
+ TimeValue masterTimeout,
+ ActionListener listener
+ ) {
+ updateOptionsTaskQueue.submitTask(
+ "delete-data-stream-options",
+ new UpdateOptionsTask(dataStreamNames, null, ackTimeout, listener),
+ masterTimeout
+ );
+ }
+
@SuppressForbidden(reason = "legacy usage of unbatched task") // TODO add support for batching here
private void submitUnbatchedTask(@SuppressWarnings("SameParameterValue") String source, ClusterStateUpdateTask task) {
clusterService.submitUnbatchedStateUpdateTask(source, task);
@@ -228,6 +276,24 @@ ClusterState updateDataLifecycle(ClusterState currentState, List dataStr
return ClusterState.builder(currentState).metadata(builder.build()).build();
}
+ /**
+ * Creates an updated cluster state in which the requested data streams have the data stream options provided.
+ * Visible for testing.
+ */
+ ClusterState updateDataStreamOptions(
+ ClusterState currentState,
+ List dataStreamNames,
+ @Nullable DataStreamOptions dataStreamOptions
+ ) {
+ Metadata metadata = currentState.metadata();
+ Metadata.Builder builder = Metadata.builder(metadata);
+ for (var dataStreamName : dataStreamNames) {
+ var dataStream = validateDataStream(metadata, dataStreamName);
+ builder.put(dataStream.copy().setDataStreamOptions(dataStreamOptions).build());
+ }
+ return ClusterState.builder(currentState).metadata(builder.build()).build();
+ }
+
/**
* Creates an updated cluster state in which the requested data stream has the flag {@link DataStream#rolloverOnWrite()}
* set to the value of the parameter rolloverOnWrite
@@ -372,6 +438,34 @@ public DataStreamLifecycle getDataLifecycle() {
}
}
+ /**
+ * A cluster state update task that consists of the cluster state request and the listeners that need to be notified upon completion.
+ */
+ static class UpdateOptionsTask extends AckedBatchedClusterStateUpdateTask {
+
+ private final List dataStreamNames;
+ private final DataStreamOptions options;
+
+ UpdateOptionsTask(
+ List dataStreamNames,
+ @Nullable DataStreamOptions options,
+ TimeValue ackTimeout,
+ ActionListener listener
+ ) {
+ super(ackTimeout, listener);
+ this.dataStreamNames = dataStreamNames;
+ this.options = options;
+ }
+
+ public List getDataStreamNames() {
+ return dataStreamNames;
+ }
+
+ public DataStreamOptions getOptions() {
+ return options;
+ }
+ }
+
/**
* A cluster state update task that consists of the cluster state request and the listeners that need to be notified upon completion.
*/
diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/DataStreamOptionsTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/DataStreamOptionsTests.java
index 020955d226a0f..9b0eb93b496a4 100644
--- a/server/src/test/java/org/elasticsearch/cluster/metadata/DataStreamOptionsTests.java
+++ b/server/src/test/java/org/elasticsearch/cluster/metadata/DataStreamOptionsTests.java
@@ -24,7 +24,16 @@ protected Writeable.Reader instanceReader() {
@Override
protected DataStreamOptions createTestInstance() {
- return new DataStreamOptions(randomBoolean() ? null : DataStreamFailureStoreTests.randomFailureStore());
+ return randomDataStreamOptions();
+ }
+
+ public static DataStreamOptions randomDataStreamOptions() {
+ return switch (randomIntBetween(0, 2)) {
+ case 0 -> DataStreamOptions.EMPTY;
+ case 1 -> DataStreamOptions.FAILURE_STORE_DISABLED;
+ case 2 -> DataStreamOptions.FAILURE_STORE_ENABLED;
+ default -> throw new IllegalArgumentException("Illegal randomisation branch");
+ };
}
@Override
diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsServiceTests.java
index 92c1103c950c0..276c20d2d1322 100644
--- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsServiceTests.java
+++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDataStreamsServiceTests.java
@@ -422,6 +422,39 @@ public void testUpdateLifecycle() {
}
}
+ public void testUpdateDataStreamOptions() {
+ String dataStream = randomAlphaOfLength(5);
+ // we want the data stream options to be non-empty, so we can see the removal in action
+ DataStreamOptions dataStreamOptions = randomValueOtherThan(
+ DataStreamOptions.EMPTY,
+ DataStreamOptionsTests::randomDataStreamOptions
+ );
+ ClusterState before = DataStreamTestHelper.getClusterStateWithDataStreams(List.of(new Tuple<>(dataStream, 2)), List.of());
+ MetadataDataStreamsService service = new MetadataDataStreamsService(
+ mock(ClusterService.class),
+ mock(IndicesService.class),
+ DataStreamGlobalRetentionSettings.create(ClusterSettings.createBuiltInClusterSettings())
+ );
+
+ // Ensure no data stream options are stored
+ DataStream updatedDataStream = before.metadata().dataStreams().get(dataStream);
+ assertNotNull(updatedDataStream);
+ assertThat(updatedDataStream.getDataStreamOptions(), equalTo(DataStreamOptions.EMPTY));
+
+ // Set non-empty data stream options
+ ClusterState after = service.updateDataStreamOptions(before, List.of(dataStream), dataStreamOptions);
+ updatedDataStream = after.metadata().dataStreams().get(dataStream);
+ assertNotNull(updatedDataStream);
+ assertThat(updatedDataStream.getDataStreamOptions(), equalTo(dataStreamOptions));
+ before = after;
+
+ // Remove data stream options
+ after = service.updateDataStreamOptions(before, List.of(dataStream), null);
+ updatedDataStream = after.metadata().dataStreams().get(dataStream);
+ assertNotNull(updatedDataStream);
+ assertThat(updatedDataStream.getDataStreamOptions(), equalTo(DataStreamOptions.EMPTY));
+ }
+
private MapperService getMapperService(IndexMetadata im) {
try {
String mapping = im.mapping().source().toString();
diff --git a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java
index d791873eb3142..b29dc0fa410b6 100644
--- a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java
+++ b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java
@@ -502,6 +502,9 @@ public class Constants {
"indices:admin/data_stream/lifecycle/get",
"indices:admin/data_stream/lifecycle/put",
"indices:admin/data_stream/lifecycle/explain",
+ "indices:admin/data_stream/options/delete",
+ "indices:admin/data_stream/options/get",
+ "indices:admin/data_stream/options/put",
"indices:admin/delete",
"indices:admin/flush",
"indices:admin/flush[s]",
From 7bd6f2ce6a708364a41b1d1620a08df3f8816258 Mon Sep 17 00:00:00 2001
From: kosabogi <105062005+kosabogi@users.noreply.github.com>
Date: Mon, 14 Oct 2024 15:57:00 +0200
Subject: [PATCH 20/77] Expands semantic_text tutorial with hybrid search
(#114398)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Creates a new page for the hybrid search tutorial
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Adds search response example
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
* Update docs/reference/search/search-your-data/semantic-text-hybrid-search
Co-authored-by: István Zoltán Szabó
---------
Co-authored-by: István Zoltán Szabó
---
.../search-your-data/semantic-search.asciidoc | 1 +
.../semantic-text-hybrid-search | 254 ++++++++++++++++++
2 files changed, 255 insertions(+)
create mode 100644 docs/reference/search/search-your-data/semantic-text-hybrid-search
diff --git a/docs/reference/search/search-your-data/semantic-search.asciidoc b/docs/reference/search/search-your-data/semantic-search.asciidoc
index 62e41b3eef3de..0ef8591e42b5d 100644
--- a/docs/reference/search/search-your-data/semantic-search.asciidoc
+++ b/docs/reference/search/search-your-data/semantic-search.asciidoc
@@ -104,6 +104,7 @@ IMPORTANT: For the easiest way to perform semantic search in the {stack}, refer
include::semantic-search-semantic-text.asciidoc[]
+include::semantic-text-hybrid-search[]
include::semantic-search-inference.asciidoc[]
include::semantic-search-elser.asciidoc[]
include::cohere-es.asciidoc[]
diff --git a/docs/reference/search/search-your-data/semantic-text-hybrid-search b/docs/reference/search/search-your-data/semantic-text-hybrid-search
new file mode 100644
index 0000000000000..c56b283434df5
--- /dev/null
+++ b/docs/reference/search/search-your-data/semantic-text-hybrid-search
@@ -0,0 +1,254 @@
+[[semantic-text-hybrid-search]]
+=== Tutorial: hybrid search with `semantic_text`
+++++
+Hybrid search with `semantic_text`
+++++
+
+This tutorial demonstrates how to perform hybrid search, combining semantic search with traditional full-text search.
+
+In hybrid search, semantic search retrieves results based on the meaning of the text, while full-text search focuses on exact word matches. By combining both methods, hybrid search delivers more relevant results, particularly in cases where relying on a single approach may not be sufficient.
+
+The recommended way to use hybrid search in the {stack} is following the `semantic_text` workflow. This tutorial uses the <> for demonstration, but you can use any service and its supported models offered by the {infer-cap} API.
+
+[discrete]
+[[semantic-text-hybrid-infer-endpoint]]
+==== Create the {infer} endpoint
+
+Create an inference endpoint by using the <>:
+
+[source,console]
+------------------------------------------------------------
+PUT _inference/sparse_embedding/my-elser-endpoint <1>
+{
+ "service": "elser", <2>
+ "service_settings": {
+ "adaptive_allocations": { <3>
+ "enabled": true,
+ "min_number_of_allocations": 3,
+ "max_number_of_allocations": 10
+ },
+ "num_threads": 1
+ }
+}
+------------------------------------------------------------
+// TEST[skip:TBD]
+<1> The task type is `sparse_embedding` in the path as the `elser` service will
+be used and ELSER creates sparse vectors. The `inference_id` is
+`my-elser-endpoint`.
+<2> The `elser` service is used in this example.
+<3> This setting enables and configures adaptive allocations.
+Adaptive allocations make it possible for ELSER to automatically scale up or down resources based on the current load on the process.
+
+[NOTE]
+====
+You might see a 502 bad gateway error in the response when using the {kib} Console.
+This error usually just reflects a timeout, while the model downloads in the background.
+You can check the download progress in the {ml-app} UI.
+====
+
+[discrete]
+[[hybrid-search-create-index-mapping]]
+==== Create an index mapping for hybrid search
+
+The destination index will contain both the embeddings for semantic search and the original text field for full-text search. This structure enables the combination of semantic search and full-text search.
+
+[source,console]
+------------------------------------------------------------
+PUT semantic-embeddings
+{
+ "mappings": {
+ "properties": {
+ "semantic_text": { <1>
+ "type": "semantic_text",
+ "inference_id": "my-elser-endpoint" <2>
+ },
+ "content": { <3>
+ "type": "text",
+ "copy_to": "semantic_text" <4>
+ }
+ }
+ }
+}
+------------------------------------------------------------
+// TEST[skip:TBD]
+<1> The name of the field to contain the generated embeddings for semantic search.
+<2> The identifier of the inference endpoint that generates the embeddings based on the input text.
+<3> The name of the field to contain the original text for lexical search.
+<4> The textual data stored in the `content` field will be copied to `semantic_text` and processed by the {infer} endpoint.
+
+[NOTE]
+====
+If you want to run a search on indices that were populated by web crawlers or connectors, you have to
+<> for these indices to
+include the `semantic_text` field. Once the mapping is updated, you'll need to run a full web crawl or a full connector sync. This ensures that all existing
+documents are reprocessed and updated with the new semantic embeddings, enabling hybrid search on the updated data.
+====
+
+[discrete]
+[[semantic-text-hybrid-load-data]]
+==== Load data
+
+In this step, you load the data that you later use to create embeddings from.
+
+Use the `msmarco-passagetest2019-top1000` data set, which is a subset of the MS MARCO Passage Ranking data set. It consists of 200 queries, each accompanied by a list of relevant text passages. All unique passages, along with their IDs, have been extracted from that data set and compiled into a https://github.com/elastic/stack-docs/blob/main/docs/en/stack/ml/nlp/data/msmarco-passagetest2019-unique.tsv[tsv file].
+
+Download the file and upload it to your cluster using the {kibana-ref}/connect-to-elasticsearch.html#upload-data-kibana[Data Visualizer] in the {ml-app} UI. After your data is analyzed, click **Override settings**. Under **Edit field names**, assign `id` to the first column and `content` to the second. Click **Apply**, then **Import**. Name the index `test-data`, and click **Import**. After the upload is complete, you will see an index named `test-data` with 182,469 documents.
+
+[discrete]
+[[hybrid-search-reindex-data]]
+==== Reindex the data for hybrid search
+
+Reindex the data from the `test-data` index into the `semantic-embeddings` index.
+The data in the `content` field of the source index is copied into the `content` field of the destination index.
+The `copy_to` parameter set in the index mapping creation ensures that the content is copied into the `semantic_text` field. The data is processed by the {infer} endpoint at ingest time to generate embeddings.
+
+[NOTE]
+====
+This step uses the reindex API to simulate data ingestion. If you are working with data that has already been indexed,
+rather than using the `test-data` set, reindexing is still required to ensure that the data is processed by the {infer} endpoint
+and the necessary embeddings are generated.
+====
+
+[source,console]
+------------------------------------------------------------
+POST _reindex?wait_for_completion=false
+{
+ "source": {
+ "index": "test-data",
+ "size": 10 <1>
+ },
+ "dest": {
+ "index": "semantic-embeddings"
+ }
+}
+------------------------------------------------------------
+// TEST[skip:TBD]
+<1> The default batch size for reindexing is 1000. Reducing size to a smaller
+number makes the update of the reindexing process quicker which enables you to
+follow the progress closely and detect errors early.
+
+The call returns a task ID to monitor the progress:
+
+[source,console]
+------------------------------------------------------------
+GET _tasks/
+------------------------------------------------------------
+// TEST[skip:TBD]
+
+Reindexing large datasets can take a long time. You can test this workflow using only a subset of the dataset.
+
+To cancel the reindexing process and generate embeddings for the subset that was reindexed:
+
+[source,console]
+------------------------------------------------------------
+POST _tasks//_cancel
+------------------------------------------------------------
+// TEST[skip:TBD]
+
+[discrete]
+[[hybrid-search-perform-search]]
+==== Perform hybrid search
+
+After reindexing the data into the `semantic-embeddings` index, you can perform hybrid search by using <>. RRF is a technique that merges the rankings from both semantic and lexical queries, giving more weight to results that rank high in either search. This ensures that the final results are balanced and relevant.
+
+[source,console]
+------------------------------------------------------------
+GET semantic-embeddings/_search
+{
+ "retriever": {
+ "rrf": {
+ "retrievers": [
+ {
+ "standard": { <1>
+ "query": {
+ "match": {
+ "content": "How to avoid muscle soreness while running?" <2>
+ }
+ }
+ }
+ },
+ {
+ "standard": { <3>
+ "query": {
+ "semantic": {
+ "field": "semantic_text", <4>
+ "query": "How to avoid muscle soreness while running?"
+ }
+ }
+ }
+ }
+ ]
+ }
+ }
+}
+------------------------------------------------------------
+// TEST[skip:TBD]
+<1> The first `standard` retriever represents the traditional lexical search.
+<2> Lexical search is performed on the `content` field using the specified phrase.
+<3> The second `standard` retriever refers to the semantic search.
+<4> The `semantic_text` field is used to perform the semantic search.
+
+
+After performing the hybrid search, the query will return the top 10 documents that match both semantic and lexical search criteria. The results include detailed information about each document:
+
+[source,console-result]
+------------------------------------------------------------
+{
+ "took": 107,
+ "timed_out": false,
+ "_shards": {
+ "total": 1,
+ "successful": 1,
+ "skipped": 0,
+ "failed": 0
+ },
+ "hits": {
+ "total": {
+ "value": 473,
+ "relation": "eq"
+ },
+ "max_score": null,
+ "hits": [
+ {
+ "_index": "semantic-embeddings",
+ "_id": "wv65epIBEMBRnhfTsOFM",
+ "_score": 0.032786883,
+ "_rank": 1,
+ "_source": {
+ "semantic_text": {
+ "inference": {
+ "inference_id": "my-elser-endpoint",
+ "model_settings": {
+ "task_type": "sparse_embedding"
+ },
+ "chunks": [
+ {
+ "text": "What so many out there do not realize is the importance of what you do after you work out. You may have done the majority of the work, but how you treat your body in the minutes and hours after you exercise has a direct effect on muscle soreness, muscle strength and growth, and staying hydrated. Cool Down. After your last exercise, your workout is not over. The first thing you need to do is cool down. Even if running was all that you did, you still should do light cardio for a few minutes. This brings your heart rate down at a slow and steady pace, which helps you avoid feeling sick after a workout.",
+ "embeddings": {
+ "exercise": 1.571044,
+ "after": 1.3603843,
+ "sick": 1.3281639,
+ "cool": 1.3227621,
+ "muscle": 1.2645415,
+ "sore": 1.2561599,
+ "cooling": 1.2335974,
+ "running": 1.1750668,
+ "hours": 1.1104802,
+ "out": 1.0991782,
+ "##io": 1.0794281,
+ "last": 1.0474665,
+ (...)
+ }
+ }
+ ]
+ }
+ },
+ "id": 8408852,
+ "content": "What so many out there do not realize is the importance of (...)"
+ }
+ }
+ ]
+ }
+}
+------------------------------------------------------------
+// NOTCONSOLE
From 4c15cc077887d00ecf0e02c39b42cf01874ab6c4 Mon Sep 17 00:00:00 2001
From: Mary Gouseti
Date: Mon, 14 Oct 2024 17:08:23 +0300
Subject: [PATCH 21/77] Add ResolvedExpression wrapper (#114592)
**Introduction**
> In order to make adoption of failure stores simpler for all users, we
are introducing a new syntactical feature to index expression
resolution: The selector. > > Selectors, denoted with a :: followed by a
recognized suffix will allow users to specify which component of an
index abstraction they would like to operate on within an API call. In
this case, an index abstraction is a concrete index, data stream, or
alias; Any abstraction that can be resolved to a set of indices/shards.
We define a component of an index abstraction to be some searchable unit
of the index abstraction. > > To start, we will support two components:
data and failures. Concrete indices are their own data components, while
the data component for index aliases are all of the indices contained
therein. For data streams, the data component corresponds to their
backing indices. Data stream aliases mirror this, treating all backing
indices of the data streams they correspond to as their data component.
> > The failure component is only supported by data streams and data
stream aliases. The failure component of these abstractions refer to the
data streams' failure stores. Indices and index aliases do not have a
failure component.
For more details and examples see
https://github.com/elastic/elasticsearch/pull/113144. All this work has
been cherry picked from there.
**Purpose of this PR**
This PR is introducing a wrapper around the resolved expression that
used to be a `String` to create the base on which the selectors are
going to be added.
The current PR is just a refactoring and does not and should not change
any existing behaviour.
---
.../TransportClusterSearchShardsAction.java | 3 +-
.../indices/resolve/ResolveIndexAction.java | 9 +-
.../query/TransportValidateQueryAction.java | 3 +-
.../explain/TransportExplainAction.java | 3 +-
.../action/search/TransportSearchAction.java | 24 +-
.../search/TransportSearchShardsAction.java | 6 +-
.../metadata/IndexNameExpressionResolver.java | 196 +++++++-----
.../elasticsearch/indices/IndicesService.java | 3 +-
.../elasticsearch/search/SearchService.java | 3 +-
.../indices/resolve/ResolveIndexTests.java | 15 +-
.../DateMathExpressionResolverTests.java | 89 +++---
.../cluster/metadata/ExpressionListTests.java | 108 ++++---
.../IndexNameExpressionResolverTests.java | 65 ++--
.../WildcardExpressionResolverTests.java | 299 ++++++++++--------
.../indices/IndicesServiceTests.java | 34 +-
15 files changed, 504 insertions(+), 356 deletions(-)
diff --git a/server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java b/server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java
index 9ffef1f178f44..b855f2cee7613 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/cluster/shards/TransportClusterSearchShardsAction.java
@@ -17,6 +17,7 @@
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.routing.ShardIterator;
@@ -84,7 +85,7 @@ protected void masterOperation(
String[] concreteIndices = indexNameExpressionResolver.concreteIndexNames(clusterState, request);
Map> routingMap = indexNameExpressionResolver.resolveSearchRouting(state, request.routing(), request.indices());
Map indicesAndFilters = new HashMap<>();
- Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, request.indices());
+ Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, request.indices());
for (String index : concreteIndices) {
final AliasFilter aliasFilter = indicesService.buildAliasFilter(clusterState, index, indicesAndAliases);
final String[] aliases = indexNameExpressionResolver.indexAliases(
diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java
index 5c5c71bc002b3..f5c100b7884bb 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/indices/resolve/ResolveIndexAction.java
@@ -25,6 +25,7 @@
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
@@ -565,8 +566,8 @@ static void resolveIndices(
if (names.length == 1 && (Metadata.ALL.equals(names[0]) || Regex.isMatchAllPattern(names[0]))) {
names = new String[] { "**" };
}
- Set resolvedIndexAbstractions = resolver.resolveExpressions(clusterState, indicesOptions, true, names);
- for (String s : resolvedIndexAbstractions) {
+ Set resolvedIndexAbstractions = resolver.resolveExpressions(clusterState, indicesOptions, true, names);
+ for (ResolvedExpression s : resolvedIndexAbstractions) {
enrichIndexAbstraction(clusterState, s, indices, aliases, dataStreams);
}
indices.sort(Comparator.comparing(ResolvedIndexAbstraction::getName));
@@ -597,12 +598,12 @@ private static void mergeResults(
private static void enrichIndexAbstraction(
ClusterState clusterState,
- String indexAbstraction,
+ ResolvedExpression indexAbstraction,
List indices,
List aliases,
List dataStreams
) {
- IndexAbstraction ia = clusterState.metadata().getIndicesLookup().get(indexAbstraction);
+ IndexAbstraction ia = clusterState.metadata().getIndicesLookup().get(indexAbstraction.resource());
if (ia != null) {
switch (ia.getType()) {
case CONCRETE_INDEX -> {
diff --git a/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java b/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java
index 4e9830fe0d14e..e01f364712676 100644
--- a/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java
+++ b/server/src/main/java/org/elasticsearch/action/admin/indices/validate/query/TransportValidateQueryAction.java
@@ -21,6 +21,7 @@
import org.elasticsearch.cluster.block.ClusterBlockException;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.cluster.routing.ShardRouting;
@@ -133,7 +134,7 @@ protected void doExecute(Task task, ValidateQueryRequest request, ActionListener
@Override
protected ShardValidateQueryRequest newShardRequest(int numShards, ShardRouting shard, ValidateQueryRequest request) {
final ClusterState clusterState = clusterService.state();
- final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, request.indices());
+ final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, request.indices());
final AliasFilter aliasFilter = searchService.buildAliasFilter(clusterState, shard.getIndexName(), indicesAndAliases);
return new ShardValidateQueryRequest(shard.shardId(), aliasFilter, request);
}
diff --git a/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java b/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java
index 9c82d032014f2..84c6df7b8a66f 100644
--- a/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java
+++ b/server/src/main/java/org/elasticsearch/action/explain/TransportExplainAction.java
@@ -18,6 +18,7 @@
import org.elasticsearch.action.support.single.shard.TransportSingleShardAction;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.io.stream.Writeable;
@@ -109,7 +110,7 @@ protected boolean resolveIndex(ExplainRequest request) {
@Override
protected void resolveRequest(ClusterState state, InternalRequest request) {
- final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(state, request.request().index());
+ final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(state, request.request().index());
final AliasFilter aliasFilter = searchService.buildAliasFilter(state, request.concreteIndex(), indicesAndAliases);
request.request().filteringAlias(aliasFilter);
}
diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
index 1645a378446a4..b5864f64a7824 100644
--- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
+++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java
@@ -37,6 +37,7 @@
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
@@ -110,6 +111,7 @@
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.LongSupplier;
+import java.util.stream.Collectors;
import static org.elasticsearch.action.search.SearchType.DFS_QUERY_THEN_FETCH;
import static org.elasticsearch.action.search.SearchType.QUERY_THEN_FETCH;
@@ -203,7 +205,7 @@ public TransportSearchAction(
private Map buildPerIndexOriginalIndices(
ClusterState clusterState,
- Set indicesAndAliases,
+ Set indicesAndAliases,
String[] indices,
IndicesOptions indicesOptions
) {
@@ -211,6 +213,9 @@ private Map buildPerIndexOriginalIndices(
var blocks = clusterState.blocks();
// optimization: mostly we do not have any blocks so there's no point in the expensive per-index checking
boolean hasBlocks = blocks.global().isEmpty() == false || blocks.indices().isEmpty() == false;
+ // Get a distinct set of index abstraction names present from the resolved expressions to help with the reverse resolution from
+ // concrete index to the expression that produced it.
+ Set indicesAndAliasesResources = indicesAndAliases.stream().map(ResolvedExpression::resource).collect(Collectors.toSet());
for (String index : indices) {
if (hasBlocks) {
blocks.indexBlockedRaiseException(ClusterBlockLevel.READ, index);
@@ -227,8 +232,8 @@ private Map buildPerIndexOriginalIndices(
String[] finalIndices = Strings.EMPTY_ARRAY;
if (aliases == null
|| aliases.length == 0
- || indicesAndAliases.contains(index)
- || hasDataStreamRef(clusterState, indicesAndAliases, index)) {
+ || indicesAndAliasesResources.contains(index)
+ || hasDataStreamRef(clusterState, indicesAndAliasesResources, index)) {
finalIndices = new String[] { index };
}
if (aliases != null) {
@@ -247,7 +252,11 @@ private static boolean hasDataStreamRef(ClusterState clusterState, Set i
return indicesAndAliases.contains(ret.getParentDataStream().getName());
}
- Map buildIndexAliasFilters(ClusterState clusterState, Set indicesAndAliases, Index[] concreteIndices) {
+ Map buildIndexAliasFilters(
+ ClusterState clusterState,
+ Set indicesAndAliases,
+ Index[] concreteIndices
+ ) {
final Map aliasFilterMap = new HashMap<>();
for (Index index : concreteIndices) {
clusterState.blocks().indexBlockedRaiseException(ClusterBlockLevel.READ, index.getName());
@@ -1237,7 +1246,10 @@ private void executeSearch(
} else {
final Index[] indices = resolvedIndices.getConcreteLocalIndices();
concreteLocalIndices = Arrays.stream(indices).map(Index::getName).toArray(String[]::new);
- final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, searchRequest.indices());
+ final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(
+ clusterState,
+ searchRequest.indices()
+ );
aliasFilter = buildIndexAliasFilters(clusterState, indicesAndAliases, indices);
aliasFilter.putAll(remoteAliasMap);
localShardIterators = getLocalShardsIterator(
@@ -1810,7 +1822,7 @@ List getLocalShardsIterator(
ClusterState clusterState,
SearchRequest searchRequest,
String clusterAlias,
- Set indicesAndAliases,
+ Set indicesAndAliases,
String[] concreteIndices
) {
var routingMap = indexNameExpressionResolver.resolveSearchRouting(clusterState, searchRequest.routing(), searchRequest.indices());
diff --git a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
index f418b5617b2a1..b94bd95c93d8a 100644
--- a/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
+++ b/server/src/main/java/org/elasticsearch/action/search/TransportSearchShardsAction.java
@@ -17,6 +17,7 @@
import org.elasticsearch.action.support.HandledTransportAction;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
+import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.ResolvedExpression;
import org.elasticsearch.cluster.routing.GroupShardsIterator;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.index.Index;
@@ -127,7 +128,10 @@ public void searchShards(Task task, SearchShardsRequest searchShardsRequest, Act
searchService.getRewriteContext(timeProvider::absoluteStartMillis, resolvedIndices, null),
listener.delegateFailureAndWrap((delegate, searchRequest) -> {
Index[] concreteIndices = resolvedIndices.getConcreteLocalIndices();
- final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(clusterState, searchRequest.indices());
+ final Set indicesAndAliases = indexNameExpressionResolver.resolveExpressions(
+ clusterState,
+ searchRequest.indices()
+ );
final Map aliasFilters = transportSearchAction.buildIndexAliasFilters(
clusterState,
indicesAndAliases,
diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
index 2229166a2d779..eaf54034b22e0 100644
--- a/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
+++ b/server/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
@@ -74,6 +74,15 @@ public IndexNameExpressionResolver(ThreadContext threadContext, SystemIndices sy
this.systemIndices = Objects.requireNonNull(systemIndices, "System Indices must not be null");
}
+ /**
+ * This contains the resolved expression in the form of the resource.
+ * Soon it will facilitate the index component selector.
+ * @param resource the resolved resolvedExpression
+ */
+ public record ResolvedExpression(String resource) {
+
+ }
+
/**
* Same as {@link #concreteIndexNames(ClusterState, IndicesOptions, String...)}, but the index expressions and options
* are encapsulated in the specified request.
@@ -191,8 +200,9 @@ public List dataStreamNames(ClusterState state, IndicesOptions options,
getSystemIndexAccessPredicate(),
getNetNewSystemIndexPredicate()
);
- final Collection expressions = resolveExpressions(context, indexExpressions);
+ final Collection expressions = resolveExpressions(context, indexExpressions);
return expressions.stream()
+ .map(ResolvedExpression::resource)
.map(x -> state.metadata().getIndicesLookup().get(x))
.filter(Objects::nonNull)
.filter(ia -> ia.getType() == Type.DATA_STREAM)
@@ -221,10 +231,11 @@ public IndexAbstraction resolveWriteIndexAbstraction(ClusterState state, DocWrit
getNetNewSystemIndexPredicate()
);
- final Collection expressions = resolveExpressions(context, request.index());
+ final Collection expressions = resolveExpressions(context, request.index());
if (expressions.size() == 1) {
- IndexAbstraction ia = state.metadata().getIndicesLookup().get(expressions.iterator().next());
+ ResolvedExpression resolvedExpression = expressions.iterator().next();
+ IndexAbstraction ia = state.metadata().getIndicesLookup().get(resolvedExpression.resource());
if (ia.getType() == Type.ALIAS) {
Index writeIndex = ia.getWriteIndex();
if (writeIndex == null) {
@@ -246,14 +257,14 @@ public IndexAbstraction resolveWriteIndexAbstraction(ClusterState state, DocWrit
}
}
- protected static Collection resolveExpressions(Context context, String... expressions) {
+ protected static Collection resolveExpressions(Context context, String... expressions) {
if (context.getOptions().expandWildcardExpressions() == false) {
if (expressions == null || expressions.length == 0 || expressions.length == 1 && Metadata.ALL.equals(expressions[0])) {
return List.of();
} else {
return ExplicitResourceNameFilter.filterUnavailable(
context,
- DateMathExpressionResolver.resolve(context, List.of(expressions))
+ DateMathExpressionResolver.resolve(context, Arrays.stream(expressions).map(ResolvedExpression::new).toList())
);
}
} else {
@@ -264,7 +275,10 @@ protected static Collection resolveExpressions(Context context, String..
} else {
return WildcardExpressionResolver.resolve(
context,
- ExplicitResourceNameFilter.filterUnavailable(context, DateMathExpressionResolver.resolve(context, List.of(expressions)))
+ ExplicitResourceNameFilter.filterUnavailable(
+ context,
+ DateMathExpressionResolver.resolve(context, Arrays.stream(expressions).map(ResolvedExpression::new).toList())
+ )
);
}
}
@@ -339,12 +353,12 @@ String[] concreteIndexNames(Context context, String... indexExpressions) {
}
Index[] concreteIndices(Context context, String... indexExpressions) {
- final Collection expressions = resolveExpressions(context, indexExpressions);
+ final Collection expressions = resolveExpressions(context, indexExpressions);
final Set concreteIndicesResult = Sets.newLinkedHashSetWithExpectedSize(expressions.size());
final Map indicesLookup = context.getState().metadata().getIndicesLookup();
- for (String expression : expressions) {
- final IndexAbstraction indexAbstraction = indicesLookup.get(expression);
+ for (ResolvedExpression resolvedExpression : expressions) {
+ final IndexAbstraction indexAbstraction = indicesLookup.get(resolvedExpression.resource());
assert indexAbstraction != null;
if (indexAbstraction.getType() == Type.ALIAS && context.isResolveToWriteIndex()) {
Index writeIndex = indexAbstraction.getWriteIndex();
@@ -378,7 +392,7 @@ Index[] concreteIndices(Context context, String... indexExpressions) {
throw new IllegalArgumentException(
indexAbstraction.getType().getDisplayName()
+ " ["
- + expression
+ + resolvedExpression.resource()
+ "] has more than one index associated with it "
+ Arrays.toString(indexNames)
+ ", can't execute a single index op"
@@ -642,7 +656,7 @@ public Index concreteSingleIndex(ClusterState state, IndicesRequest request) {
* Utility method that allows to resolve an index expression to its corresponding single write index.
*
* @param state the cluster state containing all the data to resolve to expression to a concrete index
- * @param request The request that defines how the an alias or an index need to be resolved to a concrete index
+ * @param request The request that defines how an alias or an index need to be resolved to a concrete index
* and the expression that can be resolved to an alias or an index name.
* @throws IllegalArgumentException if the index resolution does not lead to an index, or leads to more than one index
* @return the write index obtained as a result of the index resolution
@@ -734,7 +748,7 @@ public static String resolveDateMathExpression(String dateExpression, long time)
/**
* Resolve an array of expressions to the set of indices and aliases that these expressions match.
*/
- public Set resolveExpressions(ClusterState state, String... expressions) {
+ public Set resolveExpressions(ClusterState state, String... expressions) {
return resolveExpressions(state, IndicesOptions.lenientExpandOpen(), false, expressions);
}
@@ -743,7 +757,7 @@ public Set resolveExpressions(ClusterState state, String... expressions)
* If {@param preserveDataStreams} is {@code true}, datastreams that are covered by the wildcards from the
* {@param expressions} are returned as-is, without expanding them further to their respective backing indices.
*/
- public Set resolveExpressions(
+ public Set resolveExpressions(
ClusterState state,
IndicesOptions indicesOptions,
boolean preserveDataStreams,
@@ -760,10 +774,10 @@ public Set resolveExpressions(
getSystemIndexAccessPredicate(),
getNetNewSystemIndexPredicate()
);
- Collection resolved = resolveExpressions(context, expressions);
- if (resolved instanceof Set) {
+ Collection resolved = resolveExpressions(context, expressions);
+ if (resolved instanceof Set) {
// unmodifiable without creating a new collection as it might contain many items
- return Collections.unmodifiableSet((Set) resolved);
+ return Collections.unmodifiableSet((Set) resolved);
} else {
return Set.copyOf(resolved);
}
@@ -776,7 +790,7 @@ public Set resolveExpressions(
* the index itself - null is returned. Returns {@code null} if no filtering is required.
* NOTE : The provided expressions must have been resolved already via {@link #resolveExpressions}.
*/
- public String[] filteringAliases(ClusterState state, String index, Set resolvedExpressions) {
+ public String[] filteringAliases(ClusterState state, String index, Set resolvedExpressions) {
return indexAliases(state, index, AliasMetadata::filteringRequired, DataStreamAlias::filteringRequired, false, resolvedExpressions);
}
@@ -802,39 +816,39 @@ public String[] indexAliases(
Predicate requiredAlias,
Predicate requiredDataStreamAlias,
boolean skipIdentity,
- Set resolvedExpressions
+ Set resolvedExpressions
) {
- if (isAllIndices(resolvedExpressions)) {
+ if (isAllIndicesExpression(resolvedExpressions)) {
return null;
}
-
+ Set resources = resolvedExpressions.stream().map(ResolvedExpression::resource).collect(Collectors.toSet());
final IndexMetadata indexMetadata = state.metadata().getIndices().get(index);
if (indexMetadata == null) {
// Shouldn't happen
throw new IndexNotFoundException(index);
}
- if (skipIdentity == false && resolvedExpressions.contains(index)) {
+ if (skipIdentity == false && resources.contains(index)) {
return null;
}
IndexAbstraction ia = state.metadata().getIndicesLookup().get(index);
DataStream dataStream = ia.getParentDataStream();
if (dataStream != null) {
- if (skipIdentity == false && resolvedExpressions.contains(dataStream.getName())) {
+ if (skipIdentity == false && resources.contains(dataStream.getName())) {
// skip the filters when the request targets the data stream name
return null;
}
Map dataStreamAliases = state.metadata().dataStreamAliases();
List aliasesForDataStream;
- if (iterateIndexAliases(dataStreamAliases.size(), resolvedExpressions.size())) {
+ if (iterateIndexAliases(dataStreamAliases.size(), resources.size())) {
aliasesForDataStream = dataStreamAliases.values()
.stream()
- .filter(dataStreamAlias -> resolvedExpressions.contains(dataStreamAlias.getName()))
+ .filter(dataStreamAlias -> resources.contains(dataStreamAlias.getName()))
.filter(dataStreamAlias -> dataStreamAlias.getDataStreams().contains(dataStream.getName()))
.toList();
} else {
- aliasesForDataStream = resolvedExpressions.stream()
+ aliasesForDataStream = resources.stream()
.map(dataStreamAliases::get)
.filter(dataStreamAlias -> dataStreamAlias != null && dataStreamAlias.getDataStreams().contains(dataStream.getName()))
.toList();
@@ -859,18 +873,15 @@ public String[] indexAliases(
} else {
final Map indexAliases = indexMetadata.getAliases();
final AliasMetadata[] aliasCandidates;
- if (iterateIndexAliases(indexAliases.size(), resolvedExpressions.size())) {
+ if (iterateIndexAliases(indexAliases.size(), resources.size())) {
// faster to iterate indexAliases
aliasCandidates = indexAliases.values()
.stream()
- .filter(aliasMetadata -> resolvedExpressions.contains(aliasMetadata.alias()))
+ .filter(aliasMetadata -> resources.contains(aliasMetadata.alias()))
.toArray(AliasMetadata[]::new);
} else {
// faster to iterate resolvedExpressions
- aliasCandidates = resolvedExpressions.stream()
- .map(indexAliases::get)
- .filter(Objects::nonNull)
- .toArray(AliasMetadata[]::new);
+ aliasCandidates = resources.stream().map(indexAliases::get).filter(Objects::nonNull).toArray(AliasMetadata[]::new);
}
List aliases = null;
for (AliasMetadata aliasMetadata : aliasCandidates) {
@@ -909,12 +920,7 @@ public Map> resolveSearchRouting(ClusterState state, @Nullab
getSystemIndexAccessPredicate(),
getNetNewSystemIndexPredicate()
);
- final Collection resolvedExpressions = resolveExpressions(context, expressions);
-
- // TODO: it appears that this can never be true?
- if (isAllIndices(resolvedExpressions)) {
- return resolveSearchRoutingAllIndices(state.metadata(), routing);
- }
+ final Collection resolvedExpressions = resolveExpressions(context, expressions);
Map> routings = null;
Set paramRouting = null;
@@ -924,8 +930,8 @@ public Map> resolveSearchRouting(ClusterState state, @Nullab
paramRouting = Sets.newHashSet(Strings.splitStringByCommaToArray(routing));
}
- for (String expression : resolvedExpressions) {
- IndexAbstraction indexAbstraction = state.metadata().getIndicesLookup().get(expression);
+ for (ResolvedExpression resolvedExpression : resolvedExpressions) {
+ IndexAbstraction indexAbstraction = state.metadata().getIndicesLookup().get(resolvedExpression.resource);
if (indexAbstraction != null && indexAbstraction.getType() == Type.ALIAS) {
for (Index index : indexAbstraction.getIndices()) {
String concreteIndex = index.getName();
@@ -963,7 +969,7 @@ public Map> resolveSearchRouting(ClusterState state, @Nullab
}
} else {
// Index
- routings = collectRoutings(routings, paramRouting, norouting, expression);
+ routings = collectRoutings(routings, paramRouting, norouting, resolvedExpression.resource());
}
}
@@ -1009,6 +1015,17 @@ public static Map> resolveSearchRoutingAllIndices(Metadata m
return null;
}
+ /**
+ * Identifies whether the array containing index names given as argument refers to all indices
+ * The empty or null array identifies all indices
+ *
+ * @param aliasesOrIndices the array containing index names
+ * @return true if the provided array maps to all indices, false otherwise
+ */
+ public static boolean isAllIndicesExpression(Collection aliasesOrIndices) {
+ return isAllIndices(aliasesOrIndices.stream().map(ResolvedExpression::resource).toList());
+ }
+
/**
* Identifies whether the array containing index names given as argument refers to all indices
* The empty or null array identifies all indices
@@ -1249,8 +1266,8 @@ private WildcardExpressionResolver() {
* Returns all the indices, datastreams, and aliases, considering the open/closed, system, and hidden context parameters.
* Depending on the context, returns the names of the datastreams themselves or their backing indices.
*/
- public static Collection resolveAll(Context context) {
- List concreteIndices = resolveEmptyOrTrivialWildcard(context);
+ public static Collection resolveAll(Context context) {
+ List concreteIndices = resolveEmptyOrTrivialWildcard(context);
if (context.includeDataStreams() == false && context.getOptions().ignoreAliases()) {
return concreteIndices;
@@ -1265,7 +1282,7 @@ public static Collection resolveAll(Context context) {
.filter(ia -> shouldIncludeIfDataStream(ia, context) || shouldIncludeIfAlias(ia, context))
.filter(ia -> ia.isSystem() == false || context.systemIndexAccessPredicate.test(ia.getName()));
- Set resolved = expandToOpenClosed(context, ias).collect(Collectors.toSet());
+ Set resolved = expandToOpenClosed(context, ias).collect(Collectors.toSet());
resolved.addAll(concreteIndices);
return resolved;
}
@@ -1293,17 +1310,17 @@ private static boolean shouldIncludeIfAlias(IndexAbstraction ia, IndexNameExpres
* ultimately returned, instead of the alias or datastream name
*
*/
- public static Collection resolve(Context context, List expressions) {
+ public static Collection resolve(Context context, List expressions) {
ExpressionList expressionList = new ExpressionList(context, expressions);
// fast exit if there are no wildcards to evaluate
if (expressionList.hasWildcard() == false) {
return expressions;
}
- Set result = new HashSet<>();
+ Set result = new HashSet<>();
for (ExpressionList.Expression expression : expressionList) {
if (expression.isWildcard()) {
Stream matchingResources = matchResourcesToWildcard(context, expression.get());
- Stream matchingOpenClosedNames = expandToOpenClosed(context, matchingResources);
+ Stream matchingOpenClosedNames = expandToOpenClosed(context, matchingResources);
AtomicBoolean emptyWildcardExpansion = new AtomicBoolean(false);
if (context.getOptions().allowNoIndices() == false) {
emptyWildcardExpansion.set(true);
@@ -1319,9 +1336,9 @@ public static Collection resolve(Context context, List expressio
}
} else {
if (expression.isExclusion()) {
- result.remove(expression.get());
+ result.remove(new ResolvedExpression(expression.get()));
} else {
- result.add(expression.get());
+ result.add(expression.resolvedExpression());
}
}
}
@@ -1412,13 +1429,13 @@ private static Map filterIndicesLookupForSuffixWildcar
* Data streams and aliases are interpreted to refer to multiple indices,
* then all index resources are filtered by their open/closed status.
*/
- private static Stream expandToOpenClosed(Context context, Stream resources) {
+ private static Stream expandToOpenClosed(Context context, Stream resources) {
final IndexMetadata.State excludeState = excludeState(context.getOptions());
return resources.flatMap(indexAbstraction -> {
if (context.isPreserveAliases() && indexAbstraction.getType() == Type.ALIAS) {
- return Stream.of(indexAbstraction.getName());
+ return Stream.of(new ResolvedExpression(indexAbstraction.getName()));
} else if (context.isPreserveDataStreams() && indexAbstraction.getType() == Type.DATA_STREAM) {
- return Stream.of(indexAbstraction.getName());
+ return Stream.of(new ResolvedExpression(indexAbstraction.getName()));
} else {
Stream indicesStateStream = Stream.of();
if (shouldIncludeRegularIndices(context.getOptions())) {
@@ -1434,18 +1451,20 @@ private static Stream expandToOpenClosed(Context context, Stream indexMeta.getState() != excludeState);
}
- return indicesStateStream.map(indexMeta -> indexMeta.getIndex().getName());
+ return indicesStateStream.map(indexMeta -> new ResolvedExpression(indexMeta.getIndex().getName()));
}
});
}
- private static List resolveEmptyOrTrivialWildcard(Context context) {
+ private static List resolveEmptyOrTrivialWildcard(Context context) {
final String[] allIndices = resolveEmptyOrTrivialWildcardToAllIndices(context.getOptions(), context.getState().metadata());
+ Stream result;
if (context.systemIndexAccessLevel == SystemIndexAccessLevel.ALL) {
- return List.of(allIndices);
+ result = Arrays.stream(allIndices);
} else {
- return resolveEmptyOrTrivialWildcardWithAllowedSystemIndices(context, allIndices);
+ result = resolveEmptyOrTrivialWildcardWithAllowedSystemIndices(context, allIndices).stream();
}
+ return result.map(ResolvedExpression::new).toList();
}
private static List resolveEmptyOrTrivialWildcardWithAllowedSystemIndices(Context context, String[] allIndices) {
@@ -1507,8 +1526,8 @@ private DateMathExpressionResolver() {
// utility class
}
- public static List