diff --git a/.buildkite/scripts/lifecycle/post_command.sh b/.buildkite/scripts/lifecycle/post_command.sh index 47e118a402408..26578f9b9cce1 100755 --- a/.buildkite/scripts/lifecycle/post_command.sh +++ b/.buildkite/scripts/lifecycle/post_command.sh @@ -36,12 +36,15 @@ if [[ "$IS_TEST_EXECUTION_STEP" == "true" ]]; then buildkite-agent artifact upload '.es/**/*.hprof' buildkite-agent artifact upload 'data/es_debug_*.tar.gz' - if [[ $BUILDKITE_COMMAND_EXIT_STATUS -ne 0 ]] && \ - # Skip when triggered from elasticsearch's validation pipeline - [[ $BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG != 'elasticsearch-serverless-intake' ]] - then - echo "--- Run Failed Test Reporter" - node scripts/report_failed_tests --build-url="${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}" 'target/junit/**/*.xml' + if [[ $BUILDKITE_COMMAND_EXIT_STATUS -ne 0 ]]; then + if [[ $BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG == 'elasticsearch-serverless-intake' ]]; then + echo "--- Run Failed Test Reporter (only junit)" + node scripts/report_failed_tests --build-url="${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}" 'target/junit/**/*.xml'\ + --no-github-update --no-index-errors + else + echo "--- Run Failed Test Reporter" + node scripts/report_failed_tests --build-url="${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}" 'target/junit/**/*.xml' + fi fi if [[ -d 'target/test_failures' ]]; then diff --git a/.buildkite/scripts/steps/esql_grammar_sync.sh b/.buildkite/scripts/steps/esql_grammar_sync.sh index cd86c27ad324f..24d9bd9603737 100755 --- a/.buildkite/scripts/steps/esql_grammar_sync.sh +++ b/.buildkite/scripts/steps/esql_grammar_sync.sh @@ -11,15 +11,14 @@ synchronize_lexer_grammar () { # Insert the license header temp_file=$(mktemp) - printf "%s\n\n// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB.\n\n%s" "$license_header" "$(cat $destination_file)" > "$temp_file" + printf "// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB.\n\n%s" "$(cat $destination_file)" > "$temp_file" mv "$temp_file" "$destination_file" # Replace the line containing "lexer grammar" with "lexer grammar esql_lexer;" sed -i -e 's/lexer grammar.*$/lexer grammar esql_lexer;/' "$destination_file" - # Insert "options { caseInsensitive = true; }" one line below - sed -i -e '/lexer grammar esql_lexer;/a\ - options { caseInsensitive = true; }' "$destination_file" + # Replace the line containing "superClass" with "superClass=lexer_config;" + sed -i -e 's/superClass.*$/superClass=lexer_config;/' "$destination_file" echo "File copied and modified successfully." } @@ -34,14 +33,17 @@ synchronize_parser_grammar () { # Insert the license header temp_file=$(mktemp) - printf "%s\n\n// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB.\n\n%s" "$license_header" "$(cat ${destination_file})" > "$temp_file" + printf "// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB.\n\n%s" "$(cat ${destination_file})" > "$temp_file" mv "$temp_file" "$destination_file" # Replace the line containing "parser grammar" with "parser grammar esql_parser;" sed -i -e 's/parser grammar.*$/parser grammar esql_parser;/' "$destination_file" - # Replace options {tokenVocab=EsqlBaseLexer;} with options {tokenVocab=esql_lexer;} - sed -i -e 's/options {tokenVocab=EsqlBaseLexer;}/options {tokenVocab=esql_lexer;}/' "$destination_file" + # Replace tokenVocab=EsqlBaseLexer; with tokenVocab=esql_lexer; + sed -i -e 's/tokenVocab=EsqlBaseLexer;/tokenVocab=esql_lexer;/' "$destination_file" + + # Replace the line containing "superClass" with "superClass=parser_config;" + sed -i -e 's/superClass.*$/superClass=parser_config;/' "$destination_file" echo "File copied and modified successfully." } diff --git a/.buildkite/scripts/steps/functional/osquery_cypress.sh b/.buildkite/scripts/steps/functional/osquery_cypress.sh index 9ba7cabc4d1cb..0ae47edd8c8e7 100755 --- a/.buildkite/scripts/steps/functional/osquery_cypress.sh +++ b/.buildkite/scripts/steps/functional/osquery_cypress.sh @@ -4,11 +4,7 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh -# TODO: remove the line below to use build artifacts for tests. -# in addition to remove the line, we will have to expose the kibana install dir into the downloaded build location -# by exporting a var like: -# export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -node scripts/build_kibana_platform_plugins.js +export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} export JOB=kibana-osquery-cypress diff --git a/.buildkite/scripts/steps/functional/osquery_cypress_burn.sh b/.buildkite/scripts/steps/functional/osquery_cypress_burn.sh index 8068dccac64f3..bebd391d95254 100755 --- a/.buildkite/scripts/steps/functional/osquery_cypress_burn.sh +++ b/.buildkite/scripts/steps/functional/osquery_cypress_burn.sh @@ -2,10 +2,9 @@ set -euo pipefail -source .buildkite/scripts/common/util.sh +source .buildkite/scripts/steps/functional/common.sh -.buildkite/scripts/bootstrap.sh -node scripts/build_kibana_platform_plugins.js +export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} export JOB=kibana-osquery-cypress diff --git a/.buildkite/scripts/steps/functional/security_serverless_osquery.sh b/.buildkite/scripts/steps/functional/security_serverless_osquery.sh index 27ed0c79871ee..9844222e7f869 100755 --- a/.buildkite/scripts/steps/functional/security_serverless_osquery.sh +++ b/.buildkite/scripts/steps/functional/security_serverless_osquery.sh @@ -4,11 +4,7 @@ set -euo pipefail source .buildkite/scripts/steps/functional/common.sh -# TODO: remove the line below to use build artifacts for tests. -# in addition to remove the line, we will have to expose the kibana install dir into the downloaded build location -# by exporting a var like: -# export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} -node scripts/build_kibana_platform_plugins.js +export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} export JOB=kibana-osquery-cypress-serverless diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cbffef0027017..431a668ebe14c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1725,6 +1725,7 @@ x-pack/plugins/osquery @elastic/security-defend-workflows /x-pack/plugins/fleet/public/components/cloud_security_posture @elastic/fleet @elastic/kibana-cloud-security-posture /x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/cloud_security_posture @elastic/fleet @elastic/kibana-cloud-security-posture /x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/setup_technology.* @elastic/fleet @elastic/kibana-cloud-security-posture +/x-pack/plugins/security_solution/public/cloud_security_posture @elastic/kibana-cloud-security-posture # Security Solution onboarding tour /x-pack/plugins/security_solution/public/common/components/guided_onboarding @elastic/security-threat-hunting-explore diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index a9d96a42f8957..a5de0b1fbab95 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index e7b6e04447548..8c0ab2a644eb2 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index a348b7d5a8e41..a0eb3964e1552 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 58226bd0cf12c..2fa494fa1a3ca 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index 2e2467e527aa4..a33fc8633af34 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 3384b680d1e82..fc48272f266b4 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index d1617a86e5a10..0c1cad74c6322 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index f49be2c77f004..afbfef74bcc5c 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 7091f0cecdab3..956a20494b1a1 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 946ae448c273a..c7c0069aa7f1a 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 3fe39d7d87a97..5c47d041b882a 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 503c0f260f597..9ca0433ba6dd8 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 73dfb01f7878d..02e6f8a80aab3 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index efd6ef775ebe9..f21aed205d96e 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 7772a62d74e4b..0767cfe2107b5 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 3a1257852b91a..3afd966c1d202 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 0db6a0a524330..95dbb493ceaa8 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 0e79aec2b7194..39515ced90cb3 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 32d177185b23c..801c52b0e2852 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.devdocs.json b/api_docs/controls.devdocs.json index 611780f983f52..fa81eb3778122 100644 --- a/api_docs/controls.devdocs.json +++ b/api_docs/controls.devdocs.json @@ -6600,7 +6600,7 @@ "section": "def-public.PublishingSubject", "text": "PublishingSubject" }, - "; untilInitialized: () => Promise; openAddDataControlFlyout: (options?: { controlInputTransform?: ", + "; untilInitialized: () => Promise; openAddDataControlFlyout: (settings?: { controlInputTransform?: ", { "pluginId": "controls", "scope": "common", @@ -6608,7 +6608,7 @@ "section": "def-common.ControlInputTransform", "text": "ControlInputTransform" }, - " | undefined; onSave?: (() => void) | undefined; } | undefined) => void; labelPosition: ", + " | undefined; } | undefined) => void; labelPosition: ", { "pluginId": "@kbn/presentation-publishing", "scope": "public", @@ -7790,6 +7790,130 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "controls", + "id": "def-common.controlGroupInputToRawControlGroupAttributes", + "type": "Function", + "tags": [], + "label": "controlGroupInputToRawControlGroupAttributes", + "description": [], + "signature": [ + "(controlGroupInput: Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupInput", + "text": "ControlGroupInput" + }, + ", \"id\">) => ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.RawControlGroupAttributes", + "text": "RawControlGroupAttributes" + } + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.controlGroupInputToRawControlGroupAttributes.$1", + "type": "Object", + "tags": [], + "label": "controlGroupInput", + "description": [], + "signature": [ + "Omit<", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupInput", + "text": "ControlGroupInput" + }, + ", \"id\">" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "controls", + "id": "def-common.generateNewControlIds", + "type": "Function", + "tags": [], + "label": "generateNewControlIds", + "description": [], + "signature": [ + "(controlGroupInput?: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined) => { panels: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlsPanels", + "text": "ControlsPanels" + }, + "; chainingSystem: ", + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.ControlGroupChainingSystem", + "text": "ControlGroupChainingSystem" + }, + "; ignoreParentSettings?: ", + "ParentIgnoreSettings", + " | undefined; controlStyle: ", + "ControlStyle", + "; showApplySelections?: boolean | undefined; } | undefined" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "controls", + "id": "def-common.generateNewControlIds.$1", + "type": "Object", + "tags": [], + "label": "controlGroupInput", + "description": [], + "signature": [ + { + "pluginId": "controls", + "scope": "common", + "docId": "kibControlsPluginApi", + "section": "def-common.PersistableControlGroupInput", + "text": "PersistableControlGroupInput" + }, + " | undefined" + ], + "path": "src/plugins/controls/common/control_group/control_group_persistence.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "controls", "id": "def-common.getDefaultControlGroupInput", diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 70335885c2ebc..9056601e59ecf 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 390 | 0 | 381 | 28 | +| 394 | 0 | 385 | 28 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index c3fc284d460ef..ec4a973666e78 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.devdocs.json b/api_docs/dashboard.devdocs.json index 072fece856c25..805e3041563a0 100644 --- a/api_docs/dashboard.devdocs.json +++ b/api_docs/dashboard.devdocs.json @@ -959,23 +959,15 @@ "section": "def-common.SerializableRecord", "text": "SerializableRecord" }, - ")[] | undefined; controlGroupState?: (Partial<", + ")[] | undefined; controlGroupInput?: ", { "pluginId": "controls", - "scope": "public", - "docId": "kibControlsPluginApi", - "section": "def-public.ControlGroupRuntimeState", - "text": "ControlGroupRuntimeState" - }, - "> & ", - { - "pluginId": "@kbn/utility-types", "scope": "common", - "docId": "kibKbnUtilityTypesPluginApi", - "section": "def-common.SerializableRecord", - "text": "SerializableRecord" + "docId": "kibControlsPluginApi", + "section": "def-common.SerializableControlGroupInput", + "text": "SerializableControlGroupInput" }, - ") | undefined; }" + " | undefined; }" ], "path": "src/plugins/dashboard/public/dashboard_container/types.ts", "deprecated": false, diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index a1dd7fbffa488..f4b8060e85085 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index 70353bbdd7ec3..130467e8f9c6a 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 10e744b78da03..3c5e203e1f0b4 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_quality.mdx b/api_docs/data_quality.mdx index 4e27a7f498fec..2a6c0b5dbf9c6 100644 --- a/api_docs/data_quality.mdx +++ b/api_docs/data_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataQuality title: "dataQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the dataQuality plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataQuality'] --- import dataQualityObj from './data_quality.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 02148f916ae5f..3e1bfac13f603 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index c653d70c880ec..21ad6459d365c 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 5b8784fe4e44e..09651de9b90c4 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 1b68cca161294..d9406d662425d 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 72c86cd07df14..5557828789af9 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 219f59ba54762..7209b5c20ba32 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 4718541aa1238..36d9efad46a86 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index b80356f4f182d..6cc7b4b9af1ee 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 8532d47a7c98c..b8769023fb338 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index b62a87242c1d4..6b99f787e9bf7 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -654,7 +654,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/data/types.ts#:~:text=fieldFormats), [data_service.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/data/data_service.ts#:~:text=fieldFormats) | - | | | [dashboard_grid_item.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx#:~:text=EmbeddablePanel), [dashboard_grid_item.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx#:~:text=EmbeddablePanel) | - | | | [plugin.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/plugin.tsx#:~:text=registerEmbeddableFactory) | - | -| | [migrate_dashboard_input.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts#:~:text=getEmbeddableFactory), [dashboard_container.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx#:~:text=getEmbeddableFactory), [dashboard_container.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx#:~:text=getEmbeddableFactory), [dashboard_renderer.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/external_api/dashboard_renderer.tsx#:~:text=getEmbeddableFactory), [embeddable.stub.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/embeddable/embeddable.stub.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory), [migrate_dashboard_input.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts#:~:text=getEmbeddableFactory), [migrate_dashboard_input.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts#:~:text=getEmbeddableFactory)+ 2 more | - | +| | [migrate_dashboard_input.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts#:~:text=getEmbeddableFactory), [migrate_dashboard_input.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts#:~:text=getEmbeddableFactory), [create_dashboard.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts#:~:text=getEmbeddableFactory), [dashboard_container.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx#:~:text=getEmbeddableFactory), [dashboard_container.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx#:~:text=getEmbeddableFactory), [dashboard_renderer.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/external_api/dashboard_renderer.tsx#:~:text=getEmbeddableFactory), [embeddable.stub.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/embeddable/embeddable.stub.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory), [create_dashboard.test.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts#:~:text=getEmbeddableFactory)+ 9 more | - | | | [embeddable.stub.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/embeddable/embeddable.stub.ts#:~:text=getEmbeddableFactories), [embeddable.stub.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/services/embeddable/embeddable.stub.ts#:~:text=getEmbeddableFactories) | - | | | [save_modal.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx#:~:text=SavedObjectSaveModal), [add_to_library_action.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx#:~:text=SavedObjectSaveModal), [add_to_library_action.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/common/bwc/types.ts#:~:text=SavedObjectReference), [types.ts](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/common/bwc/types.ts#:~:text=SavedObjectReference) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 3c7e127bad3f5..21fcad5b028e1 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index ea1f91be71d3d..5f4d0f97cecb7 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 5164047390e41..eb843f172fc55 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 1cfbf5169cc94..daf497f00c5df 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/discover_shared.mdx b/api_docs/discover_shared.mdx index ed2eb920a2f2e..abe209a5e769a 100644 --- a/api_docs/discover_shared.mdx +++ b/api_docs/discover_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverShared title: "discoverShared" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverShared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverShared'] --- import discoverSharedObj from './discover_shared.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 295eef3ff67d2..2257c9b09c9a9 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 44353f00a69ff..95d6a9cfbd6cf 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index b48eddc9bd7a5..c4ac65a8b4ca6 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -9753,22 +9753,6 @@ "path": "src/plugins/embeddable/public/lib/containers/i_container.ts", "deprecated": false, "trackAdoption": false - }, - { - "parentPluginId": "embeddable", - "id": "def-public.EmbeddableContainerSettings.untilContainerInitialized", - "type": "Function", - "tags": [], - "label": "untilContainerInitialized", - "description": [], - "signature": [ - "(() => Promise) | undefined" - ], - "path": "src/plugins/embeddable/public/lib/containers/i_container.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] } ], "initialIsOpen": false @@ -13733,10 +13717,10 @@ "children": [ { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation", "type": "Object", "tags": [], - "label": "legacy", + "label": "annotation", "description": [], "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", "deprecated": false, @@ -13744,7 +13728,7 @@ "children": [ { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.id", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation.id", "type": "string", "tags": [], "label": "id", @@ -13755,7 +13739,7 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.getDisplayName", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation.getDisplayName", "type": "Function", "tags": [], "label": "getDisplayName", @@ -13771,7 +13755,7 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.order", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation.order", "type": "number", "tags": [], "label": "order", @@ -13784,10 +13768,10 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other", "type": "Object", "tags": [], - "label": "annotation", + "label": "other", "description": [], "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", "deprecated": false, @@ -13795,7 +13779,7 @@ "children": [ { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation.id", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.id", "type": "string", "tags": [], "label": "id", @@ -13806,7 +13790,7 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.annotation.getDisplayName", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.getDisplayName", "type": "Function", "tags": [], "label": "getDisplayName", @@ -13819,15 +13803,42 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "embeddable", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.getIconType", + "type": "Function", + "tags": [], + "label": "getIconType", + "description": [], + "signature": [ + "() => string" + ], + "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "embeddable", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.order", + "type": "number", + "tags": [], + "label": "order", + "description": [], + "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", + "deprecated": false, + "trackAdoption": false } ] }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy", "type": "Object", "tags": [], - "label": "other", + "label": "legacy", "description": [], "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", "deprecated": false, @@ -13835,7 +13846,7 @@ "children": [ { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.id", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.id", "type": "string", "tags": [], "label": "id", @@ -13846,7 +13857,7 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.getDisplayName", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.getDisplayName", "type": "Function", "tags": [], "label": "getDisplayName", @@ -13862,23 +13873,7 @@ }, { "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.getIconType", - "type": "Function", - "tags": [], - "label": "getIconType", - "description": [], - "signature": [ - "() => string" - ], - "path": "src/plugins/embeddable/public/lib/embeddables/common/constants.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "returnComment": [] - }, - { - "parentPluginId": "embeddable", - "id": "def-public.COMMON_EMBEDDABLE_GROUPING.other.order", + "id": "def-public.COMMON_EMBEDDABLE_GROUPING.legacy.order", "type": "number", "tags": [], "label": "order", @@ -14860,6 +14855,14 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts" }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts" + }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx" @@ -14896,6 +14899,26 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts" }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts" + }, + { + "plugin": "dashboard", + "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts" + }, { "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts" diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ca327b7c2a18a..e6a23ccc3d53c 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 08bdf957acfa3..ed618b7ca26dc 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index e736ec9e8d649..67f8d3c5d1cfc 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index a3240347c7770..eeb5c139dab18 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/entities_data_access.mdx b/api_docs/entities_data_access.mdx index 5053e9568c28f..75398c54e5460 100644 --- a/api_docs/entities_data_access.mdx +++ b/api_docs/entities_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entitiesDataAccess title: "entitiesDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the entitiesDataAccess plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entitiesDataAccess'] --- import entitiesDataAccessObj from './entities_data_access.devdocs.json'; diff --git a/api_docs/entity_manager.mdx b/api_docs/entity_manager.mdx index ee7a315dc646b..83fc2f9610c28 100644 --- a/api_docs/entity_manager.mdx +++ b/api_docs/entity_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entityManager title: "entityManager" image: https://source.unsplash.com/400x175/?github description: API docs for the entityManager plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entityManager'] --- import entityManagerObj from './entity_manager.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 41d16c588457b..99246ea4f5438 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/esql.mdx b/api_docs/esql.mdx index 5b58ef9e07df4..e63f6dca8e3ea 100644 --- a/api_docs/esql.mdx +++ b/api_docs/esql.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esql title: "esql" image: https://source.unsplash.com/400x175/?github description: API docs for the esql plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esql'] --- import esqlObj from './esql.devdocs.json'; diff --git a/api_docs/esql_data_grid.mdx b/api_docs/esql_data_grid.mdx index 3925db5fbbab4..6ee745b003794 100644 --- a/api_docs/esql_data_grid.mdx +++ b/api_docs/esql_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esqlDataGrid title: "esqlDataGrid" image: https://source.unsplash.com/400x175/?github description: API docs for the esqlDataGrid plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esqlDataGrid'] --- import esqlDataGridObj from './esql_data_grid.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index b802c4fdaeb0c..3734d82e8e9d3 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index 78e00d45a90a6..c0faab5ebe496 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 6602c3fe906d0..10440e6c04cae 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index 7ffccb4bed2f1..2ffaa3f07045c 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 42f243dc0a492..37f1ffb23a58f 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index e322b97ed85b0..5a62c26489a05 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 0f27f4798fd01..be647fc063a52 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 884f2111e4bf9..e1160d42f5279 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index f517d844e4cd6..2605a6f2b41d3 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 0f75d70c2e67f..eb9a9c4a44e79 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 95d383edffdb0..7fd0cd4a42380 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index c19eb03d70eab..eafabb45ab671 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index cf4251f26b316..b21591fe64360 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index b136f847e28d5..8453ee98830e9 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index a38a63547b257..7de851a5208fc 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 7a4a0138eb6ef..82a56661fc53a 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 6af98937e04ea..264aa86b03555 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 82fdf61b94248..90d813964c0a8 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 0993e80d5766b..ad91cbd5ee0e7 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 5ffb520b6ad7f..d3a66ae2dd474 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/fields_metadata.mdx b/api_docs/fields_metadata.mdx index 4d553af5d138c..c6bf76a5de583 100644 --- a/api_docs/fields_metadata.mdx +++ b/api_docs/fields_metadata.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldsMetadata title: "fieldsMetadata" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldsMetadata plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldsMetadata'] --- import fieldsMetadataObj from './fields_metadata.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 7a74e83ab837e..eefc467b35ea4 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index eaac1cbe4e941..f72c0b01da5cb 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index 1d9f8771d5b8f..9f9cdf1e0e207 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index e3514a62f90f6..b718522f6fe6d 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index aab1b754f5f35..5ebee384d33ff 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index c6a9208f7468d..68a28613a0b1a 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 0a1bd9d621145..870a26d182971 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index f2bcd790a9808..8a887750647ea 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index d777abb07c7a8..a5d7d28281a87 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index eae9b32b5fc9d..7c00262434245 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/inference.devdocs.json b/api_docs/inference.devdocs.json index 642be486024c6..f3ad7f665a14c 100644 --- a/api_docs/inference.devdocs.json +++ b/api_docs/inference.devdocs.json @@ -62,15 +62,21 @@ "label": "chatComplete", "description": [], "signature": [ - "(options: { connectorId: string; system?: string | undefined; messages: ", - "Message", - "[]; } & ", + ") => ", - "ChatCompletionResponse", - "<", + " = ", "ToolOptions", - ">" + ">(options: { connectorId: string; system?: string | undefined; messages: ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, + "[]; } & TToolOptions) => ", + "ChatCompletionResponse", + "" ], "path": "x-pack/plugins/inference/public/types.ts", "deprecated": false, @@ -86,7 +92,13 @@ "description": [], "signature": [ "{ connectorId: string; system?: string | undefined; messages: ", - "Message", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, "[]; } & TToolOptions" ], "path": "x-pack/plugins/inference/common/chat_complete/index.ts", @@ -103,7 +115,15 @@ "label": "output", "description": [], "signature": [ - "(id: TId, options: { connectorId: string; system?: string | undefined; input: string; schema?: TOutputSchema | undefined; }) => ", + "(id: TId, options: { connectorId: string; system?: string | undefined; input: string; schema?: TOutputSchema | undefined; previousMessages?: ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, + "[] | undefined; }) => ", "Observable", "<", "OutputEvent", @@ -138,7 +158,15 @@ "label": "options", "description": [], "signature": [ - "{ connectorId: string; system?: string | undefined; input: string; schema?: TOutputSchema | undefined; }" + "{ connectorId: string; system?: string | undefined; input: string; schema?: TOutputSchema | undefined; previousMessages?: ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, + "[] | undefined; }" ], "path": "x-pack/plugins/inference/common/output/index.ts", "deprecated": false, @@ -172,6 +200,77 @@ "server": { "classes": [], "functions": [ + { + "parentPluginId": "inference", + "id": "def-server.naturalLanguageToEsql", + "type": "Function", + "tags": [], + "label": "naturalLanguageToEsql", + "description": [], + "signature": [ + "({\n client,\n connectorId,\n tools,\n toolChoice,\n logger,\n ...rest\n}: { client: Pick<", + "InferenceClient", + ", \"output\" | \"chatComplete\">; connectorId: string; logger: Pick<", + { + "pluginId": "@kbn/logging", + "scope": "common", + "docId": "kibKbnLoggingPluginApi", + "section": "def-common.Logger", + "text": "Logger" + }, + ", \"debug\">; } & TToolOptions & ({ input: string; } | { messages: ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, + "[]; })) => ", + "Observable", + ">" + ], + "path": "x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-server.naturalLanguageToEsql.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n client,\n connectorId,\n tools,\n toolChoice,\n logger,\n ...rest\n}", + "description": [], + "signature": [ + "{ client: Pick<", + "InferenceClient", + ", \"output\" | \"chatComplete\">; connectorId: string; logger: Pick<", + { + "pluginId": "@kbn/logging", + "scope": "common", + "docId": "kibKbnLoggingPluginApi", + "section": "def-common.Logger", + "text": "Logger" + }, + ", \"debug\">; } & TToolOptions & ({ input: string; } | { messages: ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.Message", + "text": "Message" + }, + "[]; })" + ], + "path": "x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "inference", "id": "def-server.withoutChunkEvents", @@ -309,10 +408,447 @@ }, "common": { "classes": [], - "functions": [], + "functions": [ + { + "parentPluginId": "inference", + "id": "def-common.correctCommonEsqlMistakes", + "type": "Function", + "tags": [], + "label": "correctCommonEsqlMistakes", + "description": [], + "signature": [ + "(query: string) => { isCorrection: boolean; input: string; output: string; }" + ], + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.correctCommonEsqlMistakes.$1", + "type": "string", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.generateFakeToolCallId", + "type": "Function", + "tags": [], + "label": "generateFakeToolCallId", + "description": [], + "signature": [ + "() => string" + ], + "path": "x-pack/plugins/inference/common/chat_complete/generate_fake_tool_call_id.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionChunkEvent", + "type": "Function", + "tags": [], + "label": "isChatCompletionChunkEvent", + "description": [], + "signature": [ + "(event: ", + "ChatCompletionEvent", + "<", + "ToolOptions", + ">) => boolean" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_chunk_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionChunkEvent.$1", + "type": "CompoundType", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "ChatCompletionEvent", + "<", + "ToolOptions", + ">" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_chunk_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionEvent", + "type": "Function", + "tags": [], + "label": "isChatCompletionEvent", + "description": [], + "signature": [ + "(event: ", + "InferenceTaskEvent", + ") => boolean" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionEvent.$1", + "type": "Object", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "InferenceTaskEvent" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionMessageEvent", + "type": "Function", + "tags": [], + "label": "isChatCompletionMessageEvent", + "description": [], + "signature": [ + "(event: ", + "ChatCompletionEvent", + ") => boolean" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_message_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isChatCompletionMessageEvent.$1", + "type": "CompoundType", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "ChatCompletionEvent", + "" + ], + "path": "x-pack/plugins/inference/common/chat_complete/is_chat_completion_message_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isOutputCompleteEvent", + "type": "Function", + "tags": [], + "label": "isOutputCompleteEvent", + "description": [], + "signature": [ + "(event: TOutputEvent) => boolean" + ], + "path": "x-pack/plugins/inference/common/output/is_output_complete_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isOutputCompleteEvent.$1", + "type": "Uncategorized", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "TOutputEvent" + ], + "path": "x-pack/plugins/inference/common/output/is_output_complete_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isOutputEvent", + "type": "Function", + "tags": [], + "label": "isOutputEvent", + "description": [], + "signature": [ + "(event: ", + "InferenceTaskEvent", + ") => boolean" + ], + "path": "x-pack/plugins/inference/common/output/is_output_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isOutputEvent.$1", + "type": "Object", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "InferenceTaskEvent" + ], + "path": "x-pack/plugins/inference/common/output/is_output_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.isOutputUpdateEvent", + "type": "Function", + "tags": [], + "label": "isOutputUpdateEvent", + "description": [], + "signature": [ + "(event: ", + "OutputEvent", + ") => boolean" + ], + "path": "x-pack/plugins/inference/common/output/is_output_update_event.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.isOutputUpdateEvent.$1", + "type": "CompoundType", + "tags": [], + "label": "event", + "description": [], + "signature": [ + "OutputEvent", + "" + ], + "path": "x-pack/plugins/inference/common/output/is_output_update_event.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.splitIntoCommands", + "type": "Function", + "tags": [], + "label": "splitIntoCommands", + "description": [], + "signature": [ + "(query: string) => { name: string | undefined; command: string; }[]" + ], + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "inference", + "id": "def-common.splitIntoCommands.$1", + "type": "string", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], "interfaces": [], - "enums": [], - "misc": [], + "enums": [ + { + "parentPluginId": "inference", + "id": "def-common.MessageRole", + "type": "Enum", + "tags": [], + "label": "MessageRole", + "description": [], + "path": "x-pack/plugins/inference/common/chat_complete/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "misc": [ + { + "parentPluginId": "inference", + "id": "def-common.AssistantMessage", + "type": "Type", + "tags": [], + "label": "AssistantMessage", + "description": [], + "signature": [ + "MessageBase<", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.MessageRole", + "text": "MessageRole" + }, + ".Assistant> & { content: string | null; toolCalls?: ", + "ToolCall", + " | undefined>[] | undefined; }" + ], + "path": "x-pack/plugins/inference/common/chat_complete/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.Message", + "type": "Type", + "tags": [], + "label": "Message", + "description": [], + "signature": [ + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.UserMessage", + "text": "UserMessage" + }, + " | ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.AssistantMessage", + "text": "AssistantMessage" + }, + " | ", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.ToolMessage", + "text": "ToolMessage" + }, + "" + ], + "path": "x-pack/plugins/inference/common/chat_complete/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.ToolMessage", + "type": "Type", + "tags": [], + "label": "ToolMessage", + "description": [], + "signature": [ + "MessageBase<", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.MessageRole", + "text": "MessageRole" + }, + ".Tool> & { toolCallId: string; response: TToolResponse; }" + ], + "path": "x-pack/plugins/inference/common/chat_complete/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.ToolSchema", + "type": "Type", + "tags": [], + "label": "ToolSchema", + "description": [], + "signature": [ + "ToolSchemaTypeObject" + ], + "path": "x-pack/plugins/inference/common/chat_complete/tool_schema.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "inference", + "id": "def-common.UserMessage", + "type": "Type", + "tags": [], + "label": "UserMessage", + "description": [], + "signature": [ + "MessageBase<", + { + "pluginId": "inference", + "scope": "common", + "docId": "kibInferencePluginApi", + "section": "def-common.MessageRole", + "text": "MessageRole" + }, + ".User> & { content: string; }" + ], + "path": "x-pack/plugins/inference/common/chat_complete/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "objects": [] } } \ No newline at end of file diff --git a/api_docs/inference.mdx b/api_docs/inference.mdx index 37600fc7c5c2a..91d2efcb9bc67 100644 --- a/api_docs/inference.mdx +++ b/api_docs/inference.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inference title: "inference" image: https://source.unsplash.com/400x175/?github description: API docs for the inference plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inference'] --- import inferenceObj from './inference.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 16 | 0 | 14 | 11 | +| 41 | 0 | 39 | 13 | ## Client @@ -45,3 +45,14 @@ Contact [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai ### Functions +## Common + +### Functions + + +### Enums + + +### Consts, variables and types + + diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index bd72b6333769f..2217593593b77 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/ingest_pipelines.mdx b/api_docs/ingest_pipelines.mdx index 7ac2dcfb4ecd0..c039facb9f39d 100644 --- a/api_docs/ingest_pipelines.mdx +++ b/api_docs/ingest_pipelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ingestPipelines title: "ingestPipelines" image: https://source.unsplash.com/400x175/?github description: API docs for the ingestPipelines plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ingestPipelines'] --- import ingestPipelinesObj from './ingest_pipelines.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 7e5fb612e2868..35e358f0e8d35 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/integration_assistant.mdx b/api_docs/integration_assistant.mdx index 385a15fda876d..6309e353c9572 100644 --- a/api_docs/integration_assistant.mdx +++ b/api_docs/integration_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/integrationAssistant title: "integrationAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the integrationAssistant plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'integrationAssistant'] --- import integrationAssistantObj from './integration_assistant.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 612b0bf3967e3..86741fcbed4b9 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/investigate.mdx b/api_docs/investigate.mdx index a4a135461cf8e..98f2a809f41b1 100644 --- a/api_docs/investigate.mdx +++ b/api_docs/investigate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigate title: "investigate" image: https://source.unsplash.com/400x175/?github description: API docs for the investigate plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigate'] --- import investigateObj from './investigate.devdocs.json'; diff --git a/api_docs/investigate_app.mdx b/api_docs/investigate_app.mdx index 3dadfb125ac44..6f04af420aa24 100644 --- a/api_docs/investigate_app.mdx +++ b/api_docs/investigate_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigateApp title: "investigateApp" image: https://source.unsplash.com/400x175/?github description: API docs for the investigateApp plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigateApp'] --- import investigateAppObj from './investigate_app.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 559b84f7c7b0c..a18fc8f80c58c 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 0430dd0ff009b..bf644bb2691bc 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 9ac9be5e16de7..b73c3614c227b 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_pattern_analysis.mdx b/api_docs/kbn_aiops_log_pattern_analysis.mdx index c135ea04c7538..bf7db97d06016 100644 --- a/api_docs/kbn_aiops_log_pattern_analysis.mdx +++ b/api_docs/kbn_aiops_log_pattern_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-pattern-analysis title: "@kbn/aiops-log-pattern-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-pattern-analysis plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-pattern-analysis'] --- import kbnAiopsLogPatternAnalysisObj from './kbn_aiops_log_pattern_analysis.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_rate_analysis.mdx b/api_docs/kbn_aiops_log_rate_analysis.mdx index 7408afbd8bee9..7d629a882f469 100644 --- a/api_docs/kbn_aiops_log_rate_analysis.mdx +++ b/api_docs/kbn_aiops_log_rate_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-rate-analysis title: "@kbn/aiops-log-rate-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-rate-analysis plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-rate-analysis'] --- import kbnAiopsLogRateAnalysisObj from './kbn_aiops_log_rate_analysis.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 99fffbc22e03f..1ef7f8de25048 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_comparators.mdx b/api_docs/kbn_alerting_comparators.mdx index 630ffdc3118b8..06b6c3db61ddd 100644 --- a/api_docs/kbn_alerting_comparators.mdx +++ b/api_docs/kbn_alerting_comparators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-comparators title: "@kbn/alerting-comparators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-comparators plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-comparators'] --- import kbnAlertingComparatorsObj from './kbn_alerting_comparators.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 23eda69ed8744..99fa58d326480 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index f1d3606ee746c..25f0c57a7c6a4 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 50b620bec389a..b73c504e2ffee 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_grouping.mdx b/api_docs/kbn_alerts_grouping.mdx index b01845dbcfe4d..c70e06c886453 100644 --- a/api_docs/kbn_alerts_grouping.mdx +++ b/api_docs/kbn_alerts_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-grouping title: "@kbn/alerts-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-grouping plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-grouping'] --- import kbnAlertsGroupingObj from './kbn_alerts_grouping.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index aef34a61a447c..a5003d81ac8d5 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index f3dc0513d3bc9..5b6d10b1b2b55 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 48185cc463460..17df1d80a420e 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index f1c2410251285..480126cf27478 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_data_view.mdx b/api_docs/kbn_apm_data_view.mdx index 405dc244233ea..2af8921168f54 100644 --- a/api_docs/kbn_apm_data_view.mdx +++ b/api_docs/kbn_apm_data_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-data-view title: "@kbn/apm-data-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-data-view plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-data-view'] --- import kbnApmDataViewObj from './kbn_apm_data_view.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.devdocs.json b/api_docs/kbn_apm_synthtrace.devdocs.json index 3c806005b1463..288c90fb48d62 100644 --- a/api_docs/kbn_apm_synthtrace.devdocs.json +++ b/api_docs/kbn_apm_synthtrace.devdocs.json @@ -894,6 +894,77 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/apm-synthtrace", + "id": "def-server.SyntheticsSynthtraceEsClient", + "type": "Class", + "tags": [], + "label": "SyntheticsSynthtraceEsClient", + "description": [], + "signature": [ + { + "pluginId": "@kbn/apm-synthtrace", + "scope": "server", + "docId": "kibKbnApmSynthtracePluginApi", + "section": "def-server.SyntheticsSynthtraceEsClient", + "text": "SyntheticsSynthtraceEsClient" + }, + " extends ", + "SynthtraceEsClient", + "<", + { + "pluginId": "@kbn/apm-synthtrace-client", + "scope": "common", + "docId": "kibKbnApmSynthtraceClientPluginApi", + "section": "def-common.SyntheticsMonitorDocument", + "text": "SyntheticsMonitorDocument" + }, + ">" + ], + "path": "packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/apm-synthtrace", + "id": "def-server.SyntheticsSynthtraceEsClient.Unnamed", + "type": "Function", + "tags": [], + "label": "Constructor", + "description": [], + "signature": [ + "any" + ], + "path": "packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/apm-synthtrace", + "id": "def-server.SyntheticsSynthtraceEsClient.Unnamed.$1", + "type": "CompoundType", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "{ client: ", + "default", + "; logger: ", + "Logger", + "; } & ", + "SyntheticsSynthtraceEsClientOptions" + ], + "path": "packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false } ], "functions": [ diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 2f8bf7bf44ac2..17a8915c22a62 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 56 | 0 | 56 | 9 | +| 59 | 0 | 59 | 10 | ## Server diff --git a/api_docs/kbn_apm_synthtrace_client.devdocs.json b/api_docs/kbn_apm_synthtrace_client.devdocs.json index 94fa78faa93a5..e33639e0aa425 100644 --- a/api_docs/kbn_apm_synthtrace_client.devdocs.json +++ b/api_docs/kbn_apm_synthtrace_client.devdocs.json @@ -2780,6 +2780,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/apm-synthtrace-client", + "id": "def-common.SyntheticsMonitorDocument", + "type": "Type", + "tags": [], + "label": "SyntheticsMonitorDocument", + "description": [], + "signature": [ + "{ '@timestamp'?: number | undefined; } & Partial<{ 'data_stream.namespace': string; 'data_stream.type': string; 'data_stream.dataset': string; 'monitor.id': string; 'monitor.origin': string; 'monitor.name': string; 'monitor.type': string; 'monitor.check_group': string; 'monitor.timespan.lt': string; 'monitor.timespan.gte': string; 'monitor.duration.us'?: number | undefined; 'monitor.ip'?: string | undefined; 'monitor.project.name'?: string | undefined; 'monitor.project.id'?: string | undefined; 'monitor.fleet_managed'?: boolean | undefined; 'monitor.status'?: string | undefined; 'synthetics.type'?: string | undefined; 'synthetics.step.index'?: number | undefined; 'observer.os.name'?: string | undefined; 'observer.product'?: string | undefined; }>" + ], + "path": "packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/apm-synthtrace-client", "id": "def-common.SynthtraceESAction", @@ -3344,6 +3359,36 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/apm-synthtrace-client", + "id": "def-common.syntheticsMonitor", + "type": "Object", + "tags": [], + "label": "syntheticsMonitor", + "description": [], + "path": "packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/apm-synthtrace-client", + "id": "def-common.syntheticsMonitor.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "() => SyntheticsMonitor" + ], + "path": "packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [] + } + ], + "initialIsOpen": false } ] } diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index fcb127d8e0ec9..c7dd01bd2fd29 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 205 | 0 | 205 | 33 | +| 208 | 0 | 208 | 33 | ## Common diff --git a/api_docs/kbn_apm_types.mdx b/api_docs/kbn_apm_types.mdx index 1f83f24cfa16f..3baba11941894 100644 --- a/api_docs/kbn_apm_types.mdx +++ b/api_docs/kbn_apm_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-types title: "@kbn/apm-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-types'] --- import kbnApmTypesObj from './kbn_apm_types.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 279bb6b44de93..18be7d36856ef 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_avc_banner.mdx b/api_docs/kbn_avc_banner.mdx index cb9e2c5cd0b8f..5249046c0e70e 100644 --- a/api_docs/kbn_avc_banner.mdx +++ b/api_docs/kbn_avc_banner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-avc-banner title: "@kbn/avc-banner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/avc-banner plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/avc-banner'] --- import kbnAvcBannerObj from './kbn_avc_banner.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index e94548a4ccb27..b70d7d56b7086 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index 20471029bed9c..a0f55f29d549b 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 08a7da5344934..b6c96bc376143 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index efdf3da767da4..45ee469400b2d 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 8697c3a471d24..f650b0c33466c 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cbor.mdx b/api_docs/kbn_cbor.mdx index 0a5e0e2723943..418112b5981f1 100644 --- a/api_docs/kbn_cbor.mdx +++ b/api_docs/kbn_cbor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cbor title: "@kbn/cbor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cbor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cbor'] --- import kbnCborObj from './kbn_cbor.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index c8051ffc266f1..5da53872389c3 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 6c75269ce887b..86f63b2ff148b 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 0e38e558527a5..eb9d06ade8fa4 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 0a380ef725711..08b72485329ab 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 24a5868c040bb..71e7873ef5cd7 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index d073a89194abf..83f1c543068a4 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index 51d2d3ca4eb93..38a00acb02fb1 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture.mdx b/api_docs/kbn_cloud_security_posture.mdx index 792d5e935e42b..16837db24176a 100644 --- a/api_docs/kbn_cloud_security_posture.mdx +++ b/api_docs/kbn_cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture title: "@kbn/cloud-security-posture" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture'] --- import kbnCloudSecurityPostureObj from './kbn_cloud_security_posture.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture_common.devdocs.json b/api_docs/kbn_cloud_security_posture_common.devdocs.json index 854d90ed1a0f0..ae15a9e184a71 100644 --- a/api_docs/kbn_cloud_security_posture_common.devdocs.json +++ b/api_docs/kbn_cloud_security_posture_common.devdocs.json @@ -19,6 +19,54 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildEntityFlyoutPreviewQuery", + "type": "Function", + "tags": [], + "label": "buildEntityFlyoutPreviewQuery", + "description": [], + "signature": [ + "(field: string, queryValue?: string | undefined) => { bool: { filter: { bool: { should: { term: { [x: string]: { value: string; }; }; }[]; minimum_should_match: number; }; }[]; }; }" + ], + "path": "x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildEntityFlyoutPreviewQuery.$1", + "type": "string", + "tags": [], + "label": "field", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/cloud-security-posture-common", + "id": "def-common.buildEntityFlyoutPreviewQuery.$2", + "type": "string", + "tags": [], + "label": "queryValue", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/cloud-security-posture-common", "id": "def-common.buildMutedRulesFilter", diff --git a/api_docs/kbn_cloud_security_posture_common.mdx b/api_docs/kbn_cloud_security_posture_common.mdx index 701cae6f345c8..68711028e8df6 100644 --- a/api_docs/kbn_cloud_security_posture_common.mdx +++ b/api_docs/kbn_cloud_security_posture_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-common title: "@kbn/cloud-security-posture-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-common'] --- import kbnCloudSecurityPostureCommonObj from './kbn_cloud_security_posture_common.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 49 | 0 | 49 | 0 | +| 52 | 0 | 52 | 0 | ## Common diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index aff2682776629..2a630ba68095b 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 4ddc18f8e23f9..f5ac56c36bc7a 100644 --- a/api_docs/kbn_code_editor_mock.mdx +++ b/api_docs/kbn_code_editor_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mock title: "@kbn/code-editor-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mock plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mock'] --- import kbnCodeEditorMockObj from './kbn_code_editor_mock.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 18e8b2176b1d5..e24249f21374b 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 8880044e759f9..befaab1025ea7 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index f4ea8de69b132..bb2021e54be94 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 724fdf9db7a2a..145b9f62d049a 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 331cbf796fd67..d90b032979908 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 9a812ddbd21ee..377dccdc93b00 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_public.mdx b/api_docs/kbn_content_management_content_insights_public.mdx index f3ab445f10c3f..a85ea7719023b 100644 --- a/api_docs/kbn_content_management_content_insights_public.mdx +++ b/api_docs/kbn_content_management_content_insights_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-public title: "@kbn/content-management-content-insights-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-public plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-public'] --- import kbnContentManagementContentInsightsPublicObj from './kbn_content_management_content_insights_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_server.mdx b/api_docs/kbn_content_management_content_insights_server.mdx index 8f90f672b2d6d..8e9e7ec6fafea 100644 --- a/api_docs/kbn_content_management_content_insights_server.mdx +++ b/api_docs/kbn_content_management_content_insights_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-server title: "@kbn/content-management-content-insights-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-server'] --- import kbnContentManagementContentInsightsServerObj from './kbn_content_management_content_insights_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_public.mdx b/api_docs/kbn_content_management_favorites_public.mdx index ba4c19a325528..37e4e9f494368 100644 --- a/api_docs/kbn_content_management_favorites_public.mdx +++ b/api_docs/kbn_content_management_favorites_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-public title: "@kbn/content-management-favorites-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-public plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-public'] --- import kbnContentManagementFavoritesPublicObj from './kbn_content_management_favorites_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_server.mdx b/api_docs/kbn_content_management_favorites_server.mdx index 86c290aeb347e..aa6efdddebf3c 100644 --- a/api_docs/kbn_content_management_favorites_server.mdx +++ b/api_docs/kbn_content_management_favorites_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-server title: "@kbn/content-management-favorites-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-server'] --- import kbnContentManagementFavoritesServerObj from './kbn_content_management_favorites_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 7f74f65192d42..06e04209a3de1 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 0da2d661d111d..9338277d74679 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index 3f1a1d48170db..95fe2876b2ea3 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 22d517f7bafc8..065c22db5d5a3 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_user_profiles.mdx b/api_docs/kbn_content_management_user_profiles.mdx index e66ea0de67df4..d892797104aeb 100644 --- a/api_docs/kbn_content_management_user_profiles.mdx +++ b/api_docs/kbn_content_management_user_profiles.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-user-profiles title: "@kbn/content-management-user-profiles" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-user-profiles plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-user-profiles'] --- import kbnContentManagementUserProfilesObj from './kbn_content_management_user_profiles.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 7bfc1826263d9..140913b0f72fb 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 0ef602e7ecd61..ad66600d62c6d 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 73a750a28aee9..c5d3860d5065c 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index ec8425b7ccaa5..72a9b912b465f 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index a6bef083e2143..5dd36f1473b29 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 51a21430602e1..9f694028b13e9 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index aedf82955bc87..47189eb0a3213 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 08b390dbad8b0..c7d366880265e 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 344e1585a8b31..21f1f2d570eec 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index b7cfc11dd5881..7b3138c4d0fcf 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index fd263d0da0243..3fbe3bab6e2e5 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index a26f39e580c14..e42d9a063c0ea 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index ee897cccf0a9f..26a0458580f1f 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index d5859ccc33f09..06b4c1ac596f5 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index ca25863d9612e..fabc7413a8278 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 9ea4d7d3c4970..e741f026390b2 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index ab224b821bec6..f743d2c14fd0c 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index ef93d0899ca91..3e43de00d9401 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 6596f50dc4db1..292e8400be145 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 7c22798c5785b..6b99ebc53481c 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 36c34d2a56bd8..dbf684cb8fc4b 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 7c3db61aa23a2..7eea142874ccb 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index cc790f9c12ab0..af0812f4fa489 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 4fcf194c7d6f1..3132af991dec0 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index f5ae9aa1caa4d..edbf15af08327 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index ebb4df5788432..3e626d9195a01 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 310007143d8d6..c6f80f566d631 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 5581104e64345..34e988790069d 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 74d1d6c119109..18fb06c42a46a 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index faba4717db97b..f9df8b42456c7 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index c5b804958b60e..49252a9d63c4d 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 9a5ef43e8a7c3..d5adf78659c9c 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 528623370d127..881b50943c70d 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index f5c02b5b67ca3..5b43bd077e0ad 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 6b1153087b658..e98d5dcbb9cbf 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 1c99699305989..0bed39d4ed1c8 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 3895b1b576bfd..8bb81fcf71228 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index f974f19958e31..68917bce1d7e5 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 989d33def0047..4dbacfb396fba 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 0a9f15e852610..5e9e026449bc5 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index fa7739b740f6e..e1a3d083e3ba0 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 46c9c0384fdd6..38c4fd6e61baf 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index f5f2d338b27f8..e8749fecb07cd 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 5eb26fb820ade..215a800a9d674 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 2d63c31c73d26..c8eafed5d7433 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.devdocs.json b/api_docs/kbn_core_elasticsearch_server.devdocs.json index be09c9b65cbd1..3545ca05a5d0a 100644 --- a/api_docs/kbn_core_elasticsearch_server.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server.devdocs.json @@ -804,6 +804,22 @@ "path": "packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_service.test.ts" } ] + }, + { + "parentPluginId": "@kbn/core-elasticsearch-server", + "id": "def-server.ElasticsearchServiceSetup.publicBaseUrl", + "type": "string", + "tags": [], + "label": "publicBaseUrl", + "description": [ + "\nThe public base URL (if any) that should be used by end users to access the Elasticsearch cluster." + ], + "signature": [ + "string | undefined" + ], + "path": "packages/core/elasticsearch/core-elasticsearch-server/src/contracts.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 7a4d8c90d652d..d2b14025c8efa 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 116 | 0 | 56 | 0 | +| 117 | 0 | 56 | 0 | ## Server diff --git a/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json b/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json index 89c6626b9fd7d..a0e2b420b19bc 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server_internal.devdocs.json @@ -3170,7 +3170,7 @@ "label": "ElasticsearchConfigType", "description": [], "signature": [ - "{ readonly username?: string | undefined; readonly password?: string | undefined; readonly serviceAccountToken?: string | undefined; readonly ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; keystore: Readonly<{ password?: string | undefined; path?: string | undefined; } & {}>; truststore: Readonly<{ password?: string | undefined; path?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>; readonly healthCheck: Readonly<{} & { delay: moment.Duration; startupDelay: moment.Duration; }>; readonly hosts: string | string[]; readonly apiVersion: string; readonly customHeaders: Record; readonly sniffOnStart: boolean; readonly sniffInterval: false | moment.Duration; readonly sniffOnConnectionFault: boolean; readonly maxSockets: number; readonly maxIdleSockets: number; readonly maxResponseSize: false | ", + "{ readonly username?: string | undefined; readonly password?: string | undefined; readonly serviceAccountToken?: string | undefined; readonly publicBaseUrl?: string | undefined; readonly ssl: Readonly<{ key?: string | undefined; certificateAuthorities?: string | string[] | undefined; certificate?: string | undefined; keyPassphrase?: string | undefined; } & { verificationMode: \"none\" | \"full\" | \"certificate\"; keystore: Readonly<{ password?: string | undefined; path?: string | undefined; } & {}>; truststore: Readonly<{ password?: string | undefined; path?: string | undefined; } & {}>; alwaysPresentCertificate: boolean; }>; readonly healthCheck: Readonly<{} & { delay: moment.Duration; startupDelay: moment.Duration; }>; readonly hosts: string | string[]; readonly apiVersion: string; readonly customHeaders: Record; readonly sniffOnStart: boolean; readonly sniffInterval: false | moment.Duration; readonly sniffOnConnectionFault: boolean; readonly maxSockets: number; readonly maxIdleSockets: number; readonly maxResponseSize: false | ", { "pluginId": "@kbn/config-schema", "scope": "common", @@ -3524,7 +3524,15 @@ "section": "def-common.Type", "text": "Type" }, - "; }>" + "; publicBaseUrl: ", + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.Type", + "text": "Type" + }, + "; }>" ], "path": "packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_config.ts", "deprecated": false, diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index b862638404f10..1a3e36cb85b5a 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.devdocs.json b/api_docs/kbn_core_elasticsearch_server_mocks.devdocs.json index 903e2f228cd97..702a8890af3d9 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.devdocs.json +++ b/api_docs/kbn_core_elasticsearch_server_mocks.devdocs.json @@ -22,7 +22,7 @@ "label": "MockedElasticSearchServiceSetup", "description": [], "signature": [ - "{ setUnauthorizedErrorHandler: jest.MockInstance Promise<{ histogramBarTarget: number; }>) | undefined" + ], + "path": "packages/kbn-esql-validation-autocomplete/src/shared/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/kbn_esql_validation_autocomplete.mdx b/api_docs/kbn_esql_validation_autocomplete.mdx index 8f24b4f68ab85..3c2bac2dc54a0 100644 --- a/api_docs/kbn_esql_validation_autocomplete.mdx +++ b/api_docs/kbn_esql_validation_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-validation-autocomplete title: "@kbn/esql-validation-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-validation-autocomplete plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-validation-autocomplete'] --- import kbnEsqlValidationAutocompleteObj from './kbn_esql_validation_autocomplete.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 196 | 0 | 184 | 10 | +| 197 | 0 | 185 | 10 | ## Common diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 4068354e9f72d..693b6956a3d4c 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index f16d5e6f2d8cd..d0ec4e7ebbf85 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 3a3e454bedd2d..7c5c00a71ae50 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index e7f07db91fd62..1dff38ce61c5b 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 34b34b59b24c7..c432b29fd1c1d 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 94b18d555a77c..2644964058071 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_formatters.mdx b/api_docs/kbn_formatters.mdx index c18d2d4feaa6f..1302f882b044c 100644 --- a/api_docs/kbn_formatters.mdx +++ b/api_docs/kbn_formatters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-formatters title: "@kbn/formatters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/formatters plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/formatters'] --- import kbnFormattersObj from './kbn_formatters.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 8fb6ebf0bafe3..c6a9149830d6e 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index 35036ad4307fa..5061d2a7cd440 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index d3f681d908b88..b2d6e8faa8056 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index ab8dca013e975..241dbcc39e53b 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 290aeb7e3ad3d..9f5bf9f5d5522 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_grid_layout.mdx b/api_docs/kbn_grid_layout.mdx index 8822819530a3a..a2dd470ec8a2a 100644 --- a/api_docs/kbn_grid_layout.mdx +++ b/api_docs/kbn_grid_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grid-layout title: "@kbn/grid-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grid-layout plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grid-layout'] --- import kbnGridLayoutObj from './kbn_grid_layout.devdocs.json'; diff --git a/api_docs/kbn_grouping.mdx b/api_docs/kbn_grouping.mdx index 7abc8239f7a17..1792959ecf851 100644 --- a/api_docs/kbn_grouping.mdx +++ b/api_docs/kbn_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grouping title: "@kbn/grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grouping plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grouping'] --- import kbnGroupingObj from './kbn_grouping.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 511488182bd6e..ca0718bd540f4 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index a4208754d01e7..b6bb256b9cddf 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index b13bc8e541396..34cc9178cbcb3 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 9d60b2b4fc2f5..8d85a8c281180 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index c46dc8292555c..9b64534bd2666 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index a1d8721da3e26..cd5a355fb6319 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index f11b214e4c1b1..353b96613bd88 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 410a04682e121..f977064f37937 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index a1b0513581707..d2fbf877c1577 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_index_management.mdx b/api_docs/kbn_index_management.mdx index d67e8e0ea414a..607486ca0e208 100644 --- a/api_docs/kbn_index_management.mdx +++ b/api_docs/kbn_index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-management title: "@kbn/index-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-management plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-management'] --- import kbnIndexManagementObj from './kbn_index_management.devdocs.json'; diff --git a/api_docs/kbn_inference_integration_flyout.mdx b/api_docs/kbn_inference_integration_flyout.mdx index d6ea4cdd3955b..8f24cafac37e6 100644 --- a/api_docs/kbn_inference_integration_flyout.mdx +++ b/api_docs/kbn_inference_integration_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference_integration_flyout title: "@kbn/inference_integration_flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference_integration_flyout plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference_integration_flyout'] --- import kbnInferenceIntegrationFlyoutObj from './kbn_inference_integration_flyout.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 0b21369d169e3..fe04b9439c425 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 22fb6aeeb0b42..736e0f0acc87e 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_investigation_shared.mdx b/api_docs/kbn_investigation_shared.mdx index 64c4e845ebaba..c3c51b0fc45e1 100644 --- a/api_docs/kbn_investigation_shared.mdx +++ b/api_docs/kbn_investigation_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-investigation-shared title: "@kbn/investigation-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/investigation-shared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/investigation-shared'] --- import kbnInvestigationSharedObj from './kbn_investigation_shared.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 8d3fb0b07414a..f7b7ee5878d38 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_ipynb.mdx b/api_docs/kbn_ipynb.mdx index 1073439b7c70a..32ed1dc00ebdc 100644 --- a/api_docs/kbn_ipynb.mdx +++ b/api_docs/kbn_ipynb.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ipynb title: "@kbn/ipynb" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ipynb plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ipynb'] --- import kbnIpynbObj from './kbn_ipynb.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 941b4dd524151..7045ce79cf935 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 6fca2bfb13625..d33da1b416c56 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index c60b50a4c1612..ad065e6f82b0e 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_json_schemas.mdx b/api_docs/kbn_json_schemas.mdx index 2b5894f5902f8..fef71d5ac45ce 100644 --- a/api_docs/kbn_json_schemas.mdx +++ b/api_docs/kbn_json_schemas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-schemas title: "@kbn/json-schemas" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-schemas plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-schemas'] --- import kbnJsonSchemasObj from './kbn_json_schemas.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 90b88bf507a41..01290ba58c883 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index decddf8c1c6dc..e09316997218a 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 49ad601e68d1d..ba5df45ec8009 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_lens_formula_docs.mdx b/api_docs/kbn_lens_formula_docs.mdx index 39f17c7d5e4c8..e465902b0809c 100644 --- a/api_docs/kbn_lens_formula_docs.mdx +++ b/api_docs/kbn_lens_formula_docs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-formula-docs title: "@kbn/lens-formula-docs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-formula-docs plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-formula-docs'] --- import kbnLensFormulaDocsObj from './kbn_lens_formula_docs.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index c821a5a7ba606..9b8c73fee565f 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 3b93e22461bec..d6c195a08184e 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_content_badge.mdx b/api_docs/kbn_managed_content_badge.mdx index 87b9fb9dbff04..95437027ffcfa 100644 --- a/api_docs/kbn_managed_content_badge.mdx +++ b/api_docs/kbn_managed_content_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-content-badge title: "@kbn/managed-content-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-content-badge plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-content-badge'] --- import kbnManagedContentBadgeObj from './kbn_managed_content_badge.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 7899d63814ee8..c64ac1ed05f61 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index f827979a70045..38216ccb60d36 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index 0b5c093b0d9af..56dc420cdacf3 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index 72d2ecd893be6..17879f353b82b 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index dda8e3d9e7b62..41276872b16a4 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 7cb0210543e57..7816036b6d997 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index f2863f3f45080..5e33498671a85 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index ebfd96fd4b010..0b7b89a26c730 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index 83b24df9b40e5..a8cca5758acd1 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 6cf89e770e159..10f725e73d23d 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index c57ba88e6e8d0..56c9b663b3715 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index 60ac8e4ad5f66..3ef1a7860d24c 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 2928501aebd14..b3f9e5f8b7dfc 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 3432f3f90fa4b..943a315f43c0c 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 7f2904002c499..ffb986796cad8 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 47f28165bdf8a..223f657e44896 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 2138126b24272..1a63c3f3dc070 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index b548bc944060e..2d7633a64bdc4 100644 --- a/api_docs/kbn_ml_cancellable_search.mdx +++ b/api_docs/kbn_ml_cancellable_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-cancellable-search title: "@kbn/ml-cancellable-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-cancellable-search plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-cancellable-search'] --- import kbnMlCancellableSearchObj from './kbn_ml_cancellable_search.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index c40aace563729..0af4da26f7cb4 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index 73de4ec119c6b..61e7f34f4dd18 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 3fa5f7d9c946e..c1bd18574756b 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 156d4b84d8e7f..0b2a256e899d7 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 6da632ed5eeeb..9e8508ea1f61a 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 652c238f4973b..22c022b158d29 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index cd96d5a38eeff..1561eff2cf39c 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index f0516390e768a..80fa5d7cae138 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index a04530433bbe2..54df1f4bc2ff0 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index bc73de9254e3f..5780c410537c3 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index cc40794f097f2..3d441b0d33ae3 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 10511a9a17efc..e9545a2edee98 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index af3846a090d7b..bb4f984262829 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index 030702d4f680d..bf9191ad0f631 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index d4c5a9c24fe5a..56169650d4938 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index d22ac5d767184..b4ba29a718ce3 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 6d22b27ddc9c4..8a127c154e509 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 70917fd530a12..93f06b90e89c5 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 7fcef8bc31430..51ff752d341d4 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_time_buckets.mdx b/api_docs/kbn_ml_time_buckets.mdx index f69e7b152d8c3..3aed26f34ae63 100644 --- a/api_docs/kbn_ml_time_buckets.mdx +++ b/api_docs/kbn_ml_time_buckets.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-time-buckets title: "@kbn/ml-time-buckets" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-time-buckets plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-time-buckets'] --- import kbnMlTimeBucketsObj from './kbn_ml_time_buckets.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index d592a178610b9..521779b15573a 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index 9f484e34d2757..04dc8d051cf99 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 76796298613d7..0eeea25294d0f 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index d67cd116c2959..ee671096e6025 100644 --- a/api_docs/kbn_mock_idp_utils.mdx +++ b/api_docs/kbn_mock_idp_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mock-idp-utils title: "@kbn/mock-idp-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mock-idp-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mock-idp-utils'] --- import kbnMockIdpUtilsObj from './kbn_mock_idp_utils.devdocs.json'; diff --git a/api_docs/kbn_monaco.devdocs.json b/api_docs/kbn_monaco.devdocs.json index 6034d3f573795..50ee211f14029 100644 --- a/api_docs/kbn_monaco.devdocs.json +++ b/api_docs/kbn_monaco.devdocs.json @@ -523,6 +523,22 @@ "path": "packages/kbn-esql-validation-autocomplete/src/shared/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/monaco", + "id": "def-common.ESQLCallbacks.getPreferences", + "type": "Function", + "tags": [], + "label": "getPreferences", + "description": [], + "signature": [ + "(() => Promise<{ histogramBarTarget: number; }>) | undefined" + ], + "path": "packages/kbn-esql-validation-autocomplete/src/shared/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index cc54250116e74..85ab35a10ee7b 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 120 | 0 | 120 | 3 | +| 121 | 0 | 121 | 3 | ## Common diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 56ec5ba8cefed..ae3f016c15d5f 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_object_versioning_utils.mdx b/api_docs/kbn_object_versioning_utils.mdx index 4f6bdffbc42c0..56880e15bff3d 100644 --- a/api_docs/kbn_object_versioning_utils.mdx +++ b/api_docs/kbn_object_versioning_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning-utils title: "@kbn/object-versioning-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning-utils'] --- import kbnObjectVersioningUtilsObj from './kbn_object_versioning_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 0be7162b4177b..51e5262ce88c0 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_rule_utils.mdx b/api_docs/kbn_observability_alerting_rule_utils.mdx index 54a6b2a1439c1..56ff2c52642b4 100644 --- a/api_docs/kbn_observability_alerting_rule_utils.mdx +++ b/api_docs/kbn_observability_alerting_rule_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-rule-utils title: "@kbn/observability-alerting-rule-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-rule-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-rule-utils'] --- import kbnObservabilityAlertingRuleUtilsObj from './kbn_observability_alerting_rule_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index c65729ec169be..0865cde4f975a 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index 56b3991e4a19d..c42b538078ac5 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index a1b3574287f44..8dfab62d17710 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index 20ed1d4ee9e5f..46d4ca0a1b0e4 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 6274a608fe97f..14eba650daad3 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 6ca37eca11166..be9c399b6fd8b 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 2106f842157c4..14f8f9054c744 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 4e49a09095334..bd923556da76c 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index e3774c6034cc4..5743194a29803 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_check.mdx b/api_docs/kbn_plugin_check.mdx index 7dad7d321979c..485aea6888c8a 100644 --- a/api_docs/kbn_plugin_check.mdx +++ b/api_docs/kbn_plugin_check.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-check title: "@kbn/plugin-check" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-check plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-check'] --- import kbnPluginCheckObj from './kbn_plugin_check.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index d9c4612407a92..b067c614be8cb 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 6c3432a8e62cb..6b1122f3bc273 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_presentation_containers.mdx b/api_docs/kbn_presentation_containers.mdx index 8cf2c4ae4a739..e761941dd21a9 100644 --- a/api_docs/kbn_presentation_containers.mdx +++ b/api_docs/kbn_presentation_containers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-containers title: "@kbn/presentation-containers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-containers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index a98b30e5b8237..07585358e1775 100644 --- a/api_docs/kbn_presentation_publishing.mdx +++ b/api_docs/kbn_presentation_publishing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-publishing title: "@kbn/presentation-publishing" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-publishing plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 889a5bc39ffce..fbe5a35b6a596 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 07f210d027d18..74f493c6ddec8 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 22be016c7065b..72f153531a794 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_hooks.mdx b/api_docs/kbn_react_hooks.mdx index 2f3d31c43c10c..b6274ae6f2e4f 100644 --- a/api_docs/kbn_react_hooks.mdx +++ b/api_docs/kbn_react_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-hooks title: "@kbn/react-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-hooks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-hooks'] --- import kbnReactHooksObj from './kbn_react_hooks.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 35f9face2066f..ed83af357c5f9 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 33986673f7c9e..407130f15a530 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index 85522fbeec5cd..4410907699391 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index 522f5540a0a28..4c8275a1f844d 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 701262a1c6202..b5f922f6dc925 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index a1e811c670f38..54e03782cfe23 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_recently_accessed.mdx b/api_docs/kbn_recently_accessed.mdx index 74852cfe97930..981ffe9787144 100644 --- a/api_docs/kbn_recently_accessed.mdx +++ b/api_docs/kbn_recently_accessed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-recently-accessed title: "@kbn/recently-accessed" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/recently-accessed plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/recently-accessed'] --- import kbnRecentlyAccessedObj from './kbn_recently_accessed.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index afce45d0a4e5a..0199bb09aa92a 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 66152c140d050..cad136a4212d9 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 89598c5495039..0dab365b8cbe6 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 7212fe86162d6..f04c07e3703f8 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 5186037899cb0..63fa1216fdc45 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_csv_share_panel.mdx b/api_docs/kbn_reporting_csv_share_panel.mdx index 8aab840657761..91a1faefd4a54 100644 --- a/api_docs/kbn_reporting_csv_share_panel.mdx +++ b/api_docs/kbn_reporting_csv_share_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-csv-share-panel title: "@kbn/reporting-csv-share-panel" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-csv-share-panel plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-csv-share-panel'] --- import kbnReportingCsvSharePanelObj from './kbn_reporting_csv_share_panel.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 4c2c55b5044e6..6460d2a03cc1f 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index 1715c1683e2fc..202d6d64fd62b 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index 839d7402fa94a..d96ba3315c0b7 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 3d58778f8fb77..2df56591936ac 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 3670be002372b..05d5a12bb28f5 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index d4a5141d826d6..95174ef9a1fdc 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 256565ca78b89..55e28ad868310 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index 47114d5c0e1e2..35b8d34c3428a 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index 52eecec810e55..ea0dad1847850 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 8d8b98ddee18b..d196b7563ede8 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_response_ops_feature_flag_service.mdx b/api_docs/kbn_response_ops_feature_flag_service.mdx index 79253a7fdec43..8213d5cc1fd02 100644 --- a/api_docs/kbn_response_ops_feature_flag_service.mdx +++ b/api_docs/kbn_response_ops_feature_flag_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-feature-flag-service title: "@kbn/response-ops-feature-flag-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-feature-flag-service plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-feature-flag-service'] --- import kbnResponseOpsFeatureFlagServiceObj from './kbn_response_ops_feature_flag_service.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index f1bd8870c9afe..fb4b779f59a6a 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rollup.mdx b/api_docs/kbn_rollup.mdx index 214ba21b97491..ea1efcef77fa8 100644 --- a/api_docs/kbn_rollup.mdx +++ b/api_docs/kbn_rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rollup title: "@kbn/rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rollup plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rollup'] --- import kbnRollupObj from './kbn_rollup.devdocs.json'; diff --git a/api_docs/kbn_router_to_openapispec.mdx b/api_docs/kbn_router_to_openapispec.mdx index 781db8173e579..6651855e31879 100644 --- a/api_docs/kbn_router_to_openapispec.mdx +++ b/api_docs/kbn_router_to_openapispec.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-to-openapispec title: "@kbn/router-to-openapispec" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-to-openapispec plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-to-openapispec'] --- import kbnRouterToOpenapispecObj from './kbn_router_to_openapispec.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 9a5744269a248..7a27c8f1da04f 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 5946ec1e70f47..04a4a48a4099b 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index ca34a897bc561..ba17b5e8921e6 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index f2581007d4041..bcd6804c0b9fb 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_screenshotting_server.mdx b/api_docs/kbn_screenshotting_server.mdx index 05d28d93a2bc4..3cebd22ae896e 100644 --- a/api_docs/kbn_screenshotting_server.mdx +++ b/api_docs/kbn_screenshotting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-screenshotting-server title: "@kbn/screenshotting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/screenshotting-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/screenshotting-server'] --- import kbnScreenshottingServerObj from './kbn_screenshotting_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 5a3a7a0cc093e..e826508ba1b46 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 22ecdee55b18b..125f61c370308 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index 8a6a39916b011..c5b160de91916 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index 281e5c9ab5b42..206ce184f752e 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index 0483060fbb8a8..180105b35e6e4 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_search_types.mdx b/api_docs/kbn_search_types.mdx index 9aca26b5a155d..00892575756c1 100644 --- a/api_docs/kbn_search_types.mdx +++ b/api_docs/kbn_search_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-types title: "@kbn/search-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-types'] --- import kbnSearchTypesObj from './kbn_search_types.devdocs.json'; diff --git a/api_docs/kbn_security_api_key_management.mdx b/api_docs/kbn_security_api_key_management.mdx index 3ddb746cf6f7c..9c3d2bc316824 100644 --- a/api_docs/kbn_security_api_key_management.mdx +++ b/api_docs/kbn_security_api_key_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-api-key-management title: "@kbn/security-api-key-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-api-key-management plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-api-key-management'] --- import kbnSecurityApiKeyManagementObj from './kbn_security_api_key_management.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core.mdx b/api_docs/kbn_security_authorization_core.mdx index 0247ed5a45bce..0a5bb2b14499b 100644 --- a/api_docs/kbn_security_authorization_core.mdx +++ b/api_docs/kbn_security_authorization_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core title: "@kbn/security-authorization-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core'] --- import kbnSecurityAuthorizationCoreObj from './kbn_security_authorization_core.devdocs.json'; diff --git a/api_docs/kbn_security_form_components.mdx b/api_docs/kbn_security_form_components.mdx index ada47bf2c1198..f77da6fdeda69 100644 --- a/api_docs/kbn_security_form_components.mdx +++ b/api_docs/kbn_security_form_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-form-components title: "@kbn/security-form-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-form-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-form-components'] --- import kbnSecurityFormComponentsObj from './kbn_security_form_components.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index 18fd6c268ac43..30e5fc9f95986 100644 --- a/api_docs/kbn_security_hardening.mdx +++ b/api_docs/kbn_security_hardening.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-hardening title: "@kbn/security-hardening" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-hardening plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] --- import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index ccb7267d86577..a79d591892fdc 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 57c9bd94560f6..a3daebc35f052 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index e6d2a30443b0a..84c4d394d9359 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_role_management_model.mdx b/api_docs/kbn_security_role_management_model.mdx index ab238040178b9..fc819002a000a 100644 --- a/api_docs/kbn_security_role_management_model.mdx +++ b/api_docs/kbn_security_role_management_model.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-role-management-model title: "@kbn/security-role-management-model" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-role-management-model plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-role-management-model'] --- import kbnSecurityRoleManagementModelObj from './kbn_security_role_management_model.devdocs.json'; diff --git a/api_docs/kbn_security_solution_common.mdx b/api_docs/kbn_security_solution_common.mdx index ac8c2b774bc2b..501fcc703e7f6 100644 --- a/api_docs/kbn_security_solution_common.mdx +++ b/api_docs/kbn_security_solution_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-common title: "@kbn/security-solution-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-common plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-common'] --- import kbnSecuritySolutionCommonObj from './kbn_security_solution_common.devdocs.json'; diff --git a/api_docs/kbn_security_solution_distribution_bar.mdx b/api_docs/kbn_security_solution_distribution_bar.mdx index 3af5682c67e64..16068df97ea45 100644 --- a/api_docs/kbn_security_solution_distribution_bar.mdx +++ b/api_docs/kbn_security_solution_distribution_bar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-distribution-bar title: "@kbn/security-solution-distribution-bar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-distribution-bar plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-distribution-bar'] --- import kbnSecuritySolutionDistributionBarObj from './kbn_security_solution_distribution_bar.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 8f294d89c970b..19f3af0cb192a 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index 3b9a818ef5ba7..db71cd1bcfdb7 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index f999ee849f789..b3ba237ee78a6 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index ee7c468413ae2..250016039e855 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_security_ui_components.mdx b/api_docs/kbn_security_ui_components.mdx index 943d19da3734d..d1625f6e920cd 100644 --- a/api_docs/kbn_security_ui_components.mdx +++ b/api_docs/kbn_security_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-ui-components title: "@kbn/security-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-ui-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-ui-components'] --- import kbnSecurityUiComponentsObj from './kbn_security_ui_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 73b22d223a38f..7b57e4466c414 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 94a0497829528..6d0578a32bcfd 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index aed6d30854700..089a29aefea06 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index ab617c53cc5a5..9bfce93577d45 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 59c397bad97a2..85548f69d6d27 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index e8ea613b18bca..43abdf53cc5f1 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 7f74bbe1b4a3f..731ebacaffa47 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 1a9c8987ae96a..82201967319f1 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index fce0b8aeb01a0..f6ed7d9b759ed 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index c3cffbff1588e..36c07681a1336 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 753e45141c420..21070ad4a3af1 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 4c246a77bccc6..ee2dd11c96351 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 8dd4184bd489f..95e310196a9d4 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 589465a7e60af..a19cf38117484 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 598b8e3181072..015b67b137a0f 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index fea6f723429be..570645bb79985 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 1d468c71c1f3e..a0f958027f7f3 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index e6cdb09bcdcd7..32b9ce2128fee 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index e600e5e227130..686a378cbd168 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_client.mdx b/api_docs/kbn_server_route_repository_client.mdx index 298d6d199be78..c6c53bbac56ed 100644 --- a/api_docs/kbn_server_route_repository_client.mdx +++ b/api_docs/kbn_server_route_repository_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-client title: "@kbn/server-route-repository-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-client plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-client'] --- import kbnServerRouteRepositoryClientObj from './kbn_server_route_repository_client.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_utils.mdx b/api_docs/kbn_server_route_repository_utils.mdx index 1707958f08492..b390fdac8869a 100644 --- a/api_docs/kbn_server_route_repository_utils.mdx +++ b/api_docs/kbn_server_route_repository_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-utils title: "@kbn/server-route-repository-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-utils'] --- import kbnServerRouteRepositoryUtilsObj from './kbn_server_route_repository_utils.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 036b329a0404f..80bcbad24334d 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index daf5973ad37e3..a1139038d1ea9 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 86f7ef794a54e..884c921ba20ff 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index 360f251a9f6e0..badba1ee031b9 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index db072a8c01231..8d576f95e56f8 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index f25753ab130ac..160174ef0c582 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 336f0455bac07..9e6e246e9f91b 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index c9f95c974e2b4..2f1898161048f 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 6868f49737991..c8cea5f3f9ce9 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 0eb21c5b0aa1c..b83f24a936f3b 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index d56ff27f9f56a..f661389af532d 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index f5ea6cb6a8756..7879a537479df 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index c9e33fb5a6749..150aa5fbcbb08 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index b126750227fe9..c1edd8ee3e0b4 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 8f3e2d3bdbf8e..16ce5ab937322 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 3a7bcc434f3b4..6fec208bb40ba 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 6c1706d3c57b1..68862f3d2a8c9 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 0269fdbbf4bc7..fe20f2aa919a7 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 4f2095783395c..9bb6a34051e88 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 729fc14af688c..18dd1de18c5c9 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 2e24fe9dca0c3..65b9b8203c906 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 46a624f32dc53..ed768e8843a04 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index ac50ff0502bae..b8d85630e975f 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index a2621122b26ad..98d9f8622cfc3 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 1ee2f1621629e..474cc31905553 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 0fbc4d39797ee..d21b436edaef0 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index f2c2820ccf63e..633755bbf2e31 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index a84cf1d9209cf..a322826a76195 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 7e2df7017d582..e97e4a82610f8 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 5834fd12cb166..5c3e50b8daee1 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index f556b25893265..ed709aecf9ba3 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index 0034ed2775f04..81fef1390de92 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index d20551adc6ec7..036b423c25978 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 17448fa4d0eea..019ba1f463582 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 095523ea354c7..a44077c5140b4 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index fd82a288a2ebe..8cd73b3a96927 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 3a1cf8509382e..4dfa949a3c92c 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 7608db04c35ef..5260400321f5b 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index bc42e12c5eb5b..adcdac68c1caf 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 841b608a5daa7..03761fc3b9ca7 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 4f9ac10166644..3b80b50b06615 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 290cbc9322a2a..0399531c9034c 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index d68ab0bcc6308..c9f70b410c022 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 61707537e684c..cc899c6a93312 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_tabbed_modal.mdx b/api_docs/kbn_shared_ux_tabbed_modal.mdx index de4b9b19560d9..95fbbd145215d 100644 --- a/api_docs/kbn_shared_ux_tabbed_modal.mdx +++ b/api_docs/kbn_shared_ux_tabbed_modal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-tabbed-modal title: "@kbn/shared-ux-tabbed-modal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-tabbed-modal plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-tabbed-modal'] --- import kbnSharedUxTabbedModalObj from './kbn_shared_ux_tabbed_modal.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_table_persist.mdx b/api_docs/kbn_shared_ux_table_persist.mdx index 5b0a03edac53f..38ae8a4bd09f8 100644 --- a/api_docs/kbn_shared_ux_table_persist.mdx +++ b/api_docs/kbn_shared_ux_table_persist.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-table-persist title: "@kbn/shared-ux-table-persist" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-table-persist plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-table-persist'] --- import kbnSharedUxTablePersistObj from './kbn_shared_ux_table_persist.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index f5b92bc61f044..f7eb26133ba69 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 6d5703c52790b..0a5376aa8ca06 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 83f8b61079cf1..9b4e62c34ed68 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_predicates.mdx b/api_docs/kbn_sort_predicates.mdx index 00f0086ab1540..ccfdedc316076 100644 --- a/api_docs/kbn_sort_predicates.mdx +++ b/api_docs/kbn_sort_predicates.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-predicates title: "@kbn/sort-predicates" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-predicates plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index df938c55c590f..fc4322a4e2529 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index aaf8416dacfb0..fd56b66e79b04 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 7d040de9cc191..cd2af76db4ffb 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_synthetics_e2e.mdx b/api_docs/kbn_synthetics_e2e.mdx index 57525a0efa81d..e634dae999489 100644 --- a/api_docs/kbn_synthetics_e2e.mdx +++ b/api_docs/kbn_synthetics_e2e.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-e2e title: "@kbn/synthetics-e2e" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-e2e plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-e2e'] --- import kbnSyntheticsE2eObj from './kbn_synthetics_e2e.devdocs.json'; diff --git a/api_docs/kbn_synthetics_private_location.mdx b/api_docs/kbn_synthetics_private_location.mdx index 10c916f446831..14736d9e5583a 100644 --- a/api_docs/kbn_synthetics_private_location.mdx +++ b/api_docs/kbn_synthetics_private_location.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-private-location title: "@kbn/synthetics-private-location" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-private-location plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-private-location'] --- import kbnSyntheticsPrivateLocationObj from './kbn_synthetics_private_location.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 978e9b2524433..65377fd62be32 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 8f835b18285d7..204366b3c5d25 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_eui_helpers.mdx b/api_docs/kbn_test_eui_helpers.mdx index 7f00c708d2d69..209fa9df96bec 100644 --- a/api_docs/kbn_test_eui_helpers.mdx +++ b/api_docs/kbn_test_eui_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-eui-helpers title: "@kbn/test-eui-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-eui-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-eui-helpers'] --- import kbnTestEuiHelpersObj from './kbn_test_eui_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index d364104d8639f..547d496b3da85 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index db99dcde34184..d39d839f5616d 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 2a5a38f3dedf8..f0bad151e7de1 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_timerange.mdx b/api_docs/kbn_timerange.mdx index f17fa71943a73..253c68b01c4da 100644 --- a/api_docs/kbn_timerange.mdx +++ b/api_docs/kbn_timerange.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-timerange title: "@kbn/timerange" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/timerange plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/timerange'] --- import kbnTimerangeObj from './kbn_timerange.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index ec482d6ffc521..e4182be00fa43 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index bb1d900e584c2..64ec880d901c9 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_try_in_console.mdx b/api_docs/kbn_try_in_console.mdx index 73a20839f60ba..7f0592a409cbd 100644 --- a/api_docs/kbn_try_in_console.mdx +++ b/api_docs/kbn_try_in_console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-try-in-console title: "@kbn/try-in-console" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/try-in-console plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/try-in-console'] --- import kbnTryInConsoleObj from './kbn_try_in_console.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 811f9df289f23..24cdd0af279e3 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 1e7878abc9886..3dbfe29115b44 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 4139b45246462..40258e1c962c3 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 4f845c83a1b6e..e2f1cfa99a5d8 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 961e06aa509e3..35bd13479a314 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index d02d246cbb992..26e185c5503de 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 32bb2d5ef722e..4cc5d908f743a 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index f0ef14e11199d..2162de2a5dadc 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 485cb97701713..29596a0da92d9 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_prompt.mdx b/api_docs/kbn_unsaved_changes_prompt.mdx index 2485c4138ddb3..b5d91fa4ff9f0 100644 --- a/api_docs/kbn_unsaved_changes_prompt.mdx +++ b/api_docs/kbn_unsaved_changes_prompt.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-prompt title: "@kbn/unsaved-changes-prompt" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-prompt plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-prompt'] --- import kbnUnsavedChangesPromptObj from './kbn_unsaved_changes_prompt.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index bfd0d42c068f1..3545e1e94fa6b 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 6ab3aff6bf587..4b0504ea5ceff 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 7673ed5324131..cbdaace1a6a81 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index d2d412f5ed754..9a0a91c06adb4 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 02402120c5fbf..9e82adef9ae73 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index a547afddd5720..279bf8c61cfb4 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index aef692ac03fbc..d65381f5651d5 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 9df65573fdd10..a9dc384844979 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 5146945ed1a7e..91d251b330f3d 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod.mdx b/api_docs/kbn_zod.mdx index 37a32c8663a0e..0911aede9b97b 100644 --- a/api_docs/kbn_zod.mdx +++ b/api_docs/kbn_zod.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod title: "@kbn/zod" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod'] --- import kbnZodObj from './kbn_zod.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index 3a819e02c0c64..8db261f7a2116 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index cf03c2818767d..c1b8e3bd9455d 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 523380eae221a..9250990b38197 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index ce22af8a4af40..16e9ae91f0d74 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index d897e59c0679f..ca9b6e83a13e2 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index babb32abaf909..61522f23610cc 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index eab4906c08acc..38f1ec2520c4a 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 0cc079aefdde0..0236554d3b276 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 7c78dbd8ee683..470bc120b0eac 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 9cbb5461fbab9..71c8a1663c507 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 83370ffe7317f..5e1653a82f8ae 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_data_access.mdx b/api_docs/logs_data_access.mdx index 4eb7815516970..6e94638f6c73c 100644 --- a/api_docs/logs_data_access.mdx +++ b/api_docs/logs_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsDataAccess title: "logsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the logsDataAccess plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsDataAccess'] --- import logsDataAccessObj from './logs_data_access.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 7d38f1033707f..c49deda7fa6a1 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 2494db764b25f..6d645c22994d9 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 8152b3487d704..8dfdc31a8ee22 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 83abb95369e1b..d38516c28eb72 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index b3b00bd073e22..d4ec614b809da 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index de7f986a8678d..7f781cc33e572 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 585cadbe24612..15b093962d3f7 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index a2f6c8fc693fe..3cf1f556c3e2f 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 3d9168c9fcabf..5ffe9c9ef9fbf 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index dbf568f979cbc..b6606e5b4e461 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index b855936d2c0c7..fcd46bcc649c6 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 0a42640104e23..10f271946fddd 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 207351ad4a000..f092976a3570e 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index f7c8e011858e4..684e76c1d4882 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 92649ba2ae59c..ccee1f6ff5aa2 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 93d16c5006beb..818ca6f7d3930 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant_app.mdx b/api_docs/observability_a_i_assistant_app.mdx index 1faad687a496a..e8b7392079da1 100644 --- a/api_docs/observability_a_i_assistant_app.mdx +++ b/api_docs/observability_a_i_assistant_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistantApp title: "observabilityAIAssistantApp" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistantApp plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistantApp'] --- import observabilityAIAssistantAppObj from './observability_a_i_assistant_app.devdocs.json'; diff --git a/api_docs/observability_ai_assistant_management.mdx b/api_docs/observability_ai_assistant_management.mdx index 105b2df23e788..a0f1b8ad82df9 100644 --- a/api_docs/observability_ai_assistant_management.mdx +++ b/api_docs/observability_ai_assistant_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAiAssistantManagement title: "observabilityAiAssistantManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAiAssistantManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAiAssistantManagement'] --- import observabilityAiAssistantManagementObj from './observability_ai_assistant_management.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index 007c24e992d09..b0503effd1417 100644 --- a/api_docs/observability_logs_explorer.mdx +++ b/api_docs/observability_logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogsExplorer title: "observabilityLogsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogsExplorer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogsExplorer'] --- import observabilityLogsExplorerObj from './observability_logs_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 178d61ff04054..35b77daac7009 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index e57798321e277..0703df8d0a08a 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index f3afcde08300f..862a3e68d55f7 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index f6eb8cf0d76ac..01bf832632aef 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 2d06b51b485a7..d0d5e47c7bcec 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 52901 | 243 | 39737 | 1942 | +| 52942 | 243 | 39777 | 1945 | ## Plugin Directory @@ -49,7 +49,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | The cloud security posture plugin | 14 | 0 | 2 | 2 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 39 | 0 | 30 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Content management app | 149 | 0 | 125 | 6 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 390 | 0 | 381 | 28 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 394 | 0 | 385 | 28 | | crossClusterReplication | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | | customBranding | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Enables customization of Kibana | 0 | 0 | 0 | 0 | | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 271 | 0 | 252 | 1 | @@ -114,7 +114,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 1 | 0 | 1 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 238 | 0 | 233 | 1 | -| | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 16 | 0 | 14 | 11 | +| | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 41 | 0 | 39 | 13 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 38 | 0 | 35 | 6 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | | inputControlVis | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 | @@ -256,8 +256,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 1 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 18 | 0 | 18 | 0 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 4 | 0 | 4 | 0 | -| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 56 | 0 | 56 | 9 | -| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 205 | 0 | 205 | 33 | +| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 59 | 0 | 59 | 10 | +| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 208 | 0 | 208 | 33 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 316 | 0 | 315 | 0 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 11 | 0 | 11 | 0 | | | [@elastic/security-defend-workflows](https://github.com/orgs/elastic/teams/security-defend-workflows) | - | 3 | 0 | 3 | 0 | @@ -275,7 +275,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 62 | 0 | 17 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 2 | 0 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 22 | 0 | 22 | 0 | -| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 49 | 0 | 49 | 0 | +| | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 52 | 0 | 52 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 41 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 8 | 0 | 4 | 0 | @@ -338,7 +338,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 22 | 0 | 13 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 38 | 1 | 34 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 116 | 0 | 56 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 56 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 43 | 0 | 38 | 3 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 13 | 1 | 13 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 1 | @@ -511,7 +511,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | | | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 152 | 1 | 120 | 15 | | | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 68 | 0 | 64 | 0 | -| | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 196 | 0 | 184 | 10 | +| | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 197 | 0 | 185 | 10 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 40 | 0 | 40 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 0 | 52 | 1 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 42 | 0 | 17 | 2 | @@ -595,7 +595,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 18 | 0 | 18 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 42 | 1 | 35 | 1 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 22 | 0 | 16 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 120 | 0 | 120 | 3 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 121 | 0 | 121 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 55 | 1 | 50 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 10 | 0 | 10 | 2 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index a6a272a4847b3..98a45d13d447e 100644 --- a/api_docs/presentation_panel.mdx +++ b/api_docs/presentation_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationPanel title: "presentationPanel" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationPanel plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationPanel'] --- import presentationPanelObj from './presentation_panel.devdocs.json'; diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 4d5eb2427cc3e..5dc85d2e17c80 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 4f43ea42b1261..526e0d34b5796 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index 1afb2f3d0fe85..e61422ed31670 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index b39d2202e4132..4aded26680b42 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index d94cb4f6beab5..fcababb0a5664 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 92589ef0b0bde..acc3dc2594f36 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 4436e21f57fbe..2017213b66911 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index d4b233dcfea35..5d86bff85337e 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 00f947f89fa69..d8bee3f6841d2 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index d0708ca0b3829..9b6a0966c9c3a 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 6c1b890dfa2e4..c31d8330e9525 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 098fa86ed12fc..1cff5ca7e19dd 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index d2165d9903e0c..931642c034eea 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 56a01cb9a488f..f69efb18ff8f5 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index ebb6b4579b66c..e954f30b41c06 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 5a59c6e1a7cd0..5f0ba92ca1c2e 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/search_assistant.mdx b/api_docs/search_assistant.mdx index 464894cd90e6b..b7f82fcdcd9c0 100644 --- a/api_docs/search_assistant.mdx +++ b/api_docs/search_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchAssistant title: "searchAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the searchAssistant plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchAssistant'] --- import searchAssistantObj from './search_assistant.devdocs.json'; diff --git a/api_docs/search_connectors.mdx b/api_docs/search_connectors.mdx index 6561852261e8f..2e5f0e0853f6e 100644 --- a/api_docs/search_connectors.mdx +++ b/api_docs/search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchConnectors title: "searchConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the searchConnectors plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchConnectors'] --- import searchConnectorsObj from './search_connectors.devdocs.json'; diff --git a/api_docs/search_homepage.mdx b/api_docs/search_homepage.mdx index 85b957fc32a7b..0fc8159df88cf 100644 --- a/api_docs/search_homepage.mdx +++ b/api_docs/search_homepage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchHomepage title: "searchHomepage" image: https://source.unsplash.com/400x175/?github description: API docs for the searchHomepage plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchHomepage'] --- import searchHomepageObj from './search_homepage.devdocs.json'; diff --git a/api_docs/search_indices.mdx b/api_docs/search_indices.mdx index 249f293142ede..19baa807ed5b4 100644 --- a/api_docs/search_indices.mdx +++ b/api_docs/search_indices.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchIndices title: "searchIndices" image: https://source.unsplash.com/400x175/?github description: API docs for the searchIndices plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchIndices'] --- import searchIndicesObj from './search_indices.devdocs.json'; diff --git a/api_docs/search_inference_endpoints.mdx b/api_docs/search_inference_endpoints.mdx index a447457c453ce..897aa79e2921e 100644 --- a/api_docs/search_inference_endpoints.mdx +++ b/api_docs/search_inference_endpoints.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchInferenceEndpoints title: "searchInferenceEndpoints" image: https://source.unsplash.com/400x175/?github description: API docs for the searchInferenceEndpoints plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchInferenceEndpoints'] --- import searchInferenceEndpointsObj from './search_inference_endpoints.devdocs.json'; diff --git a/api_docs/search_notebooks.mdx b/api_docs/search_notebooks.mdx index c7066dbfcdd68..ebfc133b1e565 100644 --- a/api_docs/search_notebooks.mdx +++ b/api_docs/search_notebooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNotebooks title: "searchNotebooks" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNotebooks plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNotebooks'] --- import searchNotebooksObj from './search_notebooks.devdocs.json'; diff --git a/api_docs/search_playground.mdx b/api_docs/search_playground.mdx index 8dee517a44d0e..e3b529e4e5d0e 100644 --- a/api_docs/search_playground.mdx +++ b/api_docs/search_playground.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchPlayground title: "searchPlayground" image: https://source.unsplash.com/400x175/?github description: API docs for the searchPlayground plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchPlayground'] --- import searchPlaygroundObj from './search_playground.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index ff4d754d44a9b..b853963199089 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 908cf07283a19..18094d18ce1cf 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 28da3e74463c9..8d0c9f7546518 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index ab922a6ca531b..caeaf76f9ece1 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 63e9d4fe896af..7aac0e7cbc34c 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 168c333e3552f..bdbe6ece4486b 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index 9b13e3f4db0eb..dec90a50757cc 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index f966d1969ea3f..6d3dd5a1e6eef 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index ab976b5225130..d849bf9451e12 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/slo.mdx b/api_docs/slo.mdx index a1d7d4f35fbe8..db4b4945cd9d9 100644 --- a/api_docs/slo.mdx +++ b/api_docs/slo.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/slo title: "slo" image: https://source.unsplash.com/400x175/?github description: API docs for the slo plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'slo'] --- import sloObj from './slo.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 1b205e53302dc..84f839f49e449 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index c7df8aaa01198..6b02645ba1117 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 455b6b8ed44e4..ae9b91785e186 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index dcb5d1128ba36..7fb970b0adb6b 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index d799d6afc7b09..db0dad63c02ae 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index f9856709b2fe4..257594e5044c2 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index c42345ce4e54b..e868719e13a1b 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 8e47c67645ba3..bd81059d9e405 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index ddd60224da44b..b9e9fc35129a7 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index c6a7bcea4b600..3cbc5ac9b928d 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 32c8a1a60df3d..aadf6ba132646 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index c6b403fe1bcb3..6051be7ca4945 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index b024e1f8bee70..e9fc355edc585 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 5baf948dca658..0c4fbd411bcf1 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 9438a6bbdec7f..e7e0c2c0da13f 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index f993534b0c636..6aacc15941021 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 261df406e0d86..d1caaaf392b9e 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 644389a0f6635..197631923c0af 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 93d734215769b..4dec4c04e4178 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index d06d9758541ab..3537a3c580dd6 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 38d05c84acf76..73a13490499fd 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 3d95915bc7d82..c81e5b8ce3d4d 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index eeeb2657d3411..2d887c3c9c36b 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index d53400f12e4fe..b7a5c85a51646 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index d1d5c6798ccf9..765771356e477 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 8c7f820073b1e..2005c03b8e3b2 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 1b7ad85928ea0..64fbda65b2d79 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 0c9930f81bcf2..cc1237157ceae 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index caf3df6733519..efa98f36631d3 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 48c0038915e5f..6fe62590a8cc0 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index fca93f8baecd3..3ee1bb1874a92 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 47c8a6d390614..2c67a4f2e9e4b 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 8abf2b174ba18..c6db455a693c6 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 88482cc64e4b5..d708c57f35bed 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2024-09-04 +date: 2024-09-05 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/dev_docs/getting_started/setting_up_a_development_env.mdx b/dev_docs/getting_started/setting_up_a_development_env.mdx index a63dfdce59b4d..b69987a09da50 100644 --- a/dev_docs/getting_started/setting_up_a_development_env.mdx +++ b/dev_docs/getting_started/setting_up_a_development_env.mdx @@ -99,7 +99,7 @@ Kibana also supports using a [dev container](https://containers.dev/) which can ### Setting up the Dev Container -1. Make a copy of `.devcontainer/.env.template` and rename it to `.devcontainer/.env`. Edit any values you're interested in. +1. Make a copy of [`/.devcontainer/.env.template`](https://github.com/elastic/kibana/blob/main/.devcontainer/.env.template) and rename it to `/.devcontainer/.env`. Edit any values you're interested in. 1. There are three options for mounting the Kibana repo into the container: - **Local Filesystem**: Clone the repo locally, or use an existing copy, and open it in VS Code. When prompted, select "Reopen in Dev Container". This uses a bind mount, allowing the container to access and modify files directly on your local filesystem. Your git credentials should be automatically mounted in the container as well. Note that Bazel will create symlinks and a cache inside the container file system. So, if switching to working on your local filesystem afterwards, you will need to bootstrap again. - **Docker Repo Volume**: Use the `Dev Containers: Clone Repository in Named Container Volume...` command from the Command Palette (`F1`). This clones the repo into a Docker volume, isolating it from your local filesystem. You will need to configure your git credentials manually in this isolated environment. diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 6df6c8f3c95ee..98968780f3368 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -14,7 +14,7 @@ KBN_PATH_CONF=/home/kibana/config ./bin/kibana -- The default host and port settings configure {kib} to run on `localhost:5601`. To change this behavior and allow remote users to connect, you'll need to update your `kibana.yml` file. You can also enable SSL and set a -variety of other options. +variety of other options. Environment variables can be injected into configuration using `${MY_ENV_VAR}` syntax. By default, configuration validation will fail if an environment variable used in the config file is not present when Kibana starts. This behavior can be changed by using a default value @@ -93,7 +93,7 @@ The maximum number of sockets that can be used for communications with {es}. *Default: `Infinity`* [[elasticsearch-maxResponseSize]] `elasticsearch.maxResponseSize`:: -Either `false` or a `byteSize` value. When set, responses from {es} with a size higher than the defined limit will be rejected. +Either `false` or a `byteSize` value. When set, responses from {es} with a size higher than the defined limit will be rejected. This is intended to be used as a circuit-breaker mechanism to avoid memory errors in case of unexpectedly high responses coming from {es}. *Default: `false`* @@ -117,6 +117,9 @@ listed here must be on the same cluster. *Default: `[ "http://localhost:9200" ]` To enable SSL/TLS for outbound connections to {es}, use the `https` protocol in this setting. +[[elasticsearch-publicBaseUrl]] `elasticsearch.publicBaseUrl:`:: +The URL through which Elasticsearch is publicly accessible, if any. This will be shown to users in Kibana when they need connection details for your Elasticsearch cluster. + [[elasticsearch-pingTimeout]] `elasticsearch.pingTimeout`:: Time in milliseconds to wait for {es} to respond to pings. *Default: the value of the <> setting* @@ -470,7 +473,7 @@ identifies this {kib} instance. *Default: `"your-hostname"`* setting specifies the port to use. *Default: `5601`* `server.protocol`:: -experimental[] The http protocol to use, either `http1` or `http2`. Set to `http2` to enable `HTTP/2` support for the {kib} server. +experimental[] The http protocol to use, either `http1` or `http2`. Set to `http2` to enable `HTTP/2` support for the {kib} server. *Default: `http1`* + NOTE: By default, enabling `http2` requires a valid `h2c` configuration, meaning that TLS must be enabled via <> diff --git a/examples/controls_example/public/app/react_control_example/serialized_control_group_state.ts b/examples/controls_example/public/app/react_control_example/serialized_control_group_state.ts index 9e4b18aaffa26..b02cf450cdd73 100644 --- a/examples/controls_example/public/app/react_control_example/serialized_control_group_state.ts +++ b/examples/controls_example/public/app/react_control_example/serialized_control_group_state.ts @@ -90,12 +90,12 @@ const initialSerializedControlGroupState = { } as object, references: [ { - name: `controlGroup_${rangeSliderControlId}:rangeSliderDataView`, + name: `controlGroup_${rangeSliderControlId}:${RANGE_SLIDER_CONTROL}DataView`, type: 'index-pattern', id: WEB_LOGS_DATA_VIEW_ID, }, { - name: `controlGroup_${optionsListId}:optionsListDataView`, + name: `controlGroup_${optionsListId}:${OPTIONS_LIST_CONTROL}DataView`, type: 'index-pattern', id: WEB_LOGS_DATA_VIEW_ID, }, diff --git a/examples/portable_dashboards_example/public/dashboard_with_controls_example.tsx b/examples/portable_dashboards_example/public/dashboard_with_controls_example.tsx index f63df505f5d85..ac902c72e851f 100644 --- a/examples/portable_dashboards_example/public/dashboard_with_controls_example.tsx +++ b/examples/portable_dashboards_example/public/dashboard_with_controls_example.tsx @@ -11,7 +11,8 @@ import React, { useEffect, useState } from 'react'; import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; import { EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; -import { controlGroupStateBuilder } from '@kbn/controls-plugin/public'; +import { controlGroupInputBuilder } from '@kbn/controls-plugin/public'; +import { getDefaultControlGroupInput } from '@kbn/controls-plugin/common'; import { AwaitingDashboardAPI, DashboardRenderer, @@ -62,15 +63,16 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView => { - const controlGroupState = {}; - await controlGroupStateBuilder.addDataControlFromField(controlGroupState, { + const builder = controlGroupInputBuilder; + const controlGroupInput = getDefaultControlGroupInput(); + await builder.addDataControlFromField(controlGroupInput, { dataViewId: dataView.id ?? '', title: 'Destintion country', fieldName: 'geo.dest', width: 'medium', grow: false, }); - await controlGroupStateBuilder.addDataControlFromField(controlGroupState, { + await builder.addDataControlFromField(controlGroupInput, { dataViewId: dataView.id ?? '', fieldName: 'bytes', width: 'medium', @@ -83,7 +85,7 @@ export const DashboardWithControlsExample = ({ dataView }: { dataView: DataView getInitialInput: () => ({ timeRange: { from: 'now-30d', to: 'now' }, viewMode: ViewMode.VIEW, - controlGroupState, + controlGroupInput, }), }; }} diff --git a/package.json b/package.json index 1380fea8eeea2..51a16ffbefe18 100644 --- a/package.json +++ b/package.json @@ -1201,11 +1201,13 @@ "react-use": "^15.3.8", "react-virtualized": "^9.22.5", "react-window": "^1.8.10", + "react-window-infinite-loader": "^1.0.9", "reduce-reducers": "^1.0.4", "redux": "^4.2.1", "redux-actions": "^2.6.5", "redux-devtools-extension": "^2.13.8", "redux-saga": "^1.1.3", + "redux-saga-testing": "^2.0.2", "redux-thunk": "^2.4.2", "redux-thunks": "^1.0.0", "reflect-metadata": "^0.2.1", @@ -1597,6 +1599,7 @@ "@types/react-test-renderer": "^17.0.2", "@types/react-virtualized": "^9.21.22", "@types/react-window": "^1.8.8", + "@types/react-window-infinite-loader": "^1.0.9", "@types/redux-actions": "^2.6.1", "@types/resolve": "^1.20.1", "@types/seedrandom": ">=2.0.0 <4.0.0", @@ -1741,7 +1744,7 @@ "mochawesome-merge": "^4.3.0", "mock-fs": "^5.1.2", "ms-chromium-edge-driver": "^0.5.1", - "msw": "^2.3.5", + "msw": "^2.4.2", "multistream": "^4.1.0", "mutation-observer": "^1.0.3", "native-hdr-histogram": "^1.0.0", @@ -1774,7 +1777,7 @@ "rxjs-marbles": "^7.0.1", "sass-embedded": "^1.77.8", "sass-loader": "^10.5.1", - "selenium-webdriver": "^4.23.0", + "selenium-webdriver": "^4.24.0", "sharp": "0.32.6", "simple-git": "^3.16.0", "sinon": "^7.4.2", diff --git a/packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_config.ts b/packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_config.ts index 010bc3ac1c796..4807cfe8e598c 100644 --- a/packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_config.ts +++ b/packages/core/elasticsearch/core-elasticsearch-server-internal/src/elasticsearch_config.ts @@ -190,6 +190,7 @@ export const configSchema = schema.object({ { defaultValue: [] } ), dnsCacheTtl: schema.duration({ defaultValue: 0, min: 0 }), + publicBaseUrl: schema.maybe(hostURISchema), }); const deprecations: ConfigDeprecationProvider = () => [ diff --git a/packages/core/elasticsearch/core-elasticsearch-server/src/contracts.ts b/packages/core/elasticsearch/core-elasticsearch-server/src/contracts.ts index fced65ce95c79..e1584e9e63cf3 100644 --- a/packages/core/elasticsearch/core-elasticsearch-server/src/contracts.ts +++ b/packages/core/elasticsearch/core-elasticsearch-server/src/contracts.ts @@ -90,6 +90,12 @@ export interface ElasticsearchServiceSetup { */ readonly config$: Observable; }; + + /** + * The public base URL (if any) that should be used by end users to access the Elasticsearch cluster. + */ + + readonly publicBaseUrl?: string; } /** diff --git a/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx b/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx index 17a4d35f73e8a..0ac564dd45b80 100644 --- a/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx +++ b/packages/kbn-alerts-grouping/src/components/alerts_grouping.tsx @@ -17,7 +17,7 @@ import React, { useState, } from 'react'; import type { Filter } from '@kbn/es-query'; -import { isNoneGroup, useGrouping } from '@kbn/grouping'; +import { GroupOption, isNoneGroup, useGrouping } from '@kbn/grouping'; import { isEqual } from 'lodash/fp'; import { i18n } from '@kbn/i18n'; import { useAlertsDataView } from '@kbn/alerts-ui-shared/src/common/hooks/use_alerts_data_view'; @@ -89,7 +89,7 @@ const AlertsGroupingInternal = ( ) as [number[], Dispatch>, () => void]; const onOptionsChange = useCallback( - (options) => { + (options: GroupOption[]) => { // useGrouping > useAlertsGroupingState options sync // the available grouping options change when the user selects // a new field not in the default ones diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter_timeframe.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter_timeframe.tsx index 5b4580caa7ebf..9d8ba0decd03f 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter_timeframe.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_actions/rule_actions_alerts_filter_timeframe.tsx @@ -142,7 +142,7 @@ export const RuleActionsAlertsFilterTimeframe: React.FC { + (value: Array<{ label: string }>) => { setSelectedTimezone(value); if (value[0].label) updateTimeframe({ timezone: value[0].label }); }, diff --git a/packages/kbn-alerts-ui-shared/src/rule_form/rule_definition/rule_definition.tsx b/packages/kbn-alerts-ui-shared/src/rule_form/rule_definition/rule_definition.tsx index 104d698b343c7..5d73a0626abc4 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_form/rule_definition/rule_definition.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_form/rule_definition/rule_definition.tsx @@ -96,7 +96,7 @@ export const RuleDefinition = () => { }, [selectedRuleTypeModel, docLinks]); const onChangeMetaData = useCallback( - (newMetadata) => { + (newMetadata: Record) => { dispatch({ type: 'setMetadata', payload: newMetadata, diff --git a/packages/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_inputs.tsx b/packages/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_inputs.tsx index 6b3086df3f952..260ba4d3cce41 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_inputs.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_inputs.tsx @@ -63,14 +63,18 @@ export const RuleSettingsFlappingInputs = (props: RuleSettingsFlappingInputsProp onStatusChangeThresholdChange, } = props; - const internalOnLookBackWindowChange = useCallback( + const internalOnLookBackWindowChange = useCallback< + NonNullable['onChange']> + >( (e) => { onLookBackWindowChange(parseInt(e.currentTarget.value, 10)); }, [onLookBackWindowChange] ); - const internalOnStatusChangeThresholdChange = useCallback( + const internalOnStatusChangeThresholdChange = useCallback< + NonNullable['onChange']> + >( (e) => { onStatusChangeThresholdChange(parseInt(e.currentTarget.value, 10)); }, diff --git a/packages/kbn-apm-synthtrace-client/index.ts b/packages/kbn-apm-synthtrace-client/index.ts index 71321a8f3c67a..2553d3b08bfab 100644 --- a/packages/kbn-apm-synthtrace-client/index.ts +++ b/packages/kbn-apm-synthtrace-client/index.ts @@ -35,3 +35,4 @@ export { appendHash, hashKeysOf } from './src/lib/utils/hash'; export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator } from './src/types'; export { log, type LogDocument, LONG_FIELD_NAME } from './src/lib/logs'; export { type AssetDocument } from './src/lib/assets'; +export { syntheticsMonitor, type SyntheticsMonitorDocument } from './src/lib/synthetics'; diff --git a/packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts new file mode 100644 index 0000000000000..381c171ba5e02 --- /dev/null +++ b/packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 or the Server + * Side Public License, v 1. + */ + +import { Fields } from '../entity'; +import { Serializable } from '../serializable'; + +export type SyntheticsMonitorDocument = Fields & + Partial<{ + 'data_stream.namespace': string; + 'data_stream.type': string; + 'data_stream.dataset': string; + 'monitor.id': string; + 'monitor.origin': string; + 'monitor.name': string; + 'monitor.type': string; + 'monitor.check_group': string; + 'monitor.timespan.lt': string; + 'monitor.timespan.gte': string; + 'monitor.duration.us'?: number; + 'monitor.ip'?: string; + 'monitor.project.name'?: string; + 'monitor.project.id'?: string; + 'monitor.fleet_managed'?: boolean; + 'monitor.status'?: string; + 'synthetics.type'?: string; + 'synthetics.step.index'?: number; + 'observer.os.name'?: string; + 'observer.product'?: string; + }>; + +type MonitorDataStream = + | 'http' + | 'tcp' + | 'icmp' + | 'browser' + | 'browser.screenshot' + | 'browser.network'; + +class SyntheticsMonitor extends Serializable { + constructor(fields: SyntheticsMonitorDocument) { + super({ + ...fields, + }); + } + + namespace(value: string) { + this.fields['data_stream.namespace'] = value; + return this; + } + + dataset(value: MonitorDataStream) { + this.fields['data_stream.dataset'] = value; + + if (value === 'browser.screenshot' || value === 'browser.network') { + this.fields['monitor.type'] = 'browser'; + return this; + } + + this.fields['monitor.type'] = value; + return this; + } + + name(value: string) { + this.fields['monitor.name'] = value; + return this; + } + + origin(value: string) { + this.fields['monitor.origin'] = value; + return this; + } + + ip(value: string) { + this.fields['monitor.ip'] = value; + return this; + } + + status(value: string) { + this.fields['monitor.status'] = value; + return this; + } + + timestamp(time: number) { + super.timestamp(time); + return this; + } +} + +function create(): SyntheticsMonitor { + return new SyntheticsMonitor({ + 'data_stream.namespace': 'default', + 'data_stream.type': 'synthetics', + }).dataset('http'); +} + +export const syntheticsMonitor = { + create, +}; diff --git a/packages/kbn-apm-synthtrace/README.md b/packages/kbn-apm-synthtrace/README.md index 6daad014ff0e5..a9704b1905d1b 100644 --- a/packages/kbn-apm-synthtrace/README.md +++ b/packages/kbn-apm-synthtrace/README.md @@ -22,6 +22,7 @@ This library can currently be used in two ways: - `Timerange`: an object that will return an array of timestamps based on an interval and a rate. These timestamps can be used to generate events/metricsets. - `Transaction`, `Span`, `APMError` and `Metricset`: events/metricsets that occur on an instance. For more background, see the [explanation of the APM data model](https://www.elastic.co/guide/en/apm/get-started/7.15/apm-data-model.html) - `Log`: An instance of Log generating Service which supports additional helpers to customise fields like `messages`, `logLevel` +- `SyntheticsMonitor`: An instance of Synthetic monitor. For more information see [Synthetic monitoring](https://www.elastic.co/guide/en/observability/current/monitor-uptime-synthetics.html). #### Example diff --git a/packages/kbn-apm-synthtrace/index.ts b/packages/kbn-apm-synthtrace/index.ts index 459e3802ae660..22b947cd1bbf3 100644 --- a/packages/kbn-apm-synthtrace/index.ts +++ b/packages/kbn-apm-synthtrace/index.ts @@ -15,6 +15,7 @@ export { InfraSynthtraceKibanaClient } from './src/lib/infra/infra_synthtrace_ki export { MonitoringSynthtraceEsClient } from './src/lib/monitoring/monitoring_synthtrace_es_client'; export { LogsSynthtraceEsClient } from './src/lib/logs/logs_synthtrace_es_client'; export { AssetsSynthtraceEsClient } from './src/lib/assets/assets_synthtrace_es_client'; +export { SyntheticsSynthtraceEsClient } from './src/lib/synthetics/synthetics_synthtrace_es_client'; export { addObserverVersionTransform, deleteSummaryFieldTransform, diff --git a/packages/kbn-apm-synthtrace/src/cli/scenario.ts b/packages/kbn-apm-synthtrace/src/cli/scenario.ts index c12d8333071c6..ba5e17deb1c18 100644 --- a/packages/kbn-apm-synthtrace/src/cli/scenario.ts +++ b/packages/kbn-apm-synthtrace/src/cli/scenario.ts @@ -7,7 +7,12 @@ */ import { Timerange } from '@kbn/apm-synthtrace-client'; -import { ApmSynthtraceEsClient, InfraSynthtraceEsClient, LogsSynthtraceEsClient } from '../..'; +import { + ApmSynthtraceEsClient, + InfraSynthtraceEsClient, + LogsSynthtraceEsClient, + SyntheticsSynthtraceEsClient, +} from '../..'; import { AssetsSynthtraceEsClient } from '../lib/assets/assets_synthtrace_es_client'; import { Logger } from '../lib/utils/create_logger'; import { ScenarioReturnType } from '../lib/utils/with_client'; @@ -18,6 +23,7 @@ interface EsClients { logsEsClient: LogsSynthtraceEsClient; infraEsClient: InfraSynthtraceEsClient; assetsEsClient: AssetsSynthtraceEsClient; + syntheticsEsClient: SyntheticsSynthtraceEsClient; } type Generate = (options: { diff --git a/packages/kbn-apm-synthtrace/src/cli/utils/bootstrap.ts b/packages/kbn-apm-synthtrace/src/cli/utils/bootstrap.ts index be9f0a313fe0a..5119625b7f261 100644 --- a/packages/kbn-apm-synthtrace/src/cli/utils/bootstrap.ts +++ b/packages/kbn-apm-synthtrace/src/cli/utils/bootstrap.ts @@ -14,6 +14,7 @@ import { getKibanaClient } from './get_kibana_client'; import { getServiceUrls } from './get_service_urls'; import { RunOptions } from './parse_run_cli_flags'; import { getAssetsEsClient } from './get_assets_es_client'; +import { getSyntheticsEsClient } from './get_synthetics_es_client'; export async function bootstrap(runOptions: RunOptions) { const logger = createLogger(runOptions.logLevel); @@ -61,11 +62,18 @@ export async function bootstrap(runOptions: RunOptions) { concurrency: runOptions.concurrency, }); + const syntheticsEsClient = getSyntheticsEsClient({ + target: esUrl, + logger, + concurrency: runOptions.concurrency, + }); + if (runOptions.clean) { await apmEsClient.clean(); await logsEsClient.clean(); await infraEsClient.clean(); await assetsEsClient.clean(); + await syntheticsEsClient.clean(); } return { @@ -74,6 +82,7 @@ export async function bootstrap(runOptions: RunOptions) { logsEsClient, infraEsClient, assetsEsClient, + syntheticsEsClient, version, kibanaUrl, esUrl, diff --git a/packages/kbn-apm-synthtrace/src/cli/utils/get_synthetics_es_client.ts b/packages/kbn-apm-synthtrace/src/cli/utils/get_synthetics_es_client.ts new file mode 100644 index 0000000000000..0310dfc40dd74 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/cli/utils/get_synthetics_es_client.ts @@ -0,0 +1,33 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import { Client } from '@elastic/elasticsearch'; +import { Logger } from '../../lib/utils/create_logger'; +import { RunOptions } from './parse_run_cli_flags'; +import { getEsClientTlsSettings } from './ssl'; +import { SyntheticsSynthtraceEsClient } from '../../lib/synthetics/synthetics_synthtrace_es_client'; + +export function getSyntheticsEsClient({ + target, + logger, + concurrency, +}: Pick & { + target: string; + logger: Logger; +}) { + const client = new Client({ + node: target, + tls: getEsClientTlsSettings(target), + }); + + return new SyntheticsSynthtraceEsClient({ + client, + logger, + concurrency, + }); +} diff --git a/packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts b/packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts index fd7ddc6b42b36..253113532795d 100644 --- a/packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts +++ b/packages/kbn-apm-synthtrace/src/cli/utils/start_live_data_upload.ts @@ -25,9 +25,8 @@ export async function startLiveDataUpload({ }) { const file = runOptions.file; - const { logger, apmEsClient, logsEsClient, infraEsClient, assetsEsClient } = await bootstrap( - runOptions - ); + const { logger, apmEsClient, logsEsClient, infraEsClient, assetsEsClient, syntheticsEsClient } = + await bootstrap(runOptions); const scenario = await getScenario({ file, logger }); const { generate } = await scenario({ ...runOptions, logger }); @@ -65,7 +64,7 @@ export async function startLiveDataUpload({ const generatorsAndClients = generate({ range: timerange(bucketFrom.getTime(), bucketTo.getTime()), - clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient }, + clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient, syntheticsEsClient }, }); const generatorsAndClientsArray = castArray(generatorsAndClients); diff --git a/packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts b/packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts index fc7c70b0d6bc7..784931b5f6139 100644 --- a/packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts +++ b/packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts @@ -17,6 +17,7 @@ import { RunOptions } from './parse_run_cli_flags'; import { getLogsEsClient } from './get_logs_es_client'; import { getInfraEsClient } from './get_infra_es_client'; import { getAssetsEsClient } from './get_assets_es_client'; +import { getSyntheticsEsClient } from './get_synthetics_es_client'; export interface WorkerData { bucketFrom: Date; @@ -56,6 +57,12 @@ async function start() { logger, }); + const syntheticsEsClient = getSyntheticsEsClient({ + concurrency: runOptions.concurrency, + target: esUrl, + logger, + }); + const file = runOptions.file; const scenario = await logger.perf('get_scenario', () => getScenario({ file, logger })); @@ -70,6 +77,7 @@ async function start() { logsEsClient, infraEsClient, assetsEsClient, + syntheticsEsClient, }); } @@ -78,7 +86,7 @@ async function start() { const generatorsAndClients = logger.perf('generate_scenario', () => generate({ range: timerange(bucketFrom, bucketTo), - clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient }, + clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient, syntheticsEsClient }, }) ); diff --git a/packages/kbn-apm-synthtrace/src/lib/logs/logs_synthtrace_es_client.ts b/packages/kbn-apm-synthtrace/src/lib/logs/logs_synthtrace_es_client.ts index 95f8917c26658..3f1d5ea418026 100644 --- a/packages/kbn-apm-synthtrace/src/lib/logs/logs_synthtrace_es_client.ts +++ b/packages/kbn-apm-synthtrace/src/lib/logs/logs_synthtrace_es_client.ts @@ -7,14 +7,14 @@ */ import { Client } from '@elastic/elasticsearch'; -import { ESDocumentWithOperation } from '@kbn/apm-synthtrace-client'; -import { pipeline, Readable, Transform } from 'stream'; +import { pipeline, Readable } from 'stream'; import { LogDocument } from '@kbn/apm-synthtrace-client/src/lib/logs'; import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types'; import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client'; import { getSerializeTransform } from '../shared/get_serialize_transform'; import { Logger } from '../utils/create_logger'; import { indexTemplates, IndexTemplateName } from './custom_logsdb_index_templates'; +import { getRoutingTransform } from '../shared/data_stream_get_routing_transform'; export type LogsSynthtraceEsClientOptions = Omit; @@ -66,7 +66,7 @@ function logsPipeline() { return pipeline( base, getSerializeTransform(), - getRoutingTransform(), + getRoutingTransform('logs'), (err: unknown) => { if (err) { throw err; @@ -75,22 +75,3 @@ function logsPipeline() { ); }; } - -function getRoutingTransform() { - return new Transform({ - objectMode: true, - transform(document: ESDocumentWithOperation, encoding, callback) { - if ( - 'data_stream.type' in document && - 'data_stream.dataset' in document && - 'data_stream.namespace' in document - ) { - document._index = `${document['data_stream.type']}-${document['data_stream.dataset']}-${document['data_stream.namespace']}`; - } else { - throw new Error('Cannot determine index for event'); - } - - callback(null, document); - }, - }); -} diff --git a/packages/kbn-apm-synthtrace/src/lib/shared/data_stream_get_routing_transform.ts b/packages/kbn-apm-synthtrace/src/lib/shared/data_stream_get_routing_transform.ts new file mode 100644 index 0000000000000..3e653e71b9862 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/lib/shared/data_stream_get_routing_transform.ts @@ -0,0 +1,25 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import { ESDocumentWithOperation, Fields } from '@kbn/apm-synthtrace-client'; +import { Transform } from 'stream'; + +export function getRoutingTransform(dataStreamType: string) { + return new Transform({ + objectMode: true, + transform(document: ESDocumentWithOperation, encoding, callback) { + if ('data_stream.dataset' in document && 'data_stream.namespace' in document) { + document._index = `${dataStreamType}-${document['data_stream.dataset']}-${document['data_stream.namespace']}`; + } else { + throw new Error('Cannot determine index for event'); + } + + callback(null, document); + }, + }); +} diff --git a/packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts b/packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts new file mode 100644 index 0000000000000..65fd66538a757 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/lib/synthetics/synthetics_synthtrace_es_client.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 or the Server + * Side Public License, v 1. + */ + +import { Client } from '@elastic/elasticsearch'; +import { SyntheticsMonitorDocument } from '@kbn/apm-synthtrace-client'; +import { pipeline, Readable } from 'stream'; +import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client'; +import { getSerializeTransform } from '../shared/get_serialize_transform'; +import { Logger } from '../utils/create_logger'; +import { getRoutingTransform } from '../shared/data_stream_get_routing_transform'; + +export type SyntheticsSynthtraceEsClientOptions = Omit; + +export class SyntheticsSynthtraceEsClient extends SynthtraceEsClient { + constructor(options: { client: Client; logger: Logger } & SyntheticsSynthtraceEsClientOptions) { + super({ + ...options, + pipeline: syntheticsPipeline(), + }); + this.dataStreams = ['synthetics-*-*']; + } +} + +function syntheticsPipeline() { + return (base: Readable) => { + return pipeline( + base, + getSerializeTransform(), + getRoutingTransform('synthetics'), + (err: unknown) => { + if (err) { + throw err; + } + } + ); + }; +} diff --git a/packages/kbn-apm-synthtrace/src/scenarios/degraded_synthetics_monitors.ts b/packages/kbn-apm-synthtrace/src/scenarios/degraded_synthetics_monitors.ts new file mode 100644 index 0000000000000..3be1ac53a6518 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/scenarios/degraded_synthetics_monitors.ts @@ -0,0 +1,159 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ +import { + generateShortId, + SyntheticsMonitorDocument, + syntheticsMonitor, +} from '@kbn/apm-synthtrace-client'; +import { Scenario } from '../cli/scenario'; +import { withClient } from '../lib/utils/with_client'; +import { getIpAddress } from './helpers/logs_mock_data'; +import { getAtIndexOrRandom } from './helpers/get_at_index_or_random'; + +const MORE_THAN_1024_CHARS = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?'; + +const MONITOR_NAMES = Array(4) + .fill(null) + .map((_, idx) => `synth-monitor-${idx}`); + +const ORIGINS = Array(4) + .fill(null) + .map((_, idx) => `synth-origin-${idx}`); + +const STATUS = ['up', 'down', 'disabled']; + +const OS = ['linux', 'windows', 'mac']; + +const scenario: Scenario = async (runOptions) => { + return { + generate: ({ range, clients: { syntheticsEsClient } }) => { + const { logger } = runOptions; + + const constructSyntheticsMonitorCommonData = (isMalformed?: boolean) => { + const index = Math.floor(Math.random() * 4); + const monitorName = getAtIndexOrRandom(MONITOR_NAMES, index); + const origin = getAtIndexOrRandom(ORIGINS, index); + const ip = getIpAddress(index); + const status = getAtIndexOrRandom(STATUS, index); + const os = getAtIndexOrRandom(OS, index); + + const commonSyntheticsMonitorEntryFields: SyntheticsMonitorDocument = { + 'monitor.id': generateShortId(), + 'monitor.check_group': generateShortId(), + 'monitor.timespan.lt': '2024-08-30T11:03:33.594Z', + 'monitor.timespan.gte': '2024-08-30T11:02:33.594Z', + }; + + return { + index, + monitorName, + origin, + ip, + status, + os, + commonLongEntryFields: commonSyntheticsMonitorEntryFields, + }; + }; + + const datasetSynth1Monitors = (timestamp: number) => { + const { monitorName, origin, ip, status, commonLongEntryFields } = + constructSyntheticsMonitorCommonData(); + + return syntheticsMonitor + .create() + .dataset('http') + .name(monitorName) + .origin(origin) + .ip(ip) + .defaults(commonLongEntryFields) + .timestamp(timestamp) + .status(status); + }; + + const datasetSynth2Monitors = (i: number, timestamp: number) => { + const { monitorName, origin, commonLongEntryFields } = + constructSyntheticsMonitorCommonData(); + const isMalformed = i % 90 === 0; + return syntheticsMonitor + .create() + .dataset('browser') + .name(monitorName) + .origin(origin) + .defaults({ + ...commonLongEntryFields, + 'synthetics.type': isMalformed + ? MORE_THAN_1024_CHARS // "ignore_above": 1024 in mapping + : 'step/metrics', + }) + .timestamp(timestamp); + }; + + const datasetSynth3Monitors = (i: number, timestamp: number) => { + const { monitorName, origin, os, commonLongEntryFields } = + constructSyntheticsMonitorCommonData(); + const isMalformed = i % 60 === 0; + return syntheticsMonitor + .create() + .dataset('browser.screenshot') + .name(monitorName) + .origin(origin) + .defaults({ + ...commonLongEntryFields, + 'synthetics.type': 'step/screenshot_ref', + 'observer.os.name': isMalformed + ? MORE_THAN_1024_CHARS // "ignore_above": 1024 in mapping + : os, + }) + .timestamp(timestamp); + }; + + const datasetSynth4Monitors = (i: number, timestamp: number) => { + const { monitorName, origin, commonLongEntryFields } = + constructSyntheticsMonitorCommonData(); + const isMalformed = i % 30 === 0; + return syntheticsMonitor + .create() + .dataset('browser.network') + .name(monitorName) + .origin(origin) + .defaults({ + ...commonLongEntryFields, + 'synthetics.type': isMalformed + ? MORE_THAN_1024_CHARS // "ignore_above": 1024 in mapping + : 'journey/network_info', + 'observer.product': isMalformed + ? MORE_THAN_1024_CHARS // "ignore_above": 1024 in mapping + : `synth-product-${i}`, + }) + .timestamp(timestamp); + }; + + const monitors = range + .interval('1m') + .rate(1) + .generator((timestamp) => { + return Array(200) + .fill(0) + .flatMap((_, index) => [ + datasetSynth1Monitors(timestamp), + datasetSynth2Monitors(index, timestamp), + datasetSynth3Monitors(index, timestamp), + datasetSynth4Monitors(index, timestamp), + ]); + }); + + return withClient( + syntheticsEsClient, + logger.perf('generating_synthetics_monitors', () => monitors) + ); + }, + }; +}; + +export default scenario; diff --git a/packages/kbn-apm-synthtrace/src/scenarios/helpers/get_at_index_or_random.ts b/packages/kbn-apm-synthtrace/src/scenarios/helpers/get_at_index_or_random.ts new file mode 100644 index 0000000000000..2a8e1d60062e3 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/scenarios/helpers/get_at_index_or_random.ts @@ -0,0 +1,13 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +import { randomInt } from 'crypto'; + +// Utility function to get a random element from an array +export const getAtIndexOrRandom = (values: T[], index?: number) => + values[index ?? randomInt(values.length)]; diff --git a/packages/kbn-apm-synthtrace/src/scenarios/helpers/logs_mock_data.ts b/packages/kbn-apm-synthtrace/src/scenarios/helpers/logs_mock_data.ts index 052ccce76499f..894f72b7d317d 100644 --- a/packages/kbn-apm-synthtrace/src/scenarios/helpers/logs_mock_data.ts +++ b/packages/kbn-apm-synthtrace/src/scenarios/helpers/logs_mock_data.ts @@ -10,16 +10,13 @@ import { generateShortId } from '@kbn/apm-synthtrace-client'; import { faker } from '@faker-js/faker'; import { randomInt } from 'crypto'; import moment from 'moment'; +import { getAtIndexOrRandom } from './get_at_index_or_random'; const { internet: { ipv4, userAgent, httpMethod, httpStatusCode }, word: { noun, verb }, } = faker; -// Utility function to get a random element from an array -const getAtIndexOrRandom = (values: T[], index?: number) => - values[index ?? randomInt(values.length)]; - // Arrays for data const LOG_LEVELS: string[] = ['FATAL', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE']; diff --git a/packages/kbn-esql-ast/BUILD.bazel b/packages/kbn-esql-ast/BUILD.bazel index 34557089d0db4..61577c430c3a4 100644 --- a/packages/kbn-esql-ast/BUILD.bazel +++ b/packages/kbn-esql-ast/BUILD.bazel @@ -3,6 +3,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library") SRCS = glob( [ "**/*.ts", + "**/*.js", ], exclude = [ "**/*.config.js", diff --git a/packages/kbn-esql-ast/src/antlr/esql_lexer.g4 b/packages/kbn-esql-ast/src/antlr/esql_lexer.g4 index f9aa94252ee4d..da58f29b5527c 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_lexer.g4 +++ b/packages/kbn-esql-ast/src/antlr/esql_lexer.g4 @@ -1,14 +1,63 @@ +// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB. + /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +lexer grammar esql_lexer; -// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB. +@header { +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +} -lexer grammar esql_lexer; - options { caseInsensitive = true; } +options { + superClass=lexer_config; + caseInsensitive=true; +} + +/* + * Before modifying this file, please read the section above as changes here + * have significant impact in the ANTLR generated code and its consumption upstream + * (including Kibana). + * + * A. To add a development token (only available behind in snapshot/dev builds) + * + * Since the tokens/modes are in development, simply define them under the + * "// in development section" and follow the section comments in that section. + * That is use the DEV_ prefix and use the {this.isDevVersion()}? conditional. + * They are defined at the end of the file, to minimize the impact on the existing + * token types. + * + * B. To add a new (production-ready) token + * + * Be sure to go through step A (add a development token). + * Make sure to remove the prefix and conditional before promoting the tokens in + * production. + * Since tokens types (numbers) are generated by ANTLR in a continuous fashion, + * it is desirable to avoid changing these values hence where possible, add + * add them at the end of their respective section. + * Note that the use of lexing modes prevents this since any addition to a mode + * (regardless where it occurs) shifts all the declarations that follow in other modes. + * + * C. Renaming a token + * + * Avoid renaming the token. But if you really have to, please check with the + * Kibana team as they might be using the generated ANTLR "dictionary". + * + * D. To remove a token + * + * If the tokens haven't made it to production (and make sure to double check), + * simply remove them from the grammar. + * If the tokens get promoted to release, check with the Kibana team the impact + * they have on the UI (auto-completion, etc...) + */ DISSECT : 'dissect' -> pushMode(EXPRESSION_MODE); DROP : 'drop' -> pushMode(PROJECT_MODE); @@ -17,12 +66,9 @@ EVAL : 'eval' -> pushMode(EXPRESSION_MODE); EXPLAIN : 'explain' -> pushMode(EXPLAIN_MODE); FROM : 'from' -> pushMode(FROM_MODE); GROK : 'grok' -> pushMode(EXPRESSION_MODE); -INLINESTATS : 'inlinestats' -> pushMode(EXPRESSION_MODE); KEEP : 'keep' -> pushMode(PROJECT_MODE); LIMIT : 'limit' -> pushMode(EXPRESSION_MODE); -LOOKUP : 'lookup' -> pushMode(LOOKUP_MODE); META : 'meta' -> pushMode(META_MODE); -METRICS : 'metrics' -> pushMode(METRICS_MODE); MV_EXPAND : 'mv_expand' -> pushMode(MVEXPAND_MODE); RENAME : 'rename' -> pushMode(RENAME_MODE); ROW : 'row' -> pushMode(EXPRESSION_MODE); @@ -30,8 +76,26 @@ SHOW : 'show' -> pushMode(SHOW_MODE); SORT : 'sort' -> pushMode(EXPRESSION_MODE); STATS : 'stats' -> pushMode(EXPRESSION_MODE); WHERE : 'where' -> pushMode(EXPRESSION_MODE); -MATCH : 'match' -> pushMode(EXPRESSION_MODE); -UNKNOWN_CMD : ~[ \r\n\t[\]/]+ -> pushMode(EXPRESSION_MODE); +// +// in development +// +// Before adding a new in-development command, to sandbox the behavior when running in production environments +// +// For example: to add myCommand use the following declaration: +// DEV_MYCOMMAND : {this.isDevVersion()}? 'mycommand' -> ... +// +// Once the command has been stabilized, remove the DEV_ prefix and the {}? conditional and move the command to the +// main section while preserving alphabetical order: +// 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); + +// +// Catch-all for unrecognized commands - don't define any beyond this line +// +UNKNOWN_CMD : ~[ \r\n\t[\]/]+ -> pushMode(EXPRESSION_MODE) ; LINE_COMMENT : '//' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN) @@ -45,27 +109,6 @@ WS : [ \r\n\t]+ -> channel(HIDDEN) ; -// in 8.14 ` were not allowed -// this has been relaxed in 8.15 since " is used for quoting -fragment UNQUOTED_SOURCE_PART - : ~[:"=|,[\]/ \t\r\n] - | '/' ~[*/] // allow single / but not followed by another / or * which would start a comment -- used in index pattern date spec - ; - -UNQUOTED_SOURCE - : UNQUOTED_SOURCE_PART+ - ; - -// -// Explain -// -mode EXPLAIN_MODE; -EXPLAIN_OPENING_BRACKET : OPENING_BRACKET -> type(OPENING_BRACKET), pushMode(DEFAULT_MODE); -EXPLAIN_PIPE : PIPE -> type(PIPE), popMode; -EXPLAIN_WS : WS -> channel(HIDDEN); -EXPLAIN_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN); -EXPLAIN_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN); - // // Expression - used by most command // @@ -78,7 +121,7 @@ fragment DIGIT ; fragment LETTER - : [A-Za-z] + : [a-z] ; fragment ESCAPE_SEQUENCE @@ -90,7 +133,7 @@ fragment UNESCAPED_CHARS ; fragment EXPONENT - : [Ee] [+-]? DIGIT+ + : [e] [+-]? DIGIT+ ; fragment ASPERAND @@ -146,7 +189,6 @@ IS: 'is'; LAST : 'last'; LIKE: 'like'; LP : '('; -MATCH_OPERATOR: 'match'; NOT : 'not'; NULL : 'null'; NULLS : 'nulls'; @@ -170,8 +212,11 @@ ASTERISK : '*'; SLASH : '/'; PERCENT : '%'; +// move it in the main section if the feature gets promoted +DEV_MATCH_OP : {this.isDevVersion()}? DEV_MATCH -> type(DEV_MATCH); + NAMED_OR_POSITIONAL_PARAM - : PARAM LETTER UNQUOTED_ID_BODY* + : PARAM (LETTER | UNDERSCORE) UNQUOTED_ID_BODY* | PARAM DIGIT+ ; @@ -209,6 +254,17 @@ EXPR_MULTILINE_COMMENT EXPR_WS : WS -> channel(HIDDEN) ; + +// +// Explain +// +mode EXPLAIN_MODE; +EXPLAIN_OPENING_BRACKET : OPENING_BRACKET -> type(OPENING_BRACKET), pushMode(DEFAULT_MODE); +EXPLAIN_PIPE : PIPE -> type(PIPE), popMode; +EXPLAIN_WS : WS -> channel(HIDDEN); +EXPLAIN_LINE_COMMENT : LINE_COMMENT -> channel(HIDDEN); +EXPLAIN_MULTILINE_COMMENT : MULTILINE_COMMENT -> channel(HIDDEN); + // // FROM command // @@ -221,6 +277,17 @@ FROM_COMMA : COMMA -> type(COMMA); FROM_ASSIGN : ASSIGN -> type(ASSIGN); METADATA : 'metadata'; +// in 8.14 ` were not allowed +// this has been relaxed in 8.15 since " is used for quoting +fragment UNQUOTED_SOURCE_PART + : ~[:"=|,[\]/ \t\r\n] + | '/' ~[*/] // allow single / but not followed by another / or * which would start a comment -- used in index pattern date spec + ; + +UNQUOTED_SOURCE + : UNQUOTED_SOURCE_PART+ + ; + FROM_UNQUOTED_SOURCE : UNQUOTED_SOURCE -> type(UNQUOTED_SOURCE); FROM_QUOTED_SOURCE : QUOTED_STRING -> type(QUOTED_STRING); @@ -358,50 +425,6 @@ ENRICH_FIELD_WS : WS -> channel(HIDDEN) ; -// LOOKUP ON key -mode LOOKUP_MODE; -LOOKUP_PIPE : PIPE -> type(PIPE), popMode; -LOOKUP_COLON : COLON -> type(COLON); -LOOKUP_COMMA : COMMA -> type(COMMA); -LOOKUP_DOT: DOT -> type(DOT); -LOOKUP_ON : ON -> type(ON), pushMode(LOOKUP_FIELD_MODE); - -LOOKUP_UNQUOTED_SOURCE: UNQUOTED_SOURCE -> type(UNQUOTED_SOURCE); -LOOKUP_QUOTED_SOURCE : QUOTED_STRING -> type(QUOTED_STRING); - -LOOKUP_LINE_COMMENT - : LINE_COMMENT -> channel(HIDDEN) - ; - -LOOKUP_MULTILINE_COMMENT - : MULTILINE_COMMENT -> channel(HIDDEN) - ; - -LOOKUP_WS - : WS -> channel(HIDDEN) - ; - -mode LOOKUP_FIELD_MODE; -LOOKUP_FIELD_PIPE : PIPE -> type(PIPE), popMode, popMode; -LOOKUP_FIELD_COMMA : COMMA -> type(COMMA); -LOOKUP_FIELD_DOT: DOT -> type(DOT); - -LOOKUP_FIELD_ID_PATTERN - : ID_PATTERN -> type(ID_PATTERN) - ; - -LOOKUP_FIELD_LINE_COMMENT - : LINE_COMMENT -> channel(HIDDEN) - ; - -LOOKUP_FIELD_MULTILINE_COMMENT - : MULTILINE_COMMENT -> channel(HIDDEN) - ; - -LOOKUP_FIELD_WS - : WS -> channel(HIDDEN) - ; - mode MVEXPAND_MODE; MVEXPAND_PIPE : PIPE -> type(PIPE), popMode; MVEXPAND_DOT: DOT -> type(DOT); @@ -487,6 +510,51 @@ SETTING_WS : WS -> channel(HIDDEN) ; +// +// LOOKUP ON key +// +mode LOOKUP_MODE; +LOOKUP_PIPE : PIPE -> type(PIPE), popMode; +LOOKUP_COLON : COLON -> type(COLON); +LOOKUP_COMMA : COMMA -> type(COMMA); +LOOKUP_DOT: DOT -> type(DOT); +LOOKUP_ON : ON -> type(ON), pushMode(LOOKUP_FIELD_MODE); + +LOOKUP_UNQUOTED_SOURCE: UNQUOTED_SOURCE -> type(UNQUOTED_SOURCE); +LOOKUP_QUOTED_SOURCE : QUOTED_STRING -> type(QUOTED_STRING); + +LOOKUP_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +LOOKUP_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +LOOKUP_WS + : WS -> channel(HIDDEN) + ; + +mode LOOKUP_FIELD_MODE; +LOOKUP_FIELD_PIPE : PIPE -> type(PIPE), popMode, popMode; +LOOKUP_FIELD_COMMA : COMMA -> type(COMMA); +LOOKUP_FIELD_DOT: DOT -> type(DOT); + +LOOKUP_FIELD_ID_PATTERN + : ID_PATTERN -> type(ID_PATTERN) + ; + +LOOKUP_FIELD_LINE_COMMENT + : LINE_COMMENT -> channel(HIDDEN) + ; + +LOOKUP_FIELD_MULTILINE_COMMENT + : MULTILINE_COMMENT -> channel(HIDDEN) + ; + +LOOKUP_FIELD_WS + : WS -> channel(HIDDEN) + ; // // METRICS command diff --git a/packages/kbn-esql-ast/src/antlr/esql_lexer.interp b/packages/kbn-esql-ast/src/antlr/esql_lexer.interp index 079b01d721517..8122a56884280 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_lexer.interp +++ b/packages/kbn-esql-ast/src/antlr/esql_lexer.interp @@ -7,12 +7,9 @@ null 'explain' 'from' 'grok' -'inlinestats' 'keep' 'limit' -'lookup' 'meta' -'metrics' 'mv_expand' 'rename' 'row' @@ -28,7 +25,6 @@ null null null null -null '|' null null @@ -48,7 +44,6 @@ null 'last' 'like' '(' -null 'not' 'null' 'nulls' @@ -77,6 +72,9 @@ null null null null +null +null +null 'metadata' null null @@ -85,6 +83,7 @@ null null null null +null 'as' null null @@ -101,21 +100,21 @@ null null null null +'info' null null null +'functions' null null null -'info' +':' null null null -'functions' null null null -':' null null null @@ -136,12 +135,9 @@ EVAL EXPLAIN FROM GROK -INLINESTATS KEEP LIMIT -LOOKUP META -METRICS MV_EXPAND RENAME ROW @@ -149,15 +145,14 @@ SHOW SORT STATS WHERE -MATCH +DEV_INLINESTATS +DEV_LOOKUP +DEV_MATCH +DEV_METRICS UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS -UNQUOTED_SOURCE -EXPLAIN_WS -EXPLAIN_LINE_COMMENT -EXPLAIN_MULTILINE_COMMENT PIPE QUOTED_STRING INTEGER_LITERAL @@ -177,7 +172,6 @@ IS LAST LIKE LP -MATCH_OPERATOR NOT NULL NULLS @@ -206,7 +200,11 @@ 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 @@ -227,12 +225,6 @@ ENRICH_WS ENRICH_FIELD_LINE_COMMENT ENRICH_FIELD_MULTILINE_COMMENT ENRICH_FIELD_WS -LOOKUP_LINE_COMMENT -LOOKUP_MULTILINE_COMMENT -LOOKUP_WS -LOOKUP_FIELD_LINE_COMMENT -LOOKUP_FIELD_MULTILINE_COMMENT -LOOKUP_FIELD_WS MVEXPAND_LINE_COMMENT MVEXPAND_MULTILINE_COMMENT MVEXPAND_WS @@ -249,6 +241,12 @@ 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 @@ -264,12 +262,9 @@ EVAL EXPLAIN FROM GROK -INLINESTATS KEEP LIMIT -LOOKUP META -METRICS MV_EXPAND RENAME ROW @@ -277,18 +272,14 @@ SHOW SORT STATS WHERE -MATCH +DEV_INLINESTATS +DEV_LOOKUP +DEV_MATCH +DEV_METRICS UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS -UNQUOTED_SOURCE_PART -UNQUOTED_SOURCE -EXPLAIN_OPENING_BRACKET -EXPLAIN_PIPE -EXPLAIN_WS -EXPLAIN_LINE_COMMENT -EXPLAIN_MULTILINE_COMMENT PIPE DIGIT LETTER @@ -318,7 +309,6 @@ IS LAST LIKE LP -MATCH_OPERATOR NOT NULL NULLS @@ -339,6 +329,7 @@ MINUS ASTERISK SLASH PERCENT +DEV_MATCH_OP NAMED_OR_POSITIONAL_PARAM OPENING_BRACKET CLOSING_BRACKET @@ -348,6 +339,11 @@ 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 @@ -355,6 +351,8 @@ FROM_COLON FROM_COMMA FROM_ASSIGN METADATA +UNQUOTED_SOURCE_PART +UNQUOTED_SOURCE FROM_UNQUOTED_SOURCE FROM_QUOTED_SOURCE FROM_LINE_COMMENT @@ -398,23 +396,6 @@ ENRICH_FIELD_QUOTED_IDENTIFIER ENRICH_FIELD_LINE_COMMENT ENRICH_FIELD_MULTILINE_COMMENT ENRICH_FIELD_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 MVEXPAND_PIPE MVEXPAND_DOT MVEXPAND_QUOTED_IDENTIFIER @@ -438,6 +419,23 @@ 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 @@ -460,21 +458,21 @@ HIDDEN mode names: DEFAULT_MODE -EXPLAIN_MODE EXPRESSION_MODE +EXPLAIN_MODE FROM_MODE PROJECT_MODE RENAME_MODE ENRICH_MODE ENRICH_FIELD_MODE -LOOKUP_MODE -LOOKUP_FIELD_MODE MVEXPAND_MODE SHOW_MODE META_MODE SETTING_MODE +LOOKUP_MODE +LOOKUP_FIELD_MODE METRICS_MODE CLOSING_METRICS_MODE atn: -[4, 0, 126, 1468, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 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, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 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, 11, 1, 12, 1, 12, 1, 12, 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, 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, 14, 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, 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, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 4, 21, 587, 8, 21, 11, 21, 12, 21, 588, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 597, 8, 22, 10, 22, 12, 22, 600, 9, 22, 1, 22, 3, 22, 603, 8, 22, 1, 22, 3, 22, 606, 8, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 615, 8, 23, 10, 23, 12, 23, 618, 9, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 4, 24, 626, 8, 24, 11, 24, 12, 24, 627, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 3, 25, 635, 8, 25, 1, 26, 4, 26, 638, 8, 26, 11, 26, 12, 26, 639, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 37, 1, 37, 3, 37, 679, 8, 37, 1, 37, 4, 37, 682, 8, 37, 11, 37, 12, 37, 683, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 3, 40, 693, 8, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 3, 42, 700, 8, 42, 1, 43, 1, 43, 1, 43, 5, 43, 705, 8, 43, 10, 43, 12, 43, 708, 9, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 5, 43, 716, 8, 43, 10, 43, 12, 43, 719, 9, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 3, 43, 726, 8, 43, 1, 43, 3, 43, 729, 8, 43, 3, 43, 731, 8, 43, 1, 44, 4, 44, 734, 8, 44, 11, 44, 12, 44, 735, 1, 45, 4, 45, 739, 8, 45, 11, 45, 12, 45, 740, 1, 45, 1, 45, 5, 45, 745, 8, 45, 10, 45, 12, 45, 748, 9, 45, 1, 45, 1, 45, 4, 45, 752, 8, 45, 11, 45, 12, 45, 753, 1, 45, 4, 45, 757, 8, 45, 11, 45, 12, 45, 758, 1, 45, 1, 45, 5, 45, 763, 8, 45, 10, 45, 12, 45, 766, 9, 45, 3, 45, 768, 8, 45, 1, 45, 1, 45, 1, 45, 1, 45, 4, 45, 774, 8, 45, 11, 45, 12, 45, 775, 1, 45, 1, 45, 3, 45, 780, 8, 45, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 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, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 5, 82, 908, 8, 82, 10, 82, 12, 82, 911, 9, 82, 1, 82, 1, 82, 4, 82, 915, 8, 82, 11, 82, 12, 82, 916, 3, 82, 919, 8, 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, 5, 85, 933, 8, 85, 10, 85, 12, 85, 936, 9, 85, 1, 85, 1, 85, 3, 85, 940, 8, 85, 1, 85, 4, 85, 943, 8, 85, 11, 85, 12, 85, 944, 3, 85, 947, 8, 85, 1, 86, 1, 86, 4, 86, 951, 8, 86, 11, 86, 12, 86, 952, 1, 86, 1, 86, 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, 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, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 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, 103, 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, 1042, 8, 106, 1, 107, 1, 107, 3, 107, 1046, 8, 107, 1, 107, 5, 107, 1049, 8, 107, 10, 107, 12, 107, 1052, 9, 107, 1, 107, 1, 107, 3, 107, 1056, 8, 107, 1, 107, 4, 107, 1059, 8, 107, 11, 107, 12, 107, 1060, 3, 107, 1063, 8, 107, 1, 108, 1, 108, 4, 108, 1067, 8, 108, 11, 108, 12, 108, 1068, 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, 117, 1, 117, 1, 117, 1, 117, 1, 118, 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, 121, 1, 122, 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, 124, 1, 124, 1, 125, 1, 125, 1, 126, 4, 126, 1144, 8, 126, 11, 126, 12, 126, 1145, 1, 126, 1, 126, 3, 126, 1150, 8, 126, 1, 126, 4, 126, 1153, 8, 126, 11, 126, 12, 126, 1154, 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 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, 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, 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, 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, 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, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 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, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 171, 1, 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, 176, 1, 176, 1, 177, 1, 177, 1, 177, 1, 177, 1, 177, 4, 177, 1377, 8, 177, 11, 177, 12, 177, 1378, 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, 181, 1, 182, 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, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 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, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 192, 1, 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, 2, 616, 717, 0, 196, 16, 1, 18, 2, 20, 3, 22, 4, 24, 5, 26, 6, 28, 7, 30, 8, 32, 9, 34, 10, 36, 11, 38, 12, 40, 13, 42, 14, 44, 15, 46, 16, 48, 17, 50, 18, 52, 19, 54, 20, 56, 21, 58, 22, 60, 23, 62, 24, 64, 25, 66, 0, 68, 26, 70, 0, 72, 0, 74, 27, 76, 28, 78, 29, 80, 30, 82, 0, 84, 0, 86, 0, 88, 0, 90, 0, 92, 0, 94, 0, 96, 0, 98, 0, 100, 0, 102, 31, 104, 32, 106, 33, 108, 34, 110, 35, 112, 36, 114, 37, 116, 38, 118, 39, 120, 40, 122, 41, 124, 42, 126, 43, 128, 44, 130, 45, 132, 46, 134, 47, 136, 48, 138, 49, 140, 50, 142, 51, 144, 52, 146, 53, 148, 54, 150, 55, 152, 56, 154, 57, 156, 58, 158, 59, 160, 60, 162, 61, 164, 62, 166, 63, 168, 64, 170, 65, 172, 66, 174, 67, 176, 68, 178, 69, 180, 70, 182, 71, 184, 72, 186, 73, 188, 0, 190, 74, 192, 75, 194, 76, 196, 77, 198, 0, 200, 0, 202, 0, 204, 0, 206, 0, 208, 0, 210, 78, 212, 0, 214, 0, 216, 79, 218, 80, 220, 81, 222, 0, 224, 0, 226, 0, 228, 0, 230, 0, 232, 82, 234, 83, 236, 84, 238, 85, 240, 0, 242, 0, 244, 0, 246, 0, 248, 86, 250, 0, 252, 87, 254, 88, 256, 89, 258, 0, 260, 0, 262, 90, 264, 91, 266, 0, 268, 92, 270, 0, 272, 93, 274, 94, 276, 95, 278, 0, 280, 0, 282, 0, 284, 0, 286, 0, 288, 0, 290, 0, 292, 96, 294, 97, 296, 98, 298, 0, 300, 0, 302, 0, 304, 0, 306, 0, 308, 0, 310, 0, 312, 99, 314, 100, 316, 101, 318, 0, 320, 0, 322, 0, 324, 0, 326, 102, 328, 103, 330, 104, 332, 0, 334, 0, 336, 0, 338, 0, 340, 105, 342, 106, 344, 107, 346, 0, 348, 108, 350, 109, 352, 110, 354, 111, 356, 0, 358, 112, 360, 113, 362, 114, 364, 115, 366, 0, 368, 116, 370, 117, 372, 118, 374, 119, 376, 120, 378, 0, 380, 0, 382, 0, 384, 121, 386, 122, 388, 123, 390, 0, 392, 0, 394, 124, 396, 125, 398, 126, 400, 0, 402, 0, 404, 0, 406, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 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, 85, 85, 117, 117, 2, 0, 87, 87, 119, 119, 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, 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, 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, 35, 44, 44, 47, 47, 58, 58, 60, 60, 62, 63, 92, 92, 124, 124, 1494, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 68, 1, 0, 0, 0, 1, 70, 1, 0, 0, 0, 1, 72, 1, 0, 0, 0, 1, 74, 1, 0, 0, 0, 1, 76, 1, 0, 0, 0, 1, 78, 1, 0, 0, 0, 2, 80, 1, 0, 0, 0, 2, 102, 1, 0, 0, 0, 2, 104, 1, 0, 0, 0, 2, 106, 1, 0, 0, 0, 2, 108, 1, 0, 0, 0, 2, 110, 1, 0, 0, 0, 2, 112, 1, 0, 0, 0, 2, 114, 1, 0, 0, 0, 2, 116, 1, 0, 0, 0, 2, 118, 1, 0, 0, 0, 2, 120, 1, 0, 0, 0, 2, 122, 1, 0, 0, 0, 2, 124, 1, 0, 0, 0, 2, 126, 1, 0, 0, 0, 2, 128, 1, 0, 0, 0, 2, 130, 1, 0, 0, 0, 2, 132, 1, 0, 0, 0, 2, 134, 1, 0, 0, 0, 2, 136, 1, 0, 0, 0, 2, 138, 1, 0, 0, 0, 2, 140, 1, 0, 0, 0, 2, 142, 1, 0, 0, 0, 2, 144, 1, 0, 0, 0, 2, 146, 1, 0, 0, 0, 2, 148, 1, 0, 0, 0, 2, 150, 1, 0, 0, 0, 2, 152, 1, 0, 0, 0, 2, 154, 1, 0, 0, 0, 2, 156, 1, 0, 0, 0, 2, 158, 1, 0, 0, 0, 2, 160, 1, 0, 0, 0, 2, 162, 1, 0, 0, 0, 2, 164, 1, 0, 0, 0, 2, 166, 1, 0, 0, 0, 2, 168, 1, 0, 0, 0, 2, 170, 1, 0, 0, 0, 2, 172, 1, 0, 0, 0, 2, 174, 1, 0, 0, 0, 2, 176, 1, 0, 0, 0, 2, 178, 1, 0, 0, 0, 2, 180, 1, 0, 0, 0, 2, 182, 1, 0, 0, 0, 2, 184, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 2, 190, 1, 0, 0, 0, 2, 192, 1, 0, 0, 0, 2, 194, 1, 0, 0, 0, 2, 196, 1, 0, 0, 0, 3, 198, 1, 0, 0, 0, 3, 200, 1, 0, 0, 0, 3, 202, 1, 0, 0, 0, 3, 204, 1, 0, 0, 0, 3, 206, 1, 0, 0, 0, 3, 208, 1, 0, 0, 0, 3, 210, 1, 0, 0, 0, 3, 212, 1, 0, 0, 0, 3, 214, 1, 0, 0, 0, 3, 216, 1, 0, 0, 0, 3, 218, 1, 0, 0, 0, 3, 220, 1, 0, 0, 0, 4, 222, 1, 0, 0, 0, 4, 224, 1, 0, 0, 0, 4, 226, 1, 0, 0, 0, 4, 232, 1, 0, 0, 0, 4, 234, 1, 0, 0, 0, 4, 236, 1, 0, 0, 0, 4, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 5, 250, 1, 0, 0, 0, 5, 252, 1, 0, 0, 0, 5, 254, 1, 0, 0, 0, 5, 256, 1, 0, 0, 0, 6, 258, 1, 0, 0, 0, 6, 260, 1, 0, 0, 0, 6, 262, 1, 0, 0, 0, 6, 264, 1, 0, 0, 0, 6, 268, 1, 0, 0, 0, 6, 270, 1, 0, 0, 0, 6, 272, 1, 0, 0, 0, 6, 274, 1, 0, 0, 0, 6, 276, 1, 0, 0, 0, 7, 278, 1, 0, 0, 0, 7, 280, 1, 0, 0, 0, 7, 282, 1, 0, 0, 0, 7, 284, 1, 0, 0, 0, 7, 286, 1, 0, 0, 0, 7, 288, 1, 0, 0, 0, 7, 290, 1, 0, 0, 0, 7, 292, 1, 0, 0, 0, 7, 294, 1, 0, 0, 0, 7, 296, 1, 0, 0, 0, 8, 298, 1, 0, 0, 0, 8, 300, 1, 0, 0, 0, 8, 302, 1, 0, 0, 0, 8, 304, 1, 0, 0, 0, 8, 306, 1, 0, 0, 0, 8, 308, 1, 0, 0, 0, 8, 310, 1, 0, 0, 0, 8, 312, 1, 0, 0, 0, 8, 314, 1, 0, 0, 0, 8, 316, 1, 0, 0, 0, 9, 318, 1, 0, 0, 0, 9, 320, 1, 0, 0, 0, 9, 322, 1, 0, 0, 0, 9, 324, 1, 0, 0, 0, 9, 326, 1, 0, 0, 0, 9, 328, 1, 0, 0, 0, 9, 330, 1, 0, 0, 0, 10, 332, 1, 0, 0, 0, 10, 334, 1, 0, 0, 0, 10, 336, 1, 0, 0, 0, 10, 338, 1, 0, 0, 0, 10, 340, 1, 0, 0, 0, 10, 342, 1, 0, 0, 0, 10, 344, 1, 0, 0, 0, 11, 346, 1, 0, 0, 0, 11, 348, 1, 0, 0, 0, 11, 350, 1, 0, 0, 0, 11, 352, 1, 0, 0, 0, 11, 354, 1, 0, 0, 0, 12, 356, 1, 0, 0, 0, 12, 358, 1, 0, 0, 0, 12, 360, 1, 0, 0, 0, 12, 362, 1, 0, 0, 0, 12, 364, 1, 0, 0, 0, 13, 366, 1, 0, 0, 0, 13, 368, 1, 0, 0, 0, 13, 370, 1, 0, 0, 0, 13, 372, 1, 0, 0, 0, 13, 374, 1, 0, 0, 0, 13, 376, 1, 0, 0, 0, 14, 378, 1, 0, 0, 0, 14, 380, 1, 0, 0, 0, 14, 382, 1, 0, 0, 0, 14, 384, 1, 0, 0, 0, 14, 386, 1, 0, 0, 0, 14, 388, 1, 0, 0, 0, 15, 390, 1, 0, 0, 0, 15, 392, 1, 0, 0, 0, 15, 394, 1, 0, 0, 0, 15, 396, 1, 0, 0, 0, 15, 398, 1, 0, 0, 0, 15, 400, 1, 0, 0, 0, 15, 402, 1, 0, 0, 0, 15, 404, 1, 0, 0, 0, 15, 406, 1, 0, 0, 0, 16, 408, 1, 0, 0, 0, 18, 418, 1, 0, 0, 0, 20, 425, 1, 0, 0, 0, 22, 434, 1, 0, 0, 0, 24, 441, 1, 0, 0, 0, 26, 451, 1, 0, 0, 0, 28, 458, 1, 0, 0, 0, 30, 465, 1, 0, 0, 0, 32, 479, 1, 0, 0, 0, 34, 486, 1, 0, 0, 0, 36, 494, 1, 0, 0, 0, 38, 503, 1, 0, 0, 0, 40, 510, 1, 0, 0, 0, 42, 520, 1, 0, 0, 0, 44, 532, 1, 0, 0, 0, 46, 541, 1, 0, 0, 0, 48, 547, 1, 0, 0, 0, 50, 554, 1, 0, 0, 0, 52, 561, 1, 0, 0, 0, 54, 569, 1, 0, 0, 0, 56, 577, 1, 0, 0, 0, 58, 586, 1, 0, 0, 0, 60, 592, 1, 0, 0, 0, 62, 609, 1, 0, 0, 0, 64, 625, 1, 0, 0, 0, 66, 634, 1, 0, 0, 0, 68, 637, 1, 0, 0, 0, 70, 641, 1, 0, 0, 0, 72, 646, 1, 0, 0, 0, 74, 651, 1, 0, 0, 0, 76, 655, 1, 0, 0, 0, 78, 659, 1, 0, 0, 0, 80, 663, 1, 0, 0, 0, 82, 667, 1, 0, 0, 0, 84, 669, 1, 0, 0, 0, 86, 671, 1, 0, 0, 0, 88, 674, 1, 0, 0, 0, 90, 676, 1, 0, 0, 0, 92, 685, 1, 0, 0, 0, 94, 687, 1, 0, 0, 0, 96, 692, 1, 0, 0, 0, 98, 694, 1, 0, 0, 0, 100, 699, 1, 0, 0, 0, 102, 730, 1, 0, 0, 0, 104, 733, 1, 0, 0, 0, 106, 779, 1, 0, 0, 0, 108, 781, 1, 0, 0, 0, 110, 784, 1, 0, 0, 0, 112, 788, 1, 0, 0, 0, 114, 792, 1, 0, 0, 0, 116, 794, 1, 0, 0, 0, 118, 797, 1, 0, 0, 0, 120, 799, 1, 0, 0, 0, 122, 804, 1, 0, 0, 0, 124, 806, 1, 0, 0, 0, 126, 812, 1, 0, 0, 0, 128, 818, 1, 0, 0, 0, 130, 821, 1, 0, 0, 0, 132, 824, 1, 0, 0, 0, 134, 829, 1, 0, 0, 0, 136, 834, 1, 0, 0, 0, 138, 836, 1, 0, 0, 0, 140, 842, 1, 0, 0, 0, 142, 846, 1, 0, 0, 0, 144, 851, 1, 0, 0, 0, 146, 857, 1, 0, 0, 0, 148, 860, 1, 0, 0, 0, 150, 862, 1, 0, 0, 0, 152, 868, 1, 0, 0, 0, 154, 870, 1, 0, 0, 0, 156, 875, 1, 0, 0, 0, 158, 878, 1, 0, 0, 0, 160, 881, 1, 0, 0, 0, 162, 884, 1, 0, 0, 0, 164, 886, 1, 0, 0, 0, 166, 889, 1, 0, 0, 0, 168, 891, 1, 0, 0, 0, 170, 894, 1, 0, 0, 0, 172, 896, 1, 0, 0, 0, 174, 898, 1, 0, 0, 0, 176, 900, 1, 0, 0, 0, 178, 902, 1, 0, 0, 0, 180, 918, 1, 0, 0, 0, 182, 920, 1, 0, 0, 0, 184, 925, 1, 0, 0, 0, 186, 946, 1, 0, 0, 0, 188, 948, 1, 0, 0, 0, 190, 956, 1, 0, 0, 0, 192, 958, 1, 0, 0, 0, 194, 962, 1, 0, 0, 0, 196, 966, 1, 0, 0, 0, 198, 970, 1, 0, 0, 0, 200, 975, 1, 0, 0, 0, 202, 979, 1, 0, 0, 0, 204, 983, 1, 0, 0, 0, 206, 987, 1, 0, 0, 0, 208, 991, 1, 0, 0, 0, 210, 995, 1, 0, 0, 0, 212, 1004, 1, 0, 0, 0, 214, 1008, 1, 0, 0, 0, 216, 1012, 1, 0, 0, 0, 218, 1016, 1, 0, 0, 0, 220, 1020, 1, 0, 0, 0, 222, 1024, 1, 0, 0, 0, 224, 1029, 1, 0, 0, 0, 226, 1033, 1, 0, 0, 0, 228, 1041, 1, 0, 0, 0, 230, 1062, 1, 0, 0, 0, 232, 1066, 1, 0, 0, 0, 234, 1070, 1, 0, 0, 0, 236, 1074, 1, 0, 0, 0, 238, 1078, 1, 0, 0, 0, 240, 1082, 1, 0, 0, 0, 242, 1087, 1, 0, 0, 0, 244, 1091, 1, 0, 0, 0, 246, 1095, 1, 0, 0, 0, 248, 1099, 1, 0, 0, 0, 250, 1102, 1, 0, 0, 0, 252, 1106, 1, 0, 0, 0, 254, 1110, 1, 0, 0, 0, 256, 1114, 1, 0, 0, 0, 258, 1118, 1, 0, 0, 0, 260, 1123, 1, 0, 0, 0, 262, 1128, 1, 0, 0, 0, 264, 1133, 1, 0, 0, 0, 266, 1140, 1, 0, 0, 0, 268, 1149, 1, 0, 0, 0, 270, 1156, 1, 0, 0, 0, 272, 1160, 1, 0, 0, 0, 274, 1164, 1, 0, 0, 0, 276, 1168, 1, 0, 0, 0, 278, 1172, 1, 0, 0, 0, 280, 1178, 1, 0, 0, 0, 282, 1182, 1, 0, 0, 0, 284, 1186, 1, 0, 0, 0, 286, 1190, 1, 0, 0, 0, 288, 1194, 1, 0, 0, 0, 290, 1198, 1, 0, 0, 0, 292, 1202, 1, 0, 0, 0, 294, 1206, 1, 0, 0, 0, 296, 1210, 1, 0, 0, 0, 298, 1214, 1, 0, 0, 0, 300, 1219, 1, 0, 0, 0, 302, 1223, 1, 0, 0, 0, 304, 1227, 1, 0, 0, 0, 306, 1231, 1, 0, 0, 0, 308, 1236, 1, 0, 0, 0, 310, 1240, 1, 0, 0, 0, 312, 1244, 1, 0, 0, 0, 314, 1248, 1, 0, 0, 0, 316, 1252, 1, 0, 0, 0, 318, 1256, 1, 0, 0, 0, 320, 1262, 1, 0, 0, 0, 322, 1266, 1, 0, 0, 0, 324, 1270, 1, 0, 0, 0, 326, 1274, 1, 0, 0, 0, 328, 1278, 1, 0, 0, 0, 330, 1282, 1, 0, 0, 0, 332, 1286, 1, 0, 0, 0, 334, 1291, 1, 0, 0, 0, 336, 1295, 1, 0, 0, 0, 338, 1299, 1, 0, 0, 0, 340, 1303, 1, 0, 0, 0, 342, 1307, 1, 0, 0, 0, 344, 1311, 1, 0, 0, 0, 346, 1315, 1, 0, 0, 0, 348, 1320, 1, 0, 0, 0, 350, 1325, 1, 0, 0, 0, 352, 1329, 1, 0, 0, 0, 354, 1333, 1, 0, 0, 0, 356, 1337, 1, 0, 0, 0, 358, 1342, 1, 0, 0, 0, 360, 1352, 1, 0, 0, 0, 362, 1356, 1, 0, 0, 0, 364, 1360, 1, 0, 0, 0, 366, 1364, 1, 0, 0, 0, 368, 1369, 1, 0, 0, 0, 370, 1376, 1, 0, 0, 0, 372, 1380, 1, 0, 0, 0, 374, 1384, 1, 0, 0, 0, 376, 1388, 1, 0, 0, 0, 378, 1392, 1, 0, 0, 0, 380, 1397, 1, 0, 0, 0, 382, 1403, 1, 0, 0, 0, 384, 1409, 1, 0, 0, 0, 386, 1413, 1, 0, 0, 0, 388, 1417, 1, 0, 0, 0, 390, 1421, 1, 0, 0, 0, 392, 1427, 1, 0, 0, 0, 394, 1433, 1, 0, 0, 0, 396, 1437, 1, 0, 0, 0, 398, 1441, 1, 0, 0, 0, 400, 1445, 1, 0, 0, 0, 402, 1451, 1, 0, 0, 0, 404, 1457, 1, 0, 0, 0, 406, 1463, 1, 0, 0, 0, 408, 409, 7, 0, 0, 0, 409, 410, 7, 1, 0, 0, 410, 411, 7, 2, 0, 0, 411, 412, 7, 2, 0, 0, 412, 413, 7, 3, 0, 0, 413, 414, 7, 4, 0, 0, 414, 415, 7, 5, 0, 0, 415, 416, 1, 0, 0, 0, 416, 417, 6, 0, 0, 0, 417, 17, 1, 0, 0, 0, 418, 419, 7, 0, 0, 0, 419, 420, 7, 6, 0, 0, 420, 421, 7, 7, 0, 0, 421, 422, 7, 8, 0, 0, 422, 423, 1, 0, 0, 0, 423, 424, 6, 1, 1, 0, 424, 19, 1, 0, 0, 0, 425, 426, 7, 3, 0, 0, 426, 427, 7, 9, 0, 0, 427, 428, 7, 6, 0, 0, 428, 429, 7, 1, 0, 0, 429, 430, 7, 4, 0, 0, 430, 431, 7, 10, 0, 0, 431, 432, 1, 0, 0, 0, 432, 433, 6, 2, 2, 0, 433, 21, 1, 0, 0, 0, 434, 435, 7, 3, 0, 0, 435, 436, 7, 11, 0, 0, 436, 437, 7, 12, 0, 0, 437, 438, 7, 13, 0, 0, 438, 439, 1, 0, 0, 0, 439, 440, 6, 3, 0, 0, 440, 23, 1, 0, 0, 0, 441, 442, 7, 3, 0, 0, 442, 443, 7, 14, 0, 0, 443, 444, 7, 8, 0, 0, 444, 445, 7, 13, 0, 0, 445, 446, 7, 12, 0, 0, 446, 447, 7, 1, 0, 0, 447, 448, 7, 9, 0, 0, 448, 449, 1, 0, 0, 0, 449, 450, 6, 4, 3, 0, 450, 25, 1, 0, 0, 0, 451, 452, 7, 15, 0, 0, 452, 453, 7, 6, 0, 0, 453, 454, 7, 7, 0, 0, 454, 455, 7, 16, 0, 0, 455, 456, 1, 0, 0, 0, 456, 457, 6, 5, 4, 0, 457, 27, 1, 0, 0, 0, 458, 459, 7, 17, 0, 0, 459, 460, 7, 6, 0, 0, 460, 461, 7, 7, 0, 0, 461, 462, 7, 18, 0, 0, 462, 463, 1, 0, 0, 0, 463, 464, 6, 6, 0, 0, 464, 29, 1, 0, 0, 0, 465, 466, 7, 1, 0, 0, 466, 467, 7, 9, 0, 0, 467, 468, 7, 13, 0, 0, 468, 469, 7, 1, 0, 0, 469, 470, 7, 9, 0, 0, 470, 471, 7, 3, 0, 0, 471, 472, 7, 2, 0, 0, 472, 473, 7, 5, 0, 0, 473, 474, 7, 12, 0, 0, 474, 475, 7, 5, 0, 0, 475, 476, 7, 2, 0, 0, 476, 477, 1, 0, 0, 0, 477, 478, 6, 7, 0, 0, 478, 31, 1, 0, 0, 0, 479, 480, 7, 18, 0, 0, 480, 481, 7, 3, 0, 0, 481, 482, 7, 3, 0, 0, 482, 483, 7, 8, 0, 0, 483, 484, 1, 0, 0, 0, 484, 485, 6, 8, 1, 0, 485, 33, 1, 0, 0, 0, 486, 487, 7, 13, 0, 0, 487, 488, 7, 1, 0, 0, 488, 489, 7, 16, 0, 0, 489, 490, 7, 1, 0, 0, 490, 491, 7, 5, 0, 0, 491, 492, 1, 0, 0, 0, 492, 493, 6, 9, 0, 0, 493, 35, 1, 0, 0, 0, 494, 495, 7, 13, 0, 0, 495, 496, 7, 7, 0, 0, 496, 497, 7, 7, 0, 0, 497, 498, 7, 18, 0, 0, 498, 499, 7, 19, 0, 0, 499, 500, 7, 8, 0, 0, 500, 501, 1, 0, 0, 0, 501, 502, 6, 10, 5, 0, 502, 37, 1, 0, 0, 0, 503, 504, 7, 16, 0, 0, 504, 505, 7, 3, 0, 0, 505, 506, 7, 5, 0, 0, 506, 507, 7, 12, 0, 0, 507, 508, 1, 0, 0, 0, 508, 509, 6, 11, 6, 0, 509, 39, 1, 0, 0, 0, 510, 511, 7, 16, 0, 0, 511, 512, 7, 3, 0, 0, 512, 513, 7, 5, 0, 0, 513, 514, 7, 6, 0, 0, 514, 515, 7, 1, 0, 0, 515, 516, 7, 4, 0, 0, 516, 517, 7, 2, 0, 0, 517, 518, 1, 0, 0, 0, 518, 519, 6, 12, 7, 0, 519, 41, 1, 0, 0, 0, 520, 521, 7, 16, 0, 0, 521, 522, 7, 11, 0, 0, 522, 523, 5, 95, 0, 0, 523, 524, 7, 3, 0, 0, 524, 525, 7, 14, 0, 0, 525, 526, 7, 8, 0, 0, 526, 527, 7, 12, 0, 0, 527, 528, 7, 9, 0, 0, 528, 529, 7, 0, 0, 0, 529, 530, 1, 0, 0, 0, 530, 531, 6, 13, 8, 0, 531, 43, 1, 0, 0, 0, 532, 533, 7, 6, 0, 0, 533, 534, 7, 3, 0, 0, 534, 535, 7, 9, 0, 0, 535, 536, 7, 12, 0, 0, 536, 537, 7, 16, 0, 0, 537, 538, 7, 3, 0, 0, 538, 539, 1, 0, 0, 0, 539, 540, 6, 14, 9, 0, 540, 45, 1, 0, 0, 0, 541, 542, 7, 6, 0, 0, 542, 543, 7, 7, 0, 0, 543, 544, 7, 20, 0, 0, 544, 545, 1, 0, 0, 0, 545, 546, 6, 15, 0, 0, 546, 47, 1, 0, 0, 0, 547, 548, 7, 2, 0, 0, 548, 549, 7, 10, 0, 0, 549, 550, 7, 7, 0, 0, 550, 551, 7, 20, 0, 0, 551, 552, 1, 0, 0, 0, 552, 553, 6, 16, 10, 0, 553, 49, 1, 0, 0, 0, 554, 555, 7, 2, 0, 0, 555, 556, 7, 7, 0, 0, 556, 557, 7, 6, 0, 0, 557, 558, 7, 5, 0, 0, 558, 559, 1, 0, 0, 0, 559, 560, 6, 17, 0, 0, 560, 51, 1, 0, 0, 0, 561, 562, 7, 2, 0, 0, 562, 563, 7, 5, 0, 0, 563, 564, 7, 12, 0, 0, 564, 565, 7, 5, 0, 0, 565, 566, 7, 2, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 6, 18, 0, 0, 568, 53, 1, 0, 0, 0, 569, 570, 7, 20, 0, 0, 570, 571, 7, 10, 0, 0, 571, 572, 7, 3, 0, 0, 572, 573, 7, 6, 0, 0, 573, 574, 7, 3, 0, 0, 574, 575, 1, 0, 0, 0, 575, 576, 6, 19, 0, 0, 576, 55, 1, 0, 0, 0, 577, 578, 7, 16, 0, 0, 578, 579, 7, 12, 0, 0, 579, 580, 7, 5, 0, 0, 580, 581, 7, 4, 0, 0, 581, 582, 7, 10, 0, 0, 582, 583, 1, 0, 0, 0, 583, 584, 6, 20, 0, 0, 584, 57, 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, 21, 0, 0, 591, 59, 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, 22, 11, 0, 608, 61, 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, 62, 23, 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, 23, 11, 0, 623, 63, 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, 24, 11, 0, 630, 65, 1, 0, 0, 0, 631, 635, 8, 24, 0, 0, 632, 633, 5, 47, 0, 0, 633, 635, 8, 25, 0, 0, 634, 631, 1, 0, 0, 0, 634, 632, 1, 0, 0, 0, 635, 67, 1, 0, 0, 0, 636, 638, 3, 66, 25, 0, 637, 636, 1, 0, 0, 0, 638, 639, 1, 0, 0, 0, 639, 637, 1, 0, 0, 0, 639, 640, 1, 0, 0, 0, 640, 69, 1, 0, 0, 0, 641, 642, 3, 182, 83, 0, 642, 643, 1, 0, 0, 0, 643, 644, 6, 27, 12, 0, 644, 645, 6, 27, 13, 0, 645, 71, 1, 0, 0, 0, 646, 647, 3, 80, 32, 0, 647, 648, 1, 0, 0, 0, 648, 649, 6, 28, 14, 0, 649, 650, 6, 28, 15, 0, 650, 73, 1, 0, 0, 0, 651, 652, 3, 64, 24, 0, 652, 653, 1, 0, 0, 0, 653, 654, 6, 29, 11, 0, 654, 75, 1, 0, 0, 0, 655, 656, 3, 60, 22, 0, 656, 657, 1, 0, 0, 0, 657, 658, 6, 30, 11, 0, 658, 77, 1, 0, 0, 0, 659, 660, 3, 62, 23, 0, 660, 661, 1, 0, 0, 0, 661, 662, 6, 31, 11, 0, 662, 79, 1, 0, 0, 0, 663, 664, 5, 124, 0, 0, 664, 665, 1, 0, 0, 0, 665, 666, 6, 32, 15, 0, 666, 81, 1, 0, 0, 0, 667, 668, 7, 26, 0, 0, 668, 83, 1, 0, 0, 0, 669, 670, 7, 27, 0, 0, 670, 85, 1, 0, 0, 0, 671, 672, 5, 92, 0, 0, 672, 673, 7, 28, 0, 0, 673, 87, 1, 0, 0, 0, 674, 675, 8, 29, 0, 0, 675, 89, 1, 0, 0, 0, 676, 678, 7, 3, 0, 0, 677, 679, 7, 30, 0, 0, 678, 677, 1, 0, 0, 0, 678, 679, 1, 0, 0, 0, 679, 681, 1, 0, 0, 0, 680, 682, 3, 82, 33, 0, 681, 680, 1, 0, 0, 0, 682, 683, 1, 0, 0, 0, 683, 681, 1, 0, 0, 0, 683, 684, 1, 0, 0, 0, 684, 91, 1, 0, 0, 0, 685, 686, 5, 64, 0, 0, 686, 93, 1, 0, 0, 0, 687, 688, 5, 96, 0, 0, 688, 95, 1, 0, 0, 0, 689, 693, 8, 31, 0, 0, 690, 691, 5, 96, 0, 0, 691, 693, 5, 96, 0, 0, 692, 689, 1, 0, 0, 0, 692, 690, 1, 0, 0, 0, 693, 97, 1, 0, 0, 0, 694, 695, 5, 95, 0, 0, 695, 99, 1, 0, 0, 0, 696, 700, 3, 84, 34, 0, 697, 700, 3, 82, 33, 0, 698, 700, 3, 98, 41, 0, 699, 696, 1, 0, 0, 0, 699, 697, 1, 0, 0, 0, 699, 698, 1, 0, 0, 0, 700, 101, 1, 0, 0, 0, 701, 706, 5, 34, 0, 0, 702, 705, 3, 86, 35, 0, 703, 705, 3, 88, 36, 0, 704, 702, 1, 0, 0, 0, 704, 703, 1, 0, 0, 0, 705, 708, 1, 0, 0, 0, 706, 704, 1, 0, 0, 0, 706, 707, 1, 0, 0, 0, 707, 709, 1, 0, 0, 0, 708, 706, 1, 0, 0, 0, 709, 731, 5, 34, 0, 0, 710, 711, 5, 34, 0, 0, 711, 712, 5, 34, 0, 0, 712, 713, 5, 34, 0, 0, 713, 717, 1, 0, 0, 0, 714, 716, 8, 22, 0, 0, 715, 714, 1, 0, 0, 0, 716, 719, 1, 0, 0, 0, 717, 718, 1, 0, 0, 0, 717, 715, 1, 0, 0, 0, 718, 720, 1, 0, 0, 0, 719, 717, 1, 0, 0, 0, 720, 721, 5, 34, 0, 0, 721, 722, 5, 34, 0, 0, 722, 723, 5, 34, 0, 0, 723, 725, 1, 0, 0, 0, 724, 726, 5, 34, 0, 0, 725, 724, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 728, 1, 0, 0, 0, 727, 729, 5, 34, 0, 0, 728, 727, 1, 0, 0, 0, 728, 729, 1, 0, 0, 0, 729, 731, 1, 0, 0, 0, 730, 701, 1, 0, 0, 0, 730, 710, 1, 0, 0, 0, 731, 103, 1, 0, 0, 0, 732, 734, 3, 82, 33, 0, 733, 732, 1, 0, 0, 0, 734, 735, 1, 0, 0, 0, 735, 733, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 105, 1, 0, 0, 0, 737, 739, 3, 82, 33, 0, 738, 737, 1, 0, 0, 0, 739, 740, 1, 0, 0, 0, 740, 738, 1, 0, 0, 0, 740, 741, 1, 0, 0, 0, 741, 742, 1, 0, 0, 0, 742, 746, 3, 122, 53, 0, 743, 745, 3, 82, 33, 0, 744, 743, 1, 0, 0, 0, 745, 748, 1, 0, 0, 0, 746, 744, 1, 0, 0, 0, 746, 747, 1, 0, 0, 0, 747, 780, 1, 0, 0, 0, 748, 746, 1, 0, 0, 0, 749, 751, 3, 122, 53, 0, 750, 752, 3, 82, 33, 0, 751, 750, 1, 0, 0, 0, 752, 753, 1, 0, 0, 0, 753, 751, 1, 0, 0, 0, 753, 754, 1, 0, 0, 0, 754, 780, 1, 0, 0, 0, 755, 757, 3, 82, 33, 0, 756, 755, 1, 0, 0, 0, 757, 758, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 758, 759, 1, 0, 0, 0, 759, 767, 1, 0, 0, 0, 760, 764, 3, 122, 53, 0, 761, 763, 3, 82, 33, 0, 762, 761, 1, 0, 0, 0, 763, 766, 1, 0, 0, 0, 764, 762, 1, 0, 0, 0, 764, 765, 1, 0, 0, 0, 765, 768, 1, 0, 0, 0, 766, 764, 1, 0, 0, 0, 767, 760, 1, 0, 0, 0, 767, 768, 1, 0, 0, 0, 768, 769, 1, 0, 0, 0, 769, 770, 3, 90, 37, 0, 770, 780, 1, 0, 0, 0, 771, 773, 3, 122, 53, 0, 772, 774, 3, 82, 33, 0, 773, 772, 1, 0, 0, 0, 774, 775, 1, 0, 0, 0, 775, 773, 1, 0, 0, 0, 775, 776, 1, 0, 0, 0, 776, 777, 1, 0, 0, 0, 777, 778, 3, 90, 37, 0, 778, 780, 1, 0, 0, 0, 779, 738, 1, 0, 0, 0, 779, 749, 1, 0, 0, 0, 779, 756, 1, 0, 0, 0, 779, 771, 1, 0, 0, 0, 780, 107, 1, 0, 0, 0, 781, 782, 7, 32, 0, 0, 782, 783, 7, 33, 0, 0, 783, 109, 1, 0, 0, 0, 784, 785, 7, 12, 0, 0, 785, 786, 7, 9, 0, 0, 786, 787, 7, 0, 0, 0, 787, 111, 1, 0, 0, 0, 788, 789, 7, 12, 0, 0, 789, 790, 7, 2, 0, 0, 790, 791, 7, 4, 0, 0, 791, 113, 1, 0, 0, 0, 792, 793, 5, 61, 0, 0, 793, 115, 1, 0, 0, 0, 794, 795, 5, 58, 0, 0, 795, 796, 5, 58, 0, 0, 796, 117, 1, 0, 0, 0, 797, 798, 5, 44, 0, 0, 798, 119, 1, 0, 0, 0, 799, 800, 7, 0, 0, 0, 800, 801, 7, 3, 0, 0, 801, 802, 7, 2, 0, 0, 802, 803, 7, 4, 0, 0, 803, 121, 1, 0, 0, 0, 804, 805, 5, 46, 0, 0, 805, 123, 1, 0, 0, 0, 806, 807, 7, 15, 0, 0, 807, 808, 7, 12, 0, 0, 808, 809, 7, 13, 0, 0, 809, 810, 7, 2, 0, 0, 810, 811, 7, 3, 0, 0, 811, 125, 1, 0, 0, 0, 812, 813, 7, 15, 0, 0, 813, 814, 7, 1, 0, 0, 814, 815, 7, 6, 0, 0, 815, 816, 7, 2, 0, 0, 816, 817, 7, 5, 0, 0, 817, 127, 1, 0, 0, 0, 818, 819, 7, 1, 0, 0, 819, 820, 7, 9, 0, 0, 820, 129, 1, 0, 0, 0, 821, 822, 7, 1, 0, 0, 822, 823, 7, 2, 0, 0, 823, 131, 1, 0, 0, 0, 824, 825, 7, 13, 0, 0, 825, 826, 7, 12, 0, 0, 826, 827, 7, 2, 0, 0, 827, 828, 7, 5, 0, 0, 828, 133, 1, 0, 0, 0, 829, 830, 7, 13, 0, 0, 830, 831, 7, 1, 0, 0, 831, 832, 7, 18, 0, 0, 832, 833, 7, 3, 0, 0, 833, 135, 1, 0, 0, 0, 834, 835, 5, 40, 0, 0, 835, 137, 1, 0, 0, 0, 836, 837, 7, 16, 0, 0, 837, 838, 7, 12, 0, 0, 838, 839, 7, 5, 0, 0, 839, 840, 7, 4, 0, 0, 840, 841, 7, 10, 0, 0, 841, 139, 1, 0, 0, 0, 842, 843, 7, 9, 0, 0, 843, 844, 7, 7, 0, 0, 844, 845, 7, 5, 0, 0, 845, 141, 1, 0, 0, 0, 846, 847, 7, 9, 0, 0, 847, 848, 7, 19, 0, 0, 848, 849, 7, 13, 0, 0, 849, 850, 7, 13, 0, 0, 850, 143, 1, 0, 0, 0, 851, 852, 7, 9, 0, 0, 852, 853, 7, 19, 0, 0, 853, 854, 7, 13, 0, 0, 854, 855, 7, 13, 0, 0, 855, 856, 7, 2, 0, 0, 856, 145, 1, 0, 0, 0, 857, 858, 7, 7, 0, 0, 858, 859, 7, 6, 0, 0, 859, 147, 1, 0, 0, 0, 860, 861, 5, 63, 0, 0, 861, 149, 1, 0, 0, 0, 862, 863, 7, 6, 0, 0, 863, 864, 7, 13, 0, 0, 864, 865, 7, 1, 0, 0, 865, 866, 7, 18, 0, 0, 866, 867, 7, 3, 0, 0, 867, 151, 1, 0, 0, 0, 868, 869, 5, 41, 0, 0, 869, 153, 1, 0, 0, 0, 870, 871, 7, 5, 0, 0, 871, 872, 7, 6, 0, 0, 872, 873, 7, 19, 0, 0, 873, 874, 7, 3, 0, 0, 874, 155, 1, 0, 0, 0, 875, 876, 5, 61, 0, 0, 876, 877, 5, 61, 0, 0, 877, 157, 1, 0, 0, 0, 878, 879, 5, 61, 0, 0, 879, 880, 5, 126, 0, 0, 880, 159, 1, 0, 0, 0, 881, 882, 5, 33, 0, 0, 882, 883, 5, 61, 0, 0, 883, 161, 1, 0, 0, 0, 884, 885, 5, 60, 0, 0, 885, 163, 1, 0, 0, 0, 886, 887, 5, 60, 0, 0, 887, 888, 5, 61, 0, 0, 888, 165, 1, 0, 0, 0, 889, 890, 5, 62, 0, 0, 890, 167, 1, 0, 0, 0, 891, 892, 5, 62, 0, 0, 892, 893, 5, 61, 0, 0, 893, 169, 1, 0, 0, 0, 894, 895, 5, 43, 0, 0, 895, 171, 1, 0, 0, 0, 896, 897, 5, 45, 0, 0, 897, 173, 1, 0, 0, 0, 898, 899, 5, 42, 0, 0, 899, 175, 1, 0, 0, 0, 900, 901, 5, 47, 0, 0, 901, 177, 1, 0, 0, 0, 902, 903, 5, 37, 0, 0, 903, 179, 1, 0, 0, 0, 904, 905, 3, 148, 66, 0, 905, 909, 3, 84, 34, 0, 906, 908, 3, 100, 42, 0, 907, 906, 1, 0, 0, 0, 908, 911, 1, 0, 0, 0, 909, 907, 1, 0, 0, 0, 909, 910, 1, 0, 0, 0, 910, 919, 1, 0, 0, 0, 911, 909, 1, 0, 0, 0, 912, 914, 3, 148, 66, 0, 913, 915, 3, 82, 33, 0, 914, 913, 1, 0, 0, 0, 915, 916, 1, 0, 0, 0, 916, 914, 1, 0, 0, 0, 916, 917, 1, 0, 0, 0, 917, 919, 1, 0, 0, 0, 918, 904, 1, 0, 0, 0, 918, 912, 1, 0, 0, 0, 919, 181, 1, 0, 0, 0, 920, 921, 5, 91, 0, 0, 921, 922, 1, 0, 0, 0, 922, 923, 6, 83, 0, 0, 923, 924, 6, 83, 0, 0, 924, 183, 1, 0, 0, 0, 925, 926, 5, 93, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 6, 84, 15, 0, 928, 929, 6, 84, 15, 0, 929, 185, 1, 0, 0, 0, 930, 934, 3, 84, 34, 0, 931, 933, 3, 100, 42, 0, 932, 931, 1, 0, 0, 0, 933, 936, 1, 0, 0, 0, 934, 932, 1, 0, 0, 0, 934, 935, 1, 0, 0, 0, 935, 947, 1, 0, 0, 0, 936, 934, 1, 0, 0, 0, 937, 940, 3, 98, 41, 0, 938, 940, 3, 92, 38, 0, 939, 937, 1, 0, 0, 0, 939, 938, 1, 0, 0, 0, 940, 942, 1, 0, 0, 0, 941, 943, 3, 100, 42, 0, 942, 941, 1, 0, 0, 0, 943, 944, 1, 0, 0, 0, 944, 942, 1, 0, 0, 0, 944, 945, 1, 0, 0, 0, 945, 947, 1, 0, 0, 0, 946, 930, 1, 0, 0, 0, 946, 939, 1, 0, 0, 0, 947, 187, 1, 0, 0, 0, 948, 950, 3, 94, 39, 0, 949, 951, 3, 96, 40, 0, 950, 949, 1, 0, 0, 0, 951, 952, 1, 0, 0, 0, 952, 950, 1, 0, 0, 0, 952, 953, 1, 0, 0, 0, 953, 954, 1, 0, 0, 0, 954, 955, 3, 94, 39, 0, 955, 189, 1, 0, 0, 0, 956, 957, 3, 188, 86, 0, 957, 191, 1, 0, 0, 0, 958, 959, 3, 60, 22, 0, 959, 960, 1, 0, 0, 0, 960, 961, 6, 88, 11, 0, 961, 193, 1, 0, 0, 0, 962, 963, 3, 62, 23, 0, 963, 964, 1, 0, 0, 0, 964, 965, 6, 89, 11, 0, 965, 195, 1, 0, 0, 0, 966, 967, 3, 64, 24, 0, 967, 968, 1, 0, 0, 0, 968, 969, 6, 90, 11, 0, 969, 197, 1, 0, 0, 0, 970, 971, 3, 80, 32, 0, 971, 972, 1, 0, 0, 0, 972, 973, 6, 91, 14, 0, 973, 974, 6, 91, 15, 0, 974, 199, 1, 0, 0, 0, 975, 976, 3, 182, 83, 0, 976, 977, 1, 0, 0, 0, 977, 978, 6, 92, 12, 0, 978, 201, 1, 0, 0, 0, 979, 980, 3, 184, 84, 0, 980, 981, 1, 0, 0, 0, 981, 982, 6, 93, 16, 0, 982, 203, 1, 0, 0, 0, 983, 984, 3, 368, 176, 0, 984, 985, 1, 0, 0, 0, 985, 986, 6, 94, 17, 0, 986, 205, 1, 0, 0, 0, 987, 988, 3, 118, 51, 0, 988, 989, 1, 0, 0, 0, 989, 990, 6, 95, 18, 0, 990, 207, 1, 0, 0, 0, 991, 992, 3, 114, 49, 0, 992, 993, 1, 0, 0, 0, 993, 994, 6, 96, 19, 0, 994, 209, 1, 0, 0, 0, 995, 996, 7, 16, 0, 0, 996, 997, 7, 3, 0, 0, 997, 998, 7, 5, 0, 0, 998, 999, 7, 12, 0, 0, 999, 1000, 7, 0, 0, 0, 1000, 1001, 7, 12, 0, 0, 1001, 1002, 7, 5, 0, 0, 1002, 1003, 7, 12, 0, 0, 1003, 211, 1, 0, 0, 0, 1004, 1005, 3, 68, 26, 0, 1005, 1006, 1, 0, 0, 0, 1006, 1007, 6, 98, 20, 0, 1007, 213, 1, 0, 0, 0, 1008, 1009, 3, 102, 43, 0, 1009, 1010, 1, 0, 0, 0, 1010, 1011, 6, 99, 21, 0, 1011, 215, 1, 0, 0, 0, 1012, 1013, 3, 60, 22, 0, 1013, 1014, 1, 0, 0, 0, 1014, 1015, 6, 100, 11, 0, 1015, 217, 1, 0, 0, 0, 1016, 1017, 3, 62, 23, 0, 1017, 1018, 1, 0, 0, 0, 1018, 1019, 6, 101, 11, 0, 1019, 219, 1, 0, 0, 0, 1020, 1021, 3, 64, 24, 0, 1021, 1022, 1, 0, 0, 0, 1022, 1023, 6, 102, 11, 0, 1023, 221, 1, 0, 0, 0, 1024, 1025, 3, 80, 32, 0, 1025, 1026, 1, 0, 0, 0, 1026, 1027, 6, 103, 14, 0, 1027, 1028, 6, 103, 15, 0, 1028, 223, 1, 0, 0, 0, 1029, 1030, 3, 122, 53, 0, 1030, 1031, 1, 0, 0, 0, 1031, 1032, 6, 104, 22, 0, 1032, 225, 1, 0, 0, 0, 1033, 1034, 3, 118, 51, 0, 1034, 1035, 1, 0, 0, 0, 1035, 1036, 6, 105, 18, 0, 1036, 227, 1, 0, 0, 0, 1037, 1042, 3, 84, 34, 0, 1038, 1042, 3, 82, 33, 0, 1039, 1042, 3, 98, 41, 0, 1040, 1042, 3, 174, 79, 0, 1041, 1037, 1, 0, 0, 0, 1041, 1038, 1, 0, 0, 0, 1041, 1039, 1, 0, 0, 0, 1041, 1040, 1, 0, 0, 0, 1042, 229, 1, 0, 0, 0, 1043, 1046, 3, 84, 34, 0, 1044, 1046, 3, 174, 79, 0, 1045, 1043, 1, 0, 0, 0, 1045, 1044, 1, 0, 0, 0, 1046, 1050, 1, 0, 0, 0, 1047, 1049, 3, 228, 106, 0, 1048, 1047, 1, 0, 0, 0, 1049, 1052, 1, 0, 0, 0, 1050, 1048, 1, 0, 0, 0, 1050, 1051, 1, 0, 0, 0, 1051, 1063, 1, 0, 0, 0, 1052, 1050, 1, 0, 0, 0, 1053, 1056, 3, 98, 41, 0, 1054, 1056, 3, 92, 38, 0, 1055, 1053, 1, 0, 0, 0, 1055, 1054, 1, 0, 0, 0, 1056, 1058, 1, 0, 0, 0, 1057, 1059, 3, 228, 106, 0, 1058, 1057, 1, 0, 0, 0, 1059, 1060, 1, 0, 0, 0, 1060, 1058, 1, 0, 0, 0, 1060, 1061, 1, 0, 0, 0, 1061, 1063, 1, 0, 0, 0, 1062, 1045, 1, 0, 0, 0, 1062, 1055, 1, 0, 0, 0, 1063, 231, 1, 0, 0, 0, 1064, 1067, 3, 230, 107, 0, 1065, 1067, 3, 188, 86, 0, 1066, 1064, 1, 0, 0, 0, 1066, 1065, 1, 0, 0, 0, 1067, 1068, 1, 0, 0, 0, 1068, 1066, 1, 0, 0, 0, 1068, 1069, 1, 0, 0, 0, 1069, 233, 1, 0, 0, 0, 1070, 1071, 3, 60, 22, 0, 1071, 1072, 1, 0, 0, 0, 1072, 1073, 6, 109, 11, 0, 1073, 235, 1, 0, 0, 0, 1074, 1075, 3, 62, 23, 0, 1075, 1076, 1, 0, 0, 0, 1076, 1077, 6, 110, 11, 0, 1077, 237, 1, 0, 0, 0, 1078, 1079, 3, 64, 24, 0, 1079, 1080, 1, 0, 0, 0, 1080, 1081, 6, 111, 11, 0, 1081, 239, 1, 0, 0, 0, 1082, 1083, 3, 80, 32, 0, 1083, 1084, 1, 0, 0, 0, 1084, 1085, 6, 112, 14, 0, 1085, 1086, 6, 112, 15, 0, 1086, 241, 1, 0, 0, 0, 1087, 1088, 3, 114, 49, 0, 1088, 1089, 1, 0, 0, 0, 1089, 1090, 6, 113, 19, 0, 1090, 243, 1, 0, 0, 0, 1091, 1092, 3, 118, 51, 0, 1092, 1093, 1, 0, 0, 0, 1093, 1094, 6, 114, 18, 0, 1094, 245, 1, 0, 0, 0, 1095, 1096, 3, 122, 53, 0, 1096, 1097, 1, 0, 0, 0, 1097, 1098, 6, 115, 22, 0, 1098, 247, 1, 0, 0, 0, 1099, 1100, 7, 12, 0, 0, 1100, 1101, 7, 2, 0, 0, 1101, 249, 1, 0, 0, 0, 1102, 1103, 3, 232, 108, 0, 1103, 1104, 1, 0, 0, 0, 1104, 1105, 6, 117, 23, 0, 1105, 251, 1, 0, 0, 0, 1106, 1107, 3, 60, 22, 0, 1107, 1108, 1, 0, 0, 0, 1108, 1109, 6, 118, 11, 0, 1109, 253, 1, 0, 0, 0, 1110, 1111, 3, 62, 23, 0, 1111, 1112, 1, 0, 0, 0, 1112, 1113, 6, 119, 11, 0, 1113, 255, 1, 0, 0, 0, 1114, 1115, 3, 64, 24, 0, 1115, 1116, 1, 0, 0, 0, 1116, 1117, 6, 120, 11, 0, 1117, 257, 1, 0, 0, 0, 1118, 1119, 3, 80, 32, 0, 1119, 1120, 1, 0, 0, 0, 1120, 1121, 6, 121, 14, 0, 1121, 1122, 6, 121, 15, 0, 1122, 259, 1, 0, 0, 0, 1123, 1124, 3, 182, 83, 0, 1124, 1125, 1, 0, 0, 0, 1125, 1126, 6, 122, 12, 0, 1126, 1127, 6, 122, 24, 0, 1127, 261, 1, 0, 0, 0, 1128, 1129, 7, 7, 0, 0, 1129, 1130, 7, 9, 0, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1132, 6, 123, 25, 0, 1132, 263, 1, 0, 0, 0, 1133, 1134, 7, 20, 0, 0, 1134, 1135, 7, 1, 0, 0, 1135, 1136, 7, 5, 0, 0, 1136, 1137, 7, 10, 0, 0, 1137, 1138, 1, 0, 0, 0, 1138, 1139, 6, 124, 25, 0, 1139, 265, 1, 0, 0, 0, 1140, 1141, 8, 34, 0, 0, 1141, 267, 1, 0, 0, 0, 1142, 1144, 3, 266, 125, 0, 1143, 1142, 1, 0, 0, 0, 1144, 1145, 1, 0, 0, 0, 1145, 1143, 1, 0, 0, 0, 1145, 1146, 1, 0, 0, 0, 1146, 1147, 1, 0, 0, 0, 1147, 1148, 3, 368, 176, 0, 1148, 1150, 1, 0, 0, 0, 1149, 1143, 1, 0, 0, 0, 1149, 1150, 1, 0, 0, 0, 1150, 1152, 1, 0, 0, 0, 1151, 1153, 3, 266, 125, 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, 269, 1, 0, 0, 0, 1156, 1157, 3, 268, 126, 0, 1157, 1158, 1, 0, 0, 0, 1158, 1159, 6, 127, 26, 0, 1159, 271, 1, 0, 0, 0, 1160, 1161, 3, 60, 22, 0, 1161, 1162, 1, 0, 0, 0, 1162, 1163, 6, 128, 11, 0, 1163, 273, 1, 0, 0, 0, 1164, 1165, 3, 62, 23, 0, 1165, 1166, 1, 0, 0, 0, 1166, 1167, 6, 129, 11, 0, 1167, 275, 1, 0, 0, 0, 1168, 1169, 3, 64, 24, 0, 1169, 1170, 1, 0, 0, 0, 1170, 1171, 6, 130, 11, 0, 1171, 277, 1, 0, 0, 0, 1172, 1173, 3, 80, 32, 0, 1173, 1174, 1, 0, 0, 0, 1174, 1175, 6, 131, 14, 0, 1175, 1176, 6, 131, 15, 0, 1176, 1177, 6, 131, 15, 0, 1177, 279, 1, 0, 0, 0, 1178, 1179, 3, 114, 49, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 6, 132, 19, 0, 1181, 281, 1, 0, 0, 0, 1182, 1183, 3, 118, 51, 0, 1183, 1184, 1, 0, 0, 0, 1184, 1185, 6, 133, 18, 0, 1185, 283, 1, 0, 0, 0, 1186, 1187, 3, 122, 53, 0, 1187, 1188, 1, 0, 0, 0, 1188, 1189, 6, 134, 22, 0, 1189, 285, 1, 0, 0, 0, 1190, 1191, 3, 264, 124, 0, 1191, 1192, 1, 0, 0, 0, 1192, 1193, 6, 135, 27, 0, 1193, 287, 1, 0, 0, 0, 1194, 1195, 3, 232, 108, 0, 1195, 1196, 1, 0, 0, 0, 1196, 1197, 6, 136, 23, 0, 1197, 289, 1, 0, 0, 0, 1198, 1199, 3, 190, 87, 0, 1199, 1200, 1, 0, 0, 0, 1200, 1201, 6, 137, 28, 0, 1201, 291, 1, 0, 0, 0, 1202, 1203, 3, 60, 22, 0, 1203, 1204, 1, 0, 0, 0, 1204, 1205, 6, 138, 11, 0, 1205, 293, 1, 0, 0, 0, 1206, 1207, 3, 62, 23, 0, 1207, 1208, 1, 0, 0, 0, 1208, 1209, 6, 139, 11, 0, 1209, 295, 1, 0, 0, 0, 1210, 1211, 3, 64, 24, 0, 1211, 1212, 1, 0, 0, 0, 1212, 1213, 6, 140, 11, 0, 1213, 297, 1, 0, 0, 0, 1214, 1215, 3, 80, 32, 0, 1215, 1216, 1, 0, 0, 0, 1216, 1217, 6, 141, 14, 0, 1217, 1218, 6, 141, 15, 0, 1218, 299, 1, 0, 0, 0, 1219, 1220, 3, 368, 176, 0, 1220, 1221, 1, 0, 0, 0, 1221, 1222, 6, 142, 17, 0, 1222, 301, 1, 0, 0, 0, 1223, 1224, 3, 118, 51, 0, 1224, 1225, 1, 0, 0, 0, 1225, 1226, 6, 143, 18, 0, 1226, 303, 1, 0, 0, 0, 1227, 1228, 3, 122, 53, 0, 1228, 1229, 1, 0, 0, 0, 1229, 1230, 6, 144, 22, 0, 1230, 305, 1, 0, 0, 0, 1231, 1232, 3, 262, 123, 0, 1232, 1233, 1, 0, 0, 0, 1233, 1234, 6, 145, 29, 0, 1234, 1235, 6, 145, 30, 0, 1235, 307, 1, 0, 0, 0, 1236, 1237, 3, 68, 26, 0, 1237, 1238, 1, 0, 0, 0, 1238, 1239, 6, 146, 20, 0, 1239, 309, 1, 0, 0, 0, 1240, 1241, 3, 102, 43, 0, 1241, 1242, 1, 0, 0, 0, 1242, 1243, 6, 147, 21, 0, 1243, 311, 1, 0, 0, 0, 1244, 1245, 3, 60, 22, 0, 1245, 1246, 1, 0, 0, 0, 1246, 1247, 6, 148, 11, 0, 1247, 313, 1, 0, 0, 0, 1248, 1249, 3, 62, 23, 0, 1249, 1250, 1, 0, 0, 0, 1250, 1251, 6, 149, 11, 0, 1251, 315, 1, 0, 0, 0, 1252, 1253, 3, 64, 24, 0, 1253, 1254, 1, 0, 0, 0, 1254, 1255, 6, 150, 11, 0, 1255, 317, 1, 0, 0, 0, 1256, 1257, 3, 80, 32, 0, 1257, 1258, 1, 0, 0, 0, 1258, 1259, 6, 151, 14, 0, 1259, 1260, 6, 151, 15, 0, 1260, 1261, 6, 151, 15, 0, 1261, 319, 1, 0, 0, 0, 1262, 1263, 3, 118, 51, 0, 1263, 1264, 1, 0, 0, 0, 1264, 1265, 6, 152, 18, 0, 1265, 321, 1, 0, 0, 0, 1266, 1267, 3, 122, 53, 0, 1267, 1268, 1, 0, 0, 0, 1268, 1269, 6, 153, 22, 0, 1269, 323, 1, 0, 0, 0, 1270, 1271, 3, 232, 108, 0, 1271, 1272, 1, 0, 0, 0, 1272, 1273, 6, 154, 23, 0, 1273, 325, 1, 0, 0, 0, 1274, 1275, 3, 60, 22, 0, 1275, 1276, 1, 0, 0, 0, 1276, 1277, 6, 155, 11, 0, 1277, 327, 1, 0, 0, 0, 1278, 1279, 3, 62, 23, 0, 1279, 1280, 1, 0, 0, 0, 1280, 1281, 6, 156, 11, 0, 1281, 329, 1, 0, 0, 0, 1282, 1283, 3, 64, 24, 0, 1283, 1284, 1, 0, 0, 0, 1284, 1285, 6, 157, 11, 0, 1285, 331, 1, 0, 0, 0, 1286, 1287, 3, 80, 32, 0, 1287, 1288, 1, 0, 0, 0, 1288, 1289, 6, 158, 14, 0, 1289, 1290, 6, 158, 15, 0, 1290, 333, 1, 0, 0, 0, 1291, 1292, 3, 122, 53, 0, 1292, 1293, 1, 0, 0, 0, 1293, 1294, 6, 159, 22, 0, 1294, 335, 1, 0, 0, 0, 1295, 1296, 3, 190, 87, 0, 1296, 1297, 1, 0, 0, 0, 1297, 1298, 6, 160, 28, 0, 1298, 337, 1, 0, 0, 0, 1299, 1300, 3, 186, 85, 0, 1300, 1301, 1, 0, 0, 0, 1301, 1302, 6, 161, 31, 0, 1302, 339, 1, 0, 0, 0, 1303, 1304, 3, 60, 22, 0, 1304, 1305, 1, 0, 0, 0, 1305, 1306, 6, 162, 11, 0, 1306, 341, 1, 0, 0, 0, 1307, 1308, 3, 62, 23, 0, 1308, 1309, 1, 0, 0, 0, 1309, 1310, 6, 163, 11, 0, 1310, 343, 1, 0, 0, 0, 1311, 1312, 3, 64, 24, 0, 1312, 1313, 1, 0, 0, 0, 1313, 1314, 6, 164, 11, 0, 1314, 345, 1, 0, 0, 0, 1315, 1316, 3, 80, 32, 0, 1316, 1317, 1, 0, 0, 0, 1317, 1318, 6, 165, 14, 0, 1318, 1319, 6, 165, 15, 0, 1319, 347, 1, 0, 0, 0, 1320, 1321, 7, 1, 0, 0, 1321, 1322, 7, 9, 0, 0, 1322, 1323, 7, 15, 0, 0, 1323, 1324, 7, 7, 0, 0, 1324, 349, 1, 0, 0, 0, 1325, 1326, 3, 60, 22, 0, 1326, 1327, 1, 0, 0, 0, 1327, 1328, 6, 167, 11, 0, 1328, 351, 1, 0, 0, 0, 1329, 1330, 3, 62, 23, 0, 1330, 1331, 1, 0, 0, 0, 1331, 1332, 6, 168, 11, 0, 1332, 353, 1, 0, 0, 0, 1333, 1334, 3, 64, 24, 0, 1334, 1335, 1, 0, 0, 0, 1335, 1336, 6, 169, 11, 0, 1336, 355, 1, 0, 0, 0, 1337, 1338, 3, 80, 32, 0, 1338, 1339, 1, 0, 0, 0, 1339, 1340, 6, 170, 14, 0, 1340, 1341, 6, 170, 15, 0, 1341, 357, 1, 0, 0, 0, 1342, 1343, 7, 15, 0, 0, 1343, 1344, 7, 19, 0, 0, 1344, 1345, 7, 9, 0, 0, 1345, 1346, 7, 4, 0, 0, 1346, 1347, 7, 5, 0, 0, 1347, 1348, 7, 1, 0, 0, 1348, 1349, 7, 7, 0, 0, 1349, 1350, 7, 9, 0, 0, 1350, 1351, 7, 2, 0, 0, 1351, 359, 1, 0, 0, 0, 1352, 1353, 3, 60, 22, 0, 1353, 1354, 1, 0, 0, 0, 1354, 1355, 6, 172, 11, 0, 1355, 361, 1, 0, 0, 0, 1356, 1357, 3, 62, 23, 0, 1357, 1358, 1, 0, 0, 0, 1358, 1359, 6, 173, 11, 0, 1359, 363, 1, 0, 0, 0, 1360, 1361, 3, 64, 24, 0, 1361, 1362, 1, 0, 0, 0, 1362, 1363, 6, 174, 11, 0, 1363, 365, 1, 0, 0, 0, 1364, 1365, 3, 184, 84, 0, 1365, 1366, 1, 0, 0, 0, 1366, 1367, 6, 175, 16, 0, 1367, 1368, 6, 175, 15, 0, 1368, 367, 1, 0, 0, 0, 1369, 1370, 5, 58, 0, 0, 1370, 369, 1, 0, 0, 0, 1371, 1377, 3, 92, 38, 0, 1372, 1377, 3, 82, 33, 0, 1373, 1377, 3, 122, 53, 0, 1374, 1377, 3, 84, 34, 0, 1375, 1377, 3, 98, 41, 0, 1376, 1371, 1, 0, 0, 0, 1376, 1372, 1, 0, 0, 0, 1376, 1373, 1, 0, 0, 0, 1376, 1374, 1, 0, 0, 0, 1376, 1375, 1, 0, 0, 0, 1377, 1378, 1, 0, 0, 0, 1378, 1376, 1, 0, 0, 0, 1378, 1379, 1, 0, 0, 0, 1379, 371, 1, 0, 0, 0, 1380, 1381, 3, 60, 22, 0, 1381, 1382, 1, 0, 0, 0, 1382, 1383, 6, 178, 11, 0, 1383, 373, 1, 0, 0, 0, 1384, 1385, 3, 62, 23, 0, 1385, 1386, 1, 0, 0, 0, 1386, 1387, 6, 179, 11, 0, 1387, 375, 1, 0, 0, 0, 1388, 1389, 3, 64, 24, 0, 1389, 1390, 1, 0, 0, 0, 1390, 1391, 6, 180, 11, 0, 1391, 377, 1, 0, 0, 0, 1392, 1393, 3, 80, 32, 0, 1393, 1394, 1, 0, 0, 0, 1394, 1395, 6, 181, 14, 0, 1395, 1396, 6, 181, 15, 0, 1396, 379, 1, 0, 0, 0, 1397, 1398, 3, 68, 26, 0, 1398, 1399, 1, 0, 0, 0, 1399, 1400, 6, 182, 20, 0, 1400, 1401, 6, 182, 15, 0, 1401, 1402, 6, 182, 32, 0, 1402, 381, 1, 0, 0, 0, 1403, 1404, 3, 102, 43, 0, 1404, 1405, 1, 0, 0, 0, 1405, 1406, 6, 183, 21, 0, 1406, 1407, 6, 183, 15, 0, 1407, 1408, 6, 183, 32, 0, 1408, 383, 1, 0, 0, 0, 1409, 1410, 3, 60, 22, 0, 1410, 1411, 1, 0, 0, 0, 1411, 1412, 6, 184, 11, 0, 1412, 385, 1, 0, 0, 0, 1413, 1414, 3, 62, 23, 0, 1414, 1415, 1, 0, 0, 0, 1415, 1416, 6, 185, 11, 0, 1416, 387, 1, 0, 0, 0, 1417, 1418, 3, 64, 24, 0, 1418, 1419, 1, 0, 0, 0, 1419, 1420, 6, 186, 11, 0, 1420, 389, 1, 0, 0, 0, 1421, 1422, 3, 368, 176, 0, 1422, 1423, 1, 0, 0, 0, 1423, 1424, 6, 187, 17, 0, 1424, 1425, 6, 187, 15, 0, 1425, 1426, 6, 187, 7, 0, 1426, 391, 1, 0, 0, 0, 1427, 1428, 3, 118, 51, 0, 1428, 1429, 1, 0, 0, 0, 1429, 1430, 6, 188, 18, 0, 1430, 1431, 6, 188, 15, 0, 1431, 1432, 6, 188, 7, 0, 1432, 393, 1, 0, 0, 0, 1433, 1434, 3, 60, 22, 0, 1434, 1435, 1, 0, 0, 0, 1435, 1436, 6, 189, 11, 0, 1436, 395, 1, 0, 0, 0, 1437, 1438, 3, 62, 23, 0, 1438, 1439, 1, 0, 0, 0, 1439, 1440, 6, 190, 11, 0, 1440, 397, 1, 0, 0, 0, 1441, 1442, 3, 64, 24, 0, 1442, 1443, 1, 0, 0, 0, 1443, 1444, 6, 191, 11, 0, 1444, 399, 1, 0, 0, 0, 1445, 1446, 3, 190, 87, 0, 1446, 1447, 1, 0, 0, 0, 1447, 1448, 6, 192, 15, 0, 1448, 1449, 6, 192, 0, 0, 1449, 1450, 6, 192, 28, 0, 1450, 401, 1, 0, 0, 0, 1451, 1452, 3, 186, 85, 0, 1452, 1453, 1, 0, 0, 0, 1453, 1454, 6, 193, 15, 0, 1454, 1455, 6, 193, 0, 0, 1455, 1456, 6, 193, 31, 0, 1456, 403, 1, 0, 0, 0, 1457, 1458, 3, 108, 46, 0, 1458, 1459, 1, 0, 0, 0, 1459, 1460, 6, 194, 15, 0, 1460, 1461, 6, 194, 0, 0, 1461, 1462, 6, 194, 33, 0, 1462, 405, 1, 0, 0, 0, 1463, 1464, 3, 80, 32, 0, 1464, 1465, 1, 0, 0, 0, 1465, 1466, 6, 195, 14, 0, 1466, 1467, 6, 195, 15, 0, 1467, 407, 1, 0, 0, 0, 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 588, 598, 602, 605, 614, 616, 627, 634, 639, 678, 683, 692, 699, 704, 706, 717, 725, 728, 730, 735, 740, 746, 753, 758, 764, 767, 775, 779, 909, 916, 918, 934, 939, 944, 946, 952, 1041, 1045, 1050, 1055, 1060, 1062, 1066, 1068, 1145, 1149, 1154, 1376, 1378, 34, 5, 2, 0, 5, 4, 0, 5, 6, 0, 5, 1, 0, 5, 3, 0, 5, 8, 0, 5, 12, 0, 5, 14, 0, 5, 10, 0, 5, 5, 0, 5, 11, 0, 0, 1, 0, 7, 71, 0, 5, 0, 0, 7, 30, 0, 4, 0, 0, 7, 72, 0, 7, 116, 0, 7, 39, 0, 7, 37, 0, 7, 26, 0, 7, 31, 0, 7, 41, 0, 7, 82, 0, 5, 13, 0, 5, 7, 0, 7, 92, 0, 7, 91, 0, 7, 74, 0, 7, 90, 0, 5, 9, 0, 7, 73, 0, 5, 15, 0, 7, 34, 0] \ No newline at end of file +[4, 0, 125, 1474, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 2, 138, 7, 138, 2, 139, 7, 139, 2, 140, 7, 140, 2, 141, 7, 141, 2, 142, 7, 142, 2, 143, 7, 143, 2, 144, 7, 144, 2, 145, 7, 145, 2, 146, 7, 146, 2, 147, 7, 147, 2, 148, 7, 148, 2, 149, 7, 149, 2, 150, 7, 150, 2, 151, 7, 151, 2, 152, 7, 152, 2, 153, 7, 153, 2, 154, 7, 154, 2, 155, 7, 155, 2, 156, 7, 156, 2, 157, 7, 157, 2, 158, 7, 158, 2, 159, 7, 159, 2, 160, 7, 160, 2, 161, 7, 161, 2, 162, 7, 162, 2, 163, 7, 163, 2, 164, 7, 164, 2, 165, 7, 165, 2, 166, 7, 166, 2, 167, 7, 167, 2, 168, 7, 168, 2, 169, 7, 169, 2, 170, 7, 170, 2, 171, 7, 171, 2, 172, 7, 172, 2, 173, 7, 173, 2, 174, 7, 174, 2, 175, 7, 175, 2, 176, 7, 176, 2, 177, 7, 177, 2, 178, 7, 178, 2, 179, 7, 179, 2, 180, 7, 180, 2, 181, 7, 181, 2, 182, 7, 182, 2, 183, 7, 183, 2, 184, 7, 184, 2, 185, 7, 185, 2, 186, 7, 186, 2, 187, 7, 187, 2, 188, 7, 188, 2, 189, 7, 189, 2, 190, 7, 190, 2, 191, 7, 191, 2, 192, 7, 192, 2, 193, 7, 193, 2, 194, 7, 194, 2, 195, 7, 195, 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, 10, 1, 10, 1, 10, 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, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 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, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 4, 21, 591, 8, 21, 11, 21, 12, 21, 592, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 5, 22, 601, 8, 22, 10, 22, 12, 22, 604, 9, 22, 1, 22, 3, 22, 607, 8, 22, 1, 22, 3, 22, 610, 8, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 619, 8, 23, 10, 23, 12, 23, 622, 9, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 4, 24, 630, 8, 24, 11, 24, 12, 24, 631, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 3, 30, 651, 8, 30, 1, 30, 4, 30, 654, 8, 30, 11, 30, 12, 30, 655, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 3, 33, 665, 8, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 3, 35, 672, 8, 35, 1, 36, 1, 36, 1, 36, 5, 36, 677, 8, 36, 10, 36, 12, 36, 680, 9, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 688, 8, 36, 10, 36, 12, 36, 691, 9, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 698, 8, 36, 1, 36, 3, 36, 701, 8, 36, 3, 36, 703, 8, 36, 1, 37, 4, 37, 706, 8, 37, 11, 37, 12, 37, 707, 1, 38, 4, 38, 711, 8, 38, 11, 38, 12, 38, 712, 1, 38, 1, 38, 5, 38, 717, 8, 38, 10, 38, 12, 38, 720, 9, 38, 1, 38, 1, 38, 4, 38, 724, 8, 38, 11, 38, 12, 38, 725, 1, 38, 4, 38, 729, 8, 38, 11, 38, 12, 38, 730, 1, 38, 1, 38, 5, 38, 735, 8, 38, 10, 38, 12, 38, 738, 9, 38, 3, 38, 740, 8, 38, 1, 38, 1, 38, 1, 38, 1, 38, 4, 38, 746, 8, 38, 11, 38, 12, 38, 747, 1, 38, 1, 38, 3, 38, 752, 8, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 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, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 3, 75, 879, 8, 75, 1, 75, 5, 75, 882, 8, 75, 10, 75, 12, 75, 885, 9, 75, 1, 75, 1, 75, 4, 75, 889, 8, 75, 11, 75, 12, 75, 890, 3, 75, 893, 8, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 5, 78, 907, 8, 78, 10, 78, 12, 78, 910, 9, 78, 1, 78, 1, 78, 3, 78, 914, 8, 78, 1, 78, 4, 78, 917, 8, 78, 11, 78, 12, 78, 918, 3, 78, 921, 8, 78, 1, 79, 1, 79, 4, 79, 925, 8, 79, 11, 79, 12, 79, 926, 1, 79, 1, 79, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 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, 89, 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, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 3, 96, 1004, 8, 96, 1, 97, 4, 97, 1007, 8, 97, 11, 97, 12, 97, 1008, 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, 103, 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, 1048, 8, 106, 1, 107, 1, 107, 3, 107, 1052, 8, 107, 1, 107, 5, 107, 1055, 8, 107, 10, 107, 12, 107, 1058, 9, 107, 1, 107, 1, 107, 3, 107, 1062, 8, 107, 1, 107, 4, 107, 1065, 8, 107, 11, 107, 12, 107, 1066, 3, 107, 1069, 8, 107, 1, 108, 1, 108, 4, 108, 1073, 8, 108, 11, 108, 12, 108, 1074, 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, 117, 1, 117, 1, 117, 1, 117, 1, 118, 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, 121, 1, 122, 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, 124, 1, 124, 1, 125, 1, 125, 1, 126, 4, 126, 1150, 8, 126, 11, 126, 12, 126, 1151, 1, 126, 1, 126, 3, 126, 1156, 8, 126, 1, 126, 4, 126, 1159, 8, 126, 11, 126, 12, 126, 1160, 1, 127, 1, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 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, 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, 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, 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, 147, 1, 147, 1, 147, 1, 147, 1, 148, 1, 148, 1, 148, 1, 148, 1, 148, 1, 149, 1, 149, 1, 149, 1, 149, 1, 149, 1, 150, 1, 150, 1, 150, 1, 150, 1, 151, 1, 151, 1, 151, 1, 151, 1, 152, 1, 152, 1, 152, 1, 152, 1, 153, 1, 153, 1, 153, 1, 153, 1, 153, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 154, 1, 155, 1, 155, 1, 155, 1, 155, 1, 156, 1, 156, 1, 156, 1, 156, 1, 157, 1, 157, 1, 157, 1, 157, 1, 158, 1, 158, 1, 158, 1, 158, 1, 158, 1, 159, 1, 159, 1, 160, 1, 160, 1, 160, 1, 160, 1, 160, 4, 160, 1311, 8, 160, 11, 160, 12, 160, 1312, 1, 161, 1, 161, 1, 161, 1, 161, 1, 162, 1, 162, 1, 162, 1, 162, 1, 163, 1, 163, 1, 163, 1, 163, 1, 164, 1, 164, 1, 164, 1, 164, 1, 164, 1, 165, 1, 165, 1, 165, 1, 165, 1, 166, 1, 166, 1, 166, 1, 166, 1, 167, 1, 167, 1, 167, 1, 167, 1, 168, 1, 168, 1, 168, 1, 168, 1, 168, 1, 169, 1, 169, 1, 169, 1, 169, 1, 170, 1, 170, 1, 170, 1, 170, 1, 171, 1, 171, 1, 171, 1, 171, 1, 172, 1, 172, 1, 172, 1, 172, 1, 173, 1, 173, 1, 173, 1, 173, 1, 174, 1, 174, 1, 174, 1, 174, 1, 174, 1, 174, 1, 175, 1, 175, 1, 175, 1, 175, 1, 176, 1, 176, 1, 176, 1, 176, 1, 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, 181, 1, 182, 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, 185, 1, 185, 1, 185, 1, 185, 1, 186, 1, 186, 1, 186, 1, 186, 1, 187, 1, 187, 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, 190, 1, 190, 1, 190, 1, 190, 1, 191, 1, 191, 1, 191, 1, 191, 1, 192, 1, 192, 1, 192, 1, 192, 1, 192, 1, 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, 2, 620, 689, 0, 196, 16, 1, 18, 2, 20, 3, 22, 4, 24, 5, 26, 6, 28, 7, 30, 8, 32, 9, 34, 10, 36, 11, 38, 12, 40, 13, 42, 14, 44, 15, 46, 16, 48, 17, 50, 18, 52, 19, 54, 20, 56, 21, 58, 22, 60, 23, 62, 24, 64, 25, 66, 26, 68, 0, 70, 0, 72, 0, 74, 0, 76, 0, 78, 0, 80, 0, 82, 0, 84, 0, 86, 0, 88, 27, 90, 28, 92, 29, 94, 30, 96, 31, 98, 32, 100, 33, 102, 34, 104, 35, 106, 36, 108, 37, 110, 38, 112, 39, 114, 40, 116, 41, 118, 42, 120, 43, 122, 44, 124, 45, 126, 46, 128, 47, 130, 48, 132, 49, 134, 50, 136, 51, 138, 52, 140, 53, 142, 54, 144, 55, 146, 56, 148, 57, 150, 58, 152, 59, 154, 60, 156, 61, 158, 62, 160, 63, 162, 64, 164, 0, 166, 65, 168, 66, 170, 67, 172, 68, 174, 0, 176, 69, 178, 70, 180, 71, 182, 72, 184, 0, 186, 0, 188, 73, 190, 74, 192, 75, 194, 0, 196, 0, 198, 0, 200, 0, 202, 0, 204, 0, 206, 76, 208, 0, 210, 77, 212, 0, 214, 0, 216, 78, 218, 79, 220, 80, 222, 0, 224, 0, 226, 0, 228, 0, 230, 0, 232, 81, 234, 82, 236, 83, 238, 84, 240, 0, 242, 0, 244, 0, 246, 0, 248, 85, 250, 0, 252, 86, 254, 87, 256, 88, 258, 0, 260, 0, 262, 89, 264, 90, 266, 0, 268, 91, 270, 0, 272, 92, 274, 93, 276, 94, 278, 0, 280, 0, 282, 0, 284, 0, 286, 0, 288, 0, 290, 0, 292, 95, 294, 96, 296, 97, 298, 0, 300, 0, 302, 0, 304, 0, 306, 98, 308, 99, 310, 100, 312, 0, 314, 101, 316, 102, 318, 103, 320, 104, 322, 0, 324, 105, 326, 106, 328, 107, 330, 108, 332, 0, 334, 109, 336, 110, 338, 111, 340, 112, 342, 113, 344, 0, 346, 0, 348, 0, 350, 0, 352, 0, 354, 0, 356, 0, 358, 114, 360, 115, 362, 116, 364, 0, 366, 0, 368, 0, 370, 0, 372, 117, 374, 118, 376, 119, 378, 0, 380, 0, 382, 0, 384, 120, 386, 121, 388, 122, 390, 0, 392, 0, 394, 123, 396, 124, 398, 125, 400, 0, 402, 0, 404, 0, 406, 0, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 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, 1501, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 0, 40, 1, 0, 0, 0, 0, 42, 1, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 46, 1, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 50, 1, 0, 0, 0, 0, 52, 1, 0, 0, 0, 0, 54, 1, 0, 0, 0, 0, 56, 1, 0, 0, 0, 0, 58, 1, 0, 0, 0, 0, 60, 1, 0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 64, 1, 0, 0, 0, 1, 66, 1, 0, 0, 0, 1, 88, 1, 0, 0, 0, 1, 90, 1, 0, 0, 0, 1, 92, 1, 0, 0, 0, 1, 94, 1, 0, 0, 0, 1, 96, 1, 0, 0, 0, 1, 98, 1, 0, 0, 0, 1, 100, 1, 0, 0, 0, 1, 102, 1, 0, 0, 0, 1, 104, 1, 0, 0, 0, 1, 106, 1, 0, 0, 0, 1, 108, 1, 0, 0, 0, 1, 110, 1, 0, 0, 0, 1, 112, 1, 0, 0, 0, 1, 114, 1, 0, 0, 0, 1, 116, 1, 0, 0, 0, 1, 118, 1, 0, 0, 0, 1, 120, 1, 0, 0, 0, 1, 122, 1, 0, 0, 0, 1, 124, 1, 0, 0, 0, 1, 126, 1, 0, 0, 0, 1, 128, 1, 0, 0, 0, 1, 130, 1, 0, 0, 0, 1, 132, 1, 0, 0, 0, 1, 134, 1, 0, 0, 0, 1, 136, 1, 0, 0, 0, 1, 138, 1, 0, 0, 0, 1, 140, 1, 0, 0, 0, 1, 142, 1, 0, 0, 0, 1, 144, 1, 0, 0, 0, 1, 146, 1, 0, 0, 0, 1, 148, 1, 0, 0, 0, 1, 150, 1, 0, 0, 0, 1, 152, 1, 0, 0, 0, 1, 154, 1, 0, 0, 0, 1, 156, 1, 0, 0, 0, 1, 158, 1, 0, 0, 0, 1, 160, 1, 0, 0, 0, 1, 162, 1, 0, 0, 0, 1, 164, 1, 0, 0, 0, 1, 166, 1, 0, 0, 0, 1, 168, 1, 0, 0, 0, 1, 170, 1, 0, 0, 0, 1, 172, 1, 0, 0, 0, 1, 176, 1, 0, 0, 0, 1, 178, 1, 0, 0, 0, 1, 180, 1, 0, 0, 0, 1, 182, 1, 0, 0, 0, 2, 184, 1, 0, 0, 0, 2, 186, 1, 0, 0, 0, 2, 188, 1, 0, 0, 0, 2, 190, 1, 0, 0, 0, 2, 192, 1, 0, 0, 0, 3, 194, 1, 0, 0, 0, 3, 196, 1, 0, 0, 0, 3, 198, 1, 0, 0, 0, 3, 200, 1, 0, 0, 0, 3, 202, 1, 0, 0, 0, 3, 204, 1, 0, 0, 0, 3, 206, 1, 0, 0, 0, 3, 210, 1, 0, 0, 0, 3, 212, 1, 0, 0, 0, 3, 214, 1, 0, 0, 0, 3, 216, 1, 0, 0, 0, 3, 218, 1, 0, 0, 0, 3, 220, 1, 0, 0, 0, 4, 222, 1, 0, 0, 0, 4, 224, 1, 0, 0, 0, 4, 226, 1, 0, 0, 0, 4, 232, 1, 0, 0, 0, 4, 234, 1, 0, 0, 0, 4, 236, 1, 0, 0, 0, 4, 238, 1, 0, 0, 0, 5, 240, 1, 0, 0, 0, 5, 242, 1, 0, 0, 0, 5, 244, 1, 0, 0, 0, 5, 246, 1, 0, 0, 0, 5, 248, 1, 0, 0, 0, 5, 250, 1, 0, 0, 0, 5, 252, 1, 0, 0, 0, 5, 254, 1, 0, 0, 0, 5, 256, 1, 0, 0, 0, 6, 258, 1, 0, 0, 0, 6, 260, 1, 0, 0, 0, 6, 262, 1, 0, 0, 0, 6, 264, 1, 0, 0, 0, 6, 268, 1, 0, 0, 0, 6, 270, 1, 0, 0, 0, 6, 272, 1, 0, 0, 0, 6, 274, 1, 0, 0, 0, 6, 276, 1, 0, 0, 0, 7, 278, 1, 0, 0, 0, 7, 280, 1, 0, 0, 0, 7, 282, 1, 0, 0, 0, 7, 284, 1, 0, 0, 0, 7, 286, 1, 0, 0, 0, 7, 288, 1, 0, 0, 0, 7, 290, 1, 0, 0, 0, 7, 292, 1, 0, 0, 0, 7, 294, 1, 0, 0, 0, 7, 296, 1, 0, 0, 0, 8, 298, 1, 0, 0, 0, 8, 300, 1, 0, 0, 0, 8, 302, 1, 0, 0, 0, 8, 304, 1, 0, 0, 0, 8, 306, 1, 0, 0, 0, 8, 308, 1, 0, 0, 0, 8, 310, 1, 0, 0, 0, 9, 312, 1, 0, 0, 0, 9, 314, 1, 0, 0, 0, 9, 316, 1, 0, 0, 0, 9, 318, 1, 0, 0, 0, 9, 320, 1, 0, 0, 0, 10, 322, 1, 0, 0, 0, 10, 324, 1, 0, 0, 0, 10, 326, 1, 0, 0, 0, 10, 328, 1, 0, 0, 0, 10, 330, 1, 0, 0, 0, 11, 332, 1, 0, 0, 0, 11, 334, 1, 0, 0, 0, 11, 336, 1, 0, 0, 0, 11, 338, 1, 0, 0, 0, 11, 340, 1, 0, 0, 0, 11, 342, 1, 0, 0, 0, 12, 344, 1, 0, 0, 0, 12, 346, 1, 0, 0, 0, 12, 348, 1, 0, 0, 0, 12, 350, 1, 0, 0, 0, 12, 352, 1, 0, 0, 0, 12, 354, 1, 0, 0, 0, 12, 356, 1, 0, 0, 0, 12, 358, 1, 0, 0, 0, 12, 360, 1, 0, 0, 0, 12, 362, 1, 0, 0, 0, 13, 364, 1, 0, 0, 0, 13, 366, 1, 0, 0, 0, 13, 368, 1, 0, 0, 0, 13, 370, 1, 0, 0, 0, 13, 372, 1, 0, 0, 0, 13, 374, 1, 0, 0, 0, 13, 376, 1, 0, 0, 0, 14, 378, 1, 0, 0, 0, 14, 380, 1, 0, 0, 0, 14, 382, 1, 0, 0, 0, 14, 384, 1, 0, 0, 0, 14, 386, 1, 0, 0, 0, 14, 388, 1, 0, 0, 0, 15, 390, 1, 0, 0, 0, 15, 392, 1, 0, 0, 0, 15, 394, 1, 0, 0, 0, 15, 396, 1, 0, 0, 0, 15, 398, 1, 0, 0, 0, 15, 400, 1, 0, 0, 0, 15, 402, 1, 0, 0, 0, 15, 404, 1, 0, 0, 0, 15, 406, 1, 0, 0, 0, 16, 408, 1, 0, 0, 0, 18, 418, 1, 0, 0, 0, 20, 425, 1, 0, 0, 0, 22, 434, 1, 0, 0, 0, 24, 441, 1, 0, 0, 0, 26, 451, 1, 0, 0, 0, 28, 458, 1, 0, 0, 0, 30, 465, 1, 0, 0, 0, 32, 472, 1, 0, 0, 0, 34, 480, 1, 0, 0, 0, 36, 487, 1, 0, 0, 0, 38, 499, 1, 0, 0, 0, 40, 508, 1, 0, 0, 0, 42, 514, 1, 0, 0, 0, 44, 521, 1, 0, 0, 0, 46, 528, 1, 0, 0, 0, 48, 536, 1, 0, 0, 0, 50, 544, 1, 0, 0, 0, 52, 559, 1, 0, 0, 0, 54, 569, 1, 0, 0, 0, 56, 578, 1, 0, 0, 0, 58, 590, 1, 0, 0, 0, 60, 596, 1, 0, 0, 0, 62, 613, 1, 0, 0, 0, 64, 629, 1, 0, 0, 0, 66, 635, 1, 0, 0, 0, 68, 639, 1, 0, 0, 0, 70, 641, 1, 0, 0, 0, 72, 643, 1, 0, 0, 0, 74, 646, 1, 0, 0, 0, 76, 648, 1, 0, 0, 0, 78, 657, 1, 0, 0, 0, 80, 659, 1, 0, 0, 0, 82, 664, 1, 0, 0, 0, 84, 666, 1, 0, 0, 0, 86, 671, 1, 0, 0, 0, 88, 702, 1, 0, 0, 0, 90, 705, 1, 0, 0, 0, 92, 751, 1, 0, 0, 0, 94, 753, 1, 0, 0, 0, 96, 756, 1, 0, 0, 0, 98, 760, 1, 0, 0, 0, 100, 764, 1, 0, 0, 0, 102, 766, 1, 0, 0, 0, 104, 769, 1, 0, 0, 0, 106, 771, 1, 0, 0, 0, 108, 776, 1, 0, 0, 0, 110, 778, 1, 0, 0, 0, 112, 784, 1, 0, 0, 0, 114, 790, 1, 0, 0, 0, 116, 793, 1, 0, 0, 0, 118, 796, 1, 0, 0, 0, 120, 801, 1, 0, 0, 0, 122, 806, 1, 0, 0, 0, 124, 808, 1, 0, 0, 0, 126, 812, 1, 0, 0, 0, 128, 817, 1, 0, 0, 0, 130, 823, 1, 0, 0, 0, 132, 826, 1, 0, 0, 0, 134, 828, 1, 0, 0, 0, 136, 834, 1, 0, 0, 0, 138, 836, 1, 0, 0, 0, 140, 841, 1, 0, 0, 0, 142, 844, 1, 0, 0, 0, 144, 847, 1, 0, 0, 0, 146, 850, 1, 0, 0, 0, 148, 852, 1, 0, 0, 0, 150, 855, 1, 0, 0, 0, 152, 857, 1, 0, 0, 0, 154, 860, 1, 0, 0, 0, 156, 862, 1, 0, 0, 0, 158, 864, 1, 0, 0, 0, 160, 866, 1, 0, 0, 0, 162, 868, 1, 0, 0, 0, 164, 870, 1, 0, 0, 0, 166, 892, 1, 0, 0, 0, 168, 894, 1, 0, 0, 0, 170, 899, 1, 0, 0, 0, 172, 920, 1, 0, 0, 0, 174, 922, 1, 0, 0, 0, 176, 930, 1, 0, 0, 0, 178, 932, 1, 0, 0, 0, 180, 936, 1, 0, 0, 0, 182, 940, 1, 0, 0, 0, 184, 944, 1, 0, 0, 0, 186, 949, 1, 0, 0, 0, 188, 954, 1, 0, 0, 0, 190, 958, 1, 0, 0, 0, 192, 962, 1, 0, 0, 0, 194, 966, 1, 0, 0, 0, 196, 971, 1, 0, 0, 0, 198, 975, 1, 0, 0, 0, 200, 979, 1, 0, 0, 0, 202, 983, 1, 0, 0, 0, 204, 987, 1, 0, 0, 0, 206, 991, 1, 0, 0, 0, 208, 1003, 1, 0, 0, 0, 210, 1006, 1, 0, 0, 0, 212, 1010, 1, 0, 0, 0, 214, 1014, 1, 0, 0, 0, 216, 1018, 1, 0, 0, 0, 218, 1022, 1, 0, 0, 0, 220, 1026, 1, 0, 0, 0, 222, 1030, 1, 0, 0, 0, 224, 1035, 1, 0, 0, 0, 226, 1039, 1, 0, 0, 0, 228, 1047, 1, 0, 0, 0, 230, 1068, 1, 0, 0, 0, 232, 1072, 1, 0, 0, 0, 234, 1076, 1, 0, 0, 0, 236, 1080, 1, 0, 0, 0, 238, 1084, 1, 0, 0, 0, 240, 1088, 1, 0, 0, 0, 242, 1093, 1, 0, 0, 0, 244, 1097, 1, 0, 0, 0, 246, 1101, 1, 0, 0, 0, 248, 1105, 1, 0, 0, 0, 250, 1108, 1, 0, 0, 0, 252, 1112, 1, 0, 0, 0, 254, 1116, 1, 0, 0, 0, 256, 1120, 1, 0, 0, 0, 258, 1124, 1, 0, 0, 0, 260, 1129, 1, 0, 0, 0, 262, 1134, 1, 0, 0, 0, 264, 1139, 1, 0, 0, 0, 266, 1146, 1, 0, 0, 0, 268, 1155, 1, 0, 0, 0, 270, 1162, 1, 0, 0, 0, 272, 1166, 1, 0, 0, 0, 274, 1170, 1, 0, 0, 0, 276, 1174, 1, 0, 0, 0, 278, 1178, 1, 0, 0, 0, 280, 1184, 1, 0, 0, 0, 282, 1188, 1, 0, 0, 0, 284, 1192, 1, 0, 0, 0, 286, 1196, 1, 0, 0, 0, 288, 1200, 1, 0, 0, 0, 290, 1204, 1, 0, 0, 0, 292, 1208, 1, 0, 0, 0, 294, 1212, 1, 0, 0, 0, 296, 1216, 1, 0, 0, 0, 298, 1220, 1, 0, 0, 0, 300, 1225, 1, 0, 0, 0, 302, 1229, 1, 0, 0, 0, 304, 1233, 1, 0, 0, 0, 306, 1237, 1, 0, 0, 0, 308, 1241, 1, 0, 0, 0, 310, 1245, 1, 0, 0, 0, 312, 1249, 1, 0, 0, 0, 314, 1254, 1, 0, 0, 0, 316, 1259, 1, 0, 0, 0, 318, 1263, 1, 0, 0, 0, 320, 1267, 1, 0, 0, 0, 322, 1271, 1, 0, 0, 0, 324, 1276, 1, 0, 0, 0, 326, 1286, 1, 0, 0, 0, 328, 1290, 1, 0, 0, 0, 330, 1294, 1, 0, 0, 0, 332, 1298, 1, 0, 0, 0, 334, 1303, 1, 0, 0, 0, 336, 1310, 1, 0, 0, 0, 338, 1314, 1, 0, 0, 0, 340, 1318, 1, 0, 0, 0, 342, 1322, 1, 0, 0, 0, 344, 1326, 1, 0, 0, 0, 346, 1331, 1, 0, 0, 0, 348, 1335, 1, 0, 0, 0, 350, 1339, 1, 0, 0, 0, 352, 1343, 1, 0, 0, 0, 354, 1348, 1, 0, 0, 0, 356, 1352, 1, 0, 0, 0, 358, 1356, 1, 0, 0, 0, 360, 1360, 1, 0, 0, 0, 362, 1364, 1, 0, 0, 0, 364, 1368, 1, 0, 0, 0, 366, 1374, 1, 0, 0, 0, 368, 1378, 1, 0, 0, 0, 370, 1382, 1, 0, 0, 0, 372, 1386, 1, 0, 0, 0, 374, 1390, 1, 0, 0, 0, 376, 1394, 1, 0, 0, 0, 378, 1398, 1, 0, 0, 0, 380, 1403, 1, 0, 0, 0, 382, 1409, 1, 0, 0, 0, 384, 1415, 1, 0, 0, 0, 386, 1419, 1, 0, 0, 0, 388, 1423, 1, 0, 0, 0, 390, 1427, 1, 0, 0, 0, 392, 1433, 1, 0, 0, 0, 394, 1439, 1, 0, 0, 0, 396, 1443, 1, 0, 0, 0, 398, 1447, 1, 0, 0, 0, 400, 1451, 1, 0, 0, 0, 402, 1457, 1, 0, 0, 0, 404, 1463, 1, 0, 0, 0, 406, 1469, 1, 0, 0, 0, 408, 409, 7, 0, 0, 0, 409, 410, 7, 1, 0, 0, 410, 411, 7, 2, 0, 0, 411, 412, 7, 2, 0, 0, 412, 413, 7, 3, 0, 0, 413, 414, 7, 4, 0, 0, 414, 415, 7, 5, 0, 0, 415, 416, 1, 0, 0, 0, 416, 417, 6, 0, 0, 0, 417, 17, 1, 0, 0, 0, 418, 419, 7, 0, 0, 0, 419, 420, 7, 6, 0, 0, 420, 421, 7, 7, 0, 0, 421, 422, 7, 8, 0, 0, 422, 423, 1, 0, 0, 0, 423, 424, 6, 1, 1, 0, 424, 19, 1, 0, 0, 0, 425, 426, 7, 3, 0, 0, 426, 427, 7, 9, 0, 0, 427, 428, 7, 6, 0, 0, 428, 429, 7, 1, 0, 0, 429, 430, 7, 4, 0, 0, 430, 431, 7, 10, 0, 0, 431, 432, 1, 0, 0, 0, 432, 433, 6, 2, 2, 0, 433, 21, 1, 0, 0, 0, 434, 435, 7, 3, 0, 0, 435, 436, 7, 11, 0, 0, 436, 437, 7, 12, 0, 0, 437, 438, 7, 13, 0, 0, 438, 439, 1, 0, 0, 0, 439, 440, 6, 3, 0, 0, 440, 23, 1, 0, 0, 0, 441, 442, 7, 3, 0, 0, 442, 443, 7, 14, 0, 0, 443, 444, 7, 8, 0, 0, 444, 445, 7, 13, 0, 0, 445, 446, 7, 12, 0, 0, 446, 447, 7, 1, 0, 0, 447, 448, 7, 9, 0, 0, 448, 449, 1, 0, 0, 0, 449, 450, 6, 4, 3, 0, 450, 25, 1, 0, 0, 0, 451, 452, 7, 15, 0, 0, 452, 453, 7, 6, 0, 0, 453, 454, 7, 7, 0, 0, 454, 455, 7, 16, 0, 0, 455, 456, 1, 0, 0, 0, 456, 457, 6, 5, 4, 0, 457, 27, 1, 0, 0, 0, 458, 459, 7, 17, 0, 0, 459, 460, 7, 6, 0, 0, 460, 461, 7, 7, 0, 0, 461, 462, 7, 18, 0, 0, 462, 463, 1, 0, 0, 0, 463, 464, 6, 6, 0, 0, 464, 29, 1, 0, 0, 0, 465, 466, 7, 18, 0, 0, 466, 467, 7, 3, 0, 0, 467, 468, 7, 3, 0, 0, 468, 469, 7, 8, 0, 0, 469, 470, 1, 0, 0, 0, 470, 471, 6, 7, 1, 0, 471, 31, 1, 0, 0, 0, 472, 473, 7, 13, 0, 0, 473, 474, 7, 1, 0, 0, 474, 475, 7, 16, 0, 0, 475, 476, 7, 1, 0, 0, 476, 477, 7, 5, 0, 0, 477, 478, 1, 0, 0, 0, 478, 479, 6, 8, 0, 0, 479, 33, 1, 0, 0, 0, 480, 481, 7, 16, 0, 0, 481, 482, 7, 3, 0, 0, 482, 483, 7, 5, 0, 0, 483, 484, 7, 12, 0, 0, 484, 485, 1, 0, 0, 0, 485, 486, 6, 9, 5, 0, 486, 35, 1, 0, 0, 0, 487, 488, 7, 16, 0, 0, 488, 489, 7, 11, 0, 0, 489, 490, 5, 95, 0, 0, 490, 491, 7, 3, 0, 0, 491, 492, 7, 14, 0, 0, 492, 493, 7, 8, 0, 0, 493, 494, 7, 12, 0, 0, 494, 495, 7, 9, 0, 0, 495, 496, 7, 0, 0, 0, 496, 497, 1, 0, 0, 0, 497, 498, 6, 10, 6, 0, 498, 37, 1, 0, 0, 0, 499, 500, 7, 6, 0, 0, 500, 501, 7, 3, 0, 0, 501, 502, 7, 9, 0, 0, 502, 503, 7, 12, 0, 0, 503, 504, 7, 16, 0, 0, 504, 505, 7, 3, 0, 0, 505, 506, 1, 0, 0, 0, 506, 507, 6, 11, 7, 0, 507, 39, 1, 0, 0, 0, 508, 509, 7, 6, 0, 0, 509, 510, 7, 7, 0, 0, 510, 511, 7, 19, 0, 0, 511, 512, 1, 0, 0, 0, 512, 513, 6, 12, 0, 0, 513, 41, 1, 0, 0, 0, 514, 515, 7, 2, 0, 0, 515, 516, 7, 10, 0, 0, 516, 517, 7, 7, 0, 0, 517, 518, 7, 19, 0, 0, 518, 519, 1, 0, 0, 0, 519, 520, 6, 13, 8, 0, 520, 43, 1, 0, 0, 0, 521, 522, 7, 2, 0, 0, 522, 523, 7, 7, 0, 0, 523, 524, 7, 6, 0, 0, 524, 525, 7, 5, 0, 0, 525, 526, 1, 0, 0, 0, 526, 527, 6, 14, 0, 0, 527, 45, 1, 0, 0, 0, 528, 529, 7, 2, 0, 0, 529, 530, 7, 5, 0, 0, 530, 531, 7, 12, 0, 0, 531, 532, 7, 5, 0, 0, 532, 533, 7, 2, 0, 0, 533, 534, 1, 0, 0, 0, 534, 535, 6, 15, 0, 0, 535, 47, 1, 0, 0, 0, 536, 537, 7, 19, 0, 0, 537, 538, 7, 10, 0, 0, 538, 539, 7, 3, 0, 0, 539, 540, 7, 6, 0, 0, 540, 541, 7, 3, 0, 0, 541, 542, 1, 0, 0, 0, 542, 543, 6, 16, 0, 0, 543, 49, 1, 0, 0, 0, 544, 545, 4, 17, 0, 0, 545, 546, 7, 1, 0, 0, 546, 547, 7, 9, 0, 0, 547, 548, 7, 13, 0, 0, 548, 549, 7, 1, 0, 0, 549, 550, 7, 9, 0, 0, 550, 551, 7, 3, 0, 0, 551, 552, 7, 2, 0, 0, 552, 553, 7, 5, 0, 0, 553, 554, 7, 12, 0, 0, 554, 555, 7, 5, 0, 0, 555, 556, 7, 2, 0, 0, 556, 557, 1, 0, 0, 0, 557, 558, 6, 17, 0, 0, 558, 51, 1, 0, 0, 0, 559, 560, 4, 18, 1, 0, 560, 561, 7, 13, 0, 0, 561, 562, 7, 7, 0, 0, 562, 563, 7, 7, 0, 0, 563, 564, 7, 18, 0, 0, 564, 565, 7, 20, 0, 0, 565, 566, 7, 8, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 6, 18, 9, 0, 568, 53, 1, 0, 0, 0, 569, 570, 4, 19, 2, 0, 570, 571, 7, 16, 0, 0, 571, 572, 7, 12, 0, 0, 572, 573, 7, 5, 0, 0, 573, 574, 7, 4, 0, 0, 574, 575, 7, 10, 0, 0, 575, 576, 1, 0, 0, 0, 576, 577, 6, 19, 0, 0, 577, 55, 1, 0, 0, 0, 578, 579, 4, 20, 3, 0, 579, 580, 7, 16, 0, 0, 580, 581, 7, 3, 0, 0, 581, 582, 7, 5, 0, 0, 582, 583, 7, 6, 0, 0, 583, 584, 7, 1, 0, 0, 584, 585, 7, 4, 0, 0, 585, 586, 7, 2, 0, 0, 586, 587, 1, 0, 0, 0, 587, 588, 6, 20, 10, 0, 588, 57, 1, 0, 0, 0, 589, 591, 8, 21, 0, 0, 590, 589, 1, 0, 0, 0, 591, 592, 1, 0, 0, 0, 592, 590, 1, 0, 0, 0, 592, 593, 1, 0, 0, 0, 593, 594, 1, 0, 0, 0, 594, 595, 6, 21, 0, 0, 595, 59, 1, 0, 0, 0, 596, 597, 5, 47, 0, 0, 597, 598, 5, 47, 0, 0, 598, 602, 1, 0, 0, 0, 599, 601, 8, 22, 0, 0, 600, 599, 1, 0, 0, 0, 601, 604, 1, 0, 0, 0, 602, 600, 1, 0, 0, 0, 602, 603, 1, 0, 0, 0, 603, 606, 1, 0, 0, 0, 604, 602, 1, 0, 0, 0, 605, 607, 5, 13, 0, 0, 606, 605, 1, 0, 0, 0, 606, 607, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 610, 5, 10, 0, 0, 609, 608, 1, 0, 0, 0, 609, 610, 1, 0, 0, 0, 610, 611, 1, 0, 0, 0, 611, 612, 6, 22, 11, 0, 612, 61, 1, 0, 0, 0, 613, 614, 5, 47, 0, 0, 614, 615, 5, 42, 0, 0, 615, 620, 1, 0, 0, 0, 616, 619, 3, 62, 23, 0, 617, 619, 9, 0, 0, 0, 618, 616, 1, 0, 0, 0, 618, 617, 1, 0, 0, 0, 619, 622, 1, 0, 0, 0, 620, 621, 1, 0, 0, 0, 620, 618, 1, 0, 0, 0, 621, 623, 1, 0, 0, 0, 622, 620, 1, 0, 0, 0, 623, 624, 5, 42, 0, 0, 624, 625, 5, 47, 0, 0, 625, 626, 1, 0, 0, 0, 626, 627, 6, 23, 11, 0, 627, 63, 1, 0, 0, 0, 628, 630, 7, 23, 0, 0, 629, 628, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 629, 1, 0, 0, 0, 631, 632, 1, 0, 0, 0, 632, 633, 1, 0, 0, 0, 633, 634, 6, 24, 11, 0, 634, 65, 1, 0, 0, 0, 635, 636, 5, 124, 0, 0, 636, 637, 1, 0, 0, 0, 637, 638, 6, 25, 12, 0, 638, 67, 1, 0, 0, 0, 639, 640, 7, 24, 0, 0, 640, 69, 1, 0, 0, 0, 641, 642, 7, 25, 0, 0, 642, 71, 1, 0, 0, 0, 643, 644, 5, 92, 0, 0, 644, 645, 7, 26, 0, 0, 645, 73, 1, 0, 0, 0, 646, 647, 8, 27, 0, 0, 647, 75, 1, 0, 0, 0, 648, 650, 7, 3, 0, 0, 649, 651, 7, 28, 0, 0, 650, 649, 1, 0, 0, 0, 650, 651, 1, 0, 0, 0, 651, 653, 1, 0, 0, 0, 652, 654, 3, 68, 26, 0, 653, 652, 1, 0, 0, 0, 654, 655, 1, 0, 0, 0, 655, 653, 1, 0, 0, 0, 655, 656, 1, 0, 0, 0, 656, 77, 1, 0, 0, 0, 657, 658, 5, 64, 0, 0, 658, 79, 1, 0, 0, 0, 659, 660, 5, 96, 0, 0, 660, 81, 1, 0, 0, 0, 661, 665, 8, 29, 0, 0, 662, 663, 5, 96, 0, 0, 663, 665, 5, 96, 0, 0, 664, 661, 1, 0, 0, 0, 664, 662, 1, 0, 0, 0, 665, 83, 1, 0, 0, 0, 666, 667, 5, 95, 0, 0, 667, 85, 1, 0, 0, 0, 668, 672, 3, 70, 27, 0, 669, 672, 3, 68, 26, 0, 670, 672, 3, 84, 34, 0, 671, 668, 1, 0, 0, 0, 671, 669, 1, 0, 0, 0, 671, 670, 1, 0, 0, 0, 672, 87, 1, 0, 0, 0, 673, 678, 5, 34, 0, 0, 674, 677, 3, 72, 28, 0, 675, 677, 3, 74, 29, 0, 676, 674, 1, 0, 0, 0, 676, 675, 1, 0, 0, 0, 677, 680, 1, 0, 0, 0, 678, 676, 1, 0, 0, 0, 678, 679, 1, 0, 0, 0, 679, 681, 1, 0, 0, 0, 680, 678, 1, 0, 0, 0, 681, 703, 5, 34, 0, 0, 682, 683, 5, 34, 0, 0, 683, 684, 5, 34, 0, 0, 684, 685, 5, 34, 0, 0, 685, 689, 1, 0, 0, 0, 686, 688, 8, 22, 0, 0, 687, 686, 1, 0, 0, 0, 688, 691, 1, 0, 0, 0, 689, 690, 1, 0, 0, 0, 689, 687, 1, 0, 0, 0, 690, 692, 1, 0, 0, 0, 691, 689, 1, 0, 0, 0, 692, 693, 5, 34, 0, 0, 693, 694, 5, 34, 0, 0, 694, 695, 5, 34, 0, 0, 695, 697, 1, 0, 0, 0, 696, 698, 5, 34, 0, 0, 697, 696, 1, 0, 0, 0, 697, 698, 1, 0, 0, 0, 698, 700, 1, 0, 0, 0, 699, 701, 5, 34, 0, 0, 700, 699, 1, 0, 0, 0, 700, 701, 1, 0, 0, 0, 701, 703, 1, 0, 0, 0, 702, 673, 1, 0, 0, 0, 702, 682, 1, 0, 0, 0, 703, 89, 1, 0, 0, 0, 704, 706, 3, 68, 26, 0, 705, 704, 1, 0, 0, 0, 706, 707, 1, 0, 0, 0, 707, 705, 1, 0, 0, 0, 707, 708, 1, 0, 0, 0, 708, 91, 1, 0, 0, 0, 709, 711, 3, 68, 26, 0, 710, 709, 1, 0, 0, 0, 711, 712, 1, 0, 0, 0, 712, 710, 1, 0, 0, 0, 712, 713, 1, 0, 0, 0, 713, 714, 1, 0, 0, 0, 714, 718, 3, 108, 46, 0, 715, 717, 3, 68, 26, 0, 716, 715, 1, 0, 0, 0, 717, 720, 1, 0, 0, 0, 718, 716, 1, 0, 0, 0, 718, 719, 1, 0, 0, 0, 719, 752, 1, 0, 0, 0, 720, 718, 1, 0, 0, 0, 721, 723, 3, 108, 46, 0, 722, 724, 3, 68, 26, 0, 723, 722, 1, 0, 0, 0, 724, 725, 1, 0, 0, 0, 725, 723, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 752, 1, 0, 0, 0, 727, 729, 3, 68, 26, 0, 728, 727, 1, 0, 0, 0, 729, 730, 1, 0, 0, 0, 730, 728, 1, 0, 0, 0, 730, 731, 1, 0, 0, 0, 731, 739, 1, 0, 0, 0, 732, 736, 3, 108, 46, 0, 733, 735, 3, 68, 26, 0, 734, 733, 1, 0, 0, 0, 735, 738, 1, 0, 0, 0, 736, 734, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 740, 1, 0, 0, 0, 738, 736, 1, 0, 0, 0, 739, 732, 1, 0, 0, 0, 739, 740, 1, 0, 0, 0, 740, 741, 1, 0, 0, 0, 741, 742, 3, 76, 30, 0, 742, 752, 1, 0, 0, 0, 743, 745, 3, 108, 46, 0, 744, 746, 3, 68, 26, 0, 745, 744, 1, 0, 0, 0, 746, 747, 1, 0, 0, 0, 747, 745, 1, 0, 0, 0, 747, 748, 1, 0, 0, 0, 748, 749, 1, 0, 0, 0, 749, 750, 3, 76, 30, 0, 750, 752, 1, 0, 0, 0, 751, 710, 1, 0, 0, 0, 751, 721, 1, 0, 0, 0, 751, 728, 1, 0, 0, 0, 751, 743, 1, 0, 0, 0, 752, 93, 1, 0, 0, 0, 753, 754, 7, 30, 0, 0, 754, 755, 7, 31, 0, 0, 755, 95, 1, 0, 0, 0, 756, 757, 7, 12, 0, 0, 757, 758, 7, 9, 0, 0, 758, 759, 7, 0, 0, 0, 759, 97, 1, 0, 0, 0, 760, 761, 7, 12, 0, 0, 761, 762, 7, 2, 0, 0, 762, 763, 7, 4, 0, 0, 763, 99, 1, 0, 0, 0, 764, 765, 5, 61, 0, 0, 765, 101, 1, 0, 0, 0, 766, 767, 5, 58, 0, 0, 767, 768, 5, 58, 0, 0, 768, 103, 1, 0, 0, 0, 769, 770, 5, 44, 0, 0, 770, 105, 1, 0, 0, 0, 771, 772, 7, 0, 0, 0, 772, 773, 7, 3, 0, 0, 773, 774, 7, 2, 0, 0, 774, 775, 7, 4, 0, 0, 775, 107, 1, 0, 0, 0, 776, 777, 5, 46, 0, 0, 777, 109, 1, 0, 0, 0, 778, 779, 7, 15, 0, 0, 779, 780, 7, 12, 0, 0, 780, 781, 7, 13, 0, 0, 781, 782, 7, 2, 0, 0, 782, 783, 7, 3, 0, 0, 783, 111, 1, 0, 0, 0, 784, 785, 7, 15, 0, 0, 785, 786, 7, 1, 0, 0, 786, 787, 7, 6, 0, 0, 787, 788, 7, 2, 0, 0, 788, 789, 7, 5, 0, 0, 789, 113, 1, 0, 0, 0, 790, 791, 7, 1, 0, 0, 791, 792, 7, 9, 0, 0, 792, 115, 1, 0, 0, 0, 793, 794, 7, 1, 0, 0, 794, 795, 7, 2, 0, 0, 795, 117, 1, 0, 0, 0, 796, 797, 7, 13, 0, 0, 797, 798, 7, 12, 0, 0, 798, 799, 7, 2, 0, 0, 799, 800, 7, 5, 0, 0, 800, 119, 1, 0, 0, 0, 801, 802, 7, 13, 0, 0, 802, 803, 7, 1, 0, 0, 803, 804, 7, 18, 0, 0, 804, 805, 7, 3, 0, 0, 805, 121, 1, 0, 0, 0, 806, 807, 5, 40, 0, 0, 807, 123, 1, 0, 0, 0, 808, 809, 7, 9, 0, 0, 809, 810, 7, 7, 0, 0, 810, 811, 7, 5, 0, 0, 811, 125, 1, 0, 0, 0, 812, 813, 7, 9, 0, 0, 813, 814, 7, 20, 0, 0, 814, 815, 7, 13, 0, 0, 815, 816, 7, 13, 0, 0, 816, 127, 1, 0, 0, 0, 817, 818, 7, 9, 0, 0, 818, 819, 7, 20, 0, 0, 819, 820, 7, 13, 0, 0, 820, 821, 7, 13, 0, 0, 821, 822, 7, 2, 0, 0, 822, 129, 1, 0, 0, 0, 823, 824, 7, 7, 0, 0, 824, 825, 7, 6, 0, 0, 825, 131, 1, 0, 0, 0, 826, 827, 5, 63, 0, 0, 827, 133, 1, 0, 0, 0, 828, 829, 7, 6, 0, 0, 829, 830, 7, 13, 0, 0, 830, 831, 7, 1, 0, 0, 831, 832, 7, 18, 0, 0, 832, 833, 7, 3, 0, 0, 833, 135, 1, 0, 0, 0, 834, 835, 5, 41, 0, 0, 835, 137, 1, 0, 0, 0, 836, 837, 7, 5, 0, 0, 837, 838, 7, 6, 0, 0, 838, 839, 7, 20, 0, 0, 839, 840, 7, 3, 0, 0, 840, 139, 1, 0, 0, 0, 841, 842, 5, 61, 0, 0, 842, 843, 5, 61, 0, 0, 843, 141, 1, 0, 0, 0, 844, 845, 5, 61, 0, 0, 845, 846, 5, 126, 0, 0, 846, 143, 1, 0, 0, 0, 847, 848, 5, 33, 0, 0, 848, 849, 5, 61, 0, 0, 849, 145, 1, 0, 0, 0, 850, 851, 5, 60, 0, 0, 851, 147, 1, 0, 0, 0, 852, 853, 5, 60, 0, 0, 853, 854, 5, 61, 0, 0, 854, 149, 1, 0, 0, 0, 855, 856, 5, 62, 0, 0, 856, 151, 1, 0, 0, 0, 857, 858, 5, 62, 0, 0, 858, 859, 5, 61, 0, 0, 859, 153, 1, 0, 0, 0, 860, 861, 5, 43, 0, 0, 861, 155, 1, 0, 0, 0, 862, 863, 5, 45, 0, 0, 863, 157, 1, 0, 0, 0, 864, 865, 5, 42, 0, 0, 865, 159, 1, 0, 0, 0, 866, 867, 5, 47, 0, 0, 867, 161, 1, 0, 0, 0, 868, 869, 5, 37, 0, 0, 869, 163, 1, 0, 0, 0, 870, 871, 4, 74, 4, 0, 871, 872, 3, 54, 19, 0, 872, 873, 1, 0, 0, 0, 873, 874, 6, 74, 13, 0, 874, 165, 1, 0, 0, 0, 875, 878, 3, 132, 58, 0, 876, 879, 3, 70, 27, 0, 877, 879, 3, 84, 34, 0, 878, 876, 1, 0, 0, 0, 878, 877, 1, 0, 0, 0, 879, 883, 1, 0, 0, 0, 880, 882, 3, 86, 35, 0, 881, 880, 1, 0, 0, 0, 882, 885, 1, 0, 0, 0, 883, 881, 1, 0, 0, 0, 883, 884, 1, 0, 0, 0, 884, 893, 1, 0, 0, 0, 885, 883, 1, 0, 0, 0, 886, 888, 3, 132, 58, 0, 887, 889, 3, 68, 26, 0, 888, 887, 1, 0, 0, 0, 889, 890, 1, 0, 0, 0, 890, 888, 1, 0, 0, 0, 890, 891, 1, 0, 0, 0, 891, 893, 1, 0, 0, 0, 892, 875, 1, 0, 0, 0, 892, 886, 1, 0, 0, 0, 893, 167, 1, 0, 0, 0, 894, 895, 5, 91, 0, 0, 895, 896, 1, 0, 0, 0, 896, 897, 6, 76, 0, 0, 897, 898, 6, 76, 0, 0, 898, 169, 1, 0, 0, 0, 899, 900, 5, 93, 0, 0, 900, 901, 1, 0, 0, 0, 901, 902, 6, 77, 12, 0, 902, 903, 6, 77, 12, 0, 903, 171, 1, 0, 0, 0, 904, 908, 3, 70, 27, 0, 905, 907, 3, 86, 35, 0, 906, 905, 1, 0, 0, 0, 907, 910, 1, 0, 0, 0, 908, 906, 1, 0, 0, 0, 908, 909, 1, 0, 0, 0, 909, 921, 1, 0, 0, 0, 910, 908, 1, 0, 0, 0, 911, 914, 3, 84, 34, 0, 912, 914, 3, 78, 31, 0, 913, 911, 1, 0, 0, 0, 913, 912, 1, 0, 0, 0, 914, 916, 1, 0, 0, 0, 915, 917, 3, 86, 35, 0, 916, 915, 1, 0, 0, 0, 917, 918, 1, 0, 0, 0, 918, 916, 1, 0, 0, 0, 918, 919, 1, 0, 0, 0, 919, 921, 1, 0, 0, 0, 920, 904, 1, 0, 0, 0, 920, 913, 1, 0, 0, 0, 921, 173, 1, 0, 0, 0, 922, 924, 3, 80, 32, 0, 923, 925, 3, 82, 33, 0, 924, 923, 1, 0, 0, 0, 925, 926, 1, 0, 0, 0, 926, 924, 1, 0, 0, 0, 926, 927, 1, 0, 0, 0, 927, 928, 1, 0, 0, 0, 928, 929, 3, 80, 32, 0, 929, 175, 1, 0, 0, 0, 930, 931, 3, 174, 79, 0, 931, 177, 1, 0, 0, 0, 932, 933, 3, 60, 22, 0, 933, 934, 1, 0, 0, 0, 934, 935, 6, 81, 11, 0, 935, 179, 1, 0, 0, 0, 936, 937, 3, 62, 23, 0, 937, 938, 1, 0, 0, 0, 938, 939, 6, 82, 11, 0, 939, 181, 1, 0, 0, 0, 940, 941, 3, 64, 24, 0, 941, 942, 1, 0, 0, 0, 942, 943, 6, 83, 11, 0, 943, 183, 1, 0, 0, 0, 944, 945, 3, 168, 76, 0, 945, 946, 1, 0, 0, 0, 946, 947, 6, 84, 14, 0, 947, 948, 6, 84, 15, 0, 948, 185, 1, 0, 0, 0, 949, 950, 3, 66, 25, 0, 950, 951, 1, 0, 0, 0, 951, 952, 6, 85, 16, 0, 952, 953, 6, 85, 12, 0, 953, 187, 1, 0, 0, 0, 954, 955, 3, 64, 24, 0, 955, 956, 1, 0, 0, 0, 956, 957, 6, 86, 11, 0, 957, 189, 1, 0, 0, 0, 958, 959, 3, 60, 22, 0, 959, 960, 1, 0, 0, 0, 960, 961, 6, 87, 11, 0, 961, 191, 1, 0, 0, 0, 962, 963, 3, 62, 23, 0, 963, 964, 1, 0, 0, 0, 964, 965, 6, 88, 11, 0, 965, 193, 1, 0, 0, 0, 966, 967, 3, 66, 25, 0, 967, 968, 1, 0, 0, 0, 968, 969, 6, 89, 16, 0, 969, 970, 6, 89, 12, 0, 970, 195, 1, 0, 0, 0, 971, 972, 3, 168, 76, 0, 972, 973, 1, 0, 0, 0, 973, 974, 6, 90, 14, 0, 974, 197, 1, 0, 0, 0, 975, 976, 3, 170, 77, 0, 976, 977, 1, 0, 0, 0, 977, 978, 6, 91, 17, 0, 978, 199, 1, 0, 0, 0, 979, 980, 3, 334, 159, 0, 980, 981, 1, 0, 0, 0, 981, 982, 6, 92, 18, 0, 982, 201, 1, 0, 0, 0, 983, 984, 3, 104, 44, 0, 984, 985, 1, 0, 0, 0, 985, 986, 6, 93, 19, 0, 986, 203, 1, 0, 0, 0, 987, 988, 3, 100, 42, 0, 988, 989, 1, 0, 0, 0, 989, 990, 6, 94, 20, 0, 990, 205, 1, 0, 0, 0, 991, 992, 7, 16, 0, 0, 992, 993, 7, 3, 0, 0, 993, 994, 7, 5, 0, 0, 994, 995, 7, 12, 0, 0, 995, 996, 7, 0, 0, 0, 996, 997, 7, 12, 0, 0, 997, 998, 7, 5, 0, 0, 998, 999, 7, 12, 0, 0, 999, 207, 1, 0, 0, 0, 1000, 1004, 8, 32, 0, 0, 1001, 1002, 5, 47, 0, 0, 1002, 1004, 8, 33, 0, 0, 1003, 1000, 1, 0, 0, 0, 1003, 1001, 1, 0, 0, 0, 1004, 209, 1, 0, 0, 0, 1005, 1007, 3, 208, 96, 0, 1006, 1005, 1, 0, 0, 0, 1007, 1008, 1, 0, 0, 0, 1008, 1006, 1, 0, 0, 0, 1008, 1009, 1, 0, 0, 0, 1009, 211, 1, 0, 0, 0, 1010, 1011, 3, 210, 97, 0, 1011, 1012, 1, 0, 0, 0, 1012, 1013, 6, 98, 21, 0, 1013, 213, 1, 0, 0, 0, 1014, 1015, 3, 88, 36, 0, 1015, 1016, 1, 0, 0, 0, 1016, 1017, 6, 99, 22, 0, 1017, 215, 1, 0, 0, 0, 1018, 1019, 3, 60, 22, 0, 1019, 1020, 1, 0, 0, 0, 1020, 1021, 6, 100, 11, 0, 1021, 217, 1, 0, 0, 0, 1022, 1023, 3, 62, 23, 0, 1023, 1024, 1, 0, 0, 0, 1024, 1025, 6, 101, 11, 0, 1025, 219, 1, 0, 0, 0, 1026, 1027, 3, 64, 24, 0, 1027, 1028, 1, 0, 0, 0, 1028, 1029, 6, 102, 11, 0, 1029, 221, 1, 0, 0, 0, 1030, 1031, 3, 66, 25, 0, 1031, 1032, 1, 0, 0, 0, 1032, 1033, 6, 103, 16, 0, 1033, 1034, 6, 103, 12, 0, 1034, 223, 1, 0, 0, 0, 1035, 1036, 3, 108, 46, 0, 1036, 1037, 1, 0, 0, 0, 1037, 1038, 6, 104, 23, 0, 1038, 225, 1, 0, 0, 0, 1039, 1040, 3, 104, 44, 0, 1040, 1041, 1, 0, 0, 0, 1041, 1042, 6, 105, 19, 0, 1042, 227, 1, 0, 0, 0, 1043, 1048, 3, 70, 27, 0, 1044, 1048, 3, 68, 26, 0, 1045, 1048, 3, 84, 34, 0, 1046, 1048, 3, 158, 71, 0, 1047, 1043, 1, 0, 0, 0, 1047, 1044, 1, 0, 0, 0, 1047, 1045, 1, 0, 0, 0, 1047, 1046, 1, 0, 0, 0, 1048, 229, 1, 0, 0, 0, 1049, 1052, 3, 70, 27, 0, 1050, 1052, 3, 158, 71, 0, 1051, 1049, 1, 0, 0, 0, 1051, 1050, 1, 0, 0, 0, 1052, 1056, 1, 0, 0, 0, 1053, 1055, 3, 228, 106, 0, 1054, 1053, 1, 0, 0, 0, 1055, 1058, 1, 0, 0, 0, 1056, 1054, 1, 0, 0, 0, 1056, 1057, 1, 0, 0, 0, 1057, 1069, 1, 0, 0, 0, 1058, 1056, 1, 0, 0, 0, 1059, 1062, 3, 84, 34, 0, 1060, 1062, 3, 78, 31, 0, 1061, 1059, 1, 0, 0, 0, 1061, 1060, 1, 0, 0, 0, 1062, 1064, 1, 0, 0, 0, 1063, 1065, 3, 228, 106, 0, 1064, 1063, 1, 0, 0, 0, 1065, 1066, 1, 0, 0, 0, 1066, 1064, 1, 0, 0, 0, 1066, 1067, 1, 0, 0, 0, 1067, 1069, 1, 0, 0, 0, 1068, 1051, 1, 0, 0, 0, 1068, 1061, 1, 0, 0, 0, 1069, 231, 1, 0, 0, 0, 1070, 1073, 3, 230, 107, 0, 1071, 1073, 3, 174, 79, 0, 1072, 1070, 1, 0, 0, 0, 1072, 1071, 1, 0, 0, 0, 1073, 1074, 1, 0, 0, 0, 1074, 1072, 1, 0, 0, 0, 1074, 1075, 1, 0, 0, 0, 1075, 233, 1, 0, 0, 0, 1076, 1077, 3, 60, 22, 0, 1077, 1078, 1, 0, 0, 0, 1078, 1079, 6, 109, 11, 0, 1079, 235, 1, 0, 0, 0, 1080, 1081, 3, 62, 23, 0, 1081, 1082, 1, 0, 0, 0, 1082, 1083, 6, 110, 11, 0, 1083, 237, 1, 0, 0, 0, 1084, 1085, 3, 64, 24, 0, 1085, 1086, 1, 0, 0, 0, 1086, 1087, 6, 111, 11, 0, 1087, 239, 1, 0, 0, 0, 1088, 1089, 3, 66, 25, 0, 1089, 1090, 1, 0, 0, 0, 1090, 1091, 6, 112, 16, 0, 1091, 1092, 6, 112, 12, 0, 1092, 241, 1, 0, 0, 0, 1093, 1094, 3, 100, 42, 0, 1094, 1095, 1, 0, 0, 0, 1095, 1096, 6, 113, 20, 0, 1096, 243, 1, 0, 0, 0, 1097, 1098, 3, 104, 44, 0, 1098, 1099, 1, 0, 0, 0, 1099, 1100, 6, 114, 19, 0, 1100, 245, 1, 0, 0, 0, 1101, 1102, 3, 108, 46, 0, 1102, 1103, 1, 0, 0, 0, 1103, 1104, 6, 115, 23, 0, 1104, 247, 1, 0, 0, 0, 1105, 1106, 7, 12, 0, 0, 1106, 1107, 7, 2, 0, 0, 1107, 249, 1, 0, 0, 0, 1108, 1109, 3, 232, 108, 0, 1109, 1110, 1, 0, 0, 0, 1110, 1111, 6, 117, 24, 0, 1111, 251, 1, 0, 0, 0, 1112, 1113, 3, 60, 22, 0, 1113, 1114, 1, 0, 0, 0, 1114, 1115, 6, 118, 11, 0, 1115, 253, 1, 0, 0, 0, 1116, 1117, 3, 62, 23, 0, 1117, 1118, 1, 0, 0, 0, 1118, 1119, 6, 119, 11, 0, 1119, 255, 1, 0, 0, 0, 1120, 1121, 3, 64, 24, 0, 1121, 1122, 1, 0, 0, 0, 1122, 1123, 6, 120, 11, 0, 1123, 257, 1, 0, 0, 0, 1124, 1125, 3, 66, 25, 0, 1125, 1126, 1, 0, 0, 0, 1126, 1127, 6, 121, 16, 0, 1127, 1128, 6, 121, 12, 0, 1128, 259, 1, 0, 0, 0, 1129, 1130, 3, 168, 76, 0, 1130, 1131, 1, 0, 0, 0, 1131, 1132, 6, 122, 14, 0, 1132, 1133, 6, 122, 25, 0, 1133, 261, 1, 0, 0, 0, 1134, 1135, 7, 7, 0, 0, 1135, 1136, 7, 9, 0, 0, 1136, 1137, 1, 0, 0, 0, 1137, 1138, 6, 123, 26, 0, 1138, 263, 1, 0, 0, 0, 1139, 1140, 7, 19, 0, 0, 1140, 1141, 7, 1, 0, 0, 1141, 1142, 7, 5, 0, 0, 1142, 1143, 7, 10, 0, 0, 1143, 1144, 1, 0, 0, 0, 1144, 1145, 6, 124, 26, 0, 1145, 265, 1, 0, 0, 0, 1146, 1147, 8, 34, 0, 0, 1147, 267, 1, 0, 0, 0, 1148, 1150, 3, 266, 125, 0, 1149, 1148, 1, 0, 0, 0, 1150, 1151, 1, 0, 0, 0, 1151, 1149, 1, 0, 0, 0, 1151, 1152, 1, 0, 0, 0, 1152, 1153, 1, 0, 0, 0, 1153, 1154, 3, 334, 159, 0, 1154, 1156, 1, 0, 0, 0, 1155, 1149, 1, 0, 0, 0, 1155, 1156, 1, 0, 0, 0, 1156, 1158, 1, 0, 0, 0, 1157, 1159, 3, 266, 125, 0, 1158, 1157, 1, 0, 0, 0, 1159, 1160, 1, 0, 0, 0, 1160, 1158, 1, 0, 0, 0, 1160, 1161, 1, 0, 0, 0, 1161, 269, 1, 0, 0, 0, 1162, 1163, 3, 268, 126, 0, 1163, 1164, 1, 0, 0, 0, 1164, 1165, 6, 127, 27, 0, 1165, 271, 1, 0, 0, 0, 1166, 1167, 3, 60, 22, 0, 1167, 1168, 1, 0, 0, 0, 1168, 1169, 6, 128, 11, 0, 1169, 273, 1, 0, 0, 0, 1170, 1171, 3, 62, 23, 0, 1171, 1172, 1, 0, 0, 0, 1172, 1173, 6, 129, 11, 0, 1173, 275, 1, 0, 0, 0, 1174, 1175, 3, 64, 24, 0, 1175, 1176, 1, 0, 0, 0, 1176, 1177, 6, 130, 11, 0, 1177, 277, 1, 0, 0, 0, 1178, 1179, 3, 66, 25, 0, 1179, 1180, 1, 0, 0, 0, 1180, 1181, 6, 131, 16, 0, 1181, 1182, 6, 131, 12, 0, 1182, 1183, 6, 131, 12, 0, 1183, 279, 1, 0, 0, 0, 1184, 1185, 3, 100, 42, 0, 1185, 1186, 1, 0, 0, 0, 1186, 1187, 6, 132, 20, 0, 1187, 281, 1, 0, 0, 0, 1188, 1189, 3, 104, 44, 0, 1189, 1190, 1, 0, 0, 0, 1190, 1191, 6, 133, 19, 0, 1191, 283, 1, 0, 0, 0, 1192, 1193, 3, 108, 46, 0, 1193, 1194, 1, 0, 0, 0, 1194, 1195, 6, 134, 23, 0, 1195, 285, 1, 0, 0, 0, 1196, 1197, 3, 264, 124, 0, 1197, 1198, 1, 0, 0, 0, 1198, 1199, 6, 135, 28, 0, 1199, 287, 1, 0, 0, 0, 1200, 1201, 3, 232, 108, 0, 1201, 1202, 1, 0, 0, 0, 1202, 1203, 6, 136, 24, 0, 1203, 289, 1, 0, 0, 0, 1204, 1205, 3, 176, 80, 0, 1205, 1206, 1, 0, 0, 0, 1206, 1207, 6, 137, 29, 0, 1207, 291, 1, 0, 0, 0, 1208, 1209, 3, 60, 22, 0, 1209, 1210, 1, 0, 0, 0, 1210, 1211, 6, 138, 11, 0, 1211, 293, 1, 0, 0, 0, 1212, 1213, 3, 62, 23, 0, 1213, 1214, 1, 0, 0, 0, 1214, 1215, 6, 139, 11, 0, 1215, 295, 1, 0, 0, 0, 1216, 1217, 3, 64, 24, 0, 1217, 1218, 1, 0, 0, 0, 1218, 1219, 6, 140, 11, 0, 1219, 297, 1, 0, 0, 0, 1220, 1221, 3, 66, 25, 0, 1221, 1222, 1, 0, 0, 0, 1222, 1223, 6, 141, 16, 0, 1223, 1224, 6, 141, 12, 0, 1224, 299, 1, 0, 0, 0, 1225, 1226, 3, 108, 46, 0, 1226, 1227, 1, 0, 0, 0, 1227, 1228, 6, 142, 23, 0, 1228, 301, 1, 0, 0, 0, 1229, 1230, 3, 176, 80, 0, 1230, 1231, 1, 0, 0, 0, 1231, 1232, 6, 143, 29, 0, 1232, 303, 1, 0, 0, 0, 1233, 1234, 3, 172, 78, 0, 1234, 1235, 1, 0, 0, 0, 1235, 1236, 6, 144, 30, 0, 1236, 305, 1, 0, 0, 0, 1237, 1238, 3, 60, 22, 0, 1238, 1239, 1, 0, 0, 0, 1239, 1240, 6, 145, 11, 0, 1240, 307, 1, 0, 0, 0, 1241, 1242, 3, 62, 23, 0, 1242, 1243, 1, 0, 0, 0, 1243, 1244, 6, 146, 11, 0, 1244, 309, 1, 0, 0, 0, 1245, 1246, 3, 64, 24, 0, 1246, 1247, 1, 0, 0, 0, 1247, 1248, 6, 147, 11, 0, 1248, 311, 1, 0, 0, 0, 1249, 1250, 3, 66, 25, 0, 1250, 1251, 1, 0, 0, 0, 1251, 1252, 6, 148, 16, 0, 1252, 1253, 6, 148, 12, 0, 1253, 313, 1, 0, 0, 0, 1254, 1255, 7, 1, 0, 0, 1255, 1256, 7, 9, 0, 0, 1256, 1257, 7, 15, 0, 0, 1257, 1258, 7, 7, 0, 0, 1258, 315, 1, 0, 0, 0, 1259, 1260, 3, 60, 22, 0, 1260, 1261, 1, 0, 0, 0, 1261, 1262, 6, 150, 11, 0, 1262, 317, 1, 0, 0, 0, 1263, 1264, 3, 62, 23, 0, 1264, 1265, 1, 0, 0, 0, 1265, 1266, 6, 151, 11, 0, 1266, 319, 1, 0, 0, 0, 1267, 1268, 3, 64, 24, 0, 1268, 1269, 1, 0, 0, 0, 1269, 1270, 6, 152, 11, 0, 1270, 321, 1, 0, 0, 0, 1271, 1272, 3, 66, 25, 0, 1272, 1273, 1, 0, 0, 0, 1273, 1274, 6, 153, 16, 0, 1274, 1275, 6, 153, 12, 0, 1275, 323, 1, 0, 0, 0, 1276, 1277, 7, 15, 0, 0, 1277, 1278, 7, 20, 0, 0, 1278, 1279, 7, 9, 0, 0, 1279, 1280, 7, 4, 0, 0, 1280, 1281, 7, 5, 0, 0, 1281, 1282, 7, 1, 0, 0, 1282, 1283, 7, 7, 0, 0, 1283, 1284, 7, 9, 0, 0, 1284, 1285, 7, 2, 0, 0, 1285, 325, 1, 0, 0, 0, 1286, 1287, 3, 60, 22, 0, 1287, 1288, 1, 0, 0, 0, 1288, 1289, 6, 155, 11, 0, 1289, 327, 1, 0, 0, 0, 1290, 1291, 3, 62, 23, 0, 1291, 1292, 1, 0, 0, 0, 1292, 1293, 6, 156, 11, 0, 1293, 329, 1, 0, 0, 0, 1294, 1295, 3, 64, 24, 0, 1295, 1296, 1, 0, 0, 0, 1296, 1297, 6, 157, 11, 0, 1297, 331, 1, 0, 0, 0, 1298, 1299, 3, 170, 77, 0, 1299, 1300, 1, 0, 0, 0, 1300, 1301, 6, 158, 17, 0, 1301, 1302, 6, 158, 12, 0, 1302, 333, 1, 0, 0, 0, 1303, 1304, 5, 58, 0, 0, 1304, 335, 1, 0, 0, 0, 1305, 1311, 3, 78, 31, 0, 1306, 1311, 3, 68, 26, 0, 1307, 1311, 3, 108, 46, 0, 1308, 1311, 3, 70, 27, 0, 1309, 1311, 3, 84, 34, 0, 1310, 1305, 1, 0, 0, 0, 1310, 1306, 1, 0, 0, 0, 1310, 1307, 1, 0, 0, 0, 1310, 1308, 1, 0, 0, 0, 1310, 1309, 1, 0, 0, 0, 1311, 1312, 1, 0, 0, 0, 1312, 1310, 1, 0, 0, 0, 1312, 1313, 1, 0, 0, 0, 1313, 337, 1, 0, 0, 0, 1314, 1315, 3, 60, 22, 0, 1315, 1316, 1, 0, 0, 0, 1316, 1317, 6, 161, 11, 0, 1317, 339, 1, 0, 0, 0, 1318, 1319, 3, 62, 23, 0, 1319, 1320, 1, 0, 0, 0, 1320, 1321, 6, 162, 11, 0, 1321, 341, 1, 0, 0, 0, 1322, 1323, 3, 64, 24, 0, 1323, 1324, 1, 0, 0, 0, 1324, 1325, 6, 163, 11, 0, 1325, 343, 1, 0, 0, 0, 1326, 1327, 3, 66, 25, 0, 1327, 1328, 1, 0, 0, 0, 1328, 1329, 6, 164, 16, 0, 1329, 1330, 6, 164, 12, 0, 1330, 345, 1, 0, 0, 0, 1331, 1332, 3, 334, 159, 0, 1332, 1333, 1, 0, 0, 0, 1333, 1334, 6, 165, 18, 0, 1334, 347, 1, 0, 0, 0, 1335, 1336, 3, 104, 44, 0, 1336, 1337, 1, 0, 0, 0, 1337, 1338, 6, 166, 19, 0, 1338, 349, 1, 0, 0, 0, 1339, 1340, 3, 108, 46, 0, 1340, 1341, 1, 0, 0, 0, 1341, 1342, 6, 167, 23, 0, 1342, 351, 1, 0, 0, 0, 1343, 1344, 3, 262, 123, 0, 1344, 1345, 1, 0, 0, 0, 1345, 1346, 6, 168, 31, 0, 1346, 1347, 6, 168, 32, 0, 1347, 353, 1, 0, 0, 0, 1348, 1349, 3, 210, 97, 0, 1349, 1350, 1, 0, 0, 0, 1350, 1351, 6, 169, 21, 0, 1351, 355, 1, 0, 0, 0, 1352, 1353, 3, 88, 36, 0, 1353, 1354, 1, 0, 0, 0, 1354, 1355, 6, 170, 22, 0, 1355, 357, 1, 0, 0, 0, 1356, 1357, 3, 60, 22, 0, 1357, 1358, 1, 0, 0, 0, 1358, 1359, 6, 171, 11, 0, 1359, 359, 1, 0, 0, 0, 1360, 1361, 3, 62, 23, 0, 1361, 1362, 1, 0, 0, 0, 1362, 1363, 6, 172, 11, 0, 1363, 361, 1, 0, 0, 0, 1364, 1365, 3, 64, 24, 0, 1365, 1366, 1, 0, 0, 0, 1366, 1367, 6, 173, 11, 0, 1367, 363, 1, 0, 0, 0, 1368, 1369, 3, 66, 25, 0, 1369, 1370, 1, 0, 0, 0, 1370, 1371, 6, 174, 16, 0, 1371, 1372, 6, 174, 12, 0, 1372, 1373, 6, 174, 12, 0, 1373, 365, 1, 0, 0, 0, 1374, 1375, 3, 104, 44, 0, 1375, 1376, 1, 0, 0, 0, 1376, 1377, 6, 175, 19, 0, 1377, 367, 1, 0, 0, 0, 1378, 1379, 3, 108, 46, 0, 1379, 1380, 1, 0, 0, 0, 1380, 1381, 6, 176, 23, 0, 1381, 369, 1, 0, 0, 0, 1382, 1383, 3, 232, 108, 0, 1383, 1384, 1, 0, 0, 0, 1384, 1385, 6, 177, 24, 0, 1385, 371, 1, 0, 0, 0, 1386, 1387, 3, 60, 22, 0, 1387, 1388, 1, 0, 0, 0, 1388, 1389, 6, 178, 11, 0, 1389, 373, 1, 0, 0, 0, 1390, 1391, 3, 62, 23, 0, 1391, 1392, 1, 0, 0, 0, 1392, 1393, 6, 179, 11, 0, 1393, 375, 1, 0, 0, 0, 1394, 1395, 3, 64, 24, 0, 1395, 1396, 1, 0, 0, 0, 1396, 1397, 6, 180, 11, 0, 1397, 377, 1, 0, 0, 0, 1398, 1399, 3, 66, 25, 0, 1399, 1400, 1, 0, 0, 0, 1400, 1401, 6, 181, 16, 0, 1401, 1402, 6, 181, 12, 0, 1402, 379, 1, 0, 0, 0, 1403, 1404, 3, 210, 97, 0, 1404, 1405, 1, 0, 0, 0, 1405, 1406, 6, 182, 21, 0, 1406, 1407, 6, 182, 12, 0, 1407, 1408, 6, 182, 33, 0, 1408, 381, 1, 0, 0, 0, 1409, 1410, 3, 88, 36, 0, 1410, 1411, 1, 0, 0, 0, 1411, 1412, 6, 183, 22, 0, 1412, 1413, 6, 183, 12, 0, 1413, 1414, 6, 183, 33, 0, 1414, 383, 1, 0, 0, 0, 1415, 1416, 3, 60, 22, 0, 1416, 1417, 1, 0, 0, 0, 1417, 1418, 6, 184, 11, 0, 1418, 385, 1, 0, 0, 0, 1419, 1420, 3, 62, 23, 0, 1420, 1421, 1, 0, 0, 0, 1421, 1422, 6, 185, 11, 0, 1422, 387, 1, 0, 0, 0, 1423, 1424, 3, 64, 24, 0, 1424, 1425, 1, 0, 0, 0, 1425, 1426, 6, 186, 11, 0, 1426, 389, 1, 0, 0, 0, 1427, 1428, 3, 334, 159, 0, 1428, 1429, 1, 0, 0, 0, 1429, 1430, 6, 187, 18, 0, 1430, 1431, 6, 187, 12, 0, 1431, 1432, 6, 187, 10, 0, 1432, 391, 1, 0, 0, 0, 1433, 1434, 3, 104, 44, 0, 1434, 1435, 1, 0, 0, 0, 1435, 1436, 6, 188, 19, 0, 1436, 1437, 6, 188, 12, 0, 1437, 1438, 6, 188, 10, 0, 1438, 393, 1, 0, 0, 0, 1439, 1440, 3, 60, 22, 0, 1440, 1441, 1, 0, 0, 0, 1441, 1442, 6, 189, 11, 0, 1442, 395, 1, 0, 0, 0, 1443, 1444, 3, 62, 23, 0, 1444, 1445, 1, 0, 0, 0, 1445, 1446, 6, 190, 11, 0, 1446, 397, 1, 0, 0, 0, 1447, 1448, 3, 64, 24, 0, 1448, 1449, 1, 0, 0, 0, 1449, 1450, 6, 191, 11, 0, 1450, 399, 1, 0, 0, 0, 1451, 1452, 3, 176, 80, 0, 1452, 1453, 1, 0, 0, 0, 1453, 1454, 6, 192, 12, 0, 1454, 1455, 6, 192, 0, 0, 1455, 1456, 6, 192, 29, 0, 1456, 401, 1, 0, 0, 0, 1457, 1458, 3, 172, 78, 0, 1458, 1459, 1, 0, 0, 0, 1459, 1460, 6, 193, 12, 0, 1460, 1461, 6, 193, 0, 0, 1461, 1462, 6, 193, 30, 0, 1462, 403, 1, 0, 0, 0, 1463, 1464, 3, 94, 39, 0, 1464, 1465, 1, 0, 0, 0, 1465, 1466, 6, 194, 12, 0, 1466, 1467, 6, 194, 0, 0, 1467, 1468, 6, 194, 34, 0, 1468, 405, 1, 0, 0, 0, 1469, 1470, 3, 66, 25, 0, 1470, 1471, 1, 0, 0, 0, 1471, 1472, 6, 195, 16, 0, 1472, 1473, 6, 195, 12, 0, 1473, 407, 1, 0, 0, 0, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 592, 602, 606, 609, 618, 620, 631, 650, 655, 664, 671, 676, 678, 689, 697, 700, 702, 707, 712, 718, 725, 730, 736, 739, 747, 751, 878, 883, 890, 892, 908, 913, 918, 920, 926, 1003, 1008, 1047, 1051, 1056, 1061, 1066, 1068, 1072, 1074, 1151, 1155, 1160, 1310, 1312, 35, 5, 1, 0, 5, 4, 0, 5, 6, 0, 5, 2, 0, 5, 3, 0, 5, 10, 0, 5, 8, 0, 5, 5, 0, 5, 9, 0, 5, 12, 0, 5, 14, 0, 0, 1, 0, 4, 0, 0, 7, 20, 0, 7, 66, 0, 5, 0, 0, 7, 26, 0, 7, 67, 0, 7, 109, 0, 7, 35, 0, 7, 33, 0, 7, 77, 0, 7, 27, 0, 7, 37, 0, 7, 81, 0, 5, 11, 0, 5, 7, 0, 7, 91, 0, 7, 90, 0, 7, 69, 0, 7, 68, 0, 7, 89, 0, 5, 13, 0, 5, 15, 0, 7, 30, 0] \ No newline at end of file diff --git a/packages/kbn-esql-ast/src/antlr/esql_lexer.tokens b/packages/kbn-esql-ast/src/antlr/esql_lexer.tokens index 2d4bb481826f5..747fbbc64cf5f 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_lexer.tokens +++ b/packages/kbn-esql-ast/src/antlr/esql_lexer.tokens @@ -5,125 +5,124 @@ EVAL=4 EXPLAIN=5 FROM=6 GROK=7 -INLINESTATS=8 -KEEP=9 -LIMIT=10 -LOOKUP=11 -META=12 -METRICS=13 -MV_EXPAND=14 -RENAME=15 -ROW=16 -SHOW=17 -SORT=18 -STATS=19 -WHERE=20 -MATCH=21 +KEEP=8 +LIMIT=9 +META=10 +MV_EXPAND=11 +RENAME=12 +ROW=13 +SHOW=14 +SORT=15 +STATS=16 +WHERE=17 +DEV_INLINESTATS=18 +DEV_LOOKUP=19 +DEV_MATCH=20 +DEV_METRICS=21 UNKNOWN_CMD=22 LINE_COMMENT=23 MULTILINE_COMMENT=24 WS=25 -UNQUOTED_SOURCE=26 -EXPLAIN_WS=27 -EXPLAIN_LINE_COMMENT=28 -EXPLAIN_MULTILINE_COMMENT=29 -PIPE=30 -QUOTED_STRING=31 -INTEGER_LITERAL=32 -DECIMAL_LITERAL=33 -BY=34 -AND=35 -ASC=36 -ASSIGN=37 -CAST_OP=38 -COMMA=39 -DESC=40 -DOT=41 -FALSE=42 -FIRST=43 -IN=44 -IS=45 -LAST=46 -LIKE=47 -LP=48 -MATCH_OPERATOR=49 -NOT=50 -NULL=51 -NULLS=52 -OR=53 -PARAM=54 -RLIKE=55 -RP=56 -TRUE=57 -EQ=58 -CIEQ=59 -NEQ=60 -LT=61 -LTE=62 -GT=63 -GTE=64 -PLUS=65 -MINUS=66 -ASTERISK=67 -SLASH=68 -PERCENT=69 -NAMED_OR_POSITIONAL_PARAM=70 -OPENING_BRACKET=71 -CLOSING_BRACKET=72 -UNQUOTED_IDENTIFIER=73 -QUOTED_IDENTIFIER=74 -EXPR_LINE_COMMENT=75 -EXPR_MULTILINE_COMMENT=76 -EXPR_WS=77 -METADATA=78 -FROM_LINE_COMMENT=79 -FROM_MULTILINE_COMMENT=80 -FROM_WS=81 -ID_PATTERN=82 -PROJECT_LINE_COMMENT=83 -PROJECT_MULTILINE_COMMENT=84 -PROJECT_WS=85 -AS=86 -RENAME_LINE_COMMENT=87 -RENAME_MULTILINE_COMMENT=88 -RENAME_WS=89 -ON=90 -WITH=91 -ENRICH_POLICY_NAME=92 -ENRICH_LINE_COMMENT=93 -ENRICH_MULTILINE_COMMENT=94 -ENRICH_WS=95 -ENRICH_FIELD_LINE_COMMENT=96 -ENRICH_FIELD_MULTILINE_COMMENT=97 -ENRICH_FIELD_WS=98 -LOOKUP_LINE_COMMENT=99 -LOOKUP_MULTILINE_COMMENT=100 -LOOKUP_WS=101 -LOOKUP_FIELD_LINE_COMMENT=102 -LOOKUP_FIELD_MULTILINE_COMMENT=103 -LOOKUP_FIELD_WS=104 -MVEXPAND_LINE_COMMENT=105 -MVEXPAND_MULTILINE_COMMENT=106 -MVEXPAND_WS=107 -INFO=108 -SHOW_LINE_COMMENT=109 -SHOW_MULTILINE_COMMENT=110 -SHOW_WS=111 -FUNCTIONS=112 -META_LINE_COMMENT=113 -META_MULTILINE_COMMENT=114 -META_WS=115 -COLON=116 -SETTING=117 -SETTING_LINE_COMMENT=118 -SETTTING_MULTILINE_COMMENT=119 -SETTING_WS=120 -METRICS_LINE_COMMENT=121 -METRICS_MULTILINE_COMMENT=122 -METRICS_WS=123 -CLOSING_METRICS_LINE_COMMENT=124 -CLOSING_METRICS_MULTILINE_COMMENT=125 -CLOSING_METRICS_WS=126 +PIPE=26 +QUOTED_STRING=27 +INTEGER_LITERAL=28 +DECIMAL_LITERAL=29 +BY=30 +AND=31 +ASC=32 +ASSIGN=33 +CAST_OP=34 +COMMA=35 +DESC=36 +DOT=37 +FALSE=38 +FIRST=39 +IN=40 +IS=41 +LAST=42 +LIKE=43 +LP=44 +NOT=45 +NULL=46 +NULLS=47 +OR=48 +PARAM=49 +RLIKE=50 +RP=51 +TRUE=52 +EQ=53 +CIEQ=54 +NEQ=55 +LT=56 +LTE=57 +GT=58 +GTE=59 +PLUS=60 +MINUS=61 +ASTERISK=62 +SLASH=63 +PERCENT=64 +NAMED_OR_POSITIONAL_PARAM=65 +OPENING_BRACKET=66 +CLOSING_BRACKET=67 +UNQUOTED_IDENTIFIER=68 +QUOTED_IDENTIFIER=69 +EXPR_LINE_COMMENT=70 +EXPR_MULTILINE_COMMENT=71 +EXPR_WS=72 +EXPLAIN_WS=73 +EXPLAIN_LINE_COMMENT=74 +EXPLAIN_MULTILINE_COMMENT=75 +METADATA=76 +UNQUOTED_SOURCE=77 +FROM_LINE_COMMENT=78 +FROM_MULTILINE_COMMENT=79 +FROM_WS=80 +ID_PATTERN=81 +PROJECT_LINE_COMMENT=82 +PROJECT_MULTILINE_COMMENT=83 +PROJECT_WS=84 +AS=85 +RENAME_LINE_COMMENT=86 +RENAME_MULTILINE_COMMENT=87 +RENAME_WS=88 +ON=89 +WITH=90 +ENRICH_POLICY_NAME=91 +ENRICH_LINE_COMMENT=92 +ENRICH_MULTILINE_COMMENT=93 +ENRICH_WS=94 +ENRICH_FIELD_LINE_COMMENT=95 +ENRICH_FIELD_MULTILINE_COMMENT=96 +ENRICH_FIELD_WS=97 +MVEXPAND_LINE_COMMENT=98 +MVEXPAND_MULTILINE_COMMENT=99 +MVEXPAND_WS=100 +INFO=101 +SHOW_LINE_COMMENT=102 +SHOW_MULTILINE_COMMENT=103 +SHOW_WS=104 +FUNCTIONS=105 +META_LINE_COMMENT=106 +META_MULTILINE_COMMENT=107 +META_WS=108 +COLON=109 +SETTING=110 +SETTING_LINE_COMMENT=111 +SETTTING_MULTILINE_COMMENT=112 +SETTING_WS=113 +LOOKUP_LINE_COMMENT=114 +LOOKUP_MULTILINE_COMMENT=115 +LOOKUP_WS=116 +LOOKUP_FIELD_LINE_COMMENT=117 +LOOKUP_FIELD_MULTILINE_COMMENT=118 +LOOKUP_FIELD_WS=119 +METRICS_LINE_COMMENT=120 +METRICS_MULTILINE_COMMENT=121 +METRICS_WS=122 +CLOSING_METRICS_LINE_COMMENT=123 +CLOSING_METRICS_MULTILINE_COMMENT=124 +CLOSING_METRICS_WS=125 'dissect'=1 'drop'=2 'enrich'=3 @@ -131,60 +130,57 @@ CLOSING_METRICS_WS=126 'explain'=5 'from'=6 'grok'=7 -'inlinestats'=8 -'keep'=9 -'limit'=10 -'lookup'=11 -'meta'=12 -'metrics'=13 -'mv_expand'=14 -'rename'=15 -'row'=16 -'show'=17 -'sort'=18 -'stats'=19 -'where'=20 -'|'=30 -'by'=34 -'and'=35 -'asc'=36 -'='=37 -'::'=38 -','=39 -'desc'=40 -'.'=41 -'false'=42 -'first'=43 -'in'=44 -'is'=45 -'last'=46 -'like'=47 -'('=48 -'not'=50 -'null'=51 -'nulls'=52 -'or'=53 -'?'=54 -'rlike'=55 -')'=56 -'true'=57 -'=='=58 -'=~'=59 -'!='=60 -'<'=61 -'<='=62 -'>'=63 -'>='=64 -'+'=65 -'-'=66 -'*'=67 -'/'=68 -'%'=69 -']'=72 -'metadata'=78 -'as'=86 -'on'=90 -'with'=91 -'info'=108 -'functions'=112 -':'=116 +'keep'=8 +'limit'=9 +'meta'=10 +'mv_expand'=11 +'rename'=12 +'row'=13 +'show'=14 +'sort'=15 +'stats'=16 +'where'=17 +'|'=26 +'by'=30 +'and'=31 +'asc'=32 +'='=33 +'::'=34 +','=35 +'desc'=36 +'.'=37 +'false'=38 +'first'=39 +'in'=40 +'is'=41 +'last'=42 +'like'=43 +'('=44 +'not'=45 +'null'=46 +'nulls'=47 +'or'=48 +'?'=49 +'rlike'=50 +')'=51 +'true'=52 +'=='=53 +'=~'=54 +'!='=55 +'<'=56 +'<='=57 +'>'=58 +'>='=59 +'+'=60 +'-'=61 +'*'=62 +'/'=63 +'%'=64 +']'=67 +'metadata'=76 +'as'=85 +'on'=89 +'with'=90 +'info'=101 +'functions'=105 +':'=109 diff --git a/packages/kbn-esql-ast/src/antlr/esql_lexer.ts b/packages/kbn-esql-ast/src/antlr/esql_lexer.ts index 179382f9f736e..a3be12402651c 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_lexer.ts +++ b/packages/kbn-esql-ast/src/antlr/esql_lexer.ts @@ -12,7 +12,17 @@ import { PredictionContextCache, Token } from "antlr4"; -export default class esql_lexer extends Lexer { + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import lexer_config from './lexer_config.js'; + +export default class esql_lexer extends lexer_config { public static readonly DISSECT = 1; public static readonly DROP = 2; public static readonly ENRICH = 3; @@ -20,139 +30,138 @@ export default class esql_lexer extends Lexer { public static readonly EXPLAIN = 5; public static readonly FROM = 6; public static readonly GROK = 7; - public static readonly INLINESTATS = 8; - public static readonly KEEP = 9; - public static readonly LIMIT = 10; - public static readonly LOOKUP = 11; - public static readonly META = 12; - public static readonly METRICS = 13; - public static readonly MV_EXPAND = 14; - public static readonly RENAME = 15; - public static readonly ROW = 16; - public static readonly SHOW = 17; - public static readonly SORT = 18; - public static readonly STATS = 19; - public static readonly WHERE = 20; - public static readonly MATCH = 21; + public static readonly KEEP = 8; + public static readonly LIMIT = 9; + public static readonly META = 10; + public static readonly MV_EXPAND = 11; + public static readonly RENAME = 12; + public static readonly ROW = 13; + public static readonly SHOW = 14; + public static readonly SORT = 15; + public static readonly STATS = 16; + public static readonly WHERE = 17; + public static readonly DEV_INLINESTATS = 18; + public static readonly DEV_LOOKUP = 19; + public static readonly DEV_MATCH = 20; + public static readonly DEV_METRICS = 21; public static readonly UNKNOWN_CMD = 22; public static readonly LINE_COMMENT = 23; public static readonly MULTILINE_COMMENT = 24; public static readonly WS = 25; - public static readonly UNQUOTED_SOURCE = 26; - public static readonly EXPLAIN_WS = 27; - public static readonly EXPLAIN_LINE_COMMENT = 28; - public static readonly EXPLAIN_MULTILINE_COMMENT = 29; - public static readonly PIPE = 30; - public static readonly QUOTED_STRING = 31; - public static readonly INTEGER_LITERAL = 32; - public static readonly DECIMAL_LITERAL = 33; - public static readonly BY = 34; - public static readonly AND = 35; - public static readonly ASC = 36; - public static readonly ASSIGN = 37; - public static readonly CAST_OP = 38; - public static readonly COMMA = 39; - public static readonly DESC = 40; - public static readonly DOT = 41; - public static readonly FALSE = 42; - public static readonly FIRST = 43; - public static readonly IN = 44; - public static readonly IS = 45; - public static readonly LAST = 46; - public static readonly LIKE = 47; - public static readonly LP = 48; - public static readonly MATCH_OPERATOR = 49; - public static readonly NOT = 50; - public static readonly NULL = 51; - public static readonly NULLS = 52; - public static readonly OR = 53; - public static readonly PARAM = 54; - public static readonly RLIKE = 55; - public static readonly RP = 56; - public static readonly TRUE = 57; - public static readonly EQ = 58; - public static readonly CIEQ = 59; - public static readonly NEQ = 60; - public static readonly LT = 61; - public static readonly LTE = 62; - public static readonly GT = 63; - public static readonly GTE = 64; - public static readonly PLUS = 65; - public static readonly MINUS = 66; - public static readonly ASTERISK = 67; - public static readonly SLASH = 68; - public static readonly PERCENT = 69; - public static readonly NAMED_OR_POSITIONAL_PARAM = 70; - public static readonly OPENING_BRACKET = 71; - public static readonly CLOSING_BRACKET = 72; - public static readonly UNQUOTED_IDENTIFIER = 73; - public static readonly QUOTED_IDENTIFIER = 74; - public static readonly EXPR_LINE_COMMENT = 75; - public static readonly EXPR_MULTILINE_COMMENT = 76; - public static readonly EXPR_WS = 77; - public static readonly METADATA = 78; - public static readonly FROM_LINE_COMMENT = 79; - public static readonly FROM_MULTILINE_COMMENT = 80; - public static readonly FROM_WS = 81; - public static readonly ID_PATTERN = 82; - public static readonly PROJECT_LINE_COMMENT = 83; - public static readonly PROJECT_MULTILINE_COMMENT = 84; - public static readonly PROJECT_WS = 85; - public static readonly AS = 86; - public static readonly RENAME_LINE_COMMENT = 87; - public static readonly RENAME_MULTILINE_COMMENT = 88; - public static readonly RENAME_WS = 89; - public static readonly ON = 90; - public static readonly WITH = 91; - public static readonly ENRICH_POLICY_NAME = 92; - public static readonly ENRICH_LINE_COMMENT = 93; - public static readonly ENRICH_MULTILINE_COMMENT = 94; - public static readonly ENRICH_WS = 95; - public static readonly ENRICH_FIELD_LINE_COMMENT = 96; - public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 97; - public static readonly ENRICH_FIELD_WS = 98; - public static readonly LOOKUP_LINE_COMMENT = 99; - public static readonly LOOKUP_MULTILINE_COMMENT = 100; - public static readonly LOOKUP_WS = 101; - public static readonly LOOKUP_FIELD_LINE_COMMENT = 102; - public static readonly LOOKUP_FIELD_MULTILINE_COMMENT = 103; - public static readonly LOOKUP_FIELD_WS = 104; - public static readonly MVEXPAND_LINE_COMMENT = 105; - public static readonly MVEXPAND_MULTILINE_COMMENT = 106; - public static readonly MVEXPAND_WS = 107; - public static readonly INFO = 108; - public static readonly SHOW_LINE_COMMENT = 109; - public static readonly SHOW_MULTILINE_COMMENT = 110; - public static readonly SHOW_WS = 111; - public static readonly FUNCTIONS = 112; - public static readonly META_LINE_COMMENT = 113; - public static readonly META_MULTILINE_COMMENT = 114; - public static readonly META_WS = 115; - public static readonly COLON = 116; - public static readonly SETTING = 117; - public static readonly SETTING_LINE_COMMENT = 118; - public static readonly SETTTING_MULTILINE_COMMENT = 119; - public static readonly SETTING_WS = 120; - public static readonly METRICS_LINE_COMMENT = 121; - public static readonly METRICS_MULTILINE_COMMENT = 122; - public static readonly METRICS_WS = 123; - public static readonly CLOSING_METRICS_LINE_COMMENT = 124; - public static readonly CLOSING_METRICS_MULTILINE_COMMENT = 125; - public static readonly CLOSING_METRICS_WS = 126; + public static readonly PIPE = 26; + public static readonly QUOTED_STRING = 27; + public static readonly INTEGER_LITERAL = 28; + public static readonly DECIMAL_LITERAL = 29; + public static readonly BY = 30; + public static readonly AND = 31; + public static readonly ASC = 32; + public static readonly ASSIGN = 33; + public static readonly CAST_OP = 34; + public static readonly COMMA = 35; + public static readonly DESC = 36; + public static readonly DOT = 37; + public static readonly FALSE = 38; + public static readonly FIRST = 39; + public static readonly IN = 40; + public static readonly IS = 41; + public static readonly LAST = 42; + public static readonly LIKE = 43; + public static readonly LP = 44; + public static readonly NOT = 45; + public static readonly NULL = 46; + public static readonly NULLS = 47; + public static readonly OR = 48; + public static readonly PARAM = 49; + public static readonly RLIKE = 50; + public static readonly RP = 51; + public static readonly TRUE = 52; + public static readonly EQ = 53; + public static readonly CIEQ = 54; + public static readonly NEQ = 55; + public static readonly LT = 56; + public static readonly LTE = 57; + public static readonly GT = 58; + public static readonly GTE = 59; + public static readonly PLUS = 60; + public static readonly MINUS = 61; + public static readonly ASTERISK = 62; + public static readonly SLASH = 63; + public static readonly PERCENT = 64; + public static readonly NAMED_OR_POSITIONAL_PARAM = 65; + public static readonly OPENING_BRACKET = 66; + public static readonly CLOSING_BRACKET = 67; + public static readonly UNQUOTED_IDENTIFIER = 68; + public static readonly QUOTED_IDENTIFIER = 69; + public static readonly EXPR_LINE_COMMENT = 70; + public static readonly EXPR_MULTILINE_COMMENT = 71; + public static readonly EXPR_WS = 72; + public static readonly EXPLAIN_WS = 73; + public static readonly EXPLAIN_LINE_COMMENT = 74; + public static readonly EXPLAIN_MULTILINE_COMMENT = 75; + public static readonly METADATA = 76; + public static readonly UNQUOTED_SOURCE = 77; + public static readonly FROM_LINE_COMMENT = 78; + public static readonly FROM_MULTILINE_COMMENT = 79; + public static readonly FROM_WS = 80; + public static readonly ID_PATTERN = 81; + public static readonly PROJECT_LINE_COMMENT = 82; + public static readonly PROJECT_MULTILINE_COMMENT = 83; + public static readonly PROJECT_WS = 84; + public static readonly AS = 85; + public static readonly RENAME_LINE_COMMENT = 86; + public static readonly RENAME_MULTILINE_COMMENT = 87; + public static readonly RENAME_WS = 88; + public static readonly ON = 89; + public static readonly WITH = 90; + public static readonly ENRICH_POLICY_NAME = 91; + public static readonly ENRICH_LINE_COMMENT = 92; + public static readonly ENRICH_MULTILINE_COMMENT = 93; + public static readonly ENRICH_WS = 94; + public static readonly ENRICH_FIELD_LINE_COMMENT = 95; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 96; + public static readonly ENRICH_FIELD_WS = 97; + public static readonly MVEXPAND_LINE_COMMENT = 98; + public static readonly MVEXPAND_MULTILINE_COMMENT = 99; + public static readonly MVEXPAND_WS = 100; + public static readonly INFO = 101; + public static readonly SHOW_LINE_COMMENT = 102; + public static readonly SHOW_MULTILINE_COMMENT = 103; + public static readonly SHOW_WS = 104; + public static readonly FUNCTIONS = 105; + public static readonly META_LINE_COMMENT = 106; + public static readonly META_MULTILINE_COMMENT = 107; + public static readonly META_WS = 108; + public static readonly COLON = 109; + public static readonly SETTING = 110; + public static readonly SETTING_LINE_COMMENT = 111; + public static readonly SETTTING_MULTILINE_COMMENT = 112; + public static readonly SETTING_WS = 113; + public static readonly LOOKUP_LINE_COMMENT = 114; + public static readonly LOOKUP_MULTILINE_COMMENT = 115; + public static readonly LOOKUP_WS = 116; + public static readonly LOOKUP_FIELD_LINE_COMMENT = 117; + public static readonly LOOKUP_FIELD_MULTILINE_COMMENT = 118; + public static readonly LOOKUP_FIELD_WS = 119; + public static readonly METRICS_LINE_COMMENT = 120; + public static readonly METRICS_MULTILINE_COMMENT = 121; + public static readonly METRICS_WS = 122; + public static readonly CLOSING_METRICS_LINE_COMMENT = 123; + public static readonly CLOSING_METRICS_MULTILINE_COMMENT = 124; + public static readonly CLOSING_METRICS_WS = 125; public static readonly EOF = Token.EOF; - public static readonly EXPLAIN_MODE = 1; - public static readonly EXPRESSION_MODE = 2; + public static readonly EXPRESSION_MODE = 1; + public static readonly EXPLAIN_MODE = 2; public static readonly FROM_MODE = 3; public static readonly PROJECT_MODE = 4; public static readonly RENAME_MODE = 5; public static readonly ENRICH_MODE = 6; public static readonly ENRICH_FIELD_MODE = 7; - public static readonly LOOKUP_MODE = 8; - public static readonly LOOKUP_FIELD_MODE = 9; - public static readonly MVEXPAND_MODE = 10; - public static readonly SHOW_MODE = 11; - public static readonly META_MODE = 12; - public static readonly SETTING_MODE = 13; + public static readonly MVEXPAND_MODE = 8; + public static readonly SHOW_MODE = 9; + public static readonly META_MODE = 10; + public static readonly SETTING_MODE = 11; + public static readonly LOOKUP_MODE = 12; + public static readonly LOOKUP_FIELD_MODE = 13; public static readonly METRICS_MODE = 14; public static readonly CLOSING_METRICS_MODE = 15; @@ -161,11 +170,8 @@ export default class esql_lexer extends Lexer { "'drop'", "'enrich'", "'eval'", "'explain'", "'from'", "'grok'", - "'inlinestats'", "'keep'", "'limit'", - "'lookup'", - "'meta'", "'metrics'", - "'mv_expand'", + "'meta'", "'mv_expand'", "'rename'", "'row'", "'show'", "'sort'", "'stats'", @@ -173,17 +179,16 @@ export default class esql_lexer extends Lexer { null, null, null, null, null, null, + null, "'|'", null, null, - "'|'", null, - null, null, - "'by'", "'and'", - "'asc'", "'='", - "'::'", "','", - "'desc'", "'.'", - "'false'", "'first'", - "'in'", "'is'", - "'last'", "'like'", - "'('", null, + null, "'by'", + "'and'", "'asc'", + "'='", "'::'", + "','", "'desc'", + "'.'", "'false'", + "'first'", "'in'", + "'is'", "'last'", + "'like'", "'('", "'not'", "'null'", "'nulls'", "'or'", "'?'", "'rlike'", @@ -198,46 +203,43 @@ export default class esql_lexer extends Lexer { "']'", null, null, null, null, null, - "'metadata'", null, null, + null, "'metadata'", null, null, null, null, - null, "'as'", null, null, - null, "'on'", - "'with'", null, null, null, + "'as'", null, null, null, + "'on'", "'with'", null, null, null, null, null, null, null, null, null, null, - null, "'info'", + "'info'", null, null, null, - null, "'functions'", + "'functions'", null, null, null, "':'" ]; public static readonly symbolicNames: (string | null)[] = [ null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", - "INLINESTATS", "KEEP", "LIMIT", - "LOOKUP", "META", - "METRICS", - "MV_EXPAND", + "META", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", "WHERE", - "MATCH", "UNKNOWN_CMD", + "DEV_INLINESTATS", + "DEV_LOOKUP", + "DEV_MATCH", + "DEV_METRICS", + "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", - "WS", "UNQUOTED_SOURCE", - "EXPLAIN_WS", - "EXPLAIN_LINE_COMMENT", - "EXPLAIN_MULTILINE_COMMENT", - "PIPE", "QUOTED_STRING", + "WS", "PIPE", + "QUOTED_STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", @@ -248,7 +250,6 @@ export default class esql_lexer extends Lexer { "FIRST", "IN", "IS", "LAST", "LIKE", "LP", - "MATCH_OPERATOR", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", @@ -267,7 +268,11 @@ export default class esql_lexer extends Lexer { "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", @@ -286,12 +291,6 @@ export default class esql_lexer extends Lexer { "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", - "LOOKUP_LINE_COMMENT", - "LOOKUP_MULTILINE_COMMENT", - "LOOKUP_WS", - "LOOKUP_FIELD_LINE_COMMENT", - "LOOKUP_FIELD_MULTILINE_COMMENT", - "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", @@ -306,38 +305,44 @@ export default class esql_lexer extends Lexer { "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" ]; - public static readonly modeNames: string[] = [ "DEFAULT_MODE", "EXPLAIN_MODE", - "EXPRESSION_MODE", "FROM_MODE", + public static readonly modeNames: string[] = [ "DEFAULT_MODE", "EXPRESSION_MODE", + "EXPLAIN_MODE", "FROM_MODE", "PROJECT_MODE", "RENAME_MODE", "ENRICH_MODE", "ENRICH_FIELD_MODE", - "LOOKUP_MODE", "LOOKUP_FIELD_MODE", "MVEXPAND_MODE", "SHOW_MODE", "META_MODE", "SETTING_MODE", + "LOOKUP_MODE", "LOOKUP_FIELD_MODE", "METRICS_MODE", "CLOSING_METRICS_MODE", ]; public static readonly ruleNames: string[] = [ - "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "INLINESTATS", - "KEEP", "LIMIT", "LOOKUP", "META", "METRICS", "MV_EXPAND", "RENAME", "ROW", - "SHOW", "SORT", "STATS", "WHERE", "MATCH", "UNKNOWN_CMD", "LINE_COMMENT", - "MULTILINE_COMMENT", "WS", "UNQUOTED_SOURCE_PART", "UNQUOTED_SOURCE", - "EXPLAIN_OPENING_BRACKET", "EXPLAIN_PIPE", "EXPLAIN_WS", "EXPLAIN_LINE_COMMENT", - "EXPLAIN_MULTILINE_COMMENT", "PIPE", "DIGIT", "LETTER", "ESCAPE_SEQUENCE", - "UNESCAPED_CHARS", "EXPONENT", "ASPERAND", "BACKQUOTE", "BACKQUOTE_BLOCK", - "UNDERSCORE", "UNQUOTED_ID_BODY", "QUOTED_STRING", "INTEGER_LITERAL", - "DECIMAL_LITERAL", "BY", "AND", "ASC", "ASSIGN", "CAST_OP", "COMMA", "DESC", - "DOT", "FALSE", "FIRST", "IN", "IS", "LAST", "LIKE", "LP", "MATCH_OPERATOR", - "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_ID", "QUOTED_IDENTIFIER", "EXPR_LINE_COMMENT", - "EXPR_MULTILINE_COMMENT", "EXPR_WS", "FROM_PIPE", "FROM_OPENING_BRACKET", - "FROM_CLOSING_BRACKET", "FROM_COLON", "FROM_COMMA", "FROM_ASSIGN", "METADATA", + "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", "KEEP", + "LIMIT", "META", "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", "UNQUOTED_ID_BODY_WITH_PATTERN", "UNQUOTED_ID_PATTERN", "ID_PATTERN", "PROJECT_LINE_COMMENT", "PROJECT_MULTILINE_COMMENT", @@ -348,17 +353,16 @@ export default class esql_lexer extends Lexer { "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_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", - "ENRICH_FIELD_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", "MVEXPAND_PIPE", - "MVEXPAND_DOT", "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", - "META_PIPE", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", + "ENRICH_FIELD_WS", "MVEXPAND_PIPE", "MVEXPAND_DOT", "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", "META_PIPE", "FUNCTIONS", "META_LINE_COMMENT", "META_MULTILINE_COMMENT", "META_WS", "SETTING_CLOSING_BRACKET", "COLON", "SETTING", "SETTING_LINE_COMMENT", - "SETTTING_MULTILINE_COMMENT", "SETTING_WS", "METRICS_PIPE", "METRICS_UNQUOTED_SOURCE", + "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", @@ -383,7 +387,59 @@ export default class esql_lexer extends Lexer { public get modeNames(): string[] { return esql_lexer.modeNames; } - public static readonly _serializedATN: number[] = [4,0,126,1468,6,-1,6, + // @Override + public sempred(localctx: RuleContext, ruleIndex: number, predIndex: number): boolean { + switch (ruleIndex) { + case 17: + return this.DEV_INLINESTATS_sempred(localctx, predIndex); + case 18: + return this.DEV_LOOKUP_sempred(localctx, predIndex); + case 19: + return this.DEV_MATCH_sempred(localctx, predIndex); + case 20: + return this.DEV_METRICS_sempred(localctx, predIndex); + case 74: + return this.DEV_MATCH_OP_sempred(localctx, predIndex); + } + return true; + } + private DEV_INLINESTATS_sempred(localctx: RuleContext, predIndex: number): boolean { + switch (predIndex) { + case 0: + return this.isDevVersion(); + } + return true; + } + private DEV_LOOKUP_sempred(localctx: RuleContext, predIndex: number): boolean { + switch (predIndex) { + case 1: + return this.isDevVersion(); + } + return true; + } + private DEV_MATCH_sempred(localctx: RuleContext, predIndex: number): boolean { + switch (predIndex) { + case 2: + return this.isDevVersion(); + } + return true; + } + private DEV_METRICS_sempred(localctx: RuleContext, predIndex: number): boolean { + switch (predIndex) { + case 3: + return this.isDevVersion(); + } + return true; + } + private DEV_MATCH_OP_sempred(localctx: RuleContext, predIndex: number): boolean { + switch (predIndex) { + case 4: + return this.isDevVersion(); + } + return true; + } + + public static readonly _serializedATN: number[] = [4,0,125,1474,6,-1,6, -1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1, 2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8, 2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16, @@ -418,475 +474,477 @@ export default class esql_lexer extends Lexer { 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,7,1,7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9, - 1,9,1,9,1,9,1,9,1,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,11,1,12,1,12,1,12,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,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,14,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,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,19,1,19,1,19,1,19,1,19,1,19,1,19,1,19, - 1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,21,4,21,587,8,21,11,21,12,21, - 588,1,21,1,21,1,22,1,22,1,22,1,22,5,22,597,8,22,10,22,12,22,600,9,22,1, - 22,3,22,603,8,22,1,22,3,22,606,8,22,1,22,1,22,1,23,1,23,1,23,1,23,1,23, - 5,23,615,8,23,10,23,12,23,618,9,23,1,23,1,23,1,23,1,23,1,23,1,24,4,24,626, - 8,24,11,24,12,24,627,1,24,1,24,1,25,1,25,1,25,3,25,635,8,25,1,26,4,26,638, - 8,26,11,26,12,26,639,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28, - 1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,32,1,32,1, - 32,1,32,1,33,1,33,1,34,1,34,1,35,1,35,1,35,1,36,1,36,1,37,1,37,3,37,679, - 8,37,1,37,4,37,682,8,37,11,37,12,37,683,1,38,1,38,1,39,1,39,1,40,1,40,1, - 40,3,40,693,8,40,1,41,1,41,1,42,1,42,1,42,3,42,700,8,42,1,43,1,43,1,43, - 5,43,705,8,43,10,43,12,43,708,9,43,1,43,1,43,1,43,1,43,1,43,1,43,5,43,716, - 8,43,10,43,12,43,719,9,43,1,43,1,43,1,43,1,43,1,43,3,43,726,8,43,1,43,3, - 43,729,8,43,3,43,731,8,43,1,44,4,44,734,8,44,11,44,12,44,735,1,45,4,45, - 739,8,45,11,45,12,45,740,1,45,1,45,5,45,745,8,45,10,45,12,45,748,9,45,1, - 45,1,45,4,45,752,8,45,11,45,12,45,753,1,45,4,45,757,8,45,11,45,12,45,758, - 1,45,1,45,5,45,763,8,45,10,45,12,45,766,9,45,3,45,768,8,45,1,45,1,45,1, - 45,1,45,4,45,774,8,45,11,45,12,45,775,1,45,1,45,3,45,780,8,45,1,46,1,46, - 1,46,1,47,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,49,1,49,1,50,1,50,1,50,1, - 51,1,51,1,52,1,52,1,52,1,52,1,52,1,53,1,53,1,54,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,57,1,58,1,58,1, - 58,1,58,1,58,1,59,1,59,1,59,1,59,1,59,1,60,1,60,1,61,1,61,1,61,1,61,1,61, - 1,61,1,62,1,62,1,62,1,62,1,63,1,63,1,63,1,63,1,63,1,64,1,64,1,64,1,64,1, - 64,1,64,1,65,1,65,1,65,1,66,1,66,1,67,1,67,1,67,1,67,1,67,1,67,1,68,1,68, - 1,69,1,69,1,69,1,69,1,69,1,70,1,70,1,70,1,71,1,71,1,71,1,72,1,72,1,72,1, - 73,1,73,1,74,1,74,1,74,1,75,1,75,1,76,1,76,1,76,1,77,1,77,1,78,1,78,1,79, - 1,79,1,80,1,80,1,81,1,81,1,82,1,82,1,82,5,82,908,8,82,10,82,12,82,911,9, - 82,1,82,1,82,4,82,915,8,82,11,82,12,82,916,3,82,919,8,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,5,85,933,8,85,10,85,12,85, - 936,9,85,1,85,1,85,3,85,940,8,85,1,85,4,85,943,8,85,11,85,12,85,944,3,85, - 947,8,85,1,86,1,86,4,86,951,8,86,11,86,12,86,952,1,86,1,86,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,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, - 95,1,95,1,95,1,95,1,96,1,96,1,96,1,96,1,97,1,97,1,97,1,97,1,97,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,103,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,1042,8,106,1,107,1,107,3,107,1046,8,107,1,107,5,107,1049,8, - 107,10,107,12,107,1052,9,107,1,107,1,107,3,107,1056,8,107,1,107,4,107,1059, - 8,107,11,107,12,107,1060,3,107,1063,8,107,1,108,1,108,4,108,1067,8,108, - 11,108,12,108,1068,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,117, - 1,117,1,117,1,117,1,118,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,121,1,122,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,124, - 1,124,1,125,1,125,1,126,4,126,1144,8,126,11,126,12,126,1145,1,126,1,126, - 3,126,1150,8,126,1,126,4,126,1153,8,126,11,126,12,126,1154,1,127,1,127, - 1,127,1,127,1,128,1,128,1,128,1,128,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,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,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,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,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,156,1,156,1,156,1,156,1,157,1,157,1,157,1,157,1,158,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,161,1,161,1,161, - 1,161,1,162,1,162,1,162,1,162,1,163,1,163,1,163,1,163,1,164,1,164,1,164, - 1,164,1,165,1,165,1,165,1,165,1,165,1,166,1,166,1,166,1,166,1,166,1,167, - 1,167,1,167,1,167,1,168,1,168,1,168,1,168,1,169,1,169,1,169,1,169,1,170, - 1,170,1,170,1,170,1,170,1,171,1,171,1,171,1,171,1,171,1,171,1,171,1,171, + 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,10,1, + 10,1,10,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,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1, + 13,1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15, + 1,15,1,15,1,15,1,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1, + 17,1,17,1,17,1,17,1,17,1,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,19,1,19,1,19,1,19,1,19,1,19,1, + 19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,20,1,21, + 4,21,591,8,21,11,21,12,21,592,1,21,1,21,1,22,1,22,1,22,1,22,5,22,601,8, + 22,10,22,12,22,604,9,22,1,22,3,22,607,8,22,1,22,3,22,610,8,22,1,22,1,22, + 1,23,1,23,1,23,1,23,1,23,5,23,619,8,23,10,23,12,23,622,9,23,1,23,1,23,1, + 23,1,23,1,23,1,24,4,24,630,8,24,11,24,12,24,631,1,24,1,24,1,25,1,25,1,25, + 1,25,1,26,1,26,1,27,1,27,1,28,1,28,1,28,1,29,1,29,1,30,1,30,3,30,651,8, + 30,1,30,4,30,654,8,30,11,30,12,30,655,1,31,1,31,1,32,1,32,1,33,1,33,1,33, + 3,33,665,8,33,1,34,1,34,1,35,1,35,1,35,3,35,672,8,35,1,36,1,36,1,36,5,36, + 677,8,36,10,36,12,36,680,9,36,1,36,1,36,1,36,1,36,1,36,1,36,5,36,688,8, + 36,10,36,12,36,691,9,36,1,36,1,36,1,36,1,36,1,36,3,36,698,8,36,1,36,3,36, + 701,8,36,3,36,703,8,36,1,37,4,37,706,8,37,11,37,12,37,707,1,38,4,38,711, + 8,38,11,38,12,38,712,1,38,1,38,5,38,717,8,38,10,38,12,38,720,9,38,1,38, + 1,38,4,38,724,8,38,11,38,12,38,725,1,38,4,38,729,8,38,11,38,12,38,730,1, + 38,1,38,5,38,735,8,38,10,38,12,38,738,9,38,3,38,740,8,38,1,38,1,38,1,38, + 1,38,4,38,746,8,38,11,38,12,38,747,1,38,1,38,3,38,752,8,38,1,39,1,39,1, + 39,1,40,1,40,1,40,1,40,1,41,1,41,1,41,1,41,1,42,1,42,1,43,1,43,1,43,1,44, + 1,44,1,45,1,45,1,45,1,45,1,45,1,46,1,46,1,47,1,47,1,47,1,47,1,47,1,47,1, + 48,1,48,1,48,1,48,1,48,1,48,1,49,1,49,1,49,1,50,1,50,1,50,1,51,1,51,1,51, + 1,51,1,51,1,52,1,52,1,52,1,52,1,52,1,53,1,53,1,54,1,54,1,54,1,54,1,55,1, + 55,1,55,1,55,1,55,1,56,1,56,1,56,1,56,1,56,1,56,1,57,1,57,1,57,1,58,1,58, + 1,59,1,59,1,59,1,59,1,59,1,59,1,60,1,60,1,61,1,61,1,61,1,61,1,61,1,62,1, + 62,1,62,1,63,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,68,1,69,1,69,1,70,1,70,1,71,1,71,1,72,1,72,1,73,1,73,1,74,1, + 74,1,74,1,74,1,74,1,75,1,75,1,75,3,75,879,8,75,1,75,5,75,882,8,75,10,75, + 12,75,885,9,75,1,75,1,75,4,75,889,8,75,11,75,12,75,890,3,75,893,8,75,1, + 76,1,76,1,76,1,76,1,76,1,77,1,77,1,77,1,77,1,77,1,78,1,78,5,78,907,8,78, + 10,78,12,78,910,9,78,1,78,1,78,3,78,914,8,78,1,78,4,78,917,8,78,11,78,12, + 78,918,3,78,921,8,78,1,79,1,79,4,79,925,8,79,11,79,12,79,926,1,79,1,79, + 1,80,1,80,1,81,1,81,1,81,1,81,1,82,1,82,1,82,1,82,1,83,1,83,1,83,1,83,1, + 84,1,84,1,84,1,84,1,84,1,85,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,89,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,95,1,95,1,95,1,95,1,95,1,95,1,95,1,95,1,95,1,96,1,96,1, + 96,3,96,1004,8,96,1,97,4,97,1007,8,97,11,97,12,97,1008,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,103,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,1048,8,106, + 1,107,1,107,3,107,1052,8,107,1,107,5,107,1055,8,107,10,107,12,107,1058, + 9,107,1,107,1,107,3,107,1062,8,107,1,107,4,107,1065,8,107,11,107,12,107, + 1066,3,107,1069,8,107,1,108,1,108,4,108,1073,8,108,11,108,12,108,1074,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,117,1,117,1,117,1,117,1, + 118,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,121,1,122,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,124,1,124,1,125,1,125,1, + 126,4,126,1150,8,126,11,126,12,126,1151,1,126,1,126,3,126,1156,8,126,1, + 126,4,126,1159,8,126,11,126,12,126,1160,1,127,1,127,1,127,1,127,1,128,1, + 128,1,128,1,128,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,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,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,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,147,1,147,1,147,1,147,1,148,1,148,1, + 148,1,148,1,148,1,149,1,149,1,149,1,149,1,149,1,150,1,150,1,150,1,150,1, + 151,1,151,1,151,1,151,1,152,1,152,1,152,1,152,1,153,1,153,1,153,1,153,1, + 153,1,154,1,154,1,154,1,154,1,154,1,154,1,154,1,154,1,154,1,154,1,155,1, + 155,1,155,1,155,1,156,1,156,1,156,1,156,1,157,1,157,1,157,1,157,1,158,1, + 158,1,158,1,158,1,158,1,159,1,159,1,160,1,160,1,160,1,160,1,160,4,160,1311, + 8,160,11,160,12,160,1312,1,161,1,161,1,161,1,161,1,162,1,162,1,162,1,162, + 1,163,1,163,1,163,1,163,1,164,1,164,1,164,1,164,1,164,1,165,1,165,1,165, + 1,165,1,166,1,166,1,166,1,166,1,167,1,167,1,167,1,167,1,168,1,168,1,168, + 1,168,1,168,1,169,1,169,1,169,1,169,1,170,1,170,1,170,1,170,1,171,1,171, 1,171,1,171,1,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,176,1,176,1,177,1,177,1,177, - 1,177,1,177,4,177,1377,8,177,11,177,12,177,1378,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,181,1,182,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,185,1,185,1,185,1,185,1,186,1,186,1,186, - 1,186,1,187,1,187,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,190,1,190,1,190,1,190,1,191,1,191,1,191, - 1,191,1,192,1,192,1,192,1,192,1,192,1,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, - 2,616,717,0,196,16,1,18,2,20,3,22,4,24,5,26,6,28,7,30,8,32,9,34,10,36,11, - 38,12,40,13,42,14,44,15,46,16,48,17,50,18,52,19,54,20,56,21,58,22,60,23, - 62,24,64,25,66,0,68,26,70,0,72,0,74,27,76,28,78,29,80,30,82,0,84,0,86,0, - 88,0,90,0,92,0,94,0,96,0,98,0,100,0,102,31,104,32,106,33,108,34,110,35, - 112,36,114,37,116,38,118,39,120,40,122,41,124,42,126,43,128,44,130,45,132, - 46,134,47,136,48,138,49,140,50,142,51,144,52,146,53,148,54,150,55,152,56, - 154,57,156,58,158,59,160,60,162,61,164,62,166,63,168,64,170,65,172,66,174, - 67,176,68,178,69,180,70,182,71,184,72,186,73,188,0,190,74,192,75,194,76, - 196,77,198,0,200,0,202,0,204,0,206,0,208,0,210,78,212,0,214,0,216,79,218, - 80,220,81,222,0,224,0,226,0,228,0,230,0,232,82,234,83,236,84,238,85,240, - 0,242,0,244,0,246,0,248,86,250,0,252,87,254,88,256,89,258,0,260,0,262,90, - 264,91,266,0,268,92,270,0,272,93,274,94,276,95,278,0,280,0,282,0,284,0, - 286,0,288,0,290,0,292,96,294,97,296,98,298,0,300,0,302,0,304,0,306,0,308, - 0,310,0,312,99,314,100,316,101,318,0,320,0,322,0,324,0,326,102,328,103, - 330,104,332,0,334,0,336,0,338,0,340,105,342,106,344,107,346,0,348,108,350, - 109,352,110,354,111,356,0,358,112,360,113,362,114,364,115,366,0,368,116, - 370,117,372,118,374,119,376,120,378,0,380,0,382,0,384,121,386,122,388,123, - 390,0,392,0,394,124,396,125,398,126,400,0,402,0,404,0,406,0,16,0,1,2,3, - 4,5,6,7,8,9,10,11,12,13,14,15,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,85,85,117,117,2,0,87,87,119,119,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,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,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,35,44,44,47,47,58,58, - 60,60,62,63,92,92,124,124,1494,0,16,1,0,0,0,0,18,1,0,0,0,0,20,1,0,0,0,0, - 22,1,0,0,0,0,24,1,0,0,0,0,26,1,0,0,0,0,28,1,0,0,0,0,30,1,0,0,0,0,32,1,0, - 0,0,0,34,1,0,0,0,0,36,1,0,0,0,0,38,1,0,0,0,0,40,1,0,0,0,0,42,1,0,0,0,0, - 44,1,0,0,0,0,46,1,0,0,0,0,48,1,0,0,0,0,50,1,0,0,0,0,52,1,0,0,0,0,54,1,0, - 0,0,0,56,1,0,0,0,0,58,1,0,0,0,0,60,1,0,0,0,0,62,1,0,0,0,0,64,1,0,0,0,0, - 68,1,0,0,0,1,70,1,0,0,0,1,72,1,0,0,0,1,74,1,0,0,0,1,76,1,0,0,0,1,78,1,0, - 0,0,2,80,1,0,0,0,2,102,1,0,0,0,2,104,1,0,0,0,2,106,1,0,0,0,2,108,1,0,0, - 0,2,110,1,0,0,0,2,112,1,0,0,0,2,114,1,0,0,0,2,116,1,0,0,0,2,118,1,0,0,0, - 2,120,1,0,0,0,2,122,1,0,0,0,2,124,1,0,0,0,2,126,1,0,0,0,2,128,1,0,0,0,2, - 130,1,0,0,0,2,132,1,0,0,0,2,134,1,0,0,0,2,136,1,0,0,0,2,138,1,0,0,0,2,140, - 1,0,0,0,2,142,1,0,0,0,2,144,1,0,0,0,2,146,1,0,0,0,2,148,1,0,0,0,2,150,1, - 0,0,0,2,152,1,0,0,0,2,154,1,0,0,0,2,156,1,0,0,0,2,158,1,0,0,0,2,160,1,0, - 0,0,2,162,1,0,0,0,2,164,1,0,0,0,2,166,1,0,0,0,2,168,1,0,0,0,2,170,1,0,0, - 0,2,172,1,0,0,0,2,174,1,0,0,0,2,176,1,0,0,0,2,178,1,0,0,0,2,180,1,0,0,0, - 2,182,1,0,0,0,2,184,1,0,0,0,2,186,1,0,0,0,2,190,1,0,0,0,2,192,1,0,0,0,2, - 194,1,0,0,0,2,196,1,0,0,0,3,198,1,0,0,0,3,200,1,0,0,0,3,202,1,0,0,0,3,204, - 1,0,0,0,3,206,1,0,0,0,3,208,1,0,0,0,3,210,1,0,0,0,3,212,1,0,0,0,3,214,1, - 0,0,0,3,216,1,0,0,0,3,218,1,0,0,0,3,220,1,0,0,0,4,222,1,0,0,0,4,224,1,0, - 0,0,4,226,1,0,0,0,4,232,1,0,0,0,4,234,1,0,0,0,4,236,1,0,0,0,4,238,1,0,0, - 0,5,240,1,0,0,0,5,242,1,0,0,0,5,244,1,0,0,0,5,246,1,0,0,0,5,248,1,0,0,0, - 5,250,1,0,0,0,5,252,1,0,0,0,5,254,1,0,0,0,5,256,1,0,0,0,6,258,1,0,0,0,6, - 260,1,0,0,0,6,262,1,0,0,0,6,264,1,0,0,0,6,268,1,0,0,0,6,270,1,0,0,0,6,272, - 1,0,0,0,6,274,1,0,0,0,6,276,1,0,0,0,7,278,1,0,0,0,7,280,1,0,0,0,7,282,1, - 0,0,0,7,284,1,0,0,0,7,286,1,0,0,0,7,288,1,0,0,0,7,290,1,0,0,0,7,292,1,0, - 0,0,7,294,1,0,0,0,7,296,1,0,0,0,8,298,1,0,0,0,8,300,1,0,0,0,8,302,1,0,0, - 0,8,304,1,0,0,0,8,306,1,0,0,0,8,308,1,0,0,0,8,310,1,0,0,0,8,312,1,0,0,0, - 8,314,1,0,0,0,8,316,1,0,0,0,9,318,1,0,0,0,9,320,1,0,0,0,9,322,1,0,0,0,9, - 324,1,0,0,0,9,326,1,0,0,0,9,328,1,0,0,0,9,330,1,0,0,0,10,332,1,0,0,0,10, - 334,1,0,0,0,10,336,1,0,0,0,10,338,1,0,0,0,10,340,1,0,0,0,10,342,1,0,0,0, - 10,344,1,0,0,0,11,346,1,0,0,0,11,348,1,0,0,0,11,350,1,0,0,0,11,352,1,0, - 0,0,11,354,1,0,0,0,12,356,1,0,0,0,12,358,1,0,0,0,12,360,1,0,0,0,12,362, - 1,0,0,0,12,364,1,0,0,0,13,366,1,0,0,0,13,368,1,0,0,0,13,370,1,0,0,0,13, - 372,1,0,0,0,13,374,1,0,0,0,13,376,1,0,0,0,14,378,1,0,0,0,14,380,1,0,0,0, - 14,382,1,0,0,0,14,384,1,0,0,0,14,386,1,0,0,0,14,388,1,0,0,0,15,390,1,0, - 0,0,15,392,1,0,0,0,15,394,1,0,0,0,15,396,1,0,0,0,15,398,1,0,0,0,15,400, - 1,0,0,0,15,402,1,0,0,0,15,404,1,0,0,0,15,406,1,0,0,0,16,408,1,0,0,0,18, - 418,1,0,0,0,20,425,1,0,0,0,22,434,1,0,0,0,24,441,1,0,0,0,26,451,1,0,0,0, - 28,458,1,0,0,0,30,465,1,0,0,0,32,479,1,0,0,0,34,486,1,0,0,0,36,494,1,0, - 0,0,38,503,1,0,0,0,40,510,1,0,0,0,42,520,1,0,0,0,44,532,1,0,0,0,46,541, - 1,0,0,0,48,547,1,0,0,0,50,554,1,0,0,0,52,561,1,0,0,0,54,569,1,0,0,0,56, - 577,1,0,0,0,58,586,1,0,0,0,60,592,1,0,0,0,62,609,1,0,0,0,64,625,1,0,0,0, - 66,634,1,0,0,0,68,637,1,0,0,0,70,641,1,0,0,0,72,646,1,0,0,0,74,651,1,0, - 0,0,76,655,1,0,0,0,78,659,1,0,0,0,80,663,1,0,0,0,82,667,1,0,0,0,84,669, - 1,0,0,0,86,671,1,0,0,0,88,674,1,0,0,0,90,676,1,0,0,0,92,685,1,0,0,0,94, - 687,1,0,0,0,96,692,1,0,0,0,98,694,1,0,0,0,100,699,1,0,0,0,102,730,1,0,0, - 0,104,733,1,0,0,0,106,779,1,0,0,0,108,781,1,0,0,0,110,784,1,0,0,0,112,788, - 1,0,0,0,114,792,1,0,0,0,116,794,1,0,0,0,118,797,1,0,0,0,120,799,1,0,0,0, - 122,804,1,0,0,0,124,806,1,0,0,0,126,812,1,0,0,0,128,818,1,0,0,0,130,821, - 1,0,0,0,132,824,1,0,0,0,134,829,1,0,0,0,136,834,1,0,0,0,138,836,1,0,0,0, - 140,842,1,0,0,0,142,846,1,0,0,0,144,851,1,0,0,0,146,857,1,0,0,0,148,860, - 1,0,0,0,150,862,1,0,0,0,152,868,1,0,0,0,154,870,1,0,0,0,156,875,1,0,0,0, - 158,878,1,0,0,0,160,881,1,0,0,0,162,884,1,0,0,0,164,886,1,0,0,0,166,889, - 1,0,0,0,168,891,1,0,0,0,170,894,1,0,0,0,172,896,1,0,0,0,174,898,1,0,0,0, - 176,900,1,0,0,0,178,902,1,0,0,0,180,918,1,0,0,0,182,920,1,0,0,0,184,925, - 1,0,0,0,186,946,1,0,0,0,188,948,1,0,0,0,190,956,1,0,0,0,192,958,1,0,0,0, - 194,962,1,0,0,0,196,966,1,0,0,0,198,970,1,0,0,0,200,975,1,0,0,0,202,979, - 1,0,0,0,204,983,1,0,0,0,206,987,1,0,0,0,208,991,1,0,0,0,210,995,1,0,0,0, - 212,1004,1,0,0,0,214,1008,1,0,0,0,216,1012,1,0,0,0,218,1016,1,0,0,0,220, - 1020,1,0,0,0,222,1024,1,0,0,0,224,1029,1,0,0,0,226,1033,1,0,0,0,228,1041, - 1,0,0,0,230,1062,1,0,0,0,232,1066,1,0,0,0,234,1070,1,0,0,0,236,1074,1,0, - 0,0,238,1078,1,0,0,0,240,1082,1,0,0,0,242,1087,1,0,0,0,244,1091,1,0,0,0, - 246,1095,1,0,0,0,248,1099,1,0,0,0,250,1102,1,0,0,0,252,1106,1,0,0,0,254, - 1110,1,0,0,0,256,1114,1,0,0,0,258,1118,1,0,0,0,260,1123,1,0,0,0,262,1128, - 1,0,0,0,264,1133,1,0,0,0,266,1140,1,0,0,0,268,1149,1,0,0,0,270,1156,1,0, - 0,0,272,1160,1,0,0,0,274,1164,1,0,0,0,276,1168,1,0,0,0,278,1172,1,0,0,0, - 280,1178,1,0,0,0,282,1182,1,0,0,0,284,1186,1,0,0,0,286,1190,1,0,0,0,288, - 1194,1,0,0,0,290,1198,1,0,0,0,292,1202,1,0,0,0,294,1206,1,0,0,0,296,1210, - 1,0,0,0,298,1214,1,0,0,0,300,1219,1,0,0,0,302,1223,1,0,0,0,304,1227,1,0, - 0,0,306,1231,1,0,0,0,308,1236,1,0,0,0,310,1240,1,0,0,0,312,1244,1,0,0,0, - 314,1248,1,0,0,0,316,1252,1,0,0,0,318,1256,1,0,0,0,320,1262,1,0,0,0,322, - 1266,1,0,0,0,324,1270,1,0,0,0,326,1274,1,0,0,0,328,1278,1,0,0,0,330,1282, - 1,0,0,0,332,1286,1,0,0,0,334,1291,1,0,0,0,336,1295,1,0,0,0,338,1299,1,0, - 0,0,340,1303,1,0,0,0,342,1307,1,0,0,0,344,1311,1,0,0,0,346,1315,1,0,0,0, - 348,1320,1,0,0,0,350,1325,1,0,0,0,352,1329,1,0,0,0,354,1333,1,0,0,0,356, - 1337,1,0,0,0,358,1342,1,0,0,0,360,1352,1,0,0,0,362,1356,1,0,0,0,364,1360, - 1,0,0,0,366,1364,1,0,0,0,368,1369,1,0,0,0,370,1376,1,0,0,0,372,1380,1,0, - 0,0,374,1384,1,0,0,0,376,1388,1,0,0,0,378,1392,1,0,0,0,380,1397,1,0,0,0, - 382,1403,1,0,0,0,384,1409,1,0,0,0,386,1413,1,0,0,0,388,1417,1,0,0,0,390, - 1421,1,0,0,0,392,1427,1,0,0,0,394,1433,1,0,0,0,396,1437,1,0,0,0,398,1441, - 1,0,0,0,400,1445,1,0,0,0,402,1451,1,0,0,0,404,1457,1,0,0,0,406,1463,1,0, - 0,0,408,409,7,0,0,0,409,410,7,1,0,0,410,411,7,2,0,0,411,412,7,2,0,0,412, - 413,7,3,0,0,413,414,7,4,0,0,414,415,7,5,0,0,415,416,1,0,0,0,416,417,6,0, - 0,0,417,17,1,0,0,0,418,419,7,0,0,0,419,420,7,6,0,0,420,421,7,7,0,0,421, - 422,7,8,0,0,422,423,1,0,0,0,423,424,6,1,1,0,424,19,1,0,0,0,425,426,7,3, - 0,0,426,427,7,9,0,0,427,428,7,6,0,0,428,429,7,1,0,0,429,430,7,4,0,0,430, - 431,7,10,0,0,431,432,1,0,0,0,432,433,6,2,2,0,433,21,1,0,0,0,434,435,7,3, - 0,0,435,436,7,11,0,0,436,437,7,12,0,0,437,438,7,13,0,0,438,439,1,0,0,0, - 439,440,6,3,0,0,440,23,1,0,0,0,441,442,7,3,0,0,442,443,7,14,0,0,443,444, - 7,8,0,0,444,445,7,13,0,0,445,446,7,12,0,0,446,447,7,1,0,0,447,448,7,9,0, - 0,448,449,1,0,0,0,449,450,6,4,3,0,450,25,1,0,0,0,451,452,7,15,0,0,452,453, - 7,6,0,0,453,454,7,7,0,0,454,455,7,16,0,0,455,456,1,0,0,0,456,457,6,5,4, - 0,457,27,1,0,0,0,458,459,7,17,0,0,459,460,7,6,0,0,460,461,7,7,0,0,461,462, - 7,18,0,0,462,463,1,0,0,0,463,464,6,6,0,0,464,29,1,0,0,0,465,466,7,1,0,0, - 466,467,7,9,0,0,467,468,7,13,0,0,468,469,7,1,0,0,469,470,7,9,0,0,470,471, - 7,3,0,0,471,472,7,2,0,0,472,473,7,5,0,0,473,474,7,12,0,0,474,475,7,5,0, - 0,475,476,7,2,0,0,476,477,1,0,0,0,477,478,6,7,0,0,478,31,1,0,0,0,479,480, - 7,18,0,0,480,481,7,3,0,0,481,482,7,3,0,0,482,483,7,8,0,0,483,484,1,0,0, - 0,484,485,6,8,1,0,485,33,1,0,0,0,486,487,7,13,0,0,487,488,7,1,0,0,488,489, - 7,16,0,0,489,490,7,1,0,0,490,491,7,5,0,0,491,492,1,0,0,0,492,493,6,9,0, - 0,493,35,1,0,0,0,494,495,7,13,0,0,495,496,7,7,0,0,496,497,7,7,0,0,497,498, - 7,18,0,0,498,499,7,19,0,0,499,500,7,8,0,0,500,501,1,0,0,0,501,502,6,10, - 5,0,502,37,1,0,0,0,503,504,7,16,0,0,504,505,7,3,0,0,505,506,7,5,0,0,506, - 507,7,12,0,0,507,508,1,0,0,0,508,509,6,11,6,0,509,39,1,0,0,0,510,511,7, - 16,0,0,511,512,7,3,0,0,512,513,7,5,0,0,513,514,7,6,0,0,514,515,7,1,0,0, - 515,516,7,4,0,0,516,517,7,2,0,0,517,518,1,0,0,0,518,519,6,12,7,0,519,41, - 1,0,0,0,520,521,7,16,0,0,521,522,7,11,0,0,522,523,5,95,0,0,523,524,7,3, - 0,0,524,525,7,14,0,0,525,526,7,8,0,0,526,527,7,12,0,0,527,528,7,9,0,0,528, - 529,7,0,0,0,529,530,1,0,0,0,530,531,6,13,8,0,531,43,1,0,0,0,532,533,7,6, - 0,0,533,534,7,3,0,0,534,535,7,9,0,0,535,536,7,12,0,0,536,537,7,16,0,0,537, - 538,7,3,0,0,538,539,1,0,0,0,539,540,6,14,9,0,540,45,1,0,0,0,541,542,7,6, - 0,0,542,543,7,7,0,0,543,544,7,20,0,0,544,545,1,0,0,0,545,546,6,15,0,0,546, - 47,1,0,0,0,547,548,7,2,0,0,548,549,7,10,0,0,549,550,7,7,0,0,550,551,7,20, - 0,0,551,552,1,0,0,0,552,553,6,16,10,0,553,49,1,0,0,0,554,555,7,2,0,0,555, - 556,7,7,0,0,556,557,7,6,0,0,557,558,7,5,0,0,558,559,1,0,0,0,559,560,6,17, - 0,0,560,51,1,0,0,0,561,562,7,2,0,0,562,563,7,5,0,0,563,564,7,12,0,0,564, - 565,7,5,0,0,565,566,7,2,0,0,566,567,1,0,0,0,567,568,6,18,0,0,568,53,1,0, - 0,0,569,570,7,20,0,0,570,571,7,10,0,0,571,572,7,3,0,0,572,573,7,6,0,0,573, - 574,7,3,0,0,574,575,1,0,0,0,575,576,6,19,0,0,576,55,1,0,0,0,577,578,7,16, - 0,0,578,579,7,12,0,0,579,580,7,5,0,0,580,581,7,4,0,0,581,582,7,10,0,0,582, - 583,1,0,0,0,583,584,6,20,0,0,584,57,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,21,0,0,591,59,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,22,11,0,608,61,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,62,23,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,23,11,0,623,63,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,24,11,0,630,65,1,0,0,0,631,635,8,24,0,0,632,633,5, - 47,0,0,633,635,8,25,0,0,634,631,1,0,0,0,634,632,1,0,0,0,635,67,1,0,0,0, - 636,638,3,66,25,0,637,636,1,0,0,0,638,639,1,0,0,0,639,637,1,0,0,0,639,640, - 1,0,0,0,640,69,1,0,0,0,641,642,3,182,83,0,642,643,1,0,0,0,643,644,6,27, - 12,0,644,645,6,27,13,0,645,71,1,0,0,0,646,647,3,80,32,0,647,648,1,0,0,0, - 648,649,6,28,14,0,649,650,6,28,15,0,650,73,1,0,0,0,651,652,3,64,24,0,652, - 653,1,0,0,0,653,654,6,29,11,0,654,75,1,0,0,0,655,656,3,60,22,0,656,657, - 1,0,0,0,657,658,6,30,11,0,658,77,1,0,0,0,659,660,3,62,23,0,660,661,1,0, - 0,0,661,662,6,31,11,0,662,79,1,0,0,0,663,664,5,124,0,0,664,665,1,0,0,0, - 665,666,6,32,15,0,666,81,1,0,0,0,667,668,7,26,0,0,668,83,1,0,0,0,669,670, - 7,27,0,0,670,85,1,0,0,0,671,672,5,92,0,0,672,673,7,28,0,0,673,87,1,0,0, - 0,674,675,8,29,0,0,675,89,1,0,0,0,676,678,7,3,0,0,677,679,7,30,0,0,678, - 677,1,0,0,0,678,679,1,0,0,0,679,681,1,0,0,0,680,682,3,82,33,0,681,680,1, - 0,0,0,682,683,1,0,0,0,683,681,1,0,0,0,683,684,1,0,0,0,684,91,1,0,0,0,685, - 686,5,64,0,0,686,93,1,0,0,0,687,688,5,96,0,0,688,95,1,0,0,0,689,693,8,31, - 0,0,690,691,5,96,0,0,691,693,5,96,0,0,692,689,1,0,0,0,692,690,1,0,0,0,693, - 97,1,0,0,0,694,695,5,95,0,0,695,99,1,0,0,0,696,700,3,84,34,0,697,700,3, - 82,33,0,698,700,3,98,41,0,699,696,1,0,0,0,699,697,1,0,0,0,699,698,1,0,0, - 0,700,101,1,0,0,0,701,706,5,34,0,0,702,705,3,86,35,0,703,705,3,88,36,0, - 704,702,1,0,0,0,704,703,1,0,0,0,705,708,1,0,0,0,706,704,1,0,0,0,706,707, - 1,0,0,0,707,709,1,0,0,0,708,706,1,0,0,0,709,731,5,34,0,0,710,711,5,34,0, - 0,711,712,5,34,0,0,712,713,5,34,0,0,713,717,1,0,0,0,714,716,8,22,0,0,715, - 714,1,0,0,0,716,719,1,0,0,0,717,718,1,0,0,0,717,715,1,0,0,0,718,720,1,0, - 0,0,719,717,1,0,0,0,720,721,5,34,0,0,721,722,5,34,0,0,722,723,5,34,0,0, - 723,725,1,0,0,0,724,726,5,34,0,0,725,724,1,0,0,0,725,726,1,0,0,0,726,728, - 1,0,0,0,727,729,5,34,0,0,728,727,1,0,0,0,728,729,1,0,0,0,729,731,1,0,0, - 0,730,701,1,0,0,0,730,710,1,0,0,0,731,103,1,0,0,0,732,734,3,82,33,0,733, - 732,1,0,0,0,734,735,1,0,0,0,735,733,1,0,0,0,735,736,1,0,0,0,736,105,1,0, - 0,0,737,739,3,82,33,0,738,737,1,0,0,0,739,740,1,0,0,0,740,738,1,0,0,0,740, - 741,1,0,0,0,741,742,1,0,0,0,742,746,3,122,53,0,743,745,3,82,33,0,744,743, - 1,0,0,0,745,748,1,0,0,0,746,744,1,0,0,0,746,747,1,0,0,0,747,780,1,0,0,0, - 748,746,1,0,0,0,749,751,3,122,53,0,750,752,3,82,33,0,751,750,1,0,0,0,752, - 753,1,0,0,0,753,751,1,0,0,0,753,754,1,0,0,0,754,780,1,0,0,0,755,757,3,82, - 33,0,756,755,1,0,0,0,757,758,1,0,0,0,758,756,1,0,0,0,758,759,1,0,0,0,759, - 767,1,0,0,0,760,764,3,122,53,0,761,763,3,82,33,0,762,761,1,0,0,0,763,766, - 1,0,0,0,764,762,1,0,0,0,764,765,1,0,0,0,765,768,1,0,0,0,766,764,1,0,0,0, - 767,760,1,0,0,0,767,768,1,0,0,0,768,769,1,0,0,0,769,770,3,90,37,0,770,780, - 1,0,0,0,771,773,3,122,53,0,772,774,3,82,33,0,773,772,1,0,0,0,774,775,1, - 0,0,0,775,773,1,0,0,0,775,776,1,0,0,0,776,777,1,0,0,0,777,778,3,90,37,0, - 778,780,1,0,0,0,779,738,1,0,0,0,779,749,1,0,0,0,779,756,1,0,0,0,779,771, - 1,0,0,0,780,107,1,0,0,0,781,782,7,32,0,0,782,783,7,33,0,0,783,109,1,0,0, - 0,784,785,7,12,0,0,785,786,7,9,0,0,786,787,7,0,0,0,787,111,1,0,0,0,788, - 789,7,12,0,0,789,790,7,2,0,0,790,791,7,4,0,0,791,113,1,0,0,0,792,793,5, - 61,0,0,793,115,1,0,0,0,794,795,5,58,0,0,795,796,5,58,0,0,796,117,1,0,0, - 0,797,798,5,44,0,0,798,119,1,0,0,0,799,800,7,0,0,0,800,801,7,3,0,0,801, - 802,7,2,0,0,802,803,7,4,0,0,803,121,1,0,0,0,804,805,5,46,0,0,805,123,1, - 0,0,0,806,807,7,15,0,0,807,808,7,12,0,0,808,809,7,13,0,0,809,810,7,2,0, - 0,810,811,7,3,0,0,811,125,1,0,0,0,812,813,7,15,0,0,813,814,7,1,0,0,814, - 815,7,6,0,0,815,816,7,2,0,0,816,817,7,5,0,0,817,127,1,0,0,0,818,819,7,1, - 0,0,819,820,7,9,0,0,820,129,1,0,0,0,821,822,7,1,0,0,822,823,7,2,0,0,823, - 131,1,0,0,0,824,825,7,13,0,0,825,826,7,12,0,0,826,827,7,2,0,0,827,828,7, - 5,0,0,828,133,1,0,0,0,829,830,7,13,0,0,830,831,7,1,0,0,831,832,7,18,0,0, - 832,833,7,3,0,0,833,135,1,0,0,0,834,835,5,40,0,0,835,137,1,0,0,0,836,837, - 7,16,0,0,837,838,7,12,0,0,838,839,7,5,0,0,839,840,7,4,0,0,840,841,7,10, - 0,0,841,139,1,0,0,0,842,843,7,9,0,0,843,844,7,7,0,0,844,845,7,5,0,0,845, - 141,1,0,0,0,846,847,7,9,0,0,847,848,7,19,0,0,848,849,7,13,0,0,849,850,7, - 13,0,0,850,143,1,0,0,0,851,852,7,9,0,0,852,853,7,19,0,0,853,854,7,13,0, - 0,854,855,7,13,0,0,855,856,7,2,0,0,856,145,1,0,0,0,857,858,7,7,0,0,858, - 859,7,6,0,0,859,147,1,0,0,0,860,861,5,63,0,0,861,149,1,0,0,0,862,863,7, - 6,0,0,863,864,7,13,0,0,864,865,7,1,0,0,865,866,7,18,0,0,866,867,7,3,0,0, - 867,151,1,0,0,0,868,869,5,41,0,0,869,153,1,0,0,0,870,871,7,5,0,0,871,872, - 7,6,0,0,872,873,7,19,0,0,873,874,7,3,0,0,874,155,1,0,0,0,875,876,5,61,0, - 0,876,877,5,61,0,0,877,157,1,0,0,0,878,879,5,61,0,0,879,880,5,126,0,0,880, - 159,1,0,0,0,881,882,5,33,0,0,882,883,5,61,0,0,883,161,1,0,0,0,884,885,5, - 60,0,0,885,163,1,0,0,0,886,887,5,60,0,0,887,888,5,61,0,0,888,165,1,0,0, - 0,889,890,5,62,0,0,890,167,1,0,0,0,891,892,5,62,0,0,892,893,5,61,0,0,893, - 169,1,0,0,0,894,895,5,43,0,0,895,171,1,0,0,0,896,897,5,45,0,0,897,173,1, - 0,0,0,898,899,5,42,0,0,899,175,1,0,0,0,900,901,5,47,0,0,901,177,1,0,0,0, - 902,903,5,37,0,0,903,179,1,0,0,0,904,905,3,148,66,0,905,909,3,84,34,0,906, - 908,3,100,42,0,907,906,1,0,0,0,908,911,1,0,0,0,909,907,1,0,0,0,909,910, - 1,0,0,0,910,919,1,0,0,0,911,909,1,0,0,0,912,914,3,148,66,0,913,915,3,82, - 33,0,914,913,1,0,0,0,915,916,1,0,0,0,916,914,1,0,0,0,916,917,1,0,0,0,917, - 919,1,0,0,0,918,904,1,0,0,0,918,912,1,0,0,0,919,181,1,0,0,0,920,921,5,91, - 0,0,921,922,1,0,0,0,922,923,6,83,0,0,923,924,6,83,0,0,924,183,1,0,0,0,925, - 926,5,93,0,0,926,927,1,0,0,0,927,928,6,84,15,0,928,929,6,84,15,0,929,185, - 1,0,0,0,930,934,3,84,34,0,931,933,3,100,42,0,932,931,1,0,0,0,933,936,1, - 0,0,0,934,932,1,0,0,0,934,935,1,0,0,0,935,947,1,0,0,0,936,934,1,0,0,0,937, - 940,3,98,41,0,938,940,3,92,38,0,939,937,1,0,0,0,939,938,1,0,0,0,940,942, - 1,0,0,0,941,943,3,100,42,0,942,941,1,0,0,0,943,944,1,0,0,0,944,942,1,0, - 0,0,944,945,1,0,0,0,945,947,1,0,0,0,946,930,1,0,0,0,946,939,1,0,0,0,947, - 187,1,0,0,0,948,950,3,94,39,0,949,951,3,96,40,0,950,949,1,0,0,0,951,952, - 1,0,0,0,952,950,1,0,0,0,952,953,1,0,0,0,953,954,1,0,0,0,954,955,3,94,39, - 0,955,189,1,0,0,0,956,957,3,188,86,0,957,191,1,0,0,0,958,959,3,60,22,0, - 959,960,1,0,0,0,960,961,6,88,11,0,961,193,1,0,0,0,962,963,3,62,23,0,963, - 964,1,0,0,0,964,965,6,89,11,0,965,195,1,0,0,0,966,967,3,64,24,0,967,968, - 1,0,0,0,968,969,6,90,11,0,969,197,1,0,0,0,970,971,3,80,32,0,971,972,1,0, - 0,0,972,973,6,91,14,0,973,974,6,91,15,0,974,199,1,0,0,0,975,976,3,182,83, - 0,976,977,1,0,0,0,977,978,6,92,12,0,978,201,1,0,0,0,979,980,3,184,84,0, - 980,981,1,0,0,0,981,982,6,93,16,0,982,203,1,0,0,0,983,984,3,368,176,0,984, - 985,1,0,0,0,985,986,6,94,17,0,986,205,1,0,0,0,987,988,3,118,51,0,988,989, - 1,0,0,0,989,990,6,95,18,0,990,207,1,0,0,0,991,992,3,114,49,0,992,993,1, - 0,0,0,993,994,6,96,19,0,994,209,1,0,0,0,995,996,7,16,0,0,996,997,7,3,0, - 0,997,998,7,5,0,0,998,999,7,12,0,0,999,1000,7,0,0,0,1000,1001,7,12,0,0, - 1001,1002,7,5,0,0,1002,1003,7,12,0,0,1003,211,1,0,0,0,1004,1005,3,68,26, - 0,1005,1006,1,0,0,0,1006,1007,6,98,20,0,1007,213,1,0,0,0,1008,1009,3,102, - 43,0,1009,1010,1,0,0,0,1010,1011,6,99,21,0,1011,215,1,0,0,0,1012,1013,3, - 60,22,0,1013,1014,1,0,0,0,1014,1015,6,100,11,0,1015,217,1,0,0,0,1016,1017, - 3,62,23,0,1017,1018,1,0,0,0,1018,1019,6,101,11,0,1019,219,1,0,0,0,1020, - 1021,3,64,24,0,1021,1022,1,0,0,0,1022,1023,6,102,11,0,1023,221,1,0,0,0, - 1024,1025,3,80,32,0,1025,1026,1,0,0,0,1026,1027,6,103,14,0,1027,1028,6, - 103,15,0,1028,223,1,0,0,0,1029,1030,3,122,53,0,1030,1031,1,0,0,0,1031,1032, - 6,104,22,0,1032,225,1,0,0,0,1033,1034,3,118,51,0,1034,1035,1,0,0,0,1035, - 1036,6,105,18,0,1036,227,1,0,0,0,1037,1042,3,84,34,0,1038,1042,3,82,33, - 0,1039,1042,3,98,41,0,1040,1042,3,174,79,0,1041,1037,1,0,0,0,1041,1038, - 1,0,0,0,1041,1039,1,0,0,0,1041,1040,1,0,0,0,1042,229,1,0,0,0,1043,1046, - 3,84,34,0,1044,1046,3,174,79,0,1045,1043,1,0,0,0,1045,1044,1,0,0,0,1046, - 1050,1,0,0,0,1047,1049,3,228,106,0,1048,1047,1,0,0,0,1049,1052,1,0,0,0, - 1050,1048,1,0,0,0,1050,1051,1,0,0,0,1051,1063,1,0,0,0,1052,1050,1,0,0,0, - 1053,1056,3,98,41,0,1054,1056,3,92,38,0,1055,1053,1,0,0,0,1055,1054,1,0, - 0,0,1056,1058,1,0,0,0,1057,1059,3,228,106,0,1058,1057,1,0,0,0,1059,1060, - 1,0,0,0,1060,1058,1,0,0,0,1060,1061,1,0,0,0,1061,1063,1,0,0,0,1062,1045, - 1,0,0,0,1062,1055,1,0,0,0,1063,231,1,0,0,0,1064,1067,3,230,107,0,1065,1067, - 3,188,86,0,1066,1064,1,0,0,0,1066,1065,1,0,0,0,1067,1068,1,0,0,0,1068,1066, - 1,0,0,0,1068,1069,1,0,0,0,1069,233,1,0,0,0,1070,1071,3,60,22,0,1071,1072, - 1,0,0,0,1072,1073,6,109,11,0,1073,235,1,0,0,0,1074,1075,3,62,23,0,1075, - 1076,1,0,0,0,1076,1077,6,110,11,0,1077,237,1,0,0,0,1078,1079,3,64,24,0, - 1079,1080,1,0,0,0,1080,1081,6,111,11,0,1081,239,1,0,0,0,1082,1083,3,80, - 32,0,1083,1084,1,0,0,0,1084,1085,6,112,14,0,1085,1086,6,112,15,0,1086,241, - 1,0,0,0,1087,1088,3,114,49,0,1088,1089,1,0,0,0,1089,1090,6,113,19,0,1090, - 243,1,0,0,0,1091,1092,3,118,51,0,1092,1093,1,0,0,0,1093,1094,6,114,18,0, - 1094,245,1,0,0,0,1095,1096,3,122,53,0,1096,1097,1,0,0,0,1097,1098,6,115, - 22,0,1098,247,1,0,0,0,1099,1100,7,12,0,0,1100,1101,7,2,0,0,1101,249,1,0, - 0,0,1102,1103,3,232,108,0,1103,1104,1,0,0,0,1104,1105,6,117,23,0,1105,251, - 1,0,0,0,1106,1107,3,60,22,0,1107,1108,1,0,0,0,1108,1109,6,118,11,0,1109, - 253,1,0,0,0,1110,1111,3,62,23,0,1111,1112,1,0,0,0,1112,1113,6,119,11,0, - 1113,255,1,0,0,0,1114,1115,3,64,24,0,1115,1116,1,0,0,0,1116,1117,6,120, - 11,0,1117,257,1,0,0,0,1118,1119,3,80,32,0,1119,1120,1,0,0,0,1120,1121,6, - 121,14,0,1121,1122,6,121,15,0,1122,259,1,0,0,0,1123,1124,3,182,83,0,1124, - 1125,1,0,0,0,1125,1126,6,122,12,0,1126,1127,6,122,24,0,1127,261,1,0,0,0, - 1128,1129,7,7,0,0,1129,1130,7,9,0,0,1130,1131,1,0,0,0,1131,1132,6,123,25, - 0,1132,263,1,0,0,0,1133,1134,7,20,0,0,1134,1135,7,1,0,0,1135,1136,7,5,0, - 0,1136,1137,7,10,0,0,1137,1138,1,0,0,0,1138,1139,6,124,25,0,1139,265,1, - 0,0,0,1140,1141,8,34,0,0,1141,267,1,0,0,0,1142,1144,3,266,125,0,1143,1142, - 1,0,0,0,1144,1145,1,0,0,0,1145,1143,1,0,0,0,1145,1146,1,0,0,0,1146,1147, - 1,0,0,0,1147,1148,3,368,176,0,1148,1150,1,0,0,0,1149,1143,1,0,0,0,1149, - 1150,1,0,0,0,1150,1152,1,0,0,0,1151,1153,3,266,125,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,269,1,0,0,0, - 1156,1157,3,268,126,0,1157,1158,1,0,0,0,1158,1159,6,127,26,0,1159,271,1, - 0,0,0,1160,1161,3,60,22,0,1161,1162,1,0,0,0,1162,1163,6,128,11,0,1163,273, - 1,0,0,0,1164,1165,3,62,23,0,1165,1166,1,0,0,0,1166,1167,6,129,11,0,1167, - 275,1,0,0,0,1168,1169,3,64,24,0,1169,1170,1,0,0,0,1170,1171,6,130,11,0, - 1171,277,1,0,0,0,1172,1173,3,80,32,0,1173,1174,1,0,0,0,1174,1175,6,131, - 14,0,1175,1176,6,131,15,0,1176,1177,6,131,15,0,1177,279,1,0,0,0,1178,1179, - 3,114,49,0,1179,1180,1,0,0,0,1180,1181,6,132,19,0,1181,281,1,0,0,0,1182, - 1183,3,118,51,0,1183,1184,1,0,0,0,1184,1185,6,133,18,0,1185,283,1,0,0,0, - 1186,1187,3,122,53,0,1187,1188,1,0,0,0,1188,1189,6,134,22,0,1189,285,1, - 0,0,0,1190,1191,3,264,124,0,1191,1192,1,0,0,0,1192,1193,6,135,27,0,1193, - 287,1,0,0,0,1194,1195,3,232,108,0,1195,1196,1,0,0,0,1196,1197,6,136,23, - 0,1197,289,1,0,0,0,1198,1199,3,190,87,0,1199,1200,1,0,0,0,1200,1201,6,137, - 28,0,1201,291,1,0,0,0,1202,1203,3,60,22,0,1203,1204,1,0,0,0,1204,1205,6, - 138,11,0,1205,293,1,0,0,0,1206,1207,3,62,23,0,1207,1208,1,0,0,0,1208,1209, - 6,139,11,0,1209,295,1,0,0,0,1210,1211,3,64,24,0,1211,1212,1,0,0,0,1212, - 1213,6,140,11,0,1213,297,1,0,0,0,1214,1215,3,80,32,0,1215,1216,1,0,0,0, - 1216,1217,6,141,14,0,1217,1218,6,141,15,0,1218,299,1,0,0,0,1219,1220,3, - 368,176,0,1220,1221,1,0,0,0,1221,1222,6,142,17,0,1222,301,1,0,0,0,1223, - 1224,3,118,51,0,1224,1225,1,0,0,0,1225,1226,6,143,18,0,1226,303,1,0,0,0, - 1227,1228,3,122,53,0,1228,1229,1,0,0,0,1229,1230,6,144,22,0,1230,305,1, - 0,0,0,1231,1232,3,262,123,0,1232,1233,1,0,0,0,1233,1234,6,145,29,0,1234, - 1235,6,145,30,0,1235,307,1,0,0,0,1236,1237,3,68,26,0,1237,1238,1,0,0,0, - 1238,1239,6,146,20,0,1239,309,1,0,0,0,1240,1241,3,102,43,0,1241,1242,1, - 0,0,0,1242,1243,6,147,21,0,1243,311,1,0,0,0,1244,1245,3,60,22,0,1245,1246, - 1,0,0,0,1246,1247,6,148,11,0,1247,313,1,0,0,0,1248,1249,3,62,23,0,1249, - 1250,1,0,0,0,1250,1251,6,149,11,0,1251,315,1,0,0,0,1252,1253,3,64,24,0, - 1253,1254,1,0,0,0,1254,1255,6,150,11,0,1255,317,1,0,0,0,1256,1257,3,80, - 32,0,1257,1258,1,0,0,0,1258,1259,6,151,14,0,1259,1260,6,151,15,0,1260,1261, - 6,151,15,0,1261,319,1,0,0,0,1262,1263,3,118,51,0,1263,1264,1,0,0,0,1264, - 1265,6,152,18,0,1265,321,1,0,0,0,1266,1267,3,122,53,0,1267,1268,1,0,0,0, - 1268,1269,6,153,22,0,1269,323,1,0,0,0,1270,1271,3,232,108,0,1271,1272,1, - 0,0,0,1272,1273,6,154,23,0,1273,325,1,0,0,0,1274,1275,3,60,22,0,1275,1276, - 1,0,0,0,1276,1277,6,155,11,0,1277,327,1,0,0,0,1278,1279,3,62,23,0,1279, - 1280,1,0,0,0,1280,1281,6,156,11,0,1281,329,1,0,0,0,1282,1283,3,64,24,0, - 1283,1284,1,0,0,0,1284,1285,6,157,11,0,1285,331,1,0,0,0,1286,1287,3,80, - 32,0,1287,1288,1,0,0,0,1288,1289,6,158,14,0,1289,1290,6,158,15,0,1290,333, - 1,0,0,0,1291,1292,3,122,53,0,1292,1293,1,0,0,0,1293,1294,6,159,22,0,1294, - 335,1,0,0,0,1295,1296,3,190,87,0,1296,1297,1,0,0,0,1297,1298,6,160,28,0, - 1298,337,1,0,0,0,1299,1300,3,186,85,0,1300,1301,1,0,0,0,1301,1302,6,161, - 31,0,1302,339,1,0,0,0,1303,1304,3,60,22,0,1304,1305,1,0,0,0,1305,1306,6, - 162,11,0,1306,341,1,0,0,0,1307,1308,3,62,23,0,1308,1309,1,0,0,0,1309,1310, - 6,163,11,0,1310,343,1,0,0,0,1311,1312,3,64,24,0,1312,1313,1,0,0,0,1313, - 1314,6,164,11,0,1314,345,1,0,0,0,1315,1316,3,80,32,0,1316,1317,1,0,0,0, - 1317,1318,6,165,14,0,1318,1319,6,165,15,0,1319,347,1,0,0,0,1320,1321,7, - 1,0,0,1321,1322,7,9,0,0,1322,1323,7,15,0,0,1323,1324,7,7,0,0,1324,349,1, - 0,0,0,1325,1326,3,60,22,0,1326,1327,1,0,0,0,1327,1328,6,167,11,0,1328,351, - 1,0,0,0,1329,1330,3,62,23,0,1330,1331,1,0,0,0,1331,1332,6,168,11,0,1332, - 353,1,0,0,0,1333,1334,3,64,24,0,1334,1335,1,0,0,0,1335,1336,6,169,11,0, - 1336,355,1,0,0,0,1337,1338,3,80,32,0,1338,1339,1,0,0,0,1339,1340,6,170, - 14,0,1340,1341,6,170,15,0,1341,357,1,0,0,0,1342,1343,7,15,0,0,1343,1344, - 7,19,0,0,1344,1345,7,9,0,0,1345,1346,7,4,0,0,1346,1347,7,5,0,0,1347,1348, - 7,1,0,0,1348,1349,7,7,0,0,1349,1350,7,9,0,0,1350,1351,7,2,0,0,1351,359, - 1,0,0,0,1352,1353,3,60,22,0,1353,1354,1,0,0,0,1354,1355,6,172,11,0,1355, - 361,1,0,0,0,1356,1357,3,62,23,0,1357,1358,1,0,0,0,1358,1359,6,173,11,0, - 1359,363,1,0,0,0,1360,1361,3,64,24,0,1361,1362,1,0,0,0,1362,1363,6,174, - 11,0,1363,365,1,0,0,0,1364,1365,3,184,84,0,1365,1366,1,0,0,0,1366,1367, - 6,175,16,0,1367,1368,6,175,15,0,1368,367,1,0,0,0,1369,1370,5,58,0,0,1370, - 369,1,0,0,0,1371,1377,3,92,38,0,1372,1377,3,82,33,0,1373,1377,3,122,53, - 0,1374,1377,3,84,34,0,1375,1377,3,98,41,0,1376,1371,1,0,0,0,1376,1372,1, - 0,0,0,1376,1373,1,0,0,0,1376,1374,1,0,0,0,1376,1375,1,0,0,0,1377,1378,1, - 0,0,0,1378,1376,1,0,0,0,1378,1379,1,0,0,0,1379,371,1,0,0,0,1380,1381,3, - 60,22,0,1381,1382,1,0,0,0,1382,1383,6,178,11,0,1383,373,1,0,0,0,1384,1385, - 3,62,23,0,1385,1386,1,0,0,0,1386,1387,6,179,11,0,1387,375,1,0,0,0,1388, - 1389,3,64,24,0,1389,1390,1,0,0,0,1390,1391,6,180,11,0,1391,377,1,0,0,0, - 1392,1393,3,80,32,0,1393,1394,1,0,0,0,1394,1395,6,181,14,0,1395,1396,6, - 181,15,0,1396,379,1,0,0,0,1397,1398,3,68,26,0,1398,1399,1,0,0,0,1399,1400, - 6,182,20,0,1400,1401,6,182,15,0,1401,1402,6,182,32,0,1402,381,1,0,0,0,1403, - 1404,3,102,43,0,1404,1405,1,0,0,0,1405,1406,6,183,21,0,1406,1407,6,183, - 15,0,1407,1408,6,183,32,0,1408,383,1,0,0,0,1409,1410,3,60,22,0,1410,1411, - 1,0,0,0,1411,1412,6,184,11,0,1412,385,1,0,0,0,1413,1414,3,62,23,0,1414, - 1415,1,0,0,0,1415,1416,6,185,11,0,1416,387,1,0,0,0,1417,1418,3,64,24,0, - 1418,1419,1,0,0,0,1419,1420,6,186,11,0,1420,389,1,0,0,0,1421,1422,3,368, - 176,0,1422,1423,1,0,0,0,1423,1424,6,187,17,0,1424,1425,6,187,15,0,1425, - 1426,6,187,7,0,1426,391,1,0,0,0,1427,1428,3,118,51,0,1428,1429,1,0,0,0, - 1429,1430,6,188,18,0,1430,1431,6,188,15,0,1431,1432,6,188,7,0,1432,393, - 1,0,0,0,1433,1434,3,60,22,0,1434,1435,1,0,0,0,1435,1436,6,189,11,0,1436, - 395,1,0,0,0,1437,1438,3,62,23,0,1438,1439,1,0,0,0,1439,1440,6,190,11,0, - 1440,397,1,0,0,0,1441,1442,3,64,24,0,1442,1443,1,0,0,0,1443,1444,6,191, - 11,0,1444,399,1,0,0,0,1445,1446,3,190,87,0,1446,1447,1,0,0,0,1447,1448, - 6,192,15,0,1448,1449,6,192,0,0,1449,1450,6,192,28,0,1450,401,1,0,0,0,1451, - 1452,3,186,85,0,1452,1453,1,0,0,0,1453,1454,6,193,15,0,1454,1455,6,193, - 0,0,1455,1456,6,193,31,0,1456,403,1,0,0,0,1457,1458,3,108,46,0,1458,1459, - 1,0,0,0,1459,1460,6,194,15,0,1460,1461,6,194,0,0,1461,1462,6,194,33,0,1462, - 405,1,0,0,0,1463,1464,3,80,32,0,1464,1465,1,0,0,0,1465,1466,6,195,14,0, - 1466,1467,6,195,15,0,1467,407,1,0,0,0,65,0,1,2,3,4,5,6,7,8,9,10,11,12,13, - 14,15,588,598,602,605,614,616,627,634,639,678,683,692,699,704,706,717,725, - 728,730,735,740,746,753,758,764,767,775,779,909,916,918,934,939,944,946, - 952,1041,1045,1050,1055,1060,1062,1066,1068,1145,1149,1154,1376,1378,34, - 5,2,0,5,4,0,5,6,0,5,1,0,5,3,0,5,8,0,5,12,0,5,14,0,5,10,0,5,5,0,5,11,0,0, - 1,0,7,71,0,5,0,0,7,30,0,4,0,0,7,72,0,7,116,0,7,39,0,7,37,0,7,26,0,7,31, - 0,7,41,0,7,82,0,5,13,0,5,7,0,7,92,0,7,91,0,7,74,0,7,90,0,5,9,0,7,73,0,5, - 15,0,7,34,0]; + 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,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,181,1,182,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,185,1,185,1,185,1,185,1,186,1,186,1,186,1,186,1,187,1,187,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,190,1,190,1,190,1,190,1,191,1,191,1,191,1,191,1,192,1,192,1,192, + 1,192,1,192,1,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,2,620,689,0,196,16,1,18, + 2,20,3,22,4,24,5,26,6,28,7,30,8,32,9,34,10,36,11,38,12,40,13,42,14,44,15, + 46,16,48,17,50,18,52,19,54,20,56,21,58,22,60,23,62,24,64,25,66,26,68,0, + 70,0,72,0,74,0,76,0,78,0,80,0,82,0,84,0,86,0,88,27,90,28,92,29,94,30,96, + 31,98,32,100,33,102,34,104,35,106,36,108,37,110,38,112,39,114,40,116,41, + 118,42,120,43,122,44,124,45,126,46,128,47,130,48,132,49,134,50,136,51,138, + 52,140,53,142,54,144,55,146,56,148,57,150,58,152,59,154,60,156,61,158,62, + 160,63,162,64,164,0,166,65,168,66,170,67,172,68,174,0,176,69,178,70,180, + 71,182,72,184,0,186,0,188,73,190,74,192,75,194,0,196,0,198,0,200,0,202, + 0,204,0,206,76,208,0,210,77,212,0,214,0,216,78,218,79,220,80,222,0,224, + 0,226,0,228,0,230,0,232,81,234,82,236,83,238,84,240,0,242,0,244,0,246,0, + 248,85,250,0,252,86,254,87,256,88,258,0,260,0,262,89,264,90,266,0,268,91, + 270,0,272,92,274,93,276,94,278,0,280,0,282,0,284,0,286,0,288,0,290,0,292, + 95,294,96,296,97,298,0,300,0,302,0,304,0,306,98,308,99,310,100,312,0,314, + 101,316,102,318,103,320,104,322,0,324,105,326,106,328,107,330,108,332,0, + 334,109,336,110,338,111,340,112,342,113,344,0,346,0,348,0,350,0,352,0,354, + 0,356,0,358,114,360,115,362,116,364,0,366,0,368,0,370,0,372,117,374,118, + 376,119,378,0,380,0,382,0,384,120,386,121,388,122,390,0,392,0,394,123,396, + 124,398,125,400,0,402,0,404,0,406,0,16,0,1,2,3,4,5,6,7,8,9,10,11,12,13, + 14,15,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,1501, + 0,16,1,0,0,0,0,18,1,0,0,0,0,20,1,0,0,0,0,22,1,0,0,0,0,24,1,0,0,0,0,26,1, + 0,0,0,0,28,1,0,0,0,0,30,1,0,0,0,0,32,1,0,0,0,0,34,1,0,0,0,0,36,1,0,0,0, + 0,38,1,0,0,0,0,40,1,0,0,0,0,42,1,0,0,0,0,44,1,0,0,0,0,46,1,0,0,0,0,48,1, + 0,0,0,0,50,1,0,0,0,0,52,1,0,0,0,0,54,1,0,0,0,0,56,1,0,0,0,0,58,1,0,0,0, + 0,60,1,0,0,0,0,62,1,0,0,0,0,64,1,0,0,0,1,66,1,0,0,0,1,88,1,0,0,0,1,90,1, + 0,0,0,1,92,1,0,0,0,1,94,1,0,0,0,1,96,1,0,0,0,1,98,1,0,0,0,1,100,1,0,0,0, + 1,102,1,0,0,0,1,104,1,0,0,0,1,106,1,0,0,0,1,108,1,0,0,0,1,110,1,0,0,0,1, + 112,1,0,0,0,1,114,1,0,0,0,1,116,1,0,0,0,1,118,1,0,0,0,1,120,1,0,0,0,1,122, + 1,0,0,0,1,124,1,0,0,0,1,126,1,0,0,0,1,128,1,0,0,0,1,130,1,0,0,0,1,132,1, + 0,0,0,1,134,1,0,0,0,1,136,1,0,0,0,1,138,1,0,0,0,1,140,1,0,0,0,1,142,1,0, + 0,0,1,144,1,0,0,0,1,146,1,0,0,0,1,148,1,0,0,0,1,150,1,0,0,0,1,152,1,0,0, + 0,1,154,1,0,0,0,1,156,1,0,0,0,1,158,1,0,0,0,1,160,1,0,0,0,1,162,1,0,0,0, + 1,164,1,0,0,0,1,166,1,0,0,0,1,168,1,0,0,0,1,170,1,0,0,0,1,172,1,0,0,0,1, + 176,1,0,0,0,1,178,1,0,0,0,1,180,1,0,0,0,1,182,1,0,0,0,2,184,1,0,0,0,2,186, + 1,0,0,0,2,188,1,0,0,0,2,190,1,0,0,0,2,192,1,0,0,0,3,194,1,0,0,0,3,196,1, + 0,0,0,3,198,1,0,0,0,3,200,1,0,0,0,3,202,1,0,0,0,3,204,1,0,0,0,3,206,1,0, + 0,0,3,210,1,0,0,0,3,212,1,0,0,0,3,214,1,0,0,0,3,216,1,0,0,0,3,218,1,0,0, + 0,3,220,1,0,0,0,4,222,1,0,0,0,4,224,1,0,0,0,4,226,1,0,0,0,4,232,1,0,0,0, + 4,234,1,0,0,0,4,236,1,0,0,0,4,238,1,0,0,0,5,240,1,0,0,0,5,242,1,0,0,0,5, + 244,1,0,0,0,5,246,1,0,0,0,5,248,1,0,0,0,5,250,1,0,0,0,5,252,1,0,0,0,5,254, + 1,0,0,0,5,256,1,0,0,0,6,258,1,0,0,0,6,260,1,0,0,0,6,262,1,0,0,0,6,264,1, + 0,0,0,6,268,1,0,0,0,6,270,1,0,0,0,6,272,1,0,0,0,6,274,1,0,0,0,6,276,1,0, + 0,0,7,278,1,0,0,0,7,280,1,0,0,0,7,282,1,0,0,0,7,284,1,0,0,0,7,286,1,0,0, + 0,7,288,1,0,0,0,7,290,1,0,0,0,7,292,1,0,0,0,7,294,1,0,0,0,7,296,1,0,0,0, + 8,298,1,0,0,0,8,300,1,0,0,0,8,302,1,0,0,0,8,304,1,0,0,0,8,306,1,0,0,0,8, + 308,1,0,0,0,8,310,1,0,0,0,9,312,1,0,0,0,9,314,1,0,0,0,9,316,1,0,0,0,9,318, + 1,0,0,0,9,320,1,0,0,0,10,322,1,0,0,0,10,324,1,0,0,0,10,326,1,0,0,0,10,328, + 1,0,0,0,10,330,1,0,0,0,11,332,1,0,0,0,11,334,1,0,0,0,11,336,1,0,0,0,11, + 338,1,0,0,0,11,340,1,0,0,0,11,342,1,0,0,0,12,344,1,0,0,0,12,346,1,0,0,0, + 12,348,1,0,0,0,12,350,1,0,0,0,12,352,1,0,0,0,12,354,1,0,0,0,12,356,1,0, + 0,0,12,358,1,0,0,0,12,360,1,0,0,0,12,362,1,0,0,0,13,364,1,0,0,0,13,366, + 1,0,0,0,13,368,1,0,0,0,13,370,1,0,0,0,13,372,1,0,0,0,13,374,1,0,0,0,13, + 376,1,0,0,0,14,378,1,0,0,0,14,380,1,0,0,0,14,382,1,0,0,0,14,384,1,0,0,0, + 14,386,1,0,0,0,14,388,1,0,0,0,15,390,1,0,0,0,15,392,1,0,0,0,15,394,1,0, + 0,0,15,396,1,0,0,0,15,398,1,0,0,0,15,400,1,0,0,0,15,402,1,0,0,0,15,404, + 1,0,0,0,15,406,1,0,0,0,16,408,1,0,0,0,18,418,1,0,0,0,20,425,1,0,0,0,22, + 434,1,0,0,0,24,441,1,0,0,0,26,451,1,0,0,0,28,458,1,0,0,0,30,465,1,0,0,0, + 32,472,1,0,0,0,34,480,1,0,0,0,36,487,1,0,0,0,38,499,1,0,0,0,40,508,1,0, + 0,0,42,514,1,0,0,0,44,521,1,0,0,0,46,528,1,0,0,0,48,536,1,0,0,0,50,544, + 1,0,0,0,52,559,1,0,0,0,54,569,1,0,0,0,56,578,1,0,0,0,58,590,1,0,0,0,60, + 596,1,0,0,0,62,613,1,0,0,0,64,629,1,0,0,0,66,635,1,0,0,0,68,639,1,0,0,0, + 70,641,1,0,0,0,72,643,1,0,0,0,74,646,1,0,0,0,76,648,1,0,0,0,78,657,1,0, + 0,0,80,659,1,0,0,0,82,664,1,0,0,0,84,666,1,0,0,0,86,671,1,0,0,0,88,702, + 1,0,0,0,90,705,1,0,0,0,92,751,1,0,0,0,94,753,1,0,0,0,96,756,1,0,0,0,98, + 760,1,0,0,0,100,764,1,0,0,0,102,766,1,0,0,0,104,769,1,0,0,0,106,771,1,0, + 0,0,108,776,1,0,0,0,110,778,1,0,0,0,112,784,1,0,0,0,114,790,1,0,0,0,116, + 793,1,0,0,0,118,796,1,0,0,0,120,801,1,0,0,0,122,806,1,0,0,0,124,808,1,0, + 0,0,126,812,1,0,0,0,128,817,1,0,0,0,130,823,1,0,0,0,132,826,1,0,0,0,134, + 828,1,0,0,0,136,834,1,0,0,0,138,836,1,0,0,0,140,841,1,0,0,0,142,844,1,0, + 0,0,144,847,1,0,0,0,146,850,1,0,0,0,148,852,1,0,0,0,150,855,1,0,0,0,152, + 857,1,0,0,0,154,860,1,0,0,0,156,862,1,0,0,0,158,864,1,0,0,0,160,866,1,0, + 0,0,162,868,1,0,0,0,164,870,1,0,0,0,166,892,1,0,0,0,168,894,1,0,0,0,170, + 899,1,0,0,0,172,920,1,0,0,0,174,922,1,0,0,0,176,930,1,0,0,0,178,932,1,0, + 0,0,180,936,1,0,0,0,182,940,1,0,0,0,184,944,1,0,0,0,186,949,1,0,0,0,188, + 954,1,0,0,0,190,958,1,0,0,0,192,962,1,0,0,0,194,966,1,0,0,0,196,971,1,0, + 0,0,198,975,1,0,0,0,200,979,1,0,0,0,202,983,1,0,0,0,204,987,1,0,0,0,206, + 991,1,0,0,0,208,1003,1,0,0,0,210,1006,1,0,0,0,212,1010,1,0,0,0,214,1014, + 1,0,0,0,216,1018,1,0,0,0,218,1022,1,0,0,0,220,1026,1,0,0,0,222,1030,1,0, + 0,0,224,1035,1,0,0,0,226,1039,1,0,0,0,228,1047,1,0,0,0,230,1068,1,0,0,0, + 232,1072,1,0,0,0,234,1076,1,0,0,0,236,1080,1,0,0,0,238,1084,1,0,0,0,240, + 1088,1,0,0,0,242,1093,1,0,0,0,244,1097,1,0,0,0,246,1101,1,0,0,0,248,1105, + 1,0,0,0,250,1108,1,0,0,0,252,1112,1,0,0,0,254,1116,1,0,0,0,256,1120,1,0, + 0,0,258,1124,1,0,0,0,260,1129,1,0,0,0,262,1134,1,0,0,0,264,1139,1,0,0,0, + 266,1146,1,0,0,0,268,1155,1,0,0,0,270,1162,1,0,0,0,272,1166,1,0,0,0,274, + 1170,1,0,0,0,276,1174,1,0,0,0,278,1178,1,0,0,0,280,1184,1,0,0,0,282,1188, + 1,0,0,0,284,1192,1,0,0,0,286,1196,1,0,0,0,288,1200,1,0,0,0,290,1204,1,0, + 0,0,292,1208,1,0,0,0,294,1212,1,0,0,0,296,1216,1,0,0,0,298,1220,1,0,0,0, + 300,1225,1,0,0,0,302,1229,1,0,0,0,304,1233,1,0,0,0,306,1237,1,0,0,0,308, + 1241,1,0,0,0,310,1245,1,0,0,0,312,1249,1,0,0,0,314,1254,1,0,0,0,316,1259, + 1,0,0,0,318,1263,1,0,0,0,320,1267,1,0,0,0,322,1271,1,0,0,0,324,1276,1,0, + 0,0,326,1286,1,0,0,0,328,1290,1,0,0,0,330,1294,1,0,0,0,332,1298,1,0,0,0, + 334,1303,1,0,0,0,336,1310,1,0,0,0,338,1314,1,0,0,0,340,1318,1,0,0,0,342, + 1322,1,0,0,0,344,1326,1,0,0,0,346,1331,1,0,0,0,348,1335,1,0,0,0,350,1339, + 1,0,0,0,352,1343,1,0,0,0,354,1348,1,0,0,0,356,1352,1,0,0,0,358,1356,1,0, + 0,0,360,1360,1,0,0,0,362,1364,1,0,0,0,364,1368,1,0,0,0,366,1374,1,0,0,0, + 368,1378,1,0,0,0,370,1382,1,0,0,0,372,1386,1,0,0,0,374,1390,1,0,0,0,376, + 1394,1,0,0,0,378,1398,1,0,0,0,380,1403,1,0,0,0,382,1409,1,0,0,0,384,1415, + 1,0,0,0,386,1419,1,0,0,0,388,1423,1,0,0,0,390,1427,1,0,0,0,392,1433,1,0, + 0,0,394,1439,1,0,0,0,396,1443,1,0,0,0,398,1447,1,0,0,0,400,1451,1,0,0,0, + 402,1457,1,0,0,0,404,1463,1,0,0,0,406,1469,1,0,0,0,408,409,7,0,0,0,409, + 410,7,1,0,0,410,411,7,2,0,0,411,412,7,2,0,0,412,413,7,3,0,0,413,414,7,4, + 0,0,414,415,7,5,0,0,415,416,1,0,0,0,416,417,6,0,0,0,417,17,1,0,0,0,418, + 419,7,0,0,0,419,420,7,6,0,0,420,421,7,7,0,0,421,422,7,8,0,0,422,423,1,0, + 0,0,423,424,6,1,1,0,424,19,1,0,0,0,425,426,7,3,0,0,426,427,7,9,0,0,427, + 428,7,6,0,0,428,429,7,1,0,0,429,430,7,4,0,0,430,431,7,10,0,0,431,432,1, + 0,0,0,432,433,6,2,2,0,433,21,1,0,0,0,434,435,7,3,0,0,435,436,7,11,0,0,436, + 437,7,12,0,0,437,438,7,13,0,0,438,439,1,0,0,0,439,440,6,3,0,0,440,23,1, + 0,0,0,441,442,7,3,0,0,442,443,7,14,0,0,443,444,7,8,0,0,444,445,7,13,0,0, + 445,446,7,12,0,0,446,447,7,1,0,0,447,448,7,9,0,0,448,449,1,0,0,0,449,450, + 6,4,3,0,450,25,1,0,0,0,451,452,7,15,0,0,452,453,7,6,0,0,453,454,7,7,0,0, + 454,455,7,16,0,0,455,456,1,0,0,0,456,457,6,5,4,0,457,27,1,0,0,0,458,459, + 7,17,0,0,459,460,7,6,0,0,460,461,7,7,0,0,461,462,7,18,0,0,462,463,1,0,0, + 0,463,464,6,6,0,0,464,29,1,0,0,0,465,466,7,18,0,0,466,467,7,3,0,0,467,468, + 7,3,0,0,468,469,7,8,0,0,469,470,1,0,0,0,470,471,6,7,1,0,471,31,1,0,0,0, + 472,473,7,13,0,0,473,474,7,1,0,0,474,475,7,16,0,0,475,476,7,1,0,0,476,477, + 7,5,0,0,477,478,1,0,0,0,478,479,6,8,0,0,479,33,1,0,0,0,480,481,7,16,0,0, + 481,482,7,3,0,0,482,483,7,5,0,0,483,484,7,12,0,0,484,485,1,0,0,0,485,486, + 6,9,5,0,486,35,1,0,0,0,487,488,7,16,0,0,488,489,7,11,0,0,489,490,5,95,0, + 0,490,491,7,3,0,0,491,492,7,14,0,0,492,493,7,8,0,0,493,494,7,12,0,0,494, + 495,7,9,0,0,495,496,7,0,0,0,496,497,1,0,0,0,497,498,6,10,6,0,498,37,1,0, + 0,0,499,500,7,6,0,0,500,501,7,3,0,0,501,502,7,9,0,0,502,503,7,12,0,0,503, + 504,7,16,0,0,504,505,7,3,0,0,505,506,1,0,0,0,506,507,6,11,7,0,507,39,1, + 0,0,0,508,509,7,6,0,0,509,510,7,7,0,0,510,511,7,19,0,0,511,512,1,0,0,0, + 512,513,6,12,0,0,513,41,1,0,0,0,514,515,7,2,0,0,515,516,7,10,0,0,516,517, + 7,7,0,0,517,518,7,19,0,0,518,519,1,0,0,0,519,520,6,13,8,0,520,43,1,0,0, + 0,521,522,7,2,0,0,522,523,7,7,0,0,523,524,7,6,0,0,524,525,7,5,0,0,525,526, + 1,0,0,0,526,527,6,14,0,0,527,45,1,0,0,0,528,529,7,2,0,0,529,530,7,5,0,0, + 530,531,7,12,0,0,531,532,7,5,0,0,532,533,7,2,0,0,533,534,1,0,0,0,534,535, + 6,15,0,0,535,47,1,0,0,0,536,537,7,19,0,0,537,538,7,10,0,0,538,539,7,3,0, + 0,539,540,7,6,0,0,540,541,7,3,0,0,541,542,1,0,0,0,542,543,6,16,0,0,543, + 49,1,0,0,0,544,545,4,17,0,0,545,546,7,1,0,0,546,547,7,9,0,0,547,548,7,13, + 0,0,548,549,7,1,0,0,549,550,7,9,0,0,550,551,7,3,0,0,551,552,7,2,0,0,552, + 553,7,5,0,0,553,554,7,12,0,0,554,555,7,5,0,0,555,556,7,2,0,0,556,557,1, + 0,0,0,557,558,6,17,0,0,558,51,1,0,0,0,559,560,4,18,1,0,560,561,7,13,0,0, + 561,562,7,7,0,0,562,563,7,7,0,0,563,564,7,18,0,0,564,565,7,20,0,0,565,566, + 7,8,0,0,566,567,1,0,0,0,567,568,6,18,9,0,568,53,1,0,0,0,569,570,4,19,2, + 0,570,571,7,16,0,0,571,572,7,12,0,0,572,573,7,5,0,0,573,574,7,4,0,0,574, + 575,7,10,0,0,575,576,1,0,0,0,576,577,6,19,0,0,577,55,1,0,0,0,578,579,4, + 20,3,0,579,580,7,16,0,0,580,581,7,3,0,0,581,582,7,5,0,0,582,583,7,6,0,0, + 583,584,7,1,0,0,584,585,7,4,0,0,585,586,7,2,0,0,586,587,1,0,0,0,587,588, + 6,20,10,0,588,57,1,0,0,0,589,591,8,21,0,0,590,589,1,0,0,0,591,592,1,0,0, + 0,592,590,1,0,0,0,592,593,1,0,0,0,593,594,1,0,0,0,594,595,6,21,0,0,595, + 59,1,0,0,0,596,597,5,47,0,0,597,598,5,47,0,0,598,602,1,0,0,0,599,601,8, + 22,0,0,600,599,1,0,0,0,601,604,1,0,0,0,602,600,1,0,0,0,602,603,1,0,0,0, + 603,606,1,0,0,0,604,602,1,0,0,0,605,607,5,13,0,0,606,605,1,0,0,0,606,607, + 1,0,0,0,607,609,1,0,0,0,608,610,5,10,0,0,609,608,1,0,0,0,609,610,1,0,0, + 0,610,611,1,0,0,0,611,612,6,22,11,0,612,61,1,0,0,0,613,614,5,47,0,0,614, + 615,5,42,0,0,615,620,1,0,0,0,616,619,3,62,23,0,617,619,9,0,0,0,618,616, + 1,0,0,0,618,617,1,0,0,0,619,622,1,0,0,0,620,621,1,0,0,0,620,618,1,0,0,0, + 621,623,1,0,0,0,622,620,1,0,0,0,623,624,5,42,0,0,624,625,5,47,0,0,625,626, + 1,0,0,0,626,627,6,23,11,0,627,63,1,0,0,0,628,630,7,23,0,0,629,628,1,0,0, + 0,630,631,1,0,0,0,631,629,1,0,0,0,631,632,1,0,0,0,632,633,1,0,0,0,633,634, + 6,24,11,0,634,65,1,0,0,0,635,636,5,124,0,0,636,637,1,0,0,0,637,638,6,25, + 12,0,638,67,1,0,0,0,639,640,7,24,0,0,640,69,1,0,0,0,641,642,7,25,0,0,642, + 71,1,0,0,0,643,644,5,92,0,0,644,645,7,26,0,0,645,73,1,0,0,0,646,647,8,27, + 0,0,647,75,1,0,0,0,648,650,7,3,0,0,649,651,7,28,0,0,650,649,1,0,0,0,650, + 651,1,0,0,0,651,653,1,0,0,0,652,654,3,68,26,0,653,652,1,0,0,0,654,655,1, + 0,0,0,655,653,1,0,0,0,655,656,1,0,0,0,656,77,1,0,0,0,657,658,5,64,0,0,658, + 79,1,0,0,0,659,660,5,96,0,0,660,81,1,0,0,0,661,665,8,29,0,0,662,663,5,96, + 0,0,663,665,5,96,0,0,664,661,1,0,0,0,664,662,1,0,0,0,665,83,1,0,0,0,666, + 667,5,95,0,0,667,85,1,0,0,0,668,672,3,70,27,0,669,672,3,68,26,0,670,672, + 3,84,34,0,671,668,1,0,0,0,671,669,1,0,0,0,671,670,1,0,0,0,672,87,1,0,0, + 0,673,678,5,34,0,0,674,677,3,72,28,0,675,677,3,74,29,0,676,674,1,0,0,0, + 676,675,1,0,0,0,677,680,1,0,0,0,678,676,1,0,0,0,678,679,1,0,0,0,679,681, + 1,0,0,0,680,678,1,0,0,0,681,703,5,34,0,0,682,683,5,34,0,0,683,684,5,34, + 0,0,684,685,5,34,0,0,685,689,1,0,0,0,686,688,8,22,0,0,687,686,1,0,0,0,688, + 691,1,0,0,0,689,690,1,0,0,0,689,687,1,0,0,0,690,692,1,0,0,0,691,689,1,0, + 0,0,692,693,5,34,0,0,693,694,5,34,0,0,694,695,5,34,0,0,695,697,1,0,0,0, + 696,698,5,34,0,0,697,696,1,0,0,0,697,698,1,0,0,0,698,700,1,0,0,0,699,701, + 5,34,0,0,700,699,1,0,0,0,700,701,1,0,0,0,701,703,1,0,0,0,702,673,1,0,0, + 0,702,682,1,0,0,0,703,89,1,0,0,0,704,706,3,68,26,0,705,704,1,0,0,0,706, + 707,1,0,0,0,707,705,1,0,0,0,707,708,1,0,0,0,708,91,1,0,0,0,709,711,3,68, + 26,0,710,709,1,0,0,0,711,712,1,0,0,0,712,710,1,0,0,0,712,713,1,0,0,0,713, + 714,1,0,0,0,714,718,3,108,46,0,715,717,3,68,26,0,716,715,1,0,0,0,717,720, + 1,0,0,0,718,716,1,0,0,0,718,719,1,0,0,0,719,752,1,0,0,0,720,718,1,0,0,0, + 721,723,3,108,46,0,722,724,3,68,26,0,723,722,1,0,0,0,724,725,1,0,0,0,725, + 723,1,0,0,0,725,726,1,0,0,0,726,752,1,0,0,0,727,729,3,68,26,0,728,727,1, + 0,0,0,729,730,1,0,0,0,730,728,1,0,0,0,730,731,1,0,0,0,731,739,1,0,0,0,732, + 736,3,108,46,0,733,735,3,68,26,0,734,733,1,0,0,0,735,738,1,0,0,0,736,734, + 1,0,0,0,736,737,1,0,0,0,737,740,1,0,0,0,738,736,1,0,0,0,739,732,1,0,0,0, + 739,740,1,0,0,0,740,741,1,0,0,0,741,742,3,76,30,0,742,752,1,0,0,0,743,745, + 3,108,46,0,744,746,3,68,26,0,745,744,1,0,0,0,746,747,1,0,0,0,747,745,1, + 0,0,0,747,748,1,0,0,0,748,749,1,0,0,0,749,750,3,76,30,0,750,752,1,0,0,0, + 751,710,1,0,0,0,751,721,1,0,0,0,751,728,1,0,0,0,751,743,1,0,0,0,752,93, + 1,0,0,0,753,754,7,30,0,0,754,755,7,31,0,0,755,95,1,0,0,0,756,757,7,12,0, + 0,757,758,7,9,0,0,758,759,7,0,0,0,759,97,1,0,0,0,760,761,7,12,0,0,761,762, + 7,2,0,0,762,763,7,4,0,0,763,99,1,0,0,0,764,765,5,61,0,0,765,101,1,0,0,0, + 766,767,5,58,0,0,767,768,5,58,0,0,768,103,1,0,0,0,769,770,5,44,0,0,770, + 105,1,0,0,0,771,772,7,0,0,0,772,773,7,3,0,0,773,774,7,2,0,0,774,775,7,4, + 0,0,775,107,1,0,0,0,776,777,5,46,0,0,777,109,1,0,0,0,778,779,7,15,0,0,779, + 780,7,12,0,0,780,781,7,13,0,0,781,782,7,2,0,0,782,783,7,3,0,0,783,111,1, + 0,0,0,784,785,7,15,0,0,785,786,7,1,0,0,786,787,7,6,0,0,787,788,7,2,0,0, + 788,789,7,5,0,0,789,113,1,0,0,0,790,791,7,1,0,0,791,792,7,9,0,0,792,115, + 1,0,0,0,793,794,7,1,0,0,794,795,7,2,0,0,795,117,1,0,0,0,796,797,7,13,0, + 0,797,798,7,12,0,0,798,799,7,2,0,0,799,800,7,5,0,0,800,119,1,0,0,0,801, + 802,7,13,0,0,802,803,7,1,0,0,803,804,7,18,0,0,804,805,7,3,0,0,805,121,1, + 0,0,0,806,807,5,40,0,0,807,123,1,0,0,0,808,809,7,9,0,0,809,810,7,7,0,0, + 810,811,7,5,0,0,811,125,1,0,0,0,812,813,7,9,0,0,813,814,7,20,0,0,814,815, + 7,13,0,0,815,816,7,13,0,0,816,127,1,0,0,0,817,818,7,9,0,0,818,819,7,20, + 0,0,819,820,7,13,0,0,820,821,7,13,0,0,821,822,7,2,0,0,822,129,1,0,0,0,823, + 824,7,7,0,0,824,825,7,6,0,0,825,131,1,0,0,0,826,827,5,63,0,0,827,133,1, + 0,0,0,828,829,7,6,0,0,829,830,7,13,0,0,830,831,7,1,0,0,831,832,7,18,0,0, + 832,833,7,3,0,0,833,135,1,0,0,0,834,835,5,41,0,0,835,137,1,0,0,0,836,837, + 7,5,0,0,837,838,7,6,0,0,838,839,7,20,0,0,839,840,7,3,0,0,840,139,1,0,0, + 0,841,842,5,61,0,0,842,843,5,61,0,0,843,141,1,0,0,0,844,845,5,61,0,0,845, + 846,5,126,0,0,846,143,1,0,0,0,847,848,5,33,0,0,848,849,5,61,0,0,849,145, + 1,0,0,0,850,851,5,60,0,0,851,147,1,0,0,0,852,853,5,60,0,0,853,854,5,61, + 0,0,854,149,1,0,0,0,855,856,5,62,0,0,856,151,1,0,0,0,857,858,5,62,0,0,858, + 859,5,61,0,0,859,153,1,0,0,0,860,861,5,43,0,0,861,155,1,0,0,0,862,863,5, + 45,0,0,863,157,1,0,0,0,864,865,5,42,0,0,865,159,1,0,0,0,866,867,5,47,0, + 0,867,161,1,0,0,0,868,869,5,37,0,0,869,163,1,0,0,0,870,871,4,74,4,0,871, + 872,3,54,19,0,872,873,1,0,0,0,873,874,6,74,13,0,874,165,1,0,0,0,875,878, + 3,132,58,0,876,879,3,70,27,0,877,879,3,84,34,0,878,876,1,0,0,0,878,877, + 1,0,0,0,879,883,1,0,0,0,880,882,3,86,35,0,881,880,1,0,0,0,882,885,1,0,0, + 0,883,881,1,0,0,0,883,884,1,0,0,0,884,893,1,0,0,0,885,883,1,0,0,0,886,888, + 3,132,58,0,887,889,3,68,26,0,888,887,1,0,0,0,889,890,1,0,0,0,890,888,1, + 0,0,0,890,891,1,0,0,0,891,893,1,0,0,0,892,875,1,0,0,0,892,886,1,0,0,0,893, + 167,1,0,0,0,894,895,5,91,0,0,895,896,1,0,0,0,896,897,6,76,0,0,897,898,6, + 76,0,0,898,169,1,0,0,0,899,900,5,93,0,0,900,901,1,0,0,0,901,902,6,77,12, + 0,902,903,6,77,12,0,903,171,1,0,0,0,904,908,3,70,27,0,905,907,3,86,35,0, + 906,905,1,0,0,0,907,910,1,0,0,0,908,906,1,0,0,0,908,909,1,0,0,0,909,921, + 1,0,0,0,910,908,1,0,0,0,911,914,3,84,34,0,912,914,3,78,31,0,913,911,1,0, + 0,0,913,912,1,0,0,0,914,916,1,0,0,0,915,917,3,86,35,0,916,915,1,0,0,0,917, + 918,1,0,0,0,918,916,1,0,0,0,918,919,1,0,0,0,919,921,1,0,0,0,920,904,1,0, + 0,0,920,913,1,0,0,0,921,173,1,0,0,0,922,924,3,80,32,0,923,925,3,82,33,0, + 924,923,1,0,0,0,925,926,1,0,0,0,926,924,1,0,0,0,926,927,1,0,0,0,927,928, + 1,0,0,0,928,929,3,80,32,0,929,175,1,0,0,0,930,931,3,174,79,0,931,177,1, + 0,0,0,932,933,3,60,22,0,933,934,1,0,0,0,934,935,6,81,11,0,935,179,1,0,0, + 0,936,937,3,62,23,0,937,938,1,0,0,0,938,939,6,82,11,0,939,181,1,0,0,0,940, + 941,3,64,24,0,941,942,1,0,0,0,942,943,6,83,11,0,943,183,1,0,0,0,944,945, + 3,168,76,0,945,946,1,0,0,0,946,947,6,84,14,0,947,948,6,84,15,0,948,185, + 1,0,0,0,949,950,3,66,25,0,950,951,1,0,0,0,951,952,6,85,16,0,952,953,6,85, + 12,0,953,187,1,0,0,0,954,955,3,64,24,0,955,956,1,0,0,0,956,957,6,86,11, + 0,957,189,1,0,0,0,958,959,3,60,22,0,959,960,1,0,0,0,960,961,6,87,11,0,961, + 191,1,0,0,0,962,963,3,62,23,0,963,964,1,0,0,0,964,965,6,88,11,0,965,193, + 1,0,0,0,966,967,3,66,25,0,967,968,1,0,0,0,968,969,6,89,16,0,969,970,6,89, + 12,0,970,195,1,0,0,0,971,972,3,168,76,0,972,973,1,0,0,0,973,974,6,90,14, + 0,974,197,1,0,0,0,975,976,3,170,77,0,976,977,1,0,0,0,977,978,6,91,17,0, + 978,199,1,0,0,0,979,980,3,334,159,0,980,981,1,0,0,0,981,982,6,92,18,0,982, + 201,1,0,0,0,983,984,3,104,44,0,984,985,1,0,0,0,985,986,6,93,19,0,986,203, + 1,0,0,0,987,988,3,100,42,0,988,989,1,0,0,0,989,990,6,94,20,0,990,205,1, + 0,0,0,991,992,7,16,0,0,992,993,7,3,0,0,993,994,7,5,0,0,994,995,7,12,0,0, + 995,996,7,0,0,0,996,997,7,12,0,0,997,998,7,5,0,0,998,999,7,12,0,0,999,207, + 1,0,0,0,1000,1004,8,32,0,0,1001,1002,5,47,0,0,1002,1004,8,33,0,0,1003,1000, + 1,0,0,0,1003,1001,1,0,0,0,1004,209,1,0,0,0,1005,1007,3,208,96,0,1006,1005, + 1,0,0,0,1007,1008,1,0,0,0,1008,1006,1,0,0,0,1008,1009,1,0,0,0,1009,211, + 1,0,0,0,1010,1011,3,210,97,0,1011,1012,1,0,0,0,1012,1013,6,98,21,0,1013, + 213,1,0,0,0,1014,1015,3,88,36,0,1015,1016,1,0,0,0,1016,1017,6,99,22,0,1017, + 215,1,0,0,0,1018,1019,3,60,22,0,1019,1020,1,0,0,0,1020,1021,6,100,11,0, + 1021,217,1,0,0,0,1022,1023,3,62,23,0,1023,1024,1,0,0,0,1024,1025,6,101, + 11,0,1025,219,1,0,0,0,1026,1027,3,64,24,0,1027,1028,1,0,0,0,1028,1029,6, + 102,11,0,1029,221,1,0,0,0,1030,1031,3,66,25,0,1031,1032,1,0,0,0,1032,1033, + 6,103,16,0,1033,1034,6,103,12,0,1034,223,1,0,0,0,1035,1036,3,108,46,0,1036, + 1037,1,0,0,0,1037,1038,6,104,23,0,1038,225,1,0,0,0,1039,1040,3,104,44,0, + 1040,1041,1,0,0,0,1041,1042,6,105,19,0,1042,227,1,0,0,0,1043,1048,3,70, + 27,0,1044,1048,3,68,26,0,1045,1048,3,84,34,0,1046,1048,3,158,71,0,1047, + 1043,1,0,0,0,1047,1044,1,0,0,0,1047,1045,1,0,0,0,1047,1046,1,0,0,0,1048, + 229,1,0,0,0,1049,1052,3,70,27,0,1050,1052,3,158,71,0,1051,1049,1,0,0,0, + 1051,1050,1,0,0,0,1052,1056,1,0,0,0,1053,1055,3,228,106,0,1054,1053,1,0, + 0,0,1055,1058,1,0,0,0,1056,1054,1,0,0,0,1056,1057,1,0,0,0,1057,1069,1,0, + 0,0,1058,1056,1,0,0,0,1059,1062,3,84,34,0,1060,1062,3,78,31,0,1061,1059, + 1,0,0,0,1061,1060,1,0,0,0,1062,1064,1,0,0,0,1063,1065,3,228,106,0,1064, + 1063,1,0,0,0,1065,1066,1,0,0,0,1066,1064,1,0,0,0,1066,1067,1,0,0,0,1067, + 1069,1,0,0,0,1068,1051,1,0,0,0,1068,1061,1,0,0,0,1069,231,1,0,0,0,1070, + 1073,3,230,107,0,1071,1073,3,174,79,0,1072,1070,1,0,0,0,1072,1071,1,0,0, + 0,1073,1074,1,0,0,0,1074,1072,1,0,0,0,1074,1075,1,0,0,0,1075,233,1,0,0, + 0,1076,1077,3,60,22,0,1077,1078,1,0,0,0,1078,1079,6,109,11,0,1079,235,1, + 0,0,0,1080,1081,3,62,23,0,1081,1082,1,0,0,0,1082,1083,6,110,11,0,1083,237, + 1,0,0,0,1084,1085,3,64,24,0,1085,1086,1,0,0,0,1086,1087,6,111,11,0,1087, + 239,1,0,0,0,1088,1089,3,66,25,0,1089,1090,1,0,0,0,1090,1091,6,112,16,0, + 1091,1092,6,112,12,0,1092,241,1,0,0,0,1093,1094,3,100,42,0,1094,1095,1, + 0,0,0,1095,1096,6,113,20,0,1096,243,1,0,0,0,1097,1098,3,104,44,0,1098,1099, + 1,0,0,0,1099,1100,6,114,19,0,1100,245,1,0,0,0,1101,1102,3,108,46,0,1102, + 1103,1,0,0,0,1103,1104,6,115,23,0,1104,247,1,0,0,0,1105,1106,7,12,0,0,1106, + 1107,7,2,0,0,1107,249,1,0,0,0,1108,1109,3,232,108,0,1109,1110,1,0,0,0,1110, + 1111,6,117,24,0,1111,251,1,0,0,0,1112,1113,3,60,22,0,1113,1114,1,0,0,0, + 1114,1115,6,118,11,0,1115,253,1,0,0,0,1116,1117,3,62,23,0,1117,1118,1,0, + 0,0,1118,1119,6,119,11,0,1119,255,1,0,0,0,1120,1121,3,64,24,0,1121,1122, + 1,0,0,0,1122,1123,6,120,11,0,1123,257,1,0,0,0,1124,1125,3,66,25,0,1125, + 1126,1,0,0,0,1126,1127,6,121,16,0,1127,1128,6,121,12,0,1128,259,1,0,0,0, + 1129,1130,3,168,76,0,1130,1131,1,0,0,0,1131,1132,6,122,14,0,1132,1133,6, + 122,25,0,1133,261,1,0,0,0,1134,1135,7,7,0,0,1135,1136,7,9,0,0,1136,1137, + 1,0,0,0,1137,1138,6,123,26,0,1138,263,1,0,0,0,1139,1140,7,19,0,0,1140,1141, + 7,1,0,0,1141,1142,7,5,0,0,1142,1143,7,10,0,0,1143,1144,1,0,0,0,1144,1145, + 6,124,26,0,1145,265,1,0,0,0,1146,1147,8,34,0,0,1147,267,1,0,0,0,1148,1150, + 3,266,125,0,1149,1148,1,0,0,0,1150,1151,1,0,0,0,1151,1149,1,0,0,0,1151, + 1152,1,0,0,0,1152,1153,1,0,0,0,1153,1154,3,334,159,0,1154,1156,1,0,0,0, + 1155,1149,1,0,0,0,1155,1156,1,0,0,0,1156,1158,1,0,0,0,1157,1159,3,266,125, + 0,1158,1157,1,0,0,0,1159,1160,1,0,0,0,1160,1158,1,0,0,0,1160,1161,1,0,0, + 0,1161,269,1,0,0,0,1162,1163,3,268,126,0,1163,1164,1,0,0,0,1164,1165,6, + 127,27,0,1165,271,1,0,0,0,1166,1167,3,60,22,0,1167,1168,1,0,0,0,1168,1169, + 6,128,11,0,1169,273,1,0,0,0,1170,1171,3,62,23,0,1171,1172,1,0,0,0,1172, + 1173,6,129,11,0,1173,275,1,0,0,0,1174,1175,3,64,24,0,1175,1176,1,0,0,0, + 1176,1177,6,130,11,0,1177,277,1,0,0,0,1178,1179,3,66,25,0,1179,1180,1,0, + 0,0,1180,1181,6,131,16,0,1181,1182,6,131,12,0,1182,1183,6,131,12,0,1183, + 279,1,0,0,0,1184,1185,3,100,42,0,1185,1186,1,0,0,0,1186,1187,6,132,20,0, + 1187,281,1,0,0,0,1188,1189,3,104,44,0,1189,1190,1,0,0,0,1190,1191,6,133, + 19,0,1191,283,1,0,0,0,1192,1193,3,108,46,0,1193,1194,1,0,0,0,1194,1195, + 6,134,23,0,1195,285,1,0,0,0,1196,1197,3,264,124,0,1197,1198,1,0,0,0,1198, + 1199,6,135,28,0,1199,287,1,0,0,0,1200,1201,3,232,108,0,1201,1202,1,0,0, + 0,1202,1203,6,136,24,0,1203,289,1,0,0,0,1204,1205,3,176,80,0,1205,1206, + 1,0,0,0,1206,1207,6,137,29,0,1207,291,1,0,0,0,1208,1209,3,60,22,0,1209, + 1210,1,0,0,0,1210,1211,6,138,11,0,1211,293,1,0,0,0,1212,1213,3,62,23,0, + 1213,1214,1,0,0,0,1214,1215,6,139,11,0,1215,295,1,0,0,0,1216,1217,3,64, + 24,0,1217,1218,1,0,0,0,1218,1219,6,140,11,0,1219,297,1,0,0,0,1220,1221, + 3,66,25,0,1221,1222,1,0,0,0,1222,1223,6,141,16,0,1223,1224,6,141,12,0,1224, + 299,1,0,0,0,1225,1226,3,108,46,0,1226,1227,1,0,0,0,1227,1228,6,142,23,0, + 1228,301,1,0,0,0,1229,1230,3,176,80,0,1230,1231,1,0,0,0,1231,1232,6,143, + 29,0,1232,303,1,0,0,0,1233,1234,3,172,78,0,1234,1235,1,0,0,0,1235,1236, + 6,144,30,0,1236,305,1,0,0,0,1237,1238,3,60,22,0,1238,1239,1,0,0,0,1239, + 1240,6,145,11,0,1240,307,1,0,0,0,1241,1242,3,62,23,0,1242,1243,1,0,0,0, + 1243,1244,6,146,11,0,1244,309,1,0,0,0,1245,1246,3,64,24,0,1246,1247,1,0, + 0,0,1247,1248,6,147,11,0,1248,311,1,0,0,0,1249,1250,3,66,25,0,1250,1251, + 1,0,0,0,1251,1252,6,148,16,0,1252,1253,6,148,12,0,1253,313,1,0,0,0,1254, + 1255,7,1,0,0,1255,1256,7,9,0,0,1256,1257,7,15,0,0,1257,1258,7,7,0,0,1258, + 315,1,0,0,0,1259,1260,3,60,22,0,1260,1261,1,0,0,0,1261,1262,6,150,11,0, + 1262,317,1,0,0,0,1263,1264,3,62,23,0,1264,1265,1,0,0,0,1265,1266,6,151, + 11,0,1266,319,1,0,0,0,1267,1268,3,64,24,0,1268,1269,1,0,0,0,1269,1270,6, + 152,11,0,1270,321,1,0,0,0,1271,1272,3,66,25,0,1272,1273,1,0,0,0,1273,1274, + 6,153,16,0,1274,1275,6,153,12,0,1275,323,1,0,0,0,1276,1277,7,15,0,0,1277, + 1278,7,20,0,0,1278,1279,7,9,0,0,1279,1280,7,4,0,0,1280,1281,7,5,0,0,1281, + 1282,7,1,0,0,1282,1283,7,7,0,0,1283,1284,7,9,0,0,1284,1285,7,2,0,0,1285, + 325,1,0,0,0,1286,1287,3,60,22,0,1287,1288,1,0,0,0,1288,1289,6,155,11,0, + 1289,327,1,0,0,0,1290,1291,3,62,23,0,1291,1292,1,0,0,0,1292,1293,6,156, + 11,0,1293,329,1,0,0,0,1294,1295,3,64,24,0,1295,1296,1,0,0,0,1296,1297,6, + 157,11,0,1297,331,1,0,0,0,1298,1299,3,170,77,0,1299,1300,1,0,0,0,1300,1301, + 6,158,17,0,1301,1302,6,158,12,0,1302,333,1,0,0,0,1303,1304,5,58,0,0,1304, + 335,1,0,0,0,1305,1311,3,78,31,0,1306,1311,3,68,26,0,1307,1311,3,108,46, + 0,1308,1311,3,70,27,0,1309,1311,3,84,34,0,1310,1305,1,0,0,0,1310,1306,1, + 0,0,0,1310,1307,1,0,0,0,1310,1308,1,0,0,0,1310,1309,1,0,0,0,1311,1312,1, + 0,0,0,1312,1310,1,0,0,0,1312,1313,1,0,0,0,1313,337,1,0,0,0,1314,1315,3, + 60,22,0,1315,1316,1,0,0,0,1316,1317,6,161,11,0,1317,339,1,0,0,0,1318,1319, + 3,62,23,0,1319,1320,1,0,0,0,1320,1321,6,162,11,0,1321,341,1,0,0,0,1322, + 1323,3,64,24,0,1323,1324,1,0,0,0,1324,1325,6,163,11,0,1325,343,1,0,0,0, + 1326,1327,3,66,25,0,1327,1328,1,0,0,0,1328,1329,6,164,16,0,1329,1330,6, + 164,12,0,1330,345,1,0,0,0,1331,1332,3,334,159,0,1332,1333,1,0,0,0,1333, + 1334,6,165,18,0,1334,347,1,0,0,0,1335,1336,3,104,44,0,1336,1337,1,0,0,0, + 1337,1338,6,166,19,0,1338,349,1,0,0,0,1339,1340,3,108,46,0,1340,1341,1, + 0,0,0,1341,1342,6,167,23,0,1342,351,1,0,0,0,1343,1344,3,262,123,0,1344, + 1345,1,0,0,0,1345,1346,6,168,31,0,1346,1347,6,168,32,0,1347,353,1,0,0,0, + 1348,1349,3,210,97,0,1349,1350,1,0,0,0,1350,1351,6,169,21,0,1351,355,1, + 0,0,0,1352,1353,3,88,36,0,1353,1354,1,0,0,0,1354,1355,6,170,22,0,1355,357, + 1,0,0,0,1356,1357,3,60,22,0,1357,1358,1,0,0,0,1358,1359,6,171,11,0,1359, + 359,1,0,0,0,1360,1361,3,62,23,0,1361,1362,1,0,0,0,1362,1363,6,172,11,0, + 1363,361,1,0,0,0,1364,1365,3,64,24,0,1365,1366,1,0,0,0,1366,1367,6,173, + 11,0,1367,363,1,0,0,0,1368,1369,3,66,25,0,1369,1370,1,0,0,0,1370,1371,6, + 174,16,0,1371,1372,6,174,12,0,1372,1373,6,174,12,0,1373,365,1,0,0,0,1374, + 1375,3,104,44,0,1375,1376,1,0,0,0,1376,1377,6,175,19,0,1377,367,1,0,0,0, + 1378,1379,3,108,46,0,1379,1380,1,0,0,0,1380,1381,6,176,23,0,1381,369,1, + 0,0,0,1382,1383,3,232,108,0,1383,1384,1,0,0,0,1384,1385,6,177,24,0,1385, + 371,1,0,0,0,1386,1387,3,60,22,0,1387,1388,1,0,0,0,1388,1389,6,178,11,0, + 1389,373,1,0,0,0,1390,1391,3,62,23,0,1391,1392,1,0,0,0,1392,1393,6,179, + 11,0,1393,375,1,0,0,0,1394,1395,3,64,24,0,1395,1396,1,0,0,0,1396,1397,6, + 180,11,0,1397,377,1,0,0,0,1398,1399,3,66,25,0,1399,1400,1,0,0,0,1400,1401, + 6,181,16,0,1401,1402,6,181,12,0,1402,379,1,0,0,0,1403,1404,3,210,97,0,1404, + 1405,1,0,0,0,1405,1406,6,182,21,0,1406,1407,6,182,12,0,1407,1408,6,182, + 33,0,1408,381,1,0,0,0,1409,1410,3,88,36,0,1410,1411,1,0,0,0,1411,1412,6, + 183,22,0,1412,1413,6,183,12,0,1413,1414,6,183,33,0,1414,383,1,0,0,0,1415, + 1416,3,60,22,0,1416,1417,1,0,0,0,1417,1418,6,184,11,0,1418,385,1,0,0,0, + 1419,1420,3,62,23,0,1420,1421,1,0,0,0,1421,1422,6,185,11,0,1422,387,1,0, + 0,0,1423,1424,3,64,24,0,1424,1425,1,0,0,0,1425,1426,6,186,11,0,1426,389, + 1,0,0,0,1427,1428,3,334,159,0,1428,1429,1,0,0,0,1429,1430,6,187,18,0,1430, + 1431,6,187,12,0,1431,1432,6,187,10,0,1432,391,1,0,0,0,1433,1434,3,104,44, + 0,1434,1435,1,0,0,0,1435,1436,6,188,19,0,1436,1437,6,188,12,0,1437,1438, + 6,188,10,0,1438,393,1,0,0,0,1439,1440,3,60,22,0,1440,1441,1,0,0,0,1441, + 1442,6,189,11,0,1442,395,1,0,0,0,1443,1444,3,62,23,0,1444,1445,1,0,0,0, + 1445,1446,6,190,11,0,1446,397,1,0,0,0,1447,1448,3,64,24,0,1448,1449,1,0, + 0,0,1449,1450,6,191,11,0,1450,399,1,0,0,0,1451,1452,3,176,80,0,1452,1453, + 1,0,0,0,1453,1454,6,192,12,0,1454,1455,6,192,0,0,1455,1456,6,192,29,0,1456, + 401,1,0,0,0,1457,1458,3,172,78,0,1458,1459,1,0,0,0,1459,1460,6,193,12,0, + 1460,1461,6,193,0,0,1461,1462,6,193,30,0,1462,403,1,0,0,0,1463,1464,3,94, + 39,0,1464,1465,1,0,0,0,1465,1466,6,194,12,0,1466,1467,6,194,0,0,1467,1468, + 6,194,34,0,1468,405,1,0,0,0,1469,1470,3,66,25,0,1470,1471,1,0,0,0,1471, + 1472,6,195,16,0,1472,1473,6,195,12,0,1473,407,1,0,0,0,66,0,1,2,3,4,5,6, + 7,8,9,10,11,12,13,14,15,592,602,606,609,618,620,631,650,655,664,671,676, + 678,689,697,700,702,707,712,718,725,730,736,739,747,751,878,883,890,892, + 908,913,918,920,926,1003,1008,1047,1051,1056,1061,1066,1068,1072,1074,1151, + 1155,1160,1310,1312,35,5,1,0,5,4,0,5,6,0,5,2,0,5,3,0,5,10,0,5,8,0,5,5,0, + 5,9,0,5,12,0,5,14,0,0,1,0,4,0,0,7,20,0,7,66,0,5,0,0,7,26,0,7,67,0,7,109, + 0,7,35,0,7,33,0,7,77,0,7,27,0,7,37,0,7,81,0,5,11,0,5,7,0,7,91,0,7,90,0, + 7,69,0,7,68,0,7,89,0,5,13,0,5,15,0,7,30,0]; private static __ATN: ATN; public static get _ATN(): ATN { diff --git a/packages/kbn-esql-ast/src/antlr/esql_parser.g4 b/packages/kbn-esql-ast/src/antlr/esql_parser.g4 index d7e78ceda4578..6e6858c8f7328 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_parser.g4 +++ b/packages/kbn-esql-ast/src/antlr/esql_parser.g4 @@ -1,23 +1,26 @@ +// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB. + /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +parser grammar esql_parser; -// DO NOT MODIFY THIS FILE BY HAND. IT IS MANAGED BY A CI JOB. - - +@header { /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +} -parser grammar esql_parser; - -options {tokenVocab=esql_lexer;} +options { + superClass=parser_config; + tokenVocab=esql_lexer; +} singleStatement : query EOF @@ -31,28 +34,30 @@ query sourceCommand : explainCommand | fromCommand + | metaCommand | rowCommand - | metricsCommand | showCommand - | metaCommand + // in development + | {this.isDevVersion()}? metricsCommand ; processingCommand : evalCommand - | inlinestatsCommand - | limitCommand - | lookupCommand + | whereCommand | keepCommand - | sortCommand + | limitCommand | statsCommand - | whereCommand + | sortCommand | dropCommand | renameCommand | dissectCommand | grokCommand | enrichCommand | mvExpandCommand - | matchCommand + // in development + | {this.isDevVersion()}? inlinestatsCommand + | {this.isDevVersion()}? lookupCommand + | {this.isDevVersion()}? matchCommand ; whereCommand @@ -63,11 +68,11 @@ booleanExpression : NOT booleanExpression #logicalNot | valueExpression #booleanDefault | regexBooleanExpression #regexExpression - | matchBooleanExpression #matchExpression | left=booleanExpression operator=AND right=booleanExpression #logicalBinary | left=booleanExpression operator=OR right=booleanExpression #logicalBinary | valueExpression (NOT)? IN LP valueExpression (COMMA valueExpression)* RP #logicalIn | valueExpression IS NOT? NULL #isNull + | {this.isDevVersion()}? matchBooleanExpression #matchExpression ; regexBooleanExpression @@ -76,7 +81,7 @@ regexBooleanExpression ; matchBooleanExpression - : qualifiedName MATCH_OPERATOR queryString=string + : valueExpression DEV_MATCH queryString=string ; valueExpression @@ -152,7 +157,7 @@ deprecated_metadata ; metricsCommand - : METRICS indexPattern (COMMA indexPattern)* aggregates=fields? (BY grouping=fields)? + : DEV_METRICS indexPattern (COMMA indexPattern)* aggregates=fields? (BY grouping=fields)? ; evalCommand @@ -163,11 +168,6 @@ statsCommand : STATS stats=fields? (BY grouping=fields)? ; -inlinestatsCommand - : INLINESTATS stats=fields (BY grouping=fields)? - ; - - qualifiedName : identifier (DOT identifier)* ; @@ -304,12 +304,19 @@ enrichWithClause : (newName=qualifiedNamePattern ASSIGN)? enrichField=qualifiedNamePattern ; +// +// In development +// lookupCommand - : LOOKUP tableName=indexPattern ON matchFields=qualifiedNamePatterns + : DEV_LOOKUP tableName=indexPattern ON matchFields=qualifiedNamePatterns + ; + +inlinestatsCommand + : DEV_INLINESTATS stats=fields (BY grouping=fields)? ; matchCommand - : MATCH matchQuery + : DEV_MATCH matchQuery ; matchQuery diff --git a/packages/kbn-esql-ast/src/antlr/esql_parser.interp b/packages/kbn-esql-ast/src/antlr/esql_parser.interp index f415b4fce3170..d1d6aae8c3f52 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_parser.interp +++ b/packages/kbn-esql-ast/src/antlr/esql_parser.interp @@ -7,12 +7,9 @@ null 'explain' 'from' 'grok' -'inlinestats' 'keep' 'limit' -'lookup' 'meta' -'metrics' 'mv_expand' 'rename' 'row' @@ -28,7 +25,6 @@ null null null null -null '|' null null @@ -48,7 +44,6 @@ null 'last' 'like' '(' -null 'not' 'null' 'nulls' @@ -77,6 +72,9 @@ null null null null +null +null +null 'metadata' null null @@ -85,6 +83,7 @@ null null null null +null 'as' null null @@ -101,21 +100,21 @@ null null null null +'info' null null null +'functions' null null null -'info' +':' null null null -'functions' null null null -':' null null null @@ -136,12 +135,9 @@ EVAL EXPLAIN FROM GROK -INLINESTATS KEEP LIMIT -LOOKUP META -METRICS MV_EXPAND RENAME ROW @@ -149,15 +145,14 @@ SHOW SORT STATS WHERE -MATCH +DEV_INLINESTATS +DEV_LOOKUP +DEV_MATCH +DEV_METRICS UNKNOWN_CMD LINE_COMMENT MULTILINE_COMMENT WS -UNQUOTED_SOURCE -EXPLAIN_WS -EXPLAIN_LINE_COMMENT -EXPLAIN_MULTILINE_COMMENT PIPE QUOTED_STRING INTEGER_LITERAL @@ -177,7 +172,6 @@ IS LAST LIKE LP -MATCH_OPERATOR NOT NULL NULLS @@ -206,7 +200,11 @@ 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 @@ -227,12 +225,6 @@ ENRICH_WS ENRICH_FIELD_LINE_COMMENT ENRICH_FIELD_MULTILINE_COMMENT ENRICH_FIELD_WS -LOOKUP_LINE_COMMENT -LOOKUP_MULTILINE_COMMENT -LOOKUP_WS -LOOKUP_FIELD_LINE_COMMENT -LOOKUP_FIELD_MULTILINE_COMMENT -LOOKUP_FIELD_WS MVEXPAND_LINE_COMMENT MVEXPAND_MULTILINE_COMMENT MVEXPAND_WS @@ -249,6 +241,12 @@ 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 @@ -283,7 +281,6 @@ deprecated_metadata metricsCommand evalCommand statsCommand -inlinestatsCommand qualifiedName qualifiedNamePattern qualifiedNamePatterns @@ -316,9 +313,10 @@ metaCommand enrichCommand enrichWithClause lookupCommand +inlinestatsCommand matchCommand matchQuery atn: -[4, 1, 126, 584, 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 132, 8, 1, 10, 1, 12, 1, 135, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 143, 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, 3, 3, 160, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 173, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 180, 8, 5, 10, 5, 12, 5, 183, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 190, 8, 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, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 5, 14, 292, 8, 14, 10, 14, 12, 14, 295, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 302, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 308, 8, 16, 10, 16, 12, 16, 311, 9, 16, 1, 16, 3, 16, 314, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 321, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 329, 8, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 335, 8, 21, 10, 21, 12, 21, 338, 9, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 348, 8, 23, 10, 23, 12, 23, 351, 9, 23, 1, 23, 3, 23, 354, 8, 23, 1, 23, 1, 23, 3, 23, 358, 8, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 3, 25, 365, 8, 25, 1, 25, 1, 25, 3, 25, 369, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 375, 8, 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, 29, 5, 29, 396, 8, 29, 10, 29, 12, 29, 399, 9, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 418, 8, 32, 10, 32, 12, 32, 421, 9, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 429, 8, 32, 10, 32, 12, 32, 432, 9, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 440, 8, 32, 10, 32, 12, 32, 443, 9, 32, 1, 32, 1, 32, 3, 32, 447, 8, 32, 1, 33, 1, 33, 3, 33, 451, 8, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 460, 8, 35, 10, 35, 12, 35, 463, 9, 35, 1, 36, 1, 36, 3, 36, 467, 8, 36, 1, 36, 1, 36, 3, 36, 471, 8, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 483, 8, 39, 10, 39, 12, 39, 486, 9, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 496, 8, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 5, 44, 508, 8, 44, 10, 44, 12, 44, 511, 9, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 3, 47, 521, 8, 47, 1, 48, 3, 48, 524, 8, 48, 1, 48, 1, 48, 1, 49, 3, 49, 529, 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, 56, 1, 56, 1, 56, 1, 56, 3, 56, 554, 8, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 560, 8, 56, 10, 56, 12, 56, 563, 9, 56, 3, 56, 565, 8, 56, 1, 57, 1, 57, 1, 57, 3, 57, 570, 8, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 0, 4, 2, 10, 18, 20, 61, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 0, 8, 1, 0, 65, 66, 1, 0, 67, 69, 2, 0, 26, 26, 31, 31, 1, 0, 73, 74, 2, 0, 36, 36, 40, 40, 2, 0, 43, 43, 46, 46, 2, 0, 42, 42, 57, 57, 2, 0, 58, 58, 60, 64, 608, 0, 122, 1, 0, 0, 0, 2, 125, 1, 0, 0, 0, 4, 142, 1, 0, 0, 0, 6, 159, 1, 0, 0, 0, 8, 161, 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, 283, 1, 0, 0, 0, 26, 285, 1, 0, 0, 0, 28, 288, 1, 0, 0, 0, 30, 301, 1, 0, 0, 0, 32, 303, 1, 0, 0, 0, 34, 320, 1, 0, 0, 0, 36, 322, 1, 0, 0, 0, 38, 324, 1, 0, 0, 0, 40, 328, 1, 0, 0, 0, 42, 330, 1, 0, 0, 0, 44, 339, 1, 0, 0, 0, 46, 343, 1, 0, 0, 0, 48, 359, 1, 0, 0, 0, 50, 362, 1, 0, 0, 0, 52, 370, 1, 0, 0, 0, 54, 376, 1, 0, 0, 0, 56, 384, 1, 0, 0, 0, 58, 392, 1, 0, 0, 0, 60, 400, 1, 0, 0, 0, 62, 402, 1, 0, 0, 0, 64, 446, 1, 0, 0, 0, 66, 450, 1, 0, 0, 0, 68, 452, 1, 0, 0, 0, 70, 455, 1, 0, 0, 0, 72, 464, 1, 0, 0, 0, 74, 472, 1, 0, 0, 0, 76, 475, 1, 0, 0, 0, 78, 478, 1, 0, 0, 0, 80, 487, 1, 0, 0, 0, 82, 491, 1, 0, 0, 0, 84, 497, 1, 0, 0, 0, 86, 501, 1, 0, 0, 0, 88, 504, 1, 0, 0, 0, 90, 512, 1, 0, 0, 0, 92, 516, 1, 0, 0, 0, 94, 520, 1, 0, 0, 0, 96, 523, 1, 0, 0, 0, 98, 528, 1, 0, 0, 0, 100, 532, 1, 0, 0, 0, 102, 534, 1, 0, 0, 0, 104, 536, 1, 0, 0, 0, 106, 539, 1, 0, 0, 0, 108, 543, 1, 0, 0, 0, 110, 546, 1, 0, 0, 0, 112, 549, 1, 0, 0, 0, 114, 569, 1, 0, 0, 0, 116, 573, 1, 0, 0, 0, 118, 578, 1, 0, 0, 0, 120, 581, 1, 0, 0, 0, 122, 123, 3, 2, 1, 0, 123, 124, 5, 0, 0, 1, 124, 1, 1, 0, 0, 0, 125, 126, 6, 1, -1, 0, 126, 127, 3, 4, 2, 0, 127, 133, 1, 0, 0, 0, 128, 129, 10, 1, 0, 0, 129, 130, 5, 30, 0, 0, 130, 132, 3, 6, 3, 0, 131, 128, 1, 0, 0, 0, 132, 135, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 133, 134, 1, 0, 0, 0, 134, 3, 1, 0, 0, 0, 135, 133, 1, 0, 0, 0, 136, 143, 3, 104, 52, 0, 137, 143, 3, 32, 16, 0, 138, 143, 3, 26, 13, 0, 139, 143, 3, 46, 23, 0, 140, 143, 3, 108, 54, 0, 141, 143, 3, 110, 55, 0, 142, 136, 1, 0, 0, 0, 142, 137, 1, 0, 0, 0, 142, 138, 1, 0, 0, 0, 142, 139, 1, 0, 0, 0, 142, 140, 1, 0, 0, 0, 142, 141, 1, 0, 0, 0, 143, 5, 1, 0, 0, 0, 144, 160, 3, 48, 24, 0, 145, 160, 3, 52, 26, 0, 146, 160, 3, 68, 34, 0, 147, 160, 3, 116, 58, 0, 148, 160, 3, 74, 37, 0, 149, 160, 3, 70, 35, 0, 150, 160, 3, 50, 25, 0, 151, 160, 3, 8, 4, 0, 152, 160, 3, 76, 38, 0, 153, 160, 3, 78, 39, 0, 154, 160, 3, 82, 41, 0, 155, 160, 3, 84, 42, 0, 156, 160, 3, 112, 56, 0, 157, 160, 3, 86, 43, 0, 158, 160, 3, 118, 59, 0, 159, 144, 1, 0, 0, 0, 159, 145, 1, 0, 0, 0, 159, 146, 1, 0, 0, 0, 159, 147, 1, 0, 0, 0, 159, 148, 1, 0, 0, 0, 159, 149, 1, 0, 0, 0, 159, 150, 1, 0, 0, 0, 159, 151, 1, 0, 0, 0, 159, 152, 1, 0, 0, 0, 159, 153, 1, 0, 0, 0, 159, 154, 1, 0, 0, 0, 159, 155, 1, 0, 0, 0, 159, 156, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 159, 158, 1, 0, 0, 0, 160, 7, 1, 0, 0, 0, 161, 162, 5, 20, 0, 0, 162, 163, 3, 10, 5, 0, 163, 9, 1, 0, 0, 0, 164, 165, 6, 5, -1, 0, 165, 166, 5, 50, 0, 0, 166, 194, 3, 10, 5, 8, 167, 194, 3, 16, 8, 0, 168, 194, 3, 12, 6, 0, 169, 194, 3, 14, 7, 0, 170, 172, 3, 16, 8, 0, 171, 173, 5, 50, 0, 0, 172, 171, 1, 0, 0, 0, 172, 173, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 175, 5, 44, 0, 0, 175, 176, 5, 48, 0, 0, 176, 181, 3, 16, 8, 0, 177, 178, 5, 39, 0, 0, 178, 180, 3, 16, 8, 0, 179, 177, 1, 0, 0, 0, 180, 183, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 184, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 184, 185, 5, 56, 0, 0, 185, 194, 1, 0, 0, 0, 186, 187, 3, 16, 8, 0, 187, 189, 5, 45, 0, 0, 188, 190, 5, 50, 0, 0, 189, 188, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 191, 1, 0, 0, 0, 191, 192, 5, 51, 0, 0, 192, 194, 1, 0, 0, 0, 193, 164, 1, 0, 0, 0, 193, 167, 1, 0, 0, 0, 193, 168, 1, 0, 0, 0, 193, 169, 1, 0, 0, 0, 193, 170, 1, 0, 0, 0, 193, 186, 1, 0, 0, 0, 194, 203, 1, 0, 0, 0, 195, 196, 10, 4, 0, 0, 196, 197, 5, 35, 0, 0, 197, 202, 3, 10, 5, 5, 198, 199, 10, 3, 0, 0, 199, 200, 5, 53, 0, 0, 200, 202, 3, 10, 5, 4, 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, 50, 0, 0, 208, 207, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 210, 1, 0, 0, 0, 210, 211, 5, 47, 0, 0, 211, 212, 3, 100, 50, 0, 212, 221, 1, 0, 0, 0, 213, 215, 3, 16, 8, 0, 214, 216, 5, 50, 0, 0, 215, 214, 1, 0, 0, 0, 215, 216, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 218, 5, 55, 0, 0, 218, 219, 3, 100, 50, 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, 54, 27, 0, 223, 224, 5, 49, 0, 0, 224, 225, 3, 100, 50, 0, 225, 15, 1, 0, 0, 0, 226, 232, 3, 18, 9, 0, 227, 228, 3, 18, 9, 0, 228, 229, 3, 102, 51, 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, 48, 0, 0, 255, 256, 3, 10, 5, 0, 256, 257, 5, 56, 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, 38, 0, 0, 262, 264, 3, 24, 12, 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, 60, 30, 0, 269, 279, 5, 48, 0, 0, 270, 280, 5, 67, 0, 0, 271, 276, 3, 10, 5, 0, 272, 273, 5, 39, 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, 56, 0, 0, 282, 23, 1, 0, 0, 0, 283, 284, 3, 60, 30, 0, 284, 25, 1, 0, 0, 0, 285, 286, 5, 16, 0, 0, 286, 287, 3, 28, 14, 0, 287, 27, 1, 0, 0, 0, 288, 293, 3, 30, 15, 0, 289, 290, 5, 39, 0, 0, 290, 292, 3, 30, 15, 0, 291, 289, 1, 0, 0, 0, 292, 295, 1, 0, 0, 0, 293, 291, 1, 0, 0, 0, 293, 294, 1, 0, 0, 0, 294, 29, 1, 0, 0, 0, 295, 293, 1, 0, 0, 0, 296, 302, 3, 10, 5, 0, 297, 298, 3, 54, 27, 0, 298, 299, 5, 37, 0, 0, 299, 300, 3, 10, 5, 0, 300, 302, 1, 0, 0, 0, 301, 296, 1, 0, 0, 0, 301, 297, 1, 0, 0, 0, 302, 31, 1, 0, 0, 0, 303, 304, 5, 6, 0, 0, 304, 309, 3, 34, 17, 0, 305, 306, 5, 39, 0, 0, 306, 308, 3, 34, 17, 0, 307, 305, 1, 0, 0, 0, 308, 311, 1, 0, 0, 0, 309, 307, 1, 0, 0, 0, 309, 310, 1, 0, 0, 0, 310, 313, 1, 0, 0, 0, 311, 309, 1, 0, 0, 0, 312, 314, 3, 40, 20, 0, 313, 312, 1, 0, 0, 0, 313, 314, 1, 0, 0, 0, 314, 33, 1, 0, 0, 0, 315, 316, 3, 36, 18, 0, 316, 317, 5, 116, 0, 0, 317, 318, 3, 38, 19, 0, 318, 321, 1, 0, 0, 0, 319, 321, 3, 38, 19, 0, 320, 315, 1, 0, 0, 0, 320, 319, 1, 0, 0, 0, 321, 35, 1, 0, 0, 0, 322, 323, 5, 26, 0, 0, 323, 37, 1, 0, 0, 0, 324, 325, 7, 2, 0, 0, 325, 39, 1, 0, 0, 0, 326, 329, 3, 42, 21, 0, 327, 329, 3, 44, 22, 0, 328, 326, 1, 0, 0, 0, 328, 327, 1, 0, 0, 0, 329, 41, 1, 0, 0, 0, 330, 331, 5, 78, 0, 0, 331, 336, 5, 26, 0, 0, 332, 333, 5, 39, 0, 0, 333, 335, 5, 26, 0, 0, 334, 332, 1, 0, 0, 0, 335, 338, 1, 0, 0, 0, 336, 334, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 337, 43, 1, 0, 0, 0, 338, 336, 1, 0, 0, 0, 339, 340, 5, 71, 0, 0, 340, 341, 3, 42, 21, 0, 341, 342, 5, 72, 0, 0, 342, 45, 1, 0, 0, 0, 343, 344, 5, 13, 0, 0, 344, 349, 3, 34, 17, 0, 345, 346, 5, 39, 0, 0, 346, 348, 3, 34, 17, 0, 347, 345, 1, 0, 0, 0, 348, 351, 1, 0, 0, 0, 349, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 353, 1, 0, 0, 0, 351, 349, 1, 0, 0, 0, 352, 354, 3, 28, 14, 0, 353, 352, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 357, 1, 0, 0, 0, 355, 356, 5, 34, 0, 0, 356, 358, 3, 28, 14, 0, 357, 355, 1, 0, 0, 0, 357, 358, 1, 0, 0, 0, 358, 47, 1, 0, 0, 0, 359, 360, 5, 4, 0, 0, 360, 361, 3, 28, 14, 0, 361, 49, 1, 0, 0, 0, 362, 364, 5, 19, 0, 0, 363, 365, 3, 28, 14, 0, 364, 363, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 368, 1, 0, 0, 0, 366, 367, 5, 34, 0, 0, 367, 369, 3, 28, 14, 0, 368, 366, 1, 0, 0, 0, 368, 369, 1, 0, 0, 0, 369, 51, 1, 0, 0, 0, 370, 371, 5, 8, 0, 0, 371, 374, 3, 28, 14, 0, 372, 373, 5, 34, 0, 0, 373, 375, 3, 28, 14, 0, 374, 372, 1, 0, 0, 0, 374, 375, 1, 0, 0, 0, 375, 53, 1, 0, 0, 0, 376, 381, 3, 60, 30, 0, 377, 378, 5, 41, 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, 62, 31, 0, 385, 386, 5, 41, 0, 0, 386, 388, 3, 62, 31, 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, 397, 3, 56, 28, 0, 393, 394, 5, 39, 0, 0, 394, 396, 3, 56, 28, 0, 395, 393, 1, 0, 0, 0, 396, 399, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 398, 59, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 400, 401, 7, 3, 0, 0, 401, 61, 1, 0, 0, 0, 402, 403, 5, 82, 0, 0, 403, 63, 1, 0, 0, 0, 404, 447, 5, 51, 0, 0, 405, 406, 3, 98, 49, 0, 406, 407, 5, 73, 0, 0, 407, 447, 1, 0, 0, 0, 408, 447, 3, 96, 48, 0, 409, 447, 3, 98, 49, 0, 410, 447, 3, 92, 46, 0, 411, 447, 3, 66, 33, 0, 412, 447, 3, 100, 50, 0, 413, 414, 5, 71, 0, 0, 414, 419, 3, 94, 47, 0, 415, 416, 5, 39, 0, 0, 416, 418, 3, 94, 47, 0, 417, 415, 1, 0, 0, 0, 418, 421, 1, 0, 0, 0, 419, 417, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 422, 1, 0, 0, 0, 421, 419, 1, 0, 0, 0, 422, 423, 5, 72, 0, 0, 423, 447, 1, 0, 0, 0, 424, 425, 5, 71, 0, 0, 425, 430, 3, 92, 46, 0, 426, 427, 5, 39, 0, 0, 427, 429, 3, 92, 46, 0, 428, 426, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 433, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 434, 5, 72, 0, 0, 434, 447, 1, 0, 0, 0, 435, 436, 5, 71, 0, 0, 436, 441, 3, 100, 50, 0, 437, 438, 5, 39, 0, 0, 438, 440, 3, 100, 50, 0, 439, 437, 1, 0, 0, 0, 440, 443, 1, 0, 0, 0, 441, 439, 1, 0, 0, 0, 441, 442, 1, 0, 0, 0, 442, 444, 1, 0, 0, 0, 443, 441, 1, 0, 0, 0, 444, 445, 5, 72, 0, 0, 445, 447, 1, 0, 0, 0, 446, 404, 1, 0, 0, 0, 446, 405, 1, 0, 0, 0, 446, 408, 1, 0, 0, 0, 446, 409, 1, 0, 0, 0, 446, 410, 1, 0, 0, 0, 446, 411, 1, 0, 0, 0, 446, 412, 1, 0, 0, 0, 446, 413, 1, 0, 0, 0, 446, 424, 1, 0, 0, 0, 446, 435, 1, 0, 0, 0, 447, 65, 1, 0, 0, 0, 448, 451, 5, 54, 0, 0, 449, 451, 5, 70, 0, 0, 450, 448, 1, 0, 0, 0, 450, 449, 1, 0, 0, 0, 451, 67, 1, 0, 0, 0, 452, 453, 5, 10, 0, 0, 453, 454, 5, 32, 0, 0, 454, 69, 1, 0, 0, 0, 455, 456, 5, 18, 0, 0, 456, 461, 3, 72, 36, 0, 457, 458, 5, 39, 0, 0, 458, 460, 3, 72, 36, 0, 459, 457, 1, 0, 0, 0, 460, 463, 1, 0, 0, 0, 461, 459, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 71, 1, 0, 0, 0, 463, 461, 1, 0, 0, 0, 464, 466, 3, 10, 5, 0, 465, 467, 7, 4, 0, 0, 466, 465, 1, 0, 0, 0, 466, 467, 1, 0, 0, 0, 467, 470, 1, 0, 0, 0, 468, 469, 5, 52, 0, 0, 469, 471, 7, 5, 0, 0, 470, 468, 1, 0, 0, 0, 470, 471, 1, 0, 0, 0, 471, 73, 1, 0, 0, 0, 472, 473, 5, 9, 0, 0, 473, 474, 3, 58, 29, 0, 474, 75, 1, 0, 0, 0, 475, 476, 5, 2, 0, 0, 476, 477, 3, 58, 29, 0, 477, 77, 1, 0, 0, 0, 478, 479, 5, 15, 0, 0, 479, 484, 3, 80, 40, 0, 480, 481, 5, 39, 0, 0, 481, 483, 3, 80, 40, 0, 482, 480, 1, 0, 0, 0, 483, 486, 1, 0, 0, 0, 484, 482, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 79, 1, 0, 0, 0, 486, 484, 1, 0, 0, 0, 487, 488, 3, 56, 28, 0, 488, 489, 5, 86, 0, 0, 489, 490, 3, 56, 28, 0, 490, 81, 1, 0, 0, 0, 491, 492, 5, 1, 0, 0, 492, 493, 3, 20, 10, 0, 493, 495, 3, 100, 50, 0, 494, 496, 3, 88, 44, 0, 495, 494, 1, 0, 0, 0, 495, 496, 1, 0, 0, 0, 496, 83, 1, 0, 0, 0, 497, 498, 5, 7, 0, 0, 498, 499, 3, 20, 10, 0, 499, 500, 3, 100, 50, 0, 500, 85, 1, 0, 0, 0, 501, 502, 5, 14, 0, 0, 502, 503, 3, 54, 27, 0, 503, 87, 1, 0, 0, 0, 504, 509, 3, 90, 45, 0, 505, 506, 5, 39, 0, 0, 506, 508, 3, 90, 45, 0, 507, 505, 1, 0, 0, 0, 508, 511, 1, 0, 0, 0, 509, 507, 1, 0, 0, 0, 509, 510, 1, 0, 0, 0, 510, 89, 1, 0, 0, 0, 511, 509, 1, 0, 0, 0, 512, 513, 3, 60, 30, 0, 513, 514, 5, 37, 0, 0, 514, 515, 3, 64, 32, 0, 515, 91, 1, 0, 0, 0, 516, 517, 7, 6, 0, 0, 517, 93, 1, 0, 0, 0, 518, 521, 3, 96, 48, 0, 519, 521, 3, 98, 49, 0, 520, 518, 1, 0, 0, 0, 520, 519, 1, 0, 0, 0, 521, 95, 1, 0, 0, 0, 522, 524, 7, 0, 0, 0, 523, 522, 1, 0, 0, 0, 523, 524, 1, 0, 0, 0, 524, 525, 1, 0, 0, 0, 525, 526, 5, 33, 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, 32, 0, 0, 531, 99, 1, 0, 0, 0, 532, 533, 5, 31, 0, 0, 533, 101, 1, 0, 0, 0, 534, 535, 7, 7, 0, 0, 535, 103, 1, 0, 0, 0, 536, 537, 5, 5, 0, 0, 537, 538, 3, 106, 53, 0, 538, 105, 1, 0, 0, 0, 539, 540, 5, 71, 0, 0, 540, 541, 3, 2, 1, 0, 541, 542, 5, 72, 0, 0, 542, 107, 1, 0, 0, 0, 543, 544, 5, 17, 0, 0, 544, 545, 5, 108, 0, 0, 545, 109, 1, 0, 0, 0, 546, 547, 5, 12, 0, 0, 547, 548, 5, 112, 0, 0, 548, 111, 1, 0, 0, 0, 549, 550, 5, 3, 0, 0, 550, 553, 5, 92, 0, 0, 551, 552, 5, 90, 0, 0, 552, 554, 3, 56, 28, 0, 553, 551, 1, 0, 0, 0, 553, 554, 1, 0, 0, 0, 554, 564, 1, 0, 0, 0, 555, 556, 5, 91, 0, 0, 556, 561, 3, 114, 57, 0, 557, 558, 5, 39, 0, 0, 558, 560, 3, 114, 57, 0, 559, 557, 1, 0, 0, 0, 560, 563, 1, 0, 0, 0, 561, 559, 1, 0, 0, 0, 561, 562, 1, 0, 0, 0, 562, 565, 1, 0, 0, 0, 563, 561, 1, 0, 0, 0, 564, 555, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 113, 1, 0, 0, 0, 566, 567, 3, 56, 28, 0, 567, 568, 5, 37, 0, 0, 568, 570, 1, 0, 0, 0, 569, 566, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 571, 1, 0, 0, 0, 571, 572, 3, 56, 28, 0, 572, 115, 1, 0, 0, 0, 573, 574, 5, 11, 0, 0, 574, 575, 3, 34, 17, 0, 575, 576, 5, 90, 0, 0, 576, 577, 3, 58, 29, 0, 577, 117, 1, 0, 0, 0, 578, 579, 5, 21, 0, 0, 579, 580, 3, 120, 60, 0, 580, 119, 1, 0, 0, 0, 581, 582, 5, 31, 0, 0, 582, 121, 1, 0, 0, 0, 54, 133, 142, 159, 172, 181, 189, 193, 201, 203, 208, 215, 220, 231, 237, 245, 247, 258, 265, 276, 279, 293, 301, 309, 313, 320, 328, 336, 349, 353, 357, 364, 368, 374, 381, 389, 397, 419, 430, 441, 446, 450, 461, 466, 470, 484, 495, 509, 520, 523, 528, 553, 561, 564, 569] \ No newline at end of file +[4, 1, 125, 589, 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, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 132, 8, 1, 10, 1, 12, 1, 135, 9, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 144, 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, 1, 3, 1, 3, 3, 3, 164, 8, 3, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 176, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 183, 8, 5, 10, 5, 12, 5, 186, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 193, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 199, 8, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 5, 5, 207, 8, 5, 10, 5, 12, 5, 210, 9, 5, 1, 6, 1, 6, 3, 6, 214, 8, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 221, 8, 6, 1, 6, 1, 6, 1, 6, 3, 6, 226, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 237, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 243, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 251, 8, 9, 10, 9, 12, 9, 254, 9, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 264, 8, 10, 1, 10, 1, 10, 1, 10, 5, 10, 269, 8, 10, 10, 10, 12, 10, 272, 9, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 5, 11, 280, 8, 11, 10, 11, 12, 11, 283, 9, 11, 3, 11, 285, 8, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 5, 14, 297, 8, 14, 10, 14, 12, 14, 300, 9, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 307, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 313, 8, 16, 10, 16, 12, 16, 316, 9, 16, 1, 16, 3, 16, 319, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 3, 17, 326, 8, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 3, 20, 334, 8, 20, 1, 21, 1, 21, 1, 21, 1, 21, 5, 21, 340, 8, 21, 10, 21, 12, 21, 343, 9, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 5, 23, 353, 8, 23, 10, 23, 12, 23, 356, 9, 23, 1, 23, 3, 23, 359, 8, 23, 1, 23, 1, 23, 3, 23, 363, 8, 23, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 3, 25, 370, 8, 25, 1, 25, 1, 25, 3, 25, 374, 8, 25, 1, 26, 1, 26, 1, 26, 5, 26, 379, 8, 26, 10, 26, 12, 26, 382, 9, 26, 1, 27, 1, 27, 1, 27, 5, 27, 387, 8, 27, 10, 27, 12, 27, 390, 9, 27, 1, 28, 1, 28, 1, 28, 5, 28, 395, 8, 28, 10, 28, 12, 28, 398, 9, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 417, 8, 31, 10, 31, 12, 31, 420, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 428, 8, 31, 10, 31, 12, 31, 431, 9, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 5, 31, 439, 8, 31, 10, 31, 12, 31, 442, 9, 31, 1, 31, 1, 31, 3, 31, 446, 8, 31, 1, 32, 1, 32, 3, 32, 450, 8, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 5, 34, 459, 8, 34, 10, 34, 12, 34, 462, 9, 34, 1, 35, 1, 35, 3, 35, 466, 8, 35, 1, 35, 1, 35, 3, 35, 470, 8, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 5, 38, 482, 8, 38, 10, 38, 12, 38, 485, 9, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 495, 8, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 5, 43, 507, 8, 43, 10, 43, 12, 43, 510, 9, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 46, 1, 46, 3, 46, 520, 8, 46, 1, 47, 3, 47, 523, 8, 47, 1, 47, 1, 47, 1, 48, 3, 48, 528, 8, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 3, 55, 553, 8, 55, 1, 55, 1, 55, 1, 55, 1, 55, 5, 55, 559, 8, 55, 10, 55, 12, 55, 562, 9, 55, 3, 55, 564, 8, 55, 1, 56, 1, 56, 1, 56, 3, 56, 569, 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, 582, 8, 58, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 0, 4, 2, 10, 18, 20, 61, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 0, 8, 1, 0, 60, 61, 1, 0, 62, 64, 2, 0, 27, 27, 77, 77, 1, 0, 68, 69, 2, 0, 32, 32, 36, 36, 2, 0, 39, 39, 42, 42, 2, 0, 38, 38, 52, 52, 2, 0, 53, 53, 55, 59, 613, 0, 122, 1, 0, 0, 0, 2, 125, 1, 0, 0, 0, 4, 143, 1, 0, 0, 0, 6, 163, 1, 0, 0, 0, 8, 165, 1, 0, 0, 0, 10, 198, 1, 0, 0, 0, 12, 225, 1, 0, 0, 0, 14, 227, 1, 0, 0, 0, 16, 236, 1, 0, 0, 0, 18, 242, 1, 0, 0, 0, 20, 263, 1, 0, 0, 0, 22, 273, 1, 0, 0, 0, 24, 288, 1, 0, 0, 0, 26, 290, 1, 0, 0, 0, 28, 293, 1, 0, 0, 0, 30, 306, 1, 0, 0, 0, 32, 308, 1, 0, 0, 0, 34, 325, 1, 0, 0, 0, 36, 327, 1, 0, 0, 0, 38, 329, 1, 0, 0, 0, 40, 333, 1, 0, 0, 0, 42, 335, 1, 0, 0, 0, 44, 344, 1, 0, 0, 0, 46, 348, 1, 0, 0, 0, 48, 364, 1, 0, 0, 0, 50, 367, 1, 0, 0, 0, 52, 375, 1, 0, 0, 0, 54, 383, 1, 0, 0, 0, 56, 391, 1, 0, 0, 0, 58, 399, 1, 0, 0, 0, 60, 401, 1, 0, 0, 0, 62, 445, 1, 0, 0, 0, 64, 449, 1, 0, 0, 0, 66, 451, 1, 0, 0, 0, 68, 454, 1, 0, 0, 0, 70, 463, 1, 0, 0, 0, 72, 471, 1, 0, 0, 0, 74, 474, 1, 0, 0, 0, 76, 477, 1, 0, 0, 0, 78, 486, 1, 0, 0, 0, 80, 490, 1, 0, 0, 0, 82, 496, 1, 0, 0, 0, 84, 500, 1, 0, 0, 0, 86, 503, 1, 0, 0, 0, 88, 511, 1, 0, 0, 0, 90, 515, 1, 0, 0, 0, 92, 519, 1, 0, 0, 0, 94, 522, 1, 0, 0, 0, 96, 527, 1, 0, 0, 0, 98, 531, 1, 0, 0, 0, 100, 533, 1, 0, 0, 0, 102, 535, 1, 0, 0, 0, 104, 538, 1, 0, 0, 0, 106, 542, 1, 0, 0, 0, 108, 545, 1, 0, 0, 0, 110, 548, 1, 0, 0, 0, 112, 568, 1, 0, 0, 0, 114, 572, 1, 0, 0, 0, 116, 577, 1, 0, 0, 0, 118, 583, 1, 0, 0, 0, 120, 586, 1, 0, 0, 0, 122, 123, 3, 2, 1, 0, 123, 124, 5, 0, 0, 1, 124, 1, 1, 0, 0, 0, 125, 126, 6, 1, -1, 0, 126, 127, 3, 4, 2, 0, 127, 133, 1, 0, 0, 0, 128, 129, 10, 1, 0, 0, 129, 130, 5, 26, 0, 0, 130, 132, 3, 6, 3, 0, 131, 128, 1, 0, 0, 0, 132, 135, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 133, 134, 1, 0, 0, 0, 134, 3, 1, 0, 0, 0, 135, 133, 1, 0, 0, 0, 136, 144, 3, 102, 51, 0, 137, 144, 3, 32, 16, 0, 138, 144, 3, 108, 54, 0, 139, 144, 3, 26, 13, 0, 140, 144, 3, 106, 53, 0, 141, 142, 4, 2, 1, 0, 142, 144, 3, 46, 23, 0, 143, 136, 1, 0, 0, 0, 143, 137, 1, 0, 0, 0, 143, 138, 1, 0, 0, 0, 143, 139, 1, 0, 0, 0, 143, 140, 1, 0, 0, 0, 143, 141, 1, 0, 0, 0, 144, 5, 1, 0, 0, 0, 145, 164, 3, 48, 24, 0, 146, 164, 3, 8, 4, 0, 147, 164, 3, 72, 36, 0, 148, 164, 3, 66, 33, 0, 149, 164, 3, 50, 25, 0, 150, 164, 3, 68, 34, 0, 151, 164, 3, 74, 37, 0, 152, 164, 3, 76, 38, 0, 153, 164, 3, 80, 40, 0, 154, 164, 3, 82, 41, 0, 155, 164, 3, 110, 55, 0, 156, 164, 3, 84, 42, 0, 157, 158, 4, 3, 2, 0, 158, 164, 3, 116, 58, 0, 159, 160, 4, 3, 3, 0, 160, 164, 3, 114, 57, 0, 161, 162, 4, 3, 4, 0, 162, 164, 3, 118, 59, 0, 163, 145, 1, 0, 0, 0, 163, 146, 1, 0, 0, 0, 163, 147, 1, 0, 0, 0, 163, 148, 1, 0, 0, 0, 163, 149, 1, 0, 0, 0, 163, 150, 1, 0, 0, 0, 163, 151, 1, 0, 0, 0, 163, 152, 1, 0, 0, 0, 163, 153, 1, 0, 0, 0, 163, 154, 1, 0, 0, 0, 163, 155, 1, 0, 0, 0, 163, 156, 1, 0, 0, 0, 163, 157, 1, 0, 0, 0, 163, 159, 1, 0, 0, 0, 163, 161, 1, 0, 0, 0, 164, 7, 1, 0, 0, 0, 165, 166, 5, 17, 0, 0, 166, 167, 3, 10, 5, 0, 167, 9, 1, 0, 0, 0, 168, 169, 6, 5, -1, 0, 169, 170, 5, 45, 0, 0, 170, 199, 3, 10, 5, 8, 171, 199, 3, 16, 8, 0, 172, 199, 3, 12, 6, 0, 173, 175, 3, 16, 8, 0, 174, 176, 5, 45, 0, 0, 175, 174, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 177, 1, 0, 0, 0, 177, 178, 5, 40, 0, 0, 178, 179, 5, 44, 0, 0, 179, 184, 3, 16, 8, 0, 180, 181, 5, 35, 0, 0, 181, 183, 3, 16, 8, 0, 182, 180, 1, 0, 0, 0, 183, 186, 1, 0, 0, 0, 184, 182, 1, 0, 0, 0, 184, 185, 1, 0, 0, 0, 185, 187, 1, 0, 0, 0, 186, 184, 1, 0, 0, 0, 187, 188, 5, 51, 0, 0, 188, 199, 1, 0, 0, 0, 189, 190, 3, 16, 8, 0, 190, 192, 5, 41, 0, 0, 191, 193, 5, 45, 0, 0, 192, 191, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, 194, 1, 0, 0, 0, 194, 195, 5, 46, 0, 0, 195, 199, 1, 0, 0, 0, 196, 197, 4, 5, 5, 0, 197, 199, 3, 14, 7, 0, 198, 168, 1, 0, 0, 0, 198, 171, 1, 0, 0, 0, 198, 172, 1, 0, 0, 0, 198, 173, 1, 0, 0, 0, 198, 189, 1, 0, 0, 0, 198, 196, 1, 0, 0, 0, 199, 208, 1, 0, 0, 0, 200, 201, 10, 5, 0, 0, 201, 202, 5, 31, 0, 0, 202, 207, 3, 10, 5, 6, 203, 204, 10, 4, 0, 0, 204, 205, 5, 48, 0, 0, 205, 207, 3, 10, 5, 5, 206, 200, 1, 0, 0, 0, 206, 203, 1, 0, 0, 0, 207, 210, 1, 0, 0, 0, 208, 206, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 11, 1, 0, 0, 0, 210, 208, 1, 0, 0, 0, 211, 213, 3, 16, 8, 0, 212, 214, 5, 45, 0, 0, 213, 212, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 1, 0, 0, 0, 215, 216, 5, 43, 0, 0, 216, 217, 3, 98, 49, 0, 217, 226, 1, 0, 0, 0, 218, 220, 3, 16, 8, 0, 219, 221, 5, 45, 0, 0, 220, 219, 1, 0, 0, 0, 220, 221, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 223, 5, 50, 0, 0, 223, 224, 3, 98, 49, 0, 224, 226, 1, 0, 0, 0, 225, 211, 1, 0, 0, 0, 225, 218, 1, 0, 0, 0, 226, 13, 1, 0, 0, 0, 227, 228, 3, 16, 8, 0, 228, 229, 5, 20, 0, 0, 229, 230, 3, 98, 49, 0, 230, 15, 1, 0, 0, 0, 231, 237, 3, 18, 9, 0, 232, 233, 3, 18, 9, 0, 233, 234, 3, 100, 50, 0, 234, 235, 3, 18, 9, 0, 235, 237, 1, 0, 0, 0, 236, 231, 1, 0, 0, 0, 236, 232, 1, 0, 0, 0, 237, 17, 1, 0, 0, 0, 238, 239, 6, 9, -1, 0, 239, 243, 3, 20, 10, 0, 240, 241, 7, 0, 0, 0, 241, 243, 3, 18, 9, 3, 242, 238, 1, 0, 0, 0, 242, 240, 1, 0, 0, 0, 243, 252, 1, 0, 0, 0, 244, 245, 10, 2, 0, 0, 245, 246, 7, 1, 0, 0, 246, 251, 3, 18, 9, 3, 247, 248, 10, 1, 0, 0, 248, 249, 7, 0, 0, 0, 249, 251, 3, 18, 9, 2, 250, 244, 1, 0, 0, 0, 250, 247, 1, 0, 0, 0, 251, 254, 1, 0, 0, 0, 252, 250, 1, 0, 0, 0, 252, 253, 1, 0, 0, 0, 253, 19, 1, 0, 0, 0, 254, 252, 1, 0, 0, 0, 255, 256, 6, 10, -1, 0, 256, 264, 3, 62, 31, 0, 257, 264, 3, 52, 26, 0, 258, 264, 3, 22, 11, 0, 259, 260, 5, 44, 0, 0, 260, 261, 3, 10, 5, 0, 261, 262, 5, 51, 0, 0, 262, 264, 1, 0, 0, 0, 263, 255, 1, 0, 0, 0, 263, 257, 1, 0, 0, 0, 263, 258, 1, 0, 0, 0, 263, 259, 1, 0, 0, 0, 264, 270, 1, 0, 0, 0, 265, 266, 10, 1, 0, 0, 266, 267, 5, 34, 0, 0, 267, 269, 3, 24, 12, 0, 268, 265, 1, 0, 0, 0, 269, 272, 1, 0, 0, 0, 270, 268, 1, 0, 0, 0, 270, 271, 1, 0, 0, 0, 271, 21, 1, 0, 0, 0, 272, 270, 1, 0, 0, 0, 273, 274, 3, 58, 29, 0, 274, 284, 5, 44, 0, 0, 275, 285, 5, 62, 0, 0, 276, 281, 3, 10, 5, 0, 277, 278, 5, 35, 0, 0, 278, 280, 3, 10, 5, 0, 279, 277, 1, 0, 0, 0, 280, 283, 1, 0, 0, 0, 281, 279, 1, 0, 0, 0, 281, 282, 1, 0, 0, 0, 282, 285, 1, 0, 0, 0, 283, 281, 1, 0, 0, 0, 284, 275, 1, 0, 0, 0, 284, 276, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 286, 1, 0, 0, 0, 286, 287, 5, 51, 0, 0, 287, 23, 1, 0, 0, 0, 288, 289, 3, 58, 29, 0, 289, 25, 1, 0, 0, 0, 290, 291, 5, 13, 0, 0, 291, 292, 3, 28, 14, 0, 292, 27, 1, 0, 0, 0, 293, 298, 3, 30, 15, 0, 294, 295, 5, 35, 0, 0, 295, 297, 3, 30, 15, 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, 29, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 301, 307, 3, 10, 5, 0, 302, 303, 3, 52, 26, 0, 303, 304, 5, 33, 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, 31, 1, 0, 0, 0, 308, 309, 5, 6, 0, 0, 309, 314, 3, 34, 17, 0, 310, 311, 5, 35, 0, 0, 311, 313, 3, 34, 17, 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, 40, 20, 0, 318, 317, 1, 0, 0, 0, 318, 319, 1, 0, 0, 0, 319, 33, 1, 0, 0, 0, 320, 321, 3, 36, 18, 0, 321, 322, 5, 109, 0, 0, 322, 323, 3, 38, 19, 0, 323, 326, 1, 0, 0, 0, 324, 326, 3, 38, 19, 0, 325, 320, 1, 0, 0, 0, 325, 324, 1, 0, 0, 0, 326, 35, 1, 0, 0, 0, 327, 328, 5, 77, 0, 0, 328, 37, 1, 0, 0, 0, 329, 330, 7, 2, 0, 0, 330, 39, 1, 0, 0, 0, 331, 334, 3, 42, 21, 0, 332, 334, 3, 44, 22, 0, 333, 331, 1, 0, 0, 0, 333, 332, 1, 0, 0, 0, 334, 41, 1, 0, 0, 0, 335, 336, 5, 76, 0, 0, 336, 341, 5, 77, 0, 0, 337, 338, 5, 35, 0, 0, 338, 340, 5, 77, 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, 43, 1, 0, 0, 0, 343, 341, 1, 0, 0, 0, 344, 345, 5, 66, 0, 0, 345, 346, 3, 42, 21, 0, 346, 347, 5, 67, 0, 0, 347, 45, 1, 0, 0, 0, 348, 349, 5, 21, 0, 0, 349, 354, 3, 34, 17, 0, 350, 351, 5, 35, 0, 0, 351, 353, 3, 34, 17, 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, 28, 14, 0, 358, 357, 1, 0, 0, 0, 358, 359, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 361, 5, 30, 0, 0, 361, 363, 3, 28, 14, 0, 362, 360, 1, 0, 0, 0, 362, 363, 1, 0, 0, 0, 363, 47, 1, 0, 0, 0, 364, 365, 5, 4, 0, 0, 365, 366, 3, 28, 14, 0, 366, 49, 1, 0, 0, 0, 367, 369, 5, 16, 0, 0, 368, 370, 3, 28, 14, 0, 369, 368, 1, 0, 0, 0, 369, 370, 1, 0, 0, 0, 370, 373, 1, 0, 0, 0, 371, 372, 5, 30, 0, 0, 372, 374, 3, 28, 14, 0, 373, 371, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 51, 1, 0, 0, 0, 375, 380, 3, 58, 29, 0, 376, 377, 5, 37, 0, 0, 377, 379, 3, 58, 29, 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, 53, 1, 0, 0, 0, 382, 380, 1, 0, 0, 0, 383, 388, 3, 60, 30, 0, 384, 385, 5, 37, 0, 0, 385, 387, 3, 60, 30, 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, 55, 1, 0, 0, 0, 390, 388, 1, 0, 0, 0, 391, 396, 3, 54, 27, 0, 392, 393, 5, 35, 0, 0, 393, 395, 3, 54, 27, 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, 57, 1, 0, 0, 0, 398, 396, 1, 0, 0, 0, 399, 400, 7, 3, 0, 0, 400, 59, 1, 0, 0, 0, 401, 402, 5, 81, 0, 0, 402, 61, 1, 0, 0, 0, 403, 446, 5, 46, 0, 0, 404, 405, 3, 96, 48, 0, 405, 406, 5, 68, 0, 0, 406, 446, 1, 0, 0, 0, 407, 446, 3, 94, 47, 0, 408, 446, 3, 96, 48, 0, 409, 446, 3, 90, 45, 0, 410, 446, 3, 64, 32, 0, 411, 446, 3, 98, 49, 0, 412, 413, 5, 66, 0, 0, 413, 418, 3, 92, 46, 0, 414, 415, 5, 35, 0, 0, 415, 417, 3, 92, 46, 0, 416, 414, 1, 0, 0, 0, 417, 420, 1, 0, 0, 0, 418, 416, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 421, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 421, 422, 5, 67, 0, 0, 422, 446, 1, 0, 0, 0, 423, 424, 5, 66, 0, 0, 424, 429, 3, 90, 45, 0, 425, 426, 5, 35, 0, 0, 426, 428, 3, 90, 45, 0, 427, 425, 1, 0, 0, 0, 428, 431, 1, 0, 0, 0, 429, 427, 1, 0, 0, 0, 429, 430, 1, 0, 0, 0, 430, 432, 1, 0, 0, 0, 431, 429, 1, 0, 0, 0, 432, 433, 5, 67, 0, 0, 433, 446, 1, 0, 0, 0, 434, 435, 5, 66, 0, 0, 435, 440, 3, 98, 49, 0, 436, 437, 5, 35, 0, 0, 437, 439, 3, 98, 49, 0, 438, 436, 1, 0, 0, 0, 439, 442, 1, 0, 0, 0, 440, 438, 1, 0, 0, 0, 440, 441, 1, 0, 0, 0, 441, 443, 1, 0, 0, 0, 442, 440, 1, 0, 0, 0, 443, 444, 5, 67, 0, 0, 444, 446, 1, 0, 0, 0, 445, 403, 1, 0, 0, 0, 445, 404, 1, 0, 0, 0, 445, 407, 1, 0, 0, 0, 445, 408, 1, 0, 0, 0, 445, 409, 1, 0, 0, 0, 445, 410, 1, 0, 0, 0, 445, 411, 1, 0, 0, 0, 445, 412, 1, 0, 0, 0, 445, 423, 1, 0, 0, 0, 445, 434, 1, 0, 0, 0, 446, 63, 1, 0, 0, 0, 447, 450, 5, 49, 0, 0, 448, 450, 5, 65, 0, 0, 449, 447, 1, 0, 0, 0, 449, 448, 1, 0, 0, 0, 450, 65, 1, 0, 0, 0, 451, 452, 5, 9, 0, 0, 452, 453, 5, 28, 0, 0, 453, 67, 1, 0, 0, 0, 454, 455, 5, 15, 0, 0, 455, 460, 3, 70, 35, 0, 456, 457, 5, 35, 0, 0, 457, 459, 3, 70, 35, 0, 458, 456, 1, 0, 0, 0, 459, 462, 1, 0, 0, 0, 460, 458, 1, 0, 0, 0, 460, 461, 1, 0, 0, 0, 461, 69, 1, 0, 0, 0, 462, 460, 1, 0, 0, 0, 463, 465, 3, 10, 5, 0, 464, 466, 7, 4, 0, 0, 465, 464, 1, 0, 0, 0, 465, 466, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 468, 5, 47, 0, 0, 468, 470, 7, 5, 0, 0, 469, 467, 1, 0, 0, 0, 469, 470, 1, 0, 0, 0, 470, 71, 1, 0, 0, 0, 471, 472, 5, 8, 0, 0, 472, 473, 3, 56, 28, 0, 473, 73, 1, 0, 0, 0, 474, 475, 5, 2, 0, 0, 475, 476, 3, 56, 28, 0, 476, 75, 1, 0, 0, 0, 477, 478, 5, 12, 0, 0, 478, 483, 3, 78, 39, 0, 479, 480, 5, 35, 0, 0, 480, 482, 3, 78, 39, 0, 481, 479, 1, 0, 0, 0, 482, 485, 1, 0, 0, 0, 483, 481, 1, 0, 0, 0, 483, 484, 1, 0, 0, 0, 484, 77, 1, 0, 0, 0, 485, 483, 1, 0, 0, 0, 486, 487, 3, 54, 27, 0, 487, 488, 5, 85, 0, 0, 488, 489, 3, 54, 27, 0, 489, 79, 1, 0, 0, 0, 490, 491, 5, 1, 0, 0, 491, 492, 3, 20, 10, 0, 492, 494, 3, 98, 49, 0, 493, 495, 3, 86, 43, 0, 494, 493, 1, 0, 0, 0, 494, 495, 1, 0, 0, 0, 495, 81, 1, 0, 0, 0, 496, 497, 5, 7, 0, 0, 497, 498, 3, 20, 10, 0, 498, 499, 3, 98, 49, 0, 499, 83, 1, 0, 0, 0, 500, 501, 5, 11, 0, 0, 501, 502, 3, 52, 26, 0, 502, 85, 1, 0, 0, 0, 503, 508, 3, 88, 44, 0, 504, 505, 5, 35, 0, 0, 505, 507, 3, 88, 44, 0, 506, 504, 1, 0, 0, 0, 507, 510, 1, 0, 0, 0, 508, 506, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 87, 1, 0, 0, 0, 510, 508, 1, 0, 0, 0, 511, 512, 3, 58, 29, 0, 512, 513, 5, 33, 0, 0, 513, 514, 3, 62, 31, 0, 514, 89, 1, 0, 0, 0, 515, 516, 7, 6, 0, 0, 516, 91, 1, 0, 0, 0, 517, 520, 3, 94, 47, 0, 518, 520, 3, 96, 48, 0, 519, 517, 1, 0, 0, 0, 519, 518, 1, 0, 0, 0, 520, 93, 1, 0, 0, 0, 521, 523, 7, 0, 0, 0, 522, 521, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 524, 1, 0, 0, 0, 524, 525, 5, 29, 0, 0, 525, 95, 1, 0, 0, 0, 526, 528, 7, 0, 0, 0, 527, 526, 1, 0, 0, 0, 527, 528, 1, 0, 0, 0, 528, 529, 1, 0, 0, 0, 529, 530, 5, 28, 0, 0, 530, 97, 1, 0, 0, 0, 531, 532, 5, 27, 0, 0, 532, 99, 1, 0, 0, 0, 533, 534, 7, 7, 0, 0, 534, 101, 1, 0, 0, 0, 535, 536, 5, 5, 0, 0, 536, 537, 3, 104, 52, 0, 537, 103, 1, 0, 0, 0, 538, 539, 5, 66, 0, 0, 539, 540, 3, 2, 1, 0, 540, 541, 5, 67, 0, 0, 541, 105, 1, 0, 0, 0, 542, 543, 5, 14, 0, 0, 543, 544, 5, 101, 0, 0, 544, 107, 1, 0, 0, 0, 545, 546, 5, 10, 0, 0, 546, 547, 5, 105, 0, 0, 547, 109, 1, 0, 0, 0, 548, 549, 5, 3, 0, 0, 549, 552, 5, 91, 0, 0, 550, 551, 5, 89, 0, 0, 551, 553, 3, 54, 27, 0, 552, 550, 1, 0, 0, 0, 552, 553, 1, 0, 0, 0, 553, 563, 1, 0, 0, 0, 554, 555, 5, 90, 0, 0, 555, 560, 3, 112, 56, 0, 556, 557, 5, 35, 0, 0, 557, 559, 3, 112, 56, 0, 558, 556, 1, 0, 0, 0, 559, 562, 1, 0, 0, 0, 560, 558, 1, 0, 0, 0, 560, 561, 1, 0, 0, 0, 561, 564, 1, 0, 0, 0, 562, 560, 1, 0, 0, 0, 563, 554, 1, 0, 0, 0, 563, 564, 1, 0, 0, 0, 564, 111, 1, 0, 0, 0, 565, 566, 3, 54, 27, 0, 566, 567, 5, 33, 0, 0, 567, 569, 1, 0, 0, 0, 568, 565, 1, 0, 0, 0, 568, 569, 1, 0, 0, 0, 569, 570, 1, 0, 0, 0, 570, 571, 3, 54, 27, 0, 571, 113, 1, 0, 0, 0, 572, 573, 5, 19, 0, 0, 573, 574, 3, 34, 17, 0, 574, 575, 5, 89, 0, 0, 575, 576, 3, 56, 28, 0, 576, 115, 1, 0, 0, 0, 577, 578, 5, 18, 0, 0, 578, 581, 3, 28, 14, 0, 579, 580, 5, 30, 0, 0, 580, 582, 3, 28, 14, 0, 581, 579, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 117, 1, 0, 0, 0, 583, 584, 5, 20, 0, 0, 584, 585, 3, 120, 60, 0, 585, 119, 1, 0, 0, 0, 586, 587, 5, 27, 0, 0, 587, 121, 1, 0, 0, 0, 54, 133, 143, 163, 175, 184, 192, 198, 206, 208, 213, 220, 225, 236, 242, 250, 252, 263, 270, 281, 284, 298, 306, 314, 318, 325, 333, 341, 354, 358, 362, 369, 373, 380, 388, 396, 418, 429, 440, 445, 449, 460, 465, 469, 483, 494, 508, 519, 522, 527, 552, 560, 563, 568, 581] \ No newline at end of file diff --git a/packages/kbn-esql-ast/src/antlr/esql_parser.tokens b/packages/kbn-esql-ast/src/antlr/esql_parser.tokens index 2d4bb481826f5..747fbbc64cf5f 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_parser.tokens +++ b/packages/kbn-esql-ast/src/antlr/esql_parser.tokens @@ -5,125 +5,124 @@ EVAL=4 EXPLAIN=5 FROM=6 GROK=7 -INLINESTATS=8 -KEEP=9 -LIMIT=10 -LOOKUP=11 -META=12 -METRICS=13 -MV_EXPAND=14 -RENAME=15 -ROW=16 -SHOW=17 -SORT=18 -STATS=19 -WHERE=20 -MATCH=21 +KEEP=8 +LIMIT=9 +META=10 +MV_EXPAND=11 +RENAME=12 +ROW=13 +SHOW=14 +SORT=15 +STATS=16 +WHERE=17 +DEV_INLINESTATS=18 +DEV_LOOKUP=19 +DEV_MATCH=20 +DEV_METRICS=21 UNKNOWN_CMD=22 LINE_COMMENT=23 MULTILINE_COMMENT=24 WS=25 -UNQUOTED_SOURCE=26 -EXPLAIN_WS=27 -EXPLAIN_LINE_COMMENT=28 -EXPLAIN_MULTILINE_COMMENT=29 -PIPE=30 -QUOTED_STRING=31 -INTEGER_LITERAL=32 -DECIMAL_LITERAL=33 -BY=34 -AND=35 -ASC=36 -ASSIGN=37 -CAST_OP=38 -COMMA=39 -DESC=40 -DOT=41 -FALSE=42 -FIRST=43 -IN=44 -IS=45 -LAST=46 -LIKE=47 -LP=48 -MATCH_OPERATOR=49 -NOT=50 -NULL=51 -NULLS=52 -OR=53 -PARAM=54 -RLIKE=55 -RP=56 -TRUE=57 -EQ=58 -CIEQ=59 -NEQ=60 -LT=61 -LTE=62 -GT=63 -GTE=64 -PLUS=65 -MINUS=66 -ASTERISK=67 -SLASH=68 -PERCENT=69 -NAMED_OR_POSITIONAL_PARAM=70 -OPENING_BRACKET=71 -CLOSING_BRACKET=72 -UNQUOTED_IDENTIFIER=73 -QUOTED_IDENTIFIER=74 -EXPR_LINE_COMMENT=75 -EXPR_MULTILINE_COMMENT=76 -EXPR_WS=77 -METADATA=78 -FROM_LINE_COMMENT=79 -FROM_MULTILINE_COMMENT=80 -FROM_WS=81 -ID_PATTERN=82 -PROJECT_LINE_COMMENT=83 -PROJECT_MULTILINE_COMMENT=84 -PROJECT_WS=85 -AS=86 -RENAME_LINE_COMMENT=87 -RENAME_MULTILINE_COMMENT=88 -RENAME_WS=89 -ON=90 -WITH=91 -ENRICH_POLICY_NAME=92 -ENRICH_LINE_COMMENT=93 -ENRICH_MULTILINE_COMMENT=94 -ENRICH_WS=95 -ENRICH_FIELD_LINE_COMMENT=96 -ENRICH_FIELD_MULTILINE_COMMENT=97 -ENRICH_FIELD_WS=98 -LOOKUP_LINE_COMMENT=99 -LOOKUP_MULTILINE_COMMENT=100 -LOOKUP_WS=101 -LOOKUP_FIELD_LINE_COMMENT=102 -LOOKUP_FIELD_MULTILINE_COMMENT=103 -LOOKUP_FIELD_WS=104 -MVEXPAND_LINE_COMMENT=105 -MVEXPAND_MULTILINE_COMMENT=106 -MVEXPAND_WS=107 -INFO=108 -SHOW_LINE_COMMENT=109 -SHOW_MULTILINE_COMMENT=110 -SHOW_WS=111 -FUNCTIONS=112 -META_LINE_COMMENT=113 -META_MULTILINE_COMMENT=114 -META_WS=115 -COLON=116 -SETTING=117 -SETTING_LINE_COMMENT=118 -SETTTING_MULTILINE_COMMENT=119 -SETTING_WS=120 -METRICS_LINE_COMMENT=121 -METRICS_MULTILINE_COMMENT=122 -METRICS_WS=123 -CLOSING_METRICS_LINE_COMMENT=124 -CLOSING_METRICS_MULTILINE_COMMENT=125 -CLOSING_METRICS_WS=126 +PIPE=26 +QUOTED_STRING=27 +INTEGER_LITERAL=28 +DECIMAL_LITERAL=29 +BY=30 +AND=31 +ASC=32 +ASSIGN=33 +CAST_OP=34 +COMMA=35 +DESC=36 +DOT=37 +FALSE=38 +FIRST=39 +IN=40 +IS=41 +LAST=42 +LIKE=43 +LP=44 +NOT=45 +NULL=46 +NULLS=47 +OR=48 +PARAM=49 +RLIKE=50 +RP=51 +TRUE=52 +EQ=53 +CIEQ=54 +NEQ=55 +LT=56 +LTE=57 +GT=58 +GTE=59 +PLUS=60 +MINUS=61 +ASTERISK=62 +SLASH=63 +PERCENT=64 +NAMED_OR_POSITIONAL_PARAM=65 +OPENING_BRACKET=66 +CLOSING_BRACKET=67 +UNQUOTED_IDENTIFIER=68 +QUOTED_IDENTIFIER=69 +EXPR_LINE_COMMENT=70 +EXPR_MULTILINE_COMMENT=71 +EXPR_WS=72 +EXPLAIN_WS=73 +EXPLAIN_LINE_COMMENT=74 +EXPLAIN_MULTILINE_COMMENT=75 +METADATA=76 +UNQUOTED_SOURCE=77 +FROM_LINE_COMMENT=78 +FROM_MULTILINE_COMMENT=79 +FROM_WS=80 +ID_PATTERN=81 +PROJECT_LINE_COMMENT=82 +PROJECT_MULTILINE_COMMENT=83 +PROJECT_WS=84 +AS=85 +RENAME_LINE_COMMENT=86 +RENAME_MULTILINE_COMMENT=87 +RENAME_WS=88 +ON=89 +WITH=90 +ENRICH_POLICY_NAME=91 +ENRICH_LINE_COMMENT=92 +ENRICH_MULTILINE_COMMENT=93 +ENRICH_WS=94 +ENRICH_FIELD_LINE_COMMENT=95 +ENRICH_FIELD_MULTILINE_COMMENT=96 +ENRICH_FIELD_WS=97 +MVEXPAND_LINE_COMMENT=98 +MVEXPAND_MULTILINE_COMMENT=99 +MVEXPAND_WS=100 +INFO=101 +SHOW_LINE_COMMENT=102 +SHOW_MULTILINE_COMMENT=103 +SHOW_WS=104 +FUNCTIONS=105 +META_LINE_COMMENT=106 +META_MULTILINE_COMMENT=107 +META_WS=108 +COLON=109 +SETTING=110 +SETTING_LINE_COMMENT=111 +SETTTING_MULTILINE_COMMENT=112 +SETTING_WS=113 +LOOKUP_LINE_COMMENT=114 +LOOKUP_MULTILINE_COMMENT=115 +LOOKUP_WS=116 +LOOKUP_FIELD_LINE_COMMENT=117 +LOOKUP_FIELD_MULTILINE_COMMENT=118 +LOOKUP_FIELD_WS=119 +METRICS_LINE_COMMENT=120 +METRICS_MULTILINE_COMMENT=121 +METRICS_WS=122 +CLOSING_METRICS_LINE_COMMENT=123 +CLOSING_METRICS_MULTILINE_COMMENT=124 +CLOSING_METRICS_WS=125 'dissect'=1 'drop'=2 'enrich'=3 @@ -131,60 +130,57 @@ CLOSING_METRICS_WS=126 'explain'=5 'from'=6 'grok'=7 -'inlinestats'=8 -'keep'=9 -'limit'=10 -'lookup'=11 -'meta'=12 -'metrics'=13 -'mv_expand'=14 -'rename'=15 -'row'=16 -'show'=17 -'sort'=18 -'stats'=19 -'where'=20 -'|'=30 -'by'=34 -'and'=35 -'asc'=36 -'='=37 -'::'=38 -','=39 -'desc'=40 -'.'=41 -'false'=42 -'first'=43 -'in'=44 -'is'=45 -'last'=46 -'like'=47 -'('=48 -'not'=50 -'null'=51 -'nulls'=52 -'or'=53 -'?'=54 -'rlike'=55 -')'=56 -'true'=57 -'=='=58 -'=~'=59 -'!='=60 -'<'=61 -'<='=62 -'>'=63 -'>='=64 -'+'=65 -'-'=66 -'*'=67 -'/'=68 -'%'=69 -']'=72 -'metadata'=78 -'as'=86 -'on'=90 -'with'=91 -'info'=108 -'functions'=112 -':'=116 +'keep'=8 +'limit'=9 +'meta'=10 +'mv_expand'=11 +'rename'=12 +'row'=13 +'show'=14 +'sort'=15 +'stats'=16 +'where'=17 +'|'=26 +'by'=30 +'and'=31 +'asc'=32 +'='=33 +'::'=34 +','=35 +'desc'=36 +'.'=37 +'false'=38 +'first'=39 +'in'=40 +'is'=41 +'last'=42 +'like'=43 +'('=44 +'not'=45 +'null'=46 +'nulls'=47 +'or'=48 +'?'=49 +'rlike'=50 +')'=51 +'true'=52 +'=='=53 +'=~'=54 +'!='=55 +'<'=56 +'<='=57 +'>'=58 +'>='=59 +'+'=60 +'-'=61 +'*'=62 +'/'=63 +'%'=64 +']'=67 +'metadata'=76 +'as'=85 +'on'=89 +'with'=90 +'info'=101 +'functions'=105 +':'=109 diff --git a/packages/kbn-esql-ast/src/antlr/esql_parser.ts b/packages/kbn-esql-ast/src/antlr/esql_parser.ts index f2903de828ca5..47453c39b1466 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_parser.ts +++ b/packages/kbn-esql-ast/src/antlr/esql_parser.ts @@ -17,7 +17,17 @@ import esql_parserListener from "./esql_parserListener.js"; // eslint-disable-next-line no-unused-vars type int = number; -export default class esql_parser extends Parser { + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import parser_config from './parser_config.js'; + +export default class esql_parser extends parser_config { public static readonly DISSECT = 1; public static readonly DROP = 2; public static readonly ENRICH = 3; @@ -25,125 +35,124 @@ export default class esql_parser extends Parser { public static readonly EXPLAIN = 5; public static readonly FROM = 6; public static readonly GROK = 7; - public static readonly INLINESTATS = 8; - public static readonly KEEP = 9; - public static readonly LIMIT = 10; - public static readonly LOOKUP = 11; - public static readonly META = 12; - public static readonly METRICS = 13; - public static readonly MV_EXPAND = 14; - public static readonly RENAME = 15; - public static readonly ROW = 16; - public static readonly SHOW = 17; - public static readonly SORT = 18; - public static readonly STATS = 19; - public static readonly WHERE = 20; - public static readonly MATCH = 21; + public static readonly KEEP = 8; + public static readonly LIMIT = 9; + public static readonly META = 10; + public static readonly MV_EXPAND = 11; + public static readonly RENAME = 12; + public static readonly ROW = 13; + public static readonly SHOW = 14; + public static readonly SORT = 15; + public static readonly STATS = 16; + public static readonly WHERE = 17; + public static readonly DEV_INLINESTATS = 18; + public static readonly DEV_LOOKUP = 19; + public static readonly DEV_MATCH = 20; + public static readonly DEV_METRICS = 21; public static readonly UNKNOWN_CMD = 22; public static readonly LINE_COMMENT = 23; public static readonly MULTILINE_COMMENT = 24; public static readonly WS = 25; - public static readonly UNQUOTED_SOURCE = 26; - public static readonly EXPLAIN_WS = 27; - public static readonly EXPLAIN_LINE_COMMENT = 28; - public static readonly EXPLAIN_MULTILINE_COMMENT = 29; - public static readonly PIPE = 30; - public static readonly QUOTED_STRING = 31; - public static readonly INTEGER_LITERAL = 32; - public static readonly DECIMAL_LITERAL = 33; - public static readonly BY = 34; - public static readonly AND = 35; - public static readonly ASC = 36; - public static readonly ASSIGN = 37; - public static readonly CAST_OP = 38; - public static readonly COMMA = 39; - public static readonly DESC = 40; - public static readonly DOT = 41; - public static readonly FALSE = 42; - public static readonly FIRST = 43; - public static readonly IN = 44; - public static readonly IS = 45; - public static readonly LAST = 46; - public static readonly LIKE = 47; - public static readonly LP = 48; - public static readonly MATCH_OPERATOR = 49; - public static readonly NOT = 50; - public static readonly NULL = 51; - public static readonly NULLS = 52; - public static readonly OR = 53; - public static readonly PARAM = 54; - public static readonly RLIKE = 55; - public static readonly RP = 56; - public static readonly TRUE = 57; - public static readonly EQ = 58; - public static readonly CIEQ = 59; - public static readonly NEQ = 60; - public static readonly LT = 61; - public static readonly LTE = 62; - public static readonly GT = 63; - public static readonly GTE = 64; - public static readonly PLUS = 65; - public static readonly MINUS = 66; - public static readonly ASTERISK = 67; - public static readonly SLASH = 68; - public static readonly PERCENT = 69; - public static readonly NAMED_OR_POSITIONAL_PARAM = 70; - public static readonly OPENING_BRACKET = 71; - public static readonly CLOSING_BRACKET = 72; - public static readonly UNQUOTED_IDENTIFIER = 73; - public static readonly QUOTED_IDENTIFIER = 74; - public static readonly EXPR_LINE_COMMENT = 75; - public static readonly EXPR_MULTILINE_COMMENT = 76; - public static readonly EXPR_WS = 77; - public static readonly METADATA = 78; - public static readonly FROM_LINE_COMMENT = 79; - public static readonly FROM_MULTILINE_COMMENT = 80; - public static readonly FROM_WS = 81; - public static readonly ID_PATTERN = 82; - public static readonly PROJECT_LINE_COMMENT = 83; - public static readonly PROJECT_MULTILINE_COMMENT = 84; - public static readonly PROJECT_WS = 85; - public static readonly AS = 86; - public static readonly RENAME_LINE_COMMENT = 87; - public static readonly RENAME_MULTILINE_COMMENT = 88; - public static readonly RENAME_WS = 89; - public static readonly ON = 90; - public static readonly WITH = 91; - public static readonly ENRICH_POLICY_NAME = 92; - public static readonly ENRICH_LINE_COMMENT = 93; - public static readonly ENRICH_MULTILINE_COMMENT = 94; - public static readonly ENRICH_WS = 95; - public static readonly ENRICH_FIELD_LINE_COMMENT = 96; - public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 97; - public static readonly ENRICH_FIELD_WS = 98; - public static readonly LOOKUP_LINE_COMMENT = 99; - public static readonly LOOKUP_MULTILINE_COMMENT = 100; - public static readonly LOOKUP_WS = 101; - public static readonly LOOKUP_FIELD_LINE_COMMENT = 102; - public static readonly LOOKUP_FIELD_MULTILINE_COMMENT = 103; - public static readonly LOOKUP_FIELD_WS = 104; - public static readonly MVEXPAND_LINE_COMMENT = 105; - public static readonly MVEXPAND_MULTILINE_COMMENT = 106; - public static readonly MVEXPAND_WS = 107; - public static readonly INFO = 108; - public static readonly SHOW_LINE_COMMENT = 109; - public static readonly SHOW_MULTILINE_COMMENT = 110; - public static readonly SHOW_WS = 111; - public static readonly FUNCTIONS = 112; - public static readonly META_LINE_COMMENT = 113; - public static readonly META_MULTILINE_COMMENT = 114; - public static readonly META_WS = 115; - public static readonly COLON = 116; - public static readonly SETTING = 117; - public static readonly SETTING_LINE_COMMENT = 118; - public static readonly SETTTING_MULTILINE_COMMENT = 119; - public static readonly SETTING_WS = 120; - public static readonly METRICS_LINE_COMMENT = 121; - public static readonly METRICS_MULTILINE_COMMENT = 122; - public static readonly METRICS_WS = 123; - public static readonly CLOSING_METRICS_LINE_COMMENT = 124; - public static readonly CLOSING_METRICS_MULTILINE_COMMENT = 125; - public static readonly CLOSING_METRICS_WS = 126; + public static readonly PIPE = 26; + public static readonly QUOTED_STRING = 27; + public static readonly INTEGER_LITERAL = 28; + public static readonly DECIMAL_LITERAL = 29; + public static readonly BY = 30; + public static readonly AND = 31; + public static readonly ASC = 32; + public static readonly ASSIGN = 33; + public static readonly CAST_OP = 34; + public static readonly COMMA = 35; + public static readonly DESC = 36; + public static readonly DOT = 37; + public static readonly FALSE = 38; + public static readonly FIRST = 39; + public static readonly IN = 40; + public static readonly IS = 41; + public static readonly LAST = 42; + public static readonly LIKE = 43; + public static readonly LP = 44; + public static readonly NOT = 45; + public static readonly NULL = 46; + public static readonly NULLS = 47; + public static readonly OR = 48; + public static readonly PARAM = 49; + public static readonly RLIKE = 50; + public static readonly RP = 51; + public static readonly TRUE = 52; + public static readonly EQ = 53; + public static readonly CIEQ = 54; + public static readonly NEQ = 55; + public static readonly LT = 56; + public static readonly LTE = 57; + public static readonly GT = 58; + public static readonly GTE = 59; + public static readonly PLUS = 60; + public static readonly MINUS = 61; + public static readonly ASTERISK = 62; + public static readonly SLASH = 63; + public static readonly PERCENT = 64; + public static readonly NAMED_OR_POSITIONAL_PARAM = 65; + public static readonly OPENING_BRACKET = 66; + public static readonly CLOSING_BRACKET = 67; + public static readonly UNQUOTED_IDENTIFIER = 68; + public static readonly QUOTED_IDENTIFIER = 69; + public static readonly EXPR_LINE_COMMENT = 70; + public static readonly EXPR_MULTILINE_COMMENT = 71; + public static readonly EXPR_WS = 72; + public static readonly EXPLAIN_WS = 73; + public static readonly EXPLAIN_LINE_COMMENT = 74; + public static readonly EXPLAIN_MULTILINE_COMMENT = 75; + public static readonly METADATA = 76; + public static readonly UNQUOTED_SOURCE = 77; + public static readonly FROM_LINE_COMMENT = 78; + public static readonly FROM_MULTILINE_COMMENT = 79; + public static readonly FROM_WS = 80; + public static readonly ID_PATTERN = 81; + public static readonly PROJECT_LINE_COMMENT = 82; + public static readonly PROJECT_MULTILINE_COMMENT = 83; + public static readonly PROJECT_WS = 84; + public static readonly AS = 85; + public static readonly RENAME_LINE_COMMENT = 86; + public static readonly RENAME_MULTILINE_COMMENT = 87; + public static readonly RENAME_WS = 88; + public static readonly ON = 89; + public static readonly WITH = 90; + public static readonly ENRICH_POLICY_NAME = 91; + public static readonly ENRICH_LINE_COMMENT = 92; + public static readonly ENRICH_MULTILINE_COMMENT = 93; + public static readonly ENRICH_WS = 94; + public static readonly ENRICH_FIELD_LINE_COMMENT = 95; + public static readonly ENRICH_FIELD_MULTILINE_COMMENT = 96; + public static readonly ENRICH_FIELD_WS = 97; + public static readonly MVEXPAND_LINE_COMMENT = 98; + public static readonly MVEXPAND_MULTILINE_COMMENT = 99; + public static readonly MVEXPAND_WS = 100; + public static readonly INFO = 101; + public static readonly SHOW_LINE_COMMENT = 102; + public static readonly SHOW_MULTILINE_COMMENT = 103; + public static readonly SHOW_WS = 104; + public static readonly FUNCTIONS = 105; + public static readonly META_LINE_COMMENT = 106; + public static readonly META_MULTILINE_COMMENT = 107; + public static readonly META_WS = 108; + public static readonly COLON = 109; + public static readonly SETTING = 110; + public static readonly SETTING_LINE_COMMENT = 111; + public static readonly SETTTING_MULTILINE_COMMENT = 112; + public static readonly SETTING_WS = 113; + public static readonly LOOKUP_LINE_COMMENT = 114; + public static readonly LOOKUP_MULTILINE_COMMENT = 115; + public static readonly LOOKUP_WS = 116; + public static readonly LOOKUP_FIELD_LINE_COMMENT = 117; + public static readonly LOOKUP_FIELD_MULTILINE_COMMENT = 118; + public static readonly LOOKUP_FIELD_WS = 119; + public static readonly METRICS_LINE_COMMENT = 120; + public static readonly METRICS_MULTILINE_COMMENT = 121; + public static readonly METRICS_WS = 122; + public static readonly CLOSING_METRICS_LINE_COMMENT = 123; + public static readonly CLOSING_METRICS_MULTILINE_COMMENT = 124; + public static readonly CLOSING_METRICS_WS = 125; public static override readonly EOF = Token.EOF; public static readonly RULE_singleStatement = 0; public static readonly RULE_query = 1; @@ -171,50 +180,47 @@ export default class esql_parser extends Parser { public static readonly RULE_metricsCommand = 23; public static readonly RULE_evalCommand = 24; public static readonly RULE_statsCommand = 25; - public static readonly RULE_inlinestatsCommand = 26; - public static readonly RULE_qualifiedName = 27; - public static readonly RULE_qualifiedNamePattern = 28; - public static readonly RULE_qualifiedNamePatterns = 29; - public static readonly RULE_identifier = 30; - public static readonly RULE_identifierPattern = 31; - public static readonly RULE_constant = 32; - public static readonly RULE_params = 33; - public static readonly RULE_limitCommand = 34; - public static readonly RULE_sortCommand = 35; - public static readonly RULE_orderExpression = 36; - public static readonly RULE_keepCommand = 37; - public static readonly RULE_dropCommand = 38; - public static readonly RULE_renameCommand = 39; - public static readonly RULE_renameClause = 40; - public static readonly RULE_dissectCommand = 41; - public static readonly RULE_grokCommand = 42; - public static readonly RULE_mvExpandCommand = 43; - public static readonly RULE_commandOptions = 44; - public static readonly RULE_commandOption = 45; - public static readonly RULE_booleanValue = 46; - public static readonly RULE_numericValue = 47; - public static readonly RULE_decimalValue = 48; - public static readonly RULE_integerValue = 49; - public static readonly RULE_string = 50; - public static readonly RULE_comparisonOperator = 51; - public static readonly RULE_explainCommand = 52; - public static readonly RULE_subqueryExpression = 53; - public static readonly RULE_showCommand = 54; - public static readonly RULE_metaCommand = 55; - public static readonly RULE_enrichCommand = 56; - public static readonly RULE_enrichWithClause = 57; - public static readonly RULE_lookupCommand = 58; + public static readonly RULE_qualifiedName = 26; + public static readonly RULE_qualifiedNamePattern = 27; + public static readonly RULE_qualifiedNamePatterns = 28; + public static readonly RULE_identifier = 29; + public static readonly RULE_identifierPattern = 30; + public static readonly RULE_constant = 31; + public static readonly RULE_params = 32; + public static readonly RULE_limitCommand = 33; + public static readonly RULE_sortCommand = 34; + public static readonly RULE_orderExpression = 35; + public static readonly RULE_keepCommand = 36; + public static readonly RULE_dropCommand = 37; + public static readonly RULE_renameCommand = 38; + public static readonly RULE_renameClause = 39; + public static readonly RULE_dissectCommand = 40; + public static readonly RULE_grokCommand = 41; + public static readonly RULE_mvExpandCommand = 42; + public static readonly RULE_commandOptions = 43; + public static readonly RULE_commandOption = 44; + public static readonly RULE_booleanValue = 45; + public static readonly RULE_numericValue = 46; + public static readonly RULE_decimalValue = 47; + public static readonly RULE_integerValue = 48; + public static readonly RULE_string = 49; + public static readonly RULE_comparisonOperator = 50; + public static readonly RULE_explainCommand = 51; + public static readonly RULE_subqueryExpression = 52; + public static readonly RULE_showCommand = 53; + public static readonly RULE_metaCommand = 54; + public static readonly RULE_enrichCommand = 55; + public static readonly RULE_enrichWithClause = 56; + public static readonly RULE_lookupCommand = 57; + public static readonly RULE_inlinestatsCommand = 58; public static readonly RULE_matchCommand = 59; public static readonly RULE_matchQuery = 60; public static readonly literalNames: (string | null)[] = [ null, "'dissect'", "'drop'", "'enrich'", "'eval'", "'explain'", "'from'", "'grok'", - "'inlinestats'", "'keep'", "'limit'", - "'lookup'", - "'meta'", "'metrics'", - "'mv_expand'", + "'meta'", "'mv_expand'", "'rename'", "'row'", "'show'", "'sort'", "'stats'", @@ -222,17 +228,16 @@ export default class esql_parser extends Parser { null, null, null, null, null, null, + null, "'|'", null, null, - "'|'", null, - null, null, - "'by'", "'and'", - "'asc'", "'='", - "'::'", "','", - "'desc'", "'.'", - "'false'", "'first'", - "'in'", "'is'", - "'last'", "'like'", - "'('", null, + null, "'by'", + "'and'", "'asc'", + "'='", "'::'", + "','", "'desc'", + "'.'", "'false'", + "'first'", "'in'", + "'is'", "'last'", + "'like'", "'('", "'not'", "'null'", "'nulls'", "'or'", "'?'", "'rlike'", @@ -247,46 +252,43 @@ export default class esql_parser extends Parser { "']'", null, null, null, null, null, - "'metadata'", null, null, + null, "'metadata'", null, null, null, null, - null, "'as'", null, null, - null, "'on'", - "'with'", null, null, null, + "'as'", null, null, null, + "'on'", "'with'", null, null, null, null, null, null, null, null, null, null, - null, "'info'", + "'info'", null, null, null, - null, "'functions'", + "'functions'", null, null, null, "':'" ]; public static readonly symbolicNames: (string | null)[] = [ null, "DISSECT", "DROP", "ENRICH", "EVAL", "EXPLAIN", "FROM", "GROK", - "INLINESTATS", "KEEP", "LIMIT", - "LOOKUP", "META", - "METRICS", - "MV_EXPAND", + "META", "MV_EXPAND", "RENAME", "ROW", "SHOW", "SORT", "STATS", "WHERE", - "MATCH", "UNKNOWN_CMD", + "DEV_INLINESTATS", + "DEV_LOOKUP", + "DEV_MATCH", + "DEV_METRICS", + "UNKNOWN_CMD", "LINE_COMMENT", "MULTILINE_COMMENT", - "WS", "UNQUOTED_SOURCE", - "EXPLAIN_WS", - "EXPLAIN_LINE_COMMENT", - "EXPLAIN_MULTILINE_COMMENT", - "PIPE", "QUOTED_STRING", + "WS", "PIPE", + "QUOTED_STRING", "INTEGER_LITERAL", "DECIMAL_LITERAL", "BY", "AND", @@ -297,7 +299,6 @@ export default class esql_parser extends Parser { "FIRST", "IN", "IS", "LAST", "LIKE", "LP", - "MATCH_OPERATOR", "NOT", "NULL", "NULLS", "OR", "PARAM", "RLIKE", @@ -316,7 +317,11 @@ export default class esql_parser extends Parser { "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", @@ -335,12 +340,6 @@ export default class esql_parser extends Parser { "ENRICH_FIELD_LINE_COMMENT", "ENRICH_FIELD_MULTILINE_COMMENT", "ENRICH_FIELD_WS", - "LOOKUP_LINE_COMMENT", - "LOOKUP_MULTILINE_COMMENT", - "LOOKUP_WS", - "LOOKUP_FIELD_LINE_COMMENT", - "LOOKUP_FIELD_MULTILINE_COMMENT", - "LOOKUP_FIELD_WS", "MVEXPAND_LINE_COMMENT", "MVEXPAND_MULTILINE_COMMENT", "MVEXPAND_WS", @@ -355,6 +354,12 @@ export default class esql_parser extends Parser { "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", @@ -368,14 +373,14 @@ export default class esql_parser extends Parser { "valueExpression", "operatorExpression", "primaryExpression", "functionExpression", "dataType", "rowCommand", "fields", "field", "fromCommand", "indexPattern", "clusterString", "indexString", "metadata", "metadataOption", "deprecated_metadata", - "metricsCommand", "evalCommand", "statsCommand", "inlinestatsCommand", - "qualifiedName", "qualifiedNamePattern", "qualifiedNamePatterns", "identifier", - "identifierPattern", "constant", "params", "limitCommand", "sortCommand", - "orderExpression", "keepCommand", "dropCommand", "renameCommand", "renameClause", - "dissectCommand", "grokCommand", "mvExpandCommand", "commandOptions", - "commandOption", "booleanValue", "numericValue", "decimalValue", "integerValue", - "string", "comparisonOperator", "explainCommand", "subqueryExpression", - "showCommand", "metaCommand", "enrichCommand", "enrichWithClause", "lookupCommand", + "metricsCommand", "evalCommand", "statsCommand", "qualifiedName", "qualifiedNamePattern", + "qualifiedNamePatterns", "identifier", "identifierPattern", "constant", + "params", "limitCommand", "sortCommand", "orderExpression", "keepCommand", + "dropCommand", "renameCommand", "renameClause", "dissectCommand", "grokCommand", + "mvExpandCommand", "commandOptions", "commandOption", "booleanValue", + "numericValue", "decimalValue", "integerValue", "string", "comparisonOperator", + "explainCommand", "subqueryExpression", "showCommand", "metaCommand", + "enrichCommand", "enrichWithClause", "lookupCommand", "inlinestatsCommand", "matchCommand", "matchQuery", ]; public get grammarFileName(): string { return "esql_parser.g4"; } @@ -496,53 +501,55 @@ export default class esql_parser extends Parser { let localctx: SourceCommandContext = new SourceCommandContext(this, this._ctx, this.state); this.enterRule(localctx, 4, esql_parser.RULE_sourceCommand); try { - this.state = 142; + this.state = 143; this._errHandler.sync(this); - switch (this._input.LA(1)) { - case 5: + switch ( this._interp.adaptivePredict(this._input, 1, this._ctx) ) { + case 1: this.enterOuterAlt(localctx, 1); { this.state = 136; this.explainCommand(); } break; - case 6: + case 2: this.enterOuterAlt(localctx, 2); { this.state = 137; this.fromCommand(); } break; - case 16: + case 3: this.enterOuterAlt(localctx, 3); { this.state = 138; - this.rowCommand(); + this.metaCommand(); } break; - case 13: + case 4: this.enterOuterAlt(localctx, 4); { this.state = 139; - this.metricsCommand(); + this.rowCommand(); } break; - case 17: + case 5: this.enterOuterAlt(localctx, 5); { this.state = 140; this.showCommand(); } break; - case 12: + case 6: this.enterOuterAlt(localctx, 6); { this.state = 141; - this.metaCommand(); + if (!(this.isDevVersion())) { + throw this.createFailedPredicateException("this.isDevVersion()"); + } + this.state = 142; + this.metricsCommand(); } break; - default: - throw new NoViableAltException(this); } } catch (re) { @@ -564,116 +571,126 @@ export default class esql_parser extends Parser { let localctx: ProcessingCommandContext = new ProcessingCommandContext(this, this._ctx, this.state); this.enterRule(localctx, 6, esql_parser.RULE_processingCommand); try { - this.state = 159; + this.state = 163; this._errHandler.sync(this); - switch (this._input.LA(1)) { - case 4: + switch ( this._interp.adaptivePredict(this._input, 2, this._ctx) ) { + case 1: this.enterOuterAlt(localctx, 1); { - this.state = 144; + this.state = 145; this.evalCommand(); } break; - case 8: + case 2: this.enterOuterAlt(localctx, 2); { - this.state = 145; - this.inlinestatsCommand(); + this.state = 146; + this.whereCommand(); } break; - case 10: + case 3: this.enterOuterAlt(localctx, 3); { - this.state = 146; - this.limitCommand(); + this.state = 147; + this.keepCommand(); } break; - case 11: + case 4: this.enterOuterAlt(localctx, 4); { - this.state = 147; - this.lookupCommand(); + this.state = 148; + this.limitCommand(); } break; - case 9: + case 5: this.enterOuterAlt(localctx, 5); { - this.state = 148; - this.keepCommand(); + this.state = 149; + this.statsCommand(); } break; - case 18: + case 6: this.enterOuterAlt(localctx, 6); { - this.state = 149; + this.state = 150; this.sortCommand(); } break; - case 19: + case 7: this.enterOuterAlt(localctx, 7); { - this.state = 150; - this.statsCommand(); + this.state = 151; + this.dropCommand(); } break; - case 20: + case 8: this.enterOuterAlt(localctx, 8); { - this.state = 151; - this.whereCommand(); + this.state = 152; + this.renameCommand(); } break; - case 2: + case 9: this.enterOuterAlt(localctx, 9); { - this.state = 152; - this.dropCommand(); + this.state = 153; + this.dissectCommand(); } break; - case 15: + case 10: this.enterOuterAlt(localctx, 10); { - this.state = 153; - this.renameCommand(); + this.state = 154; + this.grokCommand(); } break; - case 1: + case 11: this.enterOuterAlt(localctx, 11); { - this.state = 154; - this.dissectCommand(); + this.state = 155; + this.enrichCommand(); } break; - case 7: + case 12: this.enterOuterAlt(localctx, 12); { - this.state = 155; - this.grokCommand(); + this.state = 156; + this.mvExpandCommand(); } break; - case 3: + case 13: this.enterOuterAlt(localctx, 13); { - this.state = 156; - this.enrichCommand(); + this.state = 157; + if (!(this.isDevVersion())) { + throw this.createFailedPredicateException("this.isDevVersion()"); + } + this.state = 158; + this.inlinestatsCommand(); } break; case 14: this.enterOuterAlt(localctx, 14); { - this.state = 157; - this.mvExpandCommand(); + this.state = 159; + if (!(this.isDevVersion())) { + throw this.createFailedPredicateException("this.isDevVersion()"); + } + this.state = 160; + this.lookupCommand(); } break; - case 21: + case 15: this.enterOuterAlt(localctx, 15); { - this.state = 158; + this.state = 161; + if (!(this.isDevVersion())) { + throw this.createFailedPredicateException("this.isDevVersion()"); + } + this.state = 162; this.matchCommand(); } break; - default: - throw new NoViableAltException(this); } } catch (re) { @@ -697,9 +714,9 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 161; + this.state = 165; this.match(esql_parser.WHERE); - this.state = 162; + this.state = 166; this.booleanExpression(0); } } @@ -737,7 +754,7 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 193; + this.state = 198; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 6, this._ctx) ) { case 1: @@ -746,9 +763,9 @@ export default class esql_parser extends Parser { this._ctx = localctx; _prevctx = localctx; - this.state = 165; + this.state = 169; this.match(esql_parser.NOT); - this.state = 166; + this.state = 170; this.booleanExpression(8); } break; @@ -757,7 +774,7 @@ export default class esql_parser extends Parser { localctx = new BooleanDefaultContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 167; + this.state = 171; this.valueExpression(); } break; @@ -766,88 +783,92 @@ export default class esql_parser extends Parser { localctx = new RegexExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 168; + this.state = 172; this.regexBooleanExpression(); } break; case 4: - { - localctx = new MatchExpressionContext(this, localctx); - this._ctx = localctx; - _prevctx = localctx; - this.state = 169; - this.matchBooleanExpression(); - } - break; - case 5: { localctx = new LogicalInContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 170; + this.state = 173; this.valueExpression(); - this.state = 172; + this.state = 175; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===50) { + if (_la===45) { { - this.state = 171; + this.state = 174; this.match(esql_parser.NOT); } } - this.state = 174; + this.state = 177; this.match(esql_parser.IN); - this.state = 175; + this.state = 178; this.match(esql_parser.LP); - this.state = 176; + this.state = 179; this.valueExpression(); - this.state = 181; + this.state = 184; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===39) { + while (_la===35) { { { - this.state = 177; + this.state = 180; this.match(esql_parser.COMMA); - this.state = 178; + this.state = 181; this.valueExpression(); } } - this.state = 183; + this.state = 186; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 184; + this.state = 187; this.match(esql_parser.RP); } break; - case 6: + case 5: { localctx = new IsNullContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 186; + this.state = 189; this.valueExpression(); - this.state = 187; + this.state = 190; this.match(esql_parser.IS); - this.state = 189; + this.state = 192; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===50) { + if (_la===45) { { - this.state = 188; + this.state = 191; this.match(esql_parser.NOT); } } - this.state = 191; + this.state = 194; this.match(esql_parser.NULL); } break; + case 6: + { + localctx = new MatchExpressionContext(this, localctx); + this._ctx = localctx; + _prevctx = localctx; + this.state = 196; + if (!(this.isDevVersion())) { + throw this.createFailedPredicateException("this.isDevVersion()"); + } + this.state = 197; + this.matchBooleanExpression(); + } + break; } this._ctx.stop = this._input.LT(-1); - this.state = 203; + this.state = 208; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 8, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -857,7 +878,7 @@ export default class esql_parser extends Parser { } _prevctx = localctx; { - this.state = 201; + this.state = 206; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 7, this._ctx) ) { case 1: @@ -865,14 +886,14 @@ export default class esql_parser extends Parser { localctx = new LogicalBinaryContext(this, new BooleanExpressionContext(this, _parentctx, _parentState)); (localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 195; - if (!(this.precpred(this._ctx, 4))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 4)"); + this.state = 200; + if (!(this.precpred(this._ctx, 5))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 5)"); } - this.state = 196; + this.state = 201; (localctx as LogicalBinaryContext)._operator = this.match(esql_parser.AND); - this.state = 197; - (localctx as LogicalBinaryContext)._right = this.booleanExpression(5); + this.state = 202; + (localctx as LogicalBinaryContext)._right = this.booleanExpression(6); } break; case 2: @@ -880,20 +901,20 @@ export default class esql_parser extends Parser { localctx = new LogicalBinaryContext(this, new BooleanExpressionContext(this, _parentctx, _parentState)); (localctx as LogicalBinaryContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, esql_parser.RULE_booleanExpression); - this.state = 198; - if (!(this.precpred(this._ctx, 3))) { - throw this.createFailedPredicateException("this.precpred(this._ctx, 3)"); + this.state = 203; + if (!(this.precpred(this._ctx, 4))) { + throw this.createFailedPredicateException("this.precpred(this._ctx, 4)"); } - this.state = 199; + this.state = 204; (localctx as LogicalBinaryContext)._operator = this.match(esql_parser.OR); - this.state = 200; - (localctx as LogicalBinaryContext)._right = this.booleanExpression(4); + this.state = 205; + (localctx as LogicalBinaryContext)._right = this.booleanExpression(5); } break; } } } - this.state = 205; + this.state = 210; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 8, this._ctx); } @@ -919,48 +940,48 @@ export default class esql_parser extends Parser { this.enterRule(localctx, 12, esql_parser.RULE_regexBooleanExpression); let _la: number; try { - this.state = 220; + this.state = 225; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 11, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 206; + this.state = 211; this.valueExpression(); - this.state = 208; + this.state = 213; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===50) { + if (_la===45) { { - this.state = 207; + this.state = 212; this.match(esql_parser.NOT); } } - this.state = 210; + this.state = 215; localctx._kind = this.match(esql_parser.LIKE); - this.state = 211; + this.state = 216; localctx._pattern = this.string_(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 213; + this.state = 218; this.valueExpression(); - this.state = 215; + this.state = 220; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===50) { + if (_la===45) { { - this.state = 214; + this.state = 219; this.match(esql_parser.NOT); } } - this.state = 217; + this.state = 222; localctx._kind = this.match(esql_parser.RLIKE); - this.state = 218; + this.state = 223; localctx._pattern = this.string_(); } break; @@ -987,11 +1008,11 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 222; - this.qualifiedName(); - this.state = 223; - this.match(esql_parser.MATCH_OPERATOR); - this.state = 224; + this.state = 227; + this.valueExpression(); + this.state = 228; + this.match(esql_parser.DEV_MATCH); + this.state = 229; localctx._queryString = this.string_(); } } @@ -1014,14 +1035,14 @@ export default class esql_parser extends Parser { let localctx: ValueExpressionContext = new ValueExpressionContext(this, this._ctx, this.state); this.enterRule(localctx, 16, esql_parser.RULE_valueExpression); try { - this.state = 231; + this.state = 236; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 12, this._ctx) ) { case 1: localctx = new ValueExpressionDefaultContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 226; + this.state = 231; this.operatorExpression(0); } break; @@ -1029,11 +1050,11 @@ export default class esql_parser extends Parser { localctx = new ComparisonContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 227; + this.state = 232; (localctx as ComparisonContext)._left = this.operatorExpression(0); - this.state = 228; + this.state = 233; this.comparisonOperator(); - this.state = 229; + this.state = 234; (localctx as ComparisonContext)._right = this.operatorExpression(0); } break; @@ -1073,7 +1094,7 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 237; + this.state = 242; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 13, this._ctx) ) { case 1: @@ -1082,7 +1103,7 @@ export default class esql_parser extends Parser { this._ctx = localctx; _prevctx = localctx; - this.state = 234; + this.state = 239; this.primaryExpression(0); } break; @@ -1091,23 +1112,23 @@ export default class esql_parser extends Parser { localctx = new ArithmeticUnaryContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 235; + this.state = 240; (localctx as ArithmeticUnaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===65 || _la===66)) { + if(!(_la===60 || _la===61)) { (localctx as ArithmeticUnaryContext)._operator = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 236; + this.state = 241; this.operatorExpression(3); } break; } this._ctx.stop = this._input.LT(-1); - this.state = 247; + this.state = 252; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 15, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -1117,7 +1138,7 @@ export default class esql_parser extends Parser { } _prevctx = localctx; { - this.state = 245; + this.state = 250; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 14, this._ctx) ) { case 1: @@ -1125,21 +1146,21 @@ export default class esql_parser extends Parser { localctx = new ArithmeticBinaryContext(this, new OperatorExpressionContext(this, _parentctx, _parentState)); (localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 239; + this.state = 244; if (!(this.precpred(this._ctx, 2))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 2)"); } - this.state = 240; + this.state = 245; (localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); - if(!(((((_la - 67)) & ~0x1F) === 0 && ((1 << (_la - 67)) & 7) !== 0))) { + if(!(((((_la - 62)) & ~0x1F) === 0 && ((1 << (_la - 62)) & 7) !== 0))) { (localctx as ArithmeticBinaryContext)._operator = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 241; + this.state = 246; (localctx as ArithmeticBinaryContext)._right = this.operatorExpression(3); } break; @@ -1148,28 +1169,28 @@ export default class esql_parser extends Parser { localctx = new ArithmeticBinaryContext(this, new OperatorExpressionContext(this, _parentctx, _parentState)); (localctx as ArithmeticBinaryContext)._left = _prevctx; this.pushNewRecursionContext(localctx, _startState, esql_parser.RULE_operatorExpression); - this.state = 242; + this.state = 247; if (!(this.precpred(this._ctx, 1))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 1)"); } - this.state = 243; + this.state = 248; (localctx as ArithmeticBinaryContext)._operator = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===65 || _la===66)) { + if(!(_la===60 || _la===61)) { (localctx as ArithmeticBinaryContext)._operator = this._errHandler.recoverInline(this); } else { this._errHandler.reportMatch(this); this.consume(); } - this.state = 244; + this.state = 249; (localctx as ArithmeticBinaryContext)._right = this.operatorExpression(2); } break; } } } - this.state = 249; + this.state = 254; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 15, this._ctx); } @@ -1208,7 +1229,7 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 258; + this.state = 263; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 16, this._ctx) ) { case 1: @@ -1217,7 +1238,7 @@ export default class esql_parser extends Parser { this._ctx = localctx; _prevctx = localctx; - this.state = 251; + this.state = 256; this.constant(); } break; @@ -1226,7 +1247,7 @@ export default class esql_parser extends Parser { localctx = new DereferenceContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 252; + this.state = 257; this.qualifiedName(); } break; @@ -1235,7 +1256,7 @@ export default class esql_parser extends Parser { localctx = new FunctionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 253; + this.state = 258; this.functionExpression(); } break; @@ -1244,17 +1265,17 @@ export default class esql_parser extends Parser { localctx = new ParenthesizedExpressionContext(this, localctx); this._ctx = localctx; _prevctx = localctx; - this.state = 254; + this.state = 259; this.match(esql_parser.LP); - this.state = 255; + this.state = 260; this.booleanExpression(0); - this.state = 256; + this.state = 261; this.match(esql_parser.RP); } break; } this._ctx.stop = this._input.LT(-1); - this.state = 265; + this.state = 270; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 17, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { @@ -1267,18 +1288,18 @@ export default class esql_parser extends Parser { { localctx = new InlineCastContext(this, new PrimaryExpressionContext(this, _parentctx, _parentState)); this.pushNewRecursionContext(localctx, _startState, esql_parser.RULE_primaryExpression); - this.state = 260; + this.state = 265; if (!(this.precpred(this._ctx, 1))) { throw this.createFailedPredicateException("this.precpred(this._ctx, 1)"); } - this.state = 261; + this.state = 266; this.match(esql_parser.CAST_OP); - this.state = 262; + this.state = 267; this.dataType(); } } } - this.state = 267; + this.state = 272; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 17, this._ctx); } @@ -1306,63 +1327,45 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 268; + this.state = 273; this.identifier(); - this.state = 269; + this.state = 274; this.match(esql_parser.LP); - this.state = 279; + this.state = 284; this._errHandler.sync(this); - switch (this._input.LA(1)) { - case 67: + switch ( this._interp.adaptivePredict(this._input, 19, this._ctx) ) { + case 1: { - this.state = 270; + this.state = 275; this.match(esql_parser.ASTERISK); } break; - case 31: - case 32: - case 33: - case 42: - case 48: - case 50: - case 51: - case 54: - case 57: - case 65: - case 66: - case 70: - case 71: - case 73: - case 74: + case 2: { { - this.state = 271; - this.booleanExpression(0); this.state = 276; + this.booleanExpression(0); + this.state = 281; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===39) { + while (_la===35) { { { - this.state = 272; + this.state = 277; this.match(esql_parser.COMMA); - this.state = 273; + this.state = 278; this.booleanExpression(0); } } - this.state = 278; + this.state = 283; this._errHandler.sync(this); _la = this._input.LA(1); } } } break; - case 56: - break; - default: - break; } - this.state = 281; + this.state = 286; this.match(esql_parser.RP); } } @@ -1388,7 +1391,7 @@ export default class esql_parser extends Parser { localctx = new ToDataTypeContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 283; + this.state = 288; this.identifier(); } } @@ -1413,9 +1416,9 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 285; + this.state = 290; this.match(esql_parser.ROW); - this.state = 286; + this.state = 291; this.fields(); } } @@ -1441,23 +1444,23 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 288; - this.field(); this.state = 293; + this.field(); + this.state = 298; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 20, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 289; + this.state = 294; this.match(esql_parser.COMMA); - this.state = 290; + this.state = 295; this.field(); } } } - this.state = 295; + this.state = 300; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 20, this._ctx); } @@ -1482,24 +1485,24 @@ export default class esql_parser extends Parser { let localctx: FieldContext = new FieldContext(this, this._ctx, this.state); this.enterRule(localctx, 30, esql_parser.RULE_field); try { - this.state = 301; + this.state = 306; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 21, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 296; + this.state = 301; this.booleanExpression(0); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 297; + this.state = 302; this.qualifiedName(); - this.state = 298; + this.state = 303; this.match(esql_parser.ASSIGN); - this.state = 299; + this.state = 304; this.booleanExpression(0); } break; @@ -1527,34 +1530,34 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 303; + this.state = 308; this.match(esql_parser.FROM); - this.state = 304; - this.indexPattern(); this.state = 309; + this.indexPattern(); + this.state = 314; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 22, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 305; + this.state = 310; this.match(esql_parser.COMMA); - this.state = 306; + this.state = 311; this.indexPattern(); } } } - this.state = 311; + this.state = 316; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 22, this._ctx); } - this.state = 313; + this.state = 318; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 23, this._ctx) ) { case 1: { - this.state = 312; + this.state = 317; this.metadata(); } break; @@ -1580,24 +1583,24 @@ export default class esql_parser extends Parser { let localctx: IndexPatternContext = new IndexPatternContext(this, this._ctx, this.state); this.enterRule(localctx, 34, esql_parser.RULE_indexPattern); try { - this.state = 320; + this.state = 325; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 24, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 315; + this.state = 320; this.clusterString(); - this.state = 316; + this.state = 321; this.match(esql_parser.COLON); - this.state = 317; + this.state = 322; this.indexString(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 319; + this.state = 324; this.indexString(); } break; @@ -1624,7 +1627,7 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 322; + this.state = 327; this.match(esql_parser.UNQUOTED_SOURCE); } } @@ -1650,9 +1653,9 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 324; + this.state = 329; _la = this._input.LA(1); - if(!(_la===26 || _la===31)) { + if(!(_la===27 || _la===77)) { this._errHandler.recoverInline(this); } else { @@ -1680,20 +1683,20 @@ export default class esql_parser extends Parser { let localctx: MetadataContext = new MetadataContext(this, this._ctx, this.state); this.enterRule(localctx, 40, esql_parser.RULE_metadata); try { - this.state = 328; + this.state = 333; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 78: + case 76: this.enterOuterAlt(localctx, 1); { - this.state = 326; + this.state = 331; this.metadataOption(); } break; - case 71: + case 66: this.enterOuterAlt(localctx, 2); { - this.state = 327; + this.state = 332; this.deprecated_metadata(); } break; @@ -1723,25 +1726,25 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 330; + this.state = 335; this.match(esql_parser.METADATA); - this.state = 331; - this.match(esql_parser.UNQUOTED_SOURCE); this.state = 336; + this.match(esql_parser.UNQUOTED_SOURCE); + this.state = 341; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 26, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 332; + this.state = 337; this.match(esql_parser.COMMA); - this.state = 333; + this.state = 338; this.match(esql_parser.UNQUOTED_SOURCE); } } } - this.state = 338; + this.state = 343; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 26, this._ctx); } @@ -1768,11 +1771,11 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 339; + this.state = 344; this.match(esql_parser.OPENING_BRACKET); - this.state = 340; + this.state = 345; this.metadataOption(); - this.state = 341; + this.state = 346; this.match(esql_parser.CLOSING_BRACKET); } } @@ -1798,46 +1801,46 @@ export default class esql_parser extends Parser { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 343; - this.match(esql_parser.METRICS); - this.state = 344; - this.indexPattern(); + this.state = 348; + this.match(esql_parser.DEV_METRICS); this.state = 349; + this.indexPattern(); + this.state = 354; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 27, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 345; + this.state = 350; this.match(esql_parser.COMMA); - this.state = 346; + this.state = 351; this.indexPattern(); } } } - this.state = 351; + this.state = 356; this._errHandler.sync(this); _alt = this._interp.adaptivePredict(this._input, 27, this._ctx); } - this.state = 353; + this.state = 358; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 28, this._ctx) ) { case 1: { - this.state = 352; + this.state = 357; localctx._aggregates = this.fields(); } break; } - this.state = 357; + this.state = 362; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 29, this._ctx) ) { case 1: { - this.state = 355; + this.state = 360; this.match(esql_parser.BY); - this.state = 356; + this.state = 361; localctx._grouping = this.fields(); } break; @@ -1865,9 +1868,9 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 359; + this.state = 364; this.match(esql_parser.EVAL); - this.state = 360; + this.state = 365; this.fields(); } } @@ -1892,65 +1895,26 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 362; + this.state = 367; this.match(esql_parser.STATS); - this.state = 364; + this.state = 369; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 30, this._ctx) ) { case 1: { - this.state = 363; + this.state = 368; localctx._stats = this.fields(); } break; } - this.state = 368; + this.state = 373; this._errHandler.sync(this); switch ( this._interp.adaptivePredict(this._input, 31, this._ctx) ) { case 1: { - this.state = 366; + this.state = 371; this.match(esql_parser.BY); - this.state = 367; - localctx._grouping = this.fields(); - } - break; - } - } - } - catch (re) { - if (re instanceof RecognitionException) { - localctx.exception = re; - this._errHandler.reportError(this, re); - this._errHandler.recover(this, re); - } else { - throw re; - } - } - finally { - this.exitRule(); - } - return localctx; - } - // @RuleVersion(0) - public inlinestatsCommand(): InlinestatsCommandContext { - let localctx: InlinestatsCommandContext = new InlinestatsCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 52, esql_parser.RULE_inlinestatsCommand); - try { - this.enterOuterAlt(localctx, 1); - { - this.state = 370; - this.match(esql_parser.INLINESTATS); - this.state = 371; - localctx._stats = this.fields(); - this.state = 374; - this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 32, this._ctx) ) { - case 1: - { this.state = 372; - this.match(esql_parser.BY); - this.state = 373; localctx._grouping = this.fields(); } break; @@ -1974,30 +1938,30 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public qualifiedName(): QualifiedNameContext { let localctx: QualifiedNameContext = new QualifiedNameContext(this, this._ctx, this.state); - this.enterRule(localctx, 54, esql_parser.RULE_qualifiedName); + this.enterRule(localctx, 52, esql_parser.RULE_qualifiedName); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 376; + this.state = 375; this.identifier(); - this.state = 381; + this.state = 380; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 32, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 377; + this.state = 376; this.match(esql_parser.DOT); - this.state = 378; + this.state = 377; this.identifier(); } } } - this.state = 383; + this.state = 382; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 32, this._ctx); } } } @@ -2018,30 +1982,30 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public qualifiedNamePattern(): QualifiedNamePatternContext { let localctx: QualifiedNamePatternContext = new QualifiedNamePatternContext(this, this._ctx, this.state); - this.enterRule(localctx, 56, esql_parser.RULE_qualifiedNamePattern); + this.enterRule(localctx, 54, esql_parser.RULE_qualifiedNamePattern); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 384; + this.state = 383; this.identifierPattern(); - this.state = 389; + this.state = 388; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 34, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 385; + this.state = 384; this.match(esql_parser.DOT); - this.state = 386; + this.state = 385; this.identifierPattern(); } } } - this.state = 391; + this.state = 390; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 34, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 33, this._ctx); } } } @@ -2062,30 +2026,30 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public qualifiedNamePatterns(): QualifiedNamePatternsContext { let localctx: QualifiedNamePatternsContext = new QualifiedNamePatternsContext(this, this._ctx, this.state); - this.enterRule(localctx, 58, esql_parser.RULE_qualifiedNamePatterns); + this.enterRule(localctx, 56, esql_parser.RULE_qualifiedNamePatterns); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 392; + this.state = 391; this.qualifiedNamePattern(); - this.state = 397; + this.state = 396; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 35, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 34, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 393; + this.state = 392; this.match(esql_parser.COMMA); - this.state = 394; + this.state = 393; this.qualifiedNamePattern(); } } } - this.state = 399; + this.state = 398; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 35, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 34, this._ctx); } } } @@ -2106,14 +2070,14 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public identifier(): IdentifierContext { let localctx: IdentifierContext = new IdentifierContext(this, this._ctx, this.state); - this.enterRule(localctx, 60, esql_parser.RULE_identifier); + this.enterRule(localctx, 58, esql_parser.RULE_identifier); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 400; + this.state = 399; _la = this._input.LA(1); - if(!(_la===73 || _la===74)) { + if(!(_la===68 || _la===69)) { this._errHandler.recoverInline(this); } else { @@ -2139,11 +2103,11 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public identifierPattern(): IdentifierPatternContext { let localctx: IdentifierPatternContext = new IdentifierPatternContext(this, this._ctx, this.state); - this.enterRule(localctx, 62, esql_parser.RULE_identifierPattern); + this.enterRule(localctx, 60, esql_parser.RULE_identifierPattern); try { this.enterOuterAlt(localctx, 1); { - this.state = 402; + this.state = 401; this.match(esql_parser.ID_PATTERN); } } @@ -2164,17 +2128,17 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public constant(): ConstantContext { let localctx: ConstantContext = new ConstantContext(this, this._ctx, this.state); - this.enterRule(localctx, 64, esql_parser.RULE_constant); + this.enterRule(localctx, 62, esql_parser.RULE_constant); let _la: number; try { - this.state = 446; + this.state = 445; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 39, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 38, this._ctx) ) { case 1: localctx = new NullLiteralContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 404; + this.state = 403; this.match(esql_parser.NULL); } break; @@ -2182,9 +2146,9 @@ export default class esql_parser extends Parser { localctx = new QualifiedIntegerLiteralContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 405; + this.state = 404; this.integerValue(); - this.state = 406; + this.state = 405; this.match(esql_parser.UNQUOTED_IDENTIFIER); } break; @@ -2192,7 +2156,7 @@ export default class esql_parser extends Parser { localctx = new DecimalLiteralContext(this, localctx); this.enterOuterAlt(localctx, 3); { - this.state = 408; + this.state = 407; this.decimalValue(); } break; @@ -2200,7 +2164,7 @@ export default class esql_parser extends Parser { localctx = new IntegerLiteralContext(this, localctx); this.enterOuterAlt(localctx, 4); { - this.state = 409; + this.state = 408; this.integerValue(); } break; @@ -2208,7 +2172,7 @@ export default class esql_parser extends Parser { localctx = new BooleanLiteralContext(this, localctx); this.enterOuterAlt(localctx, 5); { - this.state = 410; + this.state = 409; this.booleanValue(); } break; @@ -2216,7 +2180,7 @@ export default class esql_parser extends Parser { localctx = new InputParamsContext(this, localctx); this.enterOuterAlt(localctx, 6); { - this.state = 411; + this.state = 410; this.params(); } break; @@ -2224,7 +2188,7 @@ export default class esql_parser extends Parser { localctx = new StringLiteralContext(this, localctx); this.enterOuterAlt(localctx, 7); { - this.state = 412; + this.state = 411; this.string_(); } break; @@ -2232,27 +2196,27 @@ export default class esql_parser extends Parser { localctx = new NumericArrayLiteralContext(this, localctx); this.enterOuterAlt(localctx, 8); { - this.state = 413; + this.state = 412; this.match(esql_parser.OPENING_BRACKET); - this.state = 414; + this.state = 413; this.numericValue(); - this.state = 419; + this.state = 418; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===39) { + while (_la===35) { { { - this.state = 415; + this.state = 414; this.match(esql_parser.COMMA); - this.state = 416; + this.state = 415; this.numericValue(); } } - this.state = 421; + this.state = 420; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 422; + this.state = 421; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -2260,27 +2224,27 @@ export default class esql_parser extends Parser { localctx = new BooleanArrayLiteralContext(this, localctx); this.enterOuterAlt(localctx, 9); { - this.state = 424; + this.state = 423; this.match(esql_parser.OPENING_BRACKET); - this.state = 425; + this.state = 424; this.booleanValue(); - this.state = 430; + this.state = 429; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===39) { + while (_la===35) { { { - this.state = 426; + this.state = 425; this.match(esql_parser.COMMA); - this.state = 427; + this.state = 426; this.booleanValue(); } } - this.state = 432; + this.state = 431; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 433; + this.state = 432; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -2288,27 +2252,27 @@ export default class esql_parser extends Parser { localctx = new StringArrayLiteralContext(this, localctx); this.enterOuterAlt(localctx, 10); { - this.state = 435; + this.state = 434; this.match(esql_parser.OPENING_BRACKET); - this.state = 436; + this.state = 435; this.string_(); - this.state = 441; + this.state = 440; this._errHandler.sync(this); _la = this._input.LA(1); - while (_la===39) { + while (_la===35) { { { - this.state = 437; + this.state = 436; this.match(esql_parser.COMMA); - this.state = 438; + this.state = 437; this.string_(); } } - this.state = 443; + this.state = 442; this._errHandler.sync(this); _la = this._input.LA(1); } - this.state = 444; + this.state = 443; this.match(esql_parser.CLOSING_BRACKET); } break; @@ -2331,24 +2295,24 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public params(): ParamsContext { let localctx: ParamsContext = new ParamsContext(this, this._ctx, this.state); - this.enterRule(localctx, 66, esql_parser.RULE_params); + this.enterRule(localctx, 64, esql_parser.RULE_params); try { - this.state = 450; + this.state = 449; this._errHandler.sync(this); switch (this._input.LA(1)) { - case 54: + case 49: localctx = new InputParamContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 448; + this.state = 447; this.match(esql_parser.PARAM); } break; - case 70: + case 65: localctx = new InputNamedOrPositionalParamContext(this, localctx); this.enterOuterAlt(localctx, 2); { - this.state = 449; + this.state = 448; this.match(esql_parser.NAMED_OR_POSITIONAL_PARAM); } break; @@ -2373,13 +2337,13 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public limitCommand(): LimitCommandContext { let localctx: LimitCommandContext = new LimitCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 68, esql_parser.RULE_limitCommand); + this.enterRule(localctx, 66, esql_parser.RULE_limitCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 452; + this.state = 451; this.match(esql_parser.LIMIT); - this.state = 453; + this.state = 452; this.match(esql_parser.INTEGER_LITERAL); } } @@ -2400,32 +2364,32 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public sortCommand(): SortCommandContext { let localctx: SortCommandContext = new SortCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 70, esql_parser.RULE_sortCommand); + this.enterRule(localctx, 68, esql_parser.RULE_sortCommand); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 455; + this.state = 454; this.match(esql_parser.SORT); - this.state = 456; + this.state = 455; this.orderExpression(); - this.state = 461; + this.state = 460; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 41, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 40, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 457; + this.state = 456; this.match(esql_parser.COMMA); - this.state = 458; + this.state = 457; this.orderExpression(); } } } - this.state = 463; + this.state = 462; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 41, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 40, this._ctx); } } } @@ -2446,22 +2410,22 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public orderExpression(): OrderExpressionContext { let localctx: OrderExpressionContext = new OrderExpressionContext(this, this._ctx, this.state); - this.enterRule(localctx, 72, esql_parser.RULE_orderExpression); + this.enterRule(localctx, 70, esql_parser.RULE_orderExpression); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 464; + this.state = 463; this.booleanExpression(0); - this.state = 466; + this.state = 465; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 42, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 41, this._ctx) ) { case 1: { - this.state = 465; + this.state = 464; localctx._ordering = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===36 || _la===40)) { + if(!(_la===32 || _la===36)) { localctx._ordering = this._errHandler.recoverInline(this); } else { @@ -2471,17 +2435,17 @@ export default class esql_parser extends Parser { } break; } - this.state = 470; + this.state = 469; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 43, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 42, this._ctx) ) { case 1: { - this.state = 468; + this.state = 467; this.match(esql_parser.NULLS); - this.state = 469; + this.state = 468; localctx._nullOrdering = this._input.LT(1); _la = this._input.LA(1); - if(!(_la===43 || _la===46)) { + if(!(_la===39 || _la===42)) { localctx._nullOrdering = this._errHandler.recoverInline(this); } else { @@ -2510,13 +2474,13 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public keepCommand(): KeepCommandContext { let localctx: KeepCommandContext = new KeepCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 74, esql_parser.RULE_keepCommand); + this.enterRule(localctx, 72, esql_parser.RULE_keepCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 472; + this.state = 471; this.match(esql_parser.KEEP); - this.state = 473; + this.state = 472; this.qualifiedNamePatterns(); } } @@ -2537,13 +2501,13 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public dropCommand(): DropCommandContext { let localctx: DropCommandContext = new DropCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 76, esql_parser.RULE_dropCommand); + this.enterRule(localctx, 74, esql_parser.RULE_dropCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 475; + this.state = 474; this.match(esql_parser.DROP); - this.state = 476; + this.state = 475; this.qualifiedNamePatterns(); } } @@ -2564,32 +2528,32 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public renameCommand(): RenameCommandContext { let localctx: RenameCommandContext = new RenameCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 78, esql_parser.RULE_renameCommand); + this.enterRule(localctx, 76, esql_parser.RULE_renameCommand); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 478; + this.state = 477; this.match(esql_parser.RENAME); - this.state = 479; + this.state = 478; this.renameClause(); - this.state = 484; + this.state = 483; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 44, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 43, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 480; + this.state = 479; this.match(esql_parser.COMMA); - this.state = 481; + this.state = 480; this.renameClause(); } } } - this.state = 486; + this.state = 485; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 44, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 43, this._ctx); } } } @@ -2610,15 +2574,15 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public renameClause(): RenameClauseContext { let localctx: RenameClauseContext = new RenameClauseContext(this, this._ctx, this.state); - this.enterRule(localctx, 80, esql_parser.RULE_renameClause); + this.enterRule(localctx, 78, esql_parser.RULE_renameClause); try { this.enterOuterAlt(localctx, 1); { - this.state = 487; + this.state = 486; localctx._oldName = this.qualifiedNamePattern(); - this.state = 488; + this.state = 487; this.match(esql_parser.AS); - this.state = 489; + this.state = 488; localctx._newName = this.qualifiedNamePattern(); } } @@ -2639,22 +2603,22 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public dissectCommand(): DissectCommandContext { let localctx: DissectCommandContext = new DissectCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 82, esql_parser.RULE_dissectCommand); + this.enterRule(localctx, 80, esql_parser.RULE_dissectCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 491; + this.state = 490; this.match(esql_parser.DISSECT); - this.state = 492; + this.state = 491; this.primaryExpression(0); - this.state = 493; + this.state = 492; this.string_(); - this.state = 495; + this.state = 494; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 45, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 44, this._ctx) ) { case 1: { - this.state = 494; + this.state = 493; this.commandOptions(); } break; @@ -2678,15 +2642,15 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public grokCommand(): GrokCommandContext { let localctx: GrokCommandContext = new GrokCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 84, esql_parser.RULE_grokCommand); + this.enterRule(localctx, 82, esql_parser.RULE_grokCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 497; + this.state = 496; this.match(esql_parser.GROK); - this.state = 498; + this.state = 497; this.primaryExpression(0); - this.state = 499; + this.state = 498; this.string_(); } } @@ -2707,13 +2671,13 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public mvExpandCommand(): MvExpandCommandContext { let localctx: MvExpandCommandContext = new MvExpandCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 86, esql_parser.RULE_mvExpandCommand); + this.enterRule(localctx, 84, esql_parser.RULE_mvExpandCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 501; + this.state = 500; this.match(esql_parser.MV_EXPAND); - this.state = 502; + this.state = 501; this.qualifiedName(); } } @@ -2734,30 +2698,30 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public commandOptions(): CommandOptionsContext { let localctx: CommandOptionsContext = new CommandOptionsContext(this, this._ctx, this.state); - this.enterRule(localctx, 88, esql_parser.RULE_commandOptions); + this.enterRule(localctx, 86, esql_parser.RULE_commandOptions); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 504; + this.state = 503; this.commandOption(); - this.state = 509; + this.state = 508; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 46, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 45, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 505; + this.state = 504; this.match(esql_parser.COMMA); - this.state = 506; + this.state = 505; this.commandOption(); } } } - this.state = 511; + this.state = 510; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 46, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 45, this._ctx); } } } @@ -2778,15 +2742,15 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public commandOption(): CommandOptionContext { let localctx: CommandOptionContext = new CommandOptionContext(this, this._ctx, this.state); - this.enterRule(localctx, 90, esql_parser.RULE_commandOption); + this.enterRule(localctx, 88, esql_parser.RULE_commandOption); try { this.enterOuterAlt(localctx, 1); { - this.state = 512; + this.state = 511; this.identifier(); - this.state = 513; + this.state = 512; this.match(esql_parser.ASSIGN); - this.state = 514; + this.state = 513; this.constant(); } } @@ -2807,14 +2771,14 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public booleanValue(): BooleanValueContext { let localctx: BooleanValueContext = new BooleanValueContext(this, this._ctx, this.state); - this.enterRule(localctx, 92, esql_parser.RULE_booleanValue); + this.enterRule(localctx, 90, esql_parser.RULE_booleanValue); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 516; + this.state = 515; _la = this._input.LA(1); - if(!(_la===42 || _la===57)) { + if(!(_la===38 || _la===52)) { this._errHandler.recoverInline(this); } else { @@ -2840,22 +2804,22 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public numericValue(): NumericValueContext { let localctx: NumericValueContext = new NumericValueContext(this, this._ctx, this.state); - this.enterRule(localctx, 94, esql_parser.RULE_numericValue); + this.enterRule(localctx, 92, esql_parser.RULE_numericValue); try { - this.state = 520; + this.state = 519; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 47, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 46, this._ctx) ) { case 1: this.enterOuterAlt(localctx, 1); { - this.state = 518; + this.state = 517; this.decimalValue(); } break; case 2: this.enterOuterAlt(localctx, 2); { - this.state = 519; + this.state = 518; this.integerValue(); } break; @@ -2878,19 +2842,19 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public decimalValue(): DecimalValueContext { let localctx: DecimalValueContext = new DecimalValueContext(this, this._ctx, this.state); - this.enterRule(localctx, 96, esql_parser.RULE_decimalValue); + this.enterRule(localctx, 94, esql_parser.RULE_decimalValue); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 523; + this.state = 522; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===65 || _la===66) { + if (_la===60 || _la===61) { { - this.state = 522; + this.state = 521; _la = this._input.LA(1); - if(!(_la===65 || _la===66)) { + if(!(_la===60 || _la===61)) { this._errHandler.recoverInline(this); } else { @@ -2900,7 +2864,7 @@ export default class esql_parser extends Parser { } } - this.state = 525; + this.state = 524; this.match(esql_parser.DECIMAL_LITERAL); } } @@ -2921,19 +2885,19 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public integerValue(): IntegerValueContext { let localctx: IntegerValueContext = new IntegerValueContext(this, this._ctx, this.state); - this.enterRule(localctx, 98, esql_parser.RULE_integerValue); + this.enterRule(localctx, 96, esql_parser.RULE_integerValue); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 528; + this.state = 527; this._errHandler.sync(this); _la = this._input.LA(1); - if (_la===65 || _la===66) { + if (_la===60 || _la===61) { { - this.state = 527; + this.state = 526; _la = this._input.LA(1); - if(!(_la===65 || _la===66)) { + if(!(_la===60 || _la===61)) { this._errHandler.recoverInline(this); } else { @@ -2943,7 +2907,7 @@ export default class esql_parser extends Parser { } } - this.state = 530; + this.state = 529; this.match(esql_parser.INTEGER_LITERAL); } } @@ -2964,11 +2928,11 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public string_(): StringContext { let localctx: StringContext = new StringContext(this, this._ctx, this.state); - this.enterRule(localctx, 100, esql_parser.RULE_string); + this.enterRule(localctx, 98, esql_parser.RULE_string); try { this.enterOuterAlt(localctx, 1); { - this.state = 532; + this.state = 531; this.match(esql_parser.QUOTED_STRING); } } @@ -2989,14 +2953,14 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public comparisonOperator(): ComparisonOperatorContext { let localctx: ComparisonOperatorContext = new ComparisonOperatorContext(this, this._ctx, this.state); - this.enterRule(localctx, 102, esql_parser.RULE_comparisonOperator); + this.enterRule(localctx, 100, esql_parser.RULE_comparisonOperator); let _la: number; try { this.enterOuterAlt(localctx, 1); { - this.state = 534; + this.state = 533; _la = this._input.LA(1); - if(!(((((_la - 58)) & ~0x1F) === 0 && ((1 << (_la - 58)) & 125) !== 0))) { + if(!(((((_la - 53)) & ~0x1F) === 0 && ((1 << (_la - 53)) & 125) !== 0))) { this._errHandler.recoverInline(this); } else { @@ -3022,13 +2986,13 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public explainCommand(): ExplainCommandContext { let localctx: ExplainCommandContext = new ExplainCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 104, esql_parser.RULE_explainCommand); + this.enterRule(localctx, 102, esql_parser.RULE_explainCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 536; + this.state = 535; this.match(esql_parser.EXPLAIN); - this.state = 537; + this.state = 536; this.subqueryExpression(); } } @@ -3049,15 +3013,15 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public subqueryExpression(): SubqueryExpressionContext { let localctx: SubqueryExpressionContext = new SubqueryExpressionContext(this, this._ctx, this.state); - this.enterRule(localctx, 106, esql_parser.RULE_subqueryExpression); + this.enterRule(localctx, 104, esql_parser.RULE_subqueryExpression); try { this.enterOuterAlt(localctx, 1); { - this.state = 539; + this.state = 538; this.match(esql_parser.OPENING_BRACKET); - this.state = 540; + this.state = 539; this.query(0); - this.state = 541; + this.state = 540; this.match(esql_parser.CLOSING_BRACKET); } } @@ -3078,14 +3042,14 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public showCommand(): ShowCommandContext { let localctx: ShowCommandContext = new ShowCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 108, esql_parser.RULE_showCommand); + this.enterRule(localctx, 106, esql_parser.RULE_showCommand); try { localctx = new ShowInfoContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 543; + this.state = 542; this.match(esql_parser.SHOW); - this.state = 544; + this.state = 543; this.match(esql_parser.INFO); } } @@ -3106,14 +3070,14 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public metaCommand(): MetaCommandContext { let localctx: MetaCommandContext = new MetaCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 110, esql_parser.RULE_metaCommand); + this.enterRule(localctx, 108, esql_parser.RULE_metaCommand); try { localctx = new MetaFunctionsContext(this, localctx); this.enterOuterAlt(localctx, 1); { - this.state = 546; + this.state = 545; this.match(esql_parser.META); - this.state = 547; + this.state = 546; this.match(esql_parser.FUNCTIONS); } } @@ -3134,53 +3098,53 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public enrichCommand(): EnrichCommandContext { let localctx: EnrichCommandContext = new EnrichCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 112, esql_parser.RULE_enrichCommand); + this.enterRule(localctx, 110, esql_parser.RULE_enrichCommand); try { let _alt: number; this.enterOuterAlt(localctx, 1); { - this.state = 549; + this.state = 548; this.match(esql_parser.ENRICH); - this.state = 550; + this.state = 549; localctx._policyName = this.match(esql_parser.ENRICH_POLICY_NAME); - this.state = 553; + this.state = 552; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 50, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 49, this._ctx) ) { case 1: { - this.state = 551; + this.state = 550; this.match(esql_parser.ON); - this.state = 552; + this.state = 551; localctx._matchField = this.qualifiedNamePattern(); } break; } - this.state = 564; + this.state = 563; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 52, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 51, this._ctx) ) { case 1: { - this.state = 555; + this.state = 554; this.match(esql_parser.WITH); - this.state = 556; + this.state = 555; this.enrichWithClause(); - this.state = 561; + this.state = 560; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 51, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 50, this._ctx); while (_alt !== 2 && _alt !== ATN.INVALID_ALT_NUMBER) { if (_alt === 1) { { { - this.state = 557; + this.state = 556; this.match(esql_parser.COMMA); - this.state = 558; + this.state = 557; this.enrichWithClause(); } } } - this.state = 563; + this.state = 562; this._errHandler.sync(this); - _alt = this._interp.adaptivePredict(this._input, 51, this._ctx); + _alt = this._interp.adaptivePredict(this._input, 50, this._ctx); } } break; @@ -3204,23 +3168,23 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public enrichWithClause(): EnrichWithClauseContext { let localctx: EnrichWithClauseContext = new EnrichWithClauseContext(this, this._ctx, this.state); - this.enterRule(localctx, 114, esql_parser.RULE_enrichWithClause); + this.enterRule(localctx, 112, esql_parser.RULE_enrichWithClause); try { this.enterOuterAlt(localctx, 1); { - this.state = 569; + this.state = 568; this._errHandler.sync(this); - switch ( this._interp.adaptivePredict(this._input, 53, this._ctx) ) { + switch ( this._interp.adaptivePredict(this._input, 52, this._ctx) ) { case 1: { - this.state = 566; + this.state = 565; localctx._newName = this.qualifiedNamePattern(); - this.state = 567; + this.state = 566; this.match(esql_parser.ASSIGN); } break; } - this.state = 571; + this.state = 570; localctx._enrichField = this.qualifiedNamePattern(); } } @@ -3241,17 +3205,17 @@ export default class esql_parser extends Parser { // @RuleVersion(0) public lookupCommand(): LookupCommandContext { let localctx: LookupCommandContext = new LookupCommandContext(this, this._ctx, this.state); - this.enterRule(localctx, 116, esql_parser.RULE_lookupCommand); + this.enterRule(localctx, 114, esql_parser.RULE_lookupCommand); try { this.enterOuterAlt(localctx, 1); { + this.state = 572; + this.match(esql_parser.DEV_LOOKUP); this.state = 573; - this.match(esql_parser.LOOKUP); - this.state = 574; localctx._tableName = this.indexPattern(); - this.state = 575; + this.state = 574; this.match(esql_parser.ON); - this.state = 576; + this.state = 575; localctx._matchFields = this.qualifiedNamePatterns(); } } @@ -3270,15 +3234,54 @@ export default class esql_parser extends Parser { return localctx; } // @RuleVersion(0) + public inlinestatsCommand(): InlinestatsCommandContext { + let localctx: InlinestatsCommandContext = new InlinestatsCommandContext(this, this._ctx, this.state); + this.enterRule(localctx, 116, esql_parser.RULE_inlinestatsCommand); + try { + this.enterOuterAlt(localctx, 1); + { + this.state = 577; + this.match(esql_parser.DEV_INLINESTATS); + this.state = 578; + localctx._stats = this.fields(); + this.state = 581; + this._errHandler.sync(this); + switch ( this._interp.adaptivePredict(this._input, 53, this._ctx) ) { + case 1: + { + this.state = 579; + this.match(esql_parser.BY); + this.state = 580; + localctx._grouping = this.fields(); + } + break; + } + } + } + catch (re) { + if (re instanceof RecognitionException) { + localctx.exception = re; + this._errHandler.reportError(this, re); + this._errHandler.recover(this, re); + } else { + throw re; + } + } + finally { + this.exitRule(); + } + return localctx; + } + // @RuleVersion(0) public matchCommand(): MatchCommandContext { let localctx: MatchCommandContext = new MatchCommandContext(this, this._ctx, this.state); this.enterRule(localctx, 118, esql_parser.RULE_matchCommand); try { this.enterOuterAlt(localctx, 1); { - this.state = 578; - this.match(esql_parser.MATCH); - this.state = 579; + this.state = 583; + this.match(esql_parser.DEV_MATCH); + this.state = 584; this.matchQuery(); } } @@ -3303,7 +3306,7 @@ export default class esql_parser extends Parser { try { this.enterOuterAlt(localctx, 1); { - this.state = 581; + this.state = 586; this.match(esql_parser.QUOTED_STRING); } } @@ -3326,6 +3329,10 @@ export default class esql_parser extends Parser { switch (ruleIndex) { case 1: return this.query_sempred(localctx as QueryContext, predIndex); + case 2: + return this.sourceCommand_sempred(localctx as SourceCommandContext, predIndex); + case 3: + return this.processingCommand_sempred(localctx as ProcessingCommandContext, predIndex); case 5: return this.booleanExpression_sempred(localctx as BooleanExpressionContext, predIndex); case 9: @@ -3342,33 +3349,53 @@ export default class esql_parser extends Parser { } return true; } - private booleanExpression_sempred(localctx: BooleanExpressionContext, predIndex: number): boolean { + private sourceCommand_sempred(localctx: SourceCommandContext, predIndex: number): boolean { switch (predIndex) { case 1: - return this.precpred(this._ctx, 4); + return this.isDevVersion(); + } + return true; + } + private processingCommand_sempred(localctx: ProcessingCommandContext, predIndex: number): boolean { + switch (predIndex) { case 2: - return this.precpred(this._ctx, 3); + return this.isDevVersion(); + case 3: + return this.isDevVersion(); + case 4: + return this.isDevVersion(); + } + return true; + } + private booleanExpression_sempred(localctx: BooleanExpressionContext, predIndex: number): boolean { + switch (predIndex) { + case 5: + return this.isDevVersion(); + case 6: + return this.precpred(this._ctx, 5); + case 7: + return this.precpred(this._ctx, 4); } return true; } private operatorExpression_sempred(localctx: OperatorExpressionContext, predIndex: number): boolean { switch (predIndex) { - case 3: + case 8: return this.precpred(this._ctx, 2); - case 4: + case 9: return this.precpred(this._ctx, 1); } return true; } private primaryExpression_sempred(localctx: PrimaryExpressionContext, predIndex: number): boolean { switch (predIndex) { - case 5: + case 10: return this.precpred(this._ctx, 1); } return true; } - public static readonly _serializedATN: number[] = [4,1,126,584,2,0,7,0, + public static readonly _serializedATN: number[] = [4,1,125,589,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, @@ -3378,186 +3405,188 @@ export default class esql_parser extends Parser { 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,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,5,1,132,8,1,10,1,12,1,135,9,1,1, - 2,1,2,1,2,1,2,1,2,1,2,3,2,143,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,3,3,160,8,3,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,5,1, - 5,1,5,3,5,173,8,5,1,5,1,5,1,5,1,5,1,5,5,5,180,8,5,10,5,12,5,183,9,5,1,5, - 1,5,1,5,1,5,1,5,3,5,190,8,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,13,1,13,1,13,1,14,1,14,1,14,5,14,292,8,14,10,14,12,14,295,9,14, - 1,15,1,15,1,15,1,15,1,15,3,15,302,8,15,1,16,1,16,1,16,1,16,5,16,308,8,16, - 10,16,12,16,311,9,16,1,16,3,16,314,8,16,1,17,1,17,1,17,1,17,1,17,3,17,321, - 8,17,1,18,1,18,1,19,1,19,1,20,1,20,3,20,329,8,20,1,21,1,21,1,21,1,21,5, - 21,335,8,21,10,21,12,21,338,9,21,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23, - 5,23,348,8,23,10,23,12,23,351,9,23,1,23,3,23,354,8,23,1,23,1,23,3,23,358, - 8,23,1,24,1,24,1,24,1,25,1,25,3,25,365,8,25,1,25,1,25,3,25,369,8,25,1,26, - 1,26,1,26,1,26,3,26,375,8,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,29,5, - 29,396,8,29,10,29,12,29,399,9,29,1,30,1,30,1,31,1,31,1,32,1,32,1,32,1,32, - 1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,1,32,5,32,418,8,32,10,32,12,32, - 421,9,32,1,32,1,32,1,32,1,32,1,32,1,32,5,32,429,8,32,10,32,12,32,432,9, - 32,1,32,1,32,1,32,1,32,1,32,1,32,5,32,440,8,32,10,32,12,32,443,9,32,1,32, - 1,32,3,32,447,8,32,1,33,1,33,3,33,451,8,33,1,34,1,34,1,34,1,35,1,35,1,35, - 1,35,5,35,460,8,35,10,35,12,35,463,9,35,1,36,1,36,3,36,467,8,36,1,36,1, - 36,3,36,471,8,36,1,37,1,37,1,37,1,38,1,38,1,38,1,39,1,39,1,39,1,39,5,39, - 483,8,39,10,39,12,39,486,9,39,1,40,1,40,1,40,1,40,1,41,1,41,1,41,1,41,3, - 41,496,8,41,1,42,1,42,1,42,1,42,1,43,1,43,1,43,1,44,1,44,1,44,5,44,508, - 8,44,10,44,12,44,511,9,44,1,45,1,45,1,45,1,45,1,46,1,46,1,47,1,47,3,47, - 521,8,47,1,48,3,48,524,8,48,1,48,1,48,1,49,3,49,529,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,56,1,56,1,56,1,56,3,56,554,8,56,1,56,1,56,1,56,1,56,5,56,560, - 8,56,10,56,12,56,563,9,56,3,56,565,8,56,1,57,1,57,1,57,3,57,570,8,57,1, - 57,1,57,1,58,1,58,1,58,1,58,1,58,1,59,1,59,1,59,1,60,1,60,1,60,0,4,2,10, - 18,20,61,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44, - 46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92, - 94,96,98,100,102,104,106,108,110,112,114,116,118,120,0,8,1,0,65,66,1,0, - 67,69,2,0,26,26,31,31,1,0,73,74,2,0,36,36,40,40,2,0,43,43,46,46,2,0,42, - 42,57,57,2,0,58,58,60,64,608,0,122,1,0,0,0,2,125,1,0,0,0,4,142,1,0,0,0, - 6,159,1,0,0,0,8,161,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,283,1, - 0,0,0,26,285,1,0,0,0,28,288,1,0,0,0,30,301,1,0,0,0,32,303,1,0,0,0,34,320, - 1,0,0,0,36,322,1,0,0,0,38,324,1,0,0,0,40,328,1,0,0,0,42,330,1,0,0,0,44, - 339,1,0,0,0,46,343,1,0,0,0,48,359,1,0,0,0,50,362,1,0,0,0,52,370,1,0,0,0, - 54,376,1,0,0,0,56,384,1,0,0,0,58,392,1,0,0,0,60,400,1,0,0,0,62,402,1,0, - 0,0,64,446,1,0,0,0,66,450,1,0,0,0,68,452,1,0,0,0,70,455,1,0,0,0,72,464, - 1,0,0,0,74,472,1,0,0,0,76,475,1,0,0,0,78,478,1,0,0,0,80,487,1,0,0,0,82, - 491,1,0,0,0,84,497,1,0,0,0,86,501,1,0,0,0,88,504,1,0,0,0,90,512,1,0,0,0, - 92,516,1,0,0,0,94,520,1,0,0,0,96,523,1,0,0,0,98,528,1,0,0,0,100,532,1,0, - 0,0,102,534,1,0,0,0,104,536,1,0,0,0,106,539,1,0,0,0,108,543,1,0,0,0,110, - 546,1,0,0,0,112,549,1,0,0,0,114,569,1,0,0,0,116,573,1,0,0,0,118,578,1,0, - 0,0,120,581,1,0,0,0,122,123,3,2,1,0,123,124,5,0,0,1,124,1,1,0,0,0,125,126, - 6,1,-1,0,126,127,3,4,2,0,127,133,1,0,0,0,128,129,10,1,0,0,129,130,5,30, - 0,0,130,132,3,6,3,0,131,128,1,0,0,0,132,135,1,0,0,0,133,131,1,0,0,0,133, - 134,1,0,0,0,134,3,1,0,0,0,135,133,1,0,0,0,136,143,3,104,52,0,137,143,3, - 32,16,0,138,143,3,26,13,0,139,143,3,46,23,0,140,143,3,108,54,0,141,143, - 3,110,55,0,142,136,1,0,0,0,142,137,1,0,0,0,142,138,1,0,0,0,142,139,1,0, - 0,0,142,140,1,0,0,0,142,141,1,0,0,0,143,5,1,0,0,0,144,160,3,48,24,0,145, - 160,3,52,26,0,146,160,3,68,34,0,147,160,3,116,58,0,148,160,3,74,37,0,149, - 160,3,70,35,0,150,160,3,50,25,0,151,160,3,8,4,0,152,160,3,76,38,0,153,160, - 3,78,39,0,154,160,3,82,41,0,155,160,3,84,42,0,156,160,3,112,56,0,157,160, - 3,86,43,0,158,160,3,118,59,0,159,144,1,0,0,0,159,145,1,0,0,0,159,146,1, - 0,0,0,159,147,1,0,0,0,159,148,1,0,0,0,159,149,1,0,0,0,159,150,1,0,0,0,159, - 151,1,0,0,0,159,152,1,0,0,0,159,153,1,0,0,0,159,154,1,0,0,0,159,155,1,0, - 0,0,159,156,1,0,0,0,159,157,1,0,0,0,159,158,1,0,0,0,160,7,1,0,0,0,161,162, - 5,20,0,0,162,163,3,10,5,0,163,9,1,0,0,0,164,165,6,5,-1,0,165,166,5,50,0, - 0,166,194,3,10,5,8,167,194,3,16,8,0,168,194,3,12,6,0,169,194,3,14,7,0,170, - 172,3,16,8,0,171,173,5,50,0,0,172,171,1,0,0,0,172,173,1,0,0,0,173,174,1, - 0,0,0,174,175,5,44,0,0,175,176,5,48,0,0,176,181,3,16,8,0,177,178,5,39,0, - 0,178,180,3,16,8,0,179,177,1,0,0,0,180,183,1,0,0,0,181,179,1,0,0,0,181, - 182,1,0,0,0,182,184,1,0,0,0,183,181,1,0,0,0,184,185,5,56,0,0,185,194,1, - 0,0,0,186,187,3,16,8,0,187,189,5,45,0,0,188,190,5,50,0,0,189,188,1,0,0, - 0,189,190,1,0,0,0,190,191,1,0,0,0,191,192,5,51,0,0,192,194,1,0,0,0,193, - 164,1,0,0,0,193,167,1,0,0,0,193,168,1,0,0,0,193,169,1,0,0,0,193,170,1,0, - 0,0,193,186,1,0,0,0,194,203,1,0,0,0,195,196,10,4,0,0,196,197,5,35,0,0,197, - 202,3,10,5,5,198,199,10,3,0,0,199,200,5,53,0,0,200,202,3,10,5,4,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,50,0,0,208,207, - 1,0,0,0,208,209,1,0,0,0,209,210,1,0,0,0,210,211,5,47,0,0,211,212,3,100, - 50,0,212,221,1,0,0,0,213,215,3,16,8,0,214,216,5,50,0,0,215,214,1,0,0,0, - 215,216,1,0,0,0,216,217,1,0,0,0,217,218,5,55,0,0,218,219,3,100,50,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,54, - 27,0,223,224,5,49,0,0,224,225,3,100,50,0,225,15,1,0,0,0,226,232,3,18,9, - 0,227,228,3,18,9,0,228,229,3,102,51,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,48,0,0,255,256,3,10,5,0,256,257,5,56,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,38,0,0,262,264,3,24,12,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,60,30,0,269,279,5,48,0,0,270,280,5,67,0,0,271, - 276,3,10,5,0,272,273,5,39,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,56,0,0,282,23,1,0,0,0,283,284,3,60,30,0,284,25,1,0,0,0,285,286,5,16,0, - 0,286,287,3,28,14,0,287,27,1,0,0,0,288,293,3,30,15,0,289,290,5,39,0,0,290, - 292,3,30,15,0,291,289,1,0,0,0,292,295,1,0,0,0,293,291,1,0,0,0,293,294,1, - 0,0,0,294,29,1,0,0,0,295,293,1,0,0,0,296,302,3,10,5,0,297,298,3,54,27,0, - 298,299,5,37,0,0,299,300,3,10,5,0,300,302,1,0,0,0,301,296,1,0,0,0,301,297, - 1,0,0,0,302,31,1,0,0,0,303,304,5,6,0,0,304,309,3,34,17,0,305,306,5,39,0, - 0,306,308,3,34,17,0,307,305,1,0,0,0,308,311,1,0,0,0,309,307,1,0,0,0,309, - 310,1,0,0,0,310,313,1,0,0,0,311,309,1,0,0,0,312,314,3,40,20,0,313,312,1, - 0,0,0,313,314,1,0,0,0,314,33,1,0,0,0,315,316,3,36,18,0,316,317,5,116,0, - 0,317,318,3,38,19,0,318,321,1,0,0,0,319,321,3,38,19,0,320,315,1,0,0,0,320, - 319,1,0,0,0,321,35,1,0,0,0,322,323,5,26,0,0,323,37,1,0,0,0,324,325,7,2, - 0,0,325,39,1,0,0,0,326,329,3,42,21,0,327,329,3,44,22,0,328,326,1,0,0,0, - 328,327,1,0,0,0,329,41,1,0,0,0,330,331,5,78,0,0,331,336,5,26,0,0,332,333, - 5,39,0,0,333,335,5,26,0,0,334,332,1,0,0,0,335,338,1,0,0,0,336,334,1,0,0, - 0,336,337,1,0,0,0,337,43,1,0,0,0,338,336,1,0,0,0,339,340,5,71,0,0,340,341, - 3,42,21,0,341,342,5,72,0,0,342,45,1,0,0,0,343,344,5,13,0,0,344,349,3,34, - 17,0,345,346,5,39,0,0,346,348,3,34,17,0,347,345,1,0,0,0,348,351,1,0,0,0, - 349,347,1,0,0,0,349,350,1,0,0,0,350,353,1,0,0,0,351,349,1,0,0,0,352,354, - 3,28,14,0,353,352,1,0,0,0,353,354,1,0,0,0,354,357,1,0,0,0,355,356,5,34, - 0,0,356,358,3,28,14,0,357,355,1,0,0,0,357,358,1,0,0,0,358,47,1,0,0,0,359, - 360,5,4,0,0,360,361,3,28,14,0,361,49,1,0,0,0,362,364,5,19,0,0,363,365,3, - 28,14,0,364,363,1,0,0,0,364,365,1,0,0,0,365,368,1,0,0,0,366,367,5,34,0, - 0,367,369,3,28,14,0,368,366,1,0,0,0,368,369,1,0,0,0,369,51,1,0,0,0,370, - 371,5,8,0,0,371,374,3,28,14,0,372,373,5,34,0,0,373,375,3,28,14,0,374,372, - 1,0,0,0,374,375,1,0,0,0,375,53,1,0,0,0,376,381,3,60,30,0,377,378,5,41,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,62,31,0,385,386,5, - 41,0,0,386,388,3,62,31,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,397,3,56,28,0,393, - 394,5,39,0,0,394,396,3,56,28,0,395,393,1,0,0,0,396,399,1,0,0,0,397,395, - 1,0,0,0,397,398,1,0,0,0,398,59,1,0,0,0,399,397,1,0,0,0,400,401,7,3,0,0, - 401,61,1,0,0,0,402,403,5,82,0,0,403,63,1,0,0,0,404,447,5,51,0,0,405,406, - 3,98,49,0,406,407,5,73,0,0,407,447,1,0,0,0,408,447,3,96,48,0,409,447,3, - 98,49,0,410,447,3,92,46,0,411,447,3,66,33,0,412,447,3,100,50,0,413,414, - 5,71,0,0,414,419,3,94,47,0,415,416,5,39,0,0,416,418,3,94,47,0,417,415,1, - 0,0,0,418,421,1,0,0,0,419,417,1,0,0,0,419,420,1,0,0,0,420,422,1,0,0,0,421, - 419,1,0,0,0,422,423,5,72,0,0,423,447,1,0,0,0,424,425,5,71,0,0,425,430,3, - 92,46,0,426,427,5,39,0,0,427,429,3,92,46,0,428,426,1,0,0,0,429,432,1,0, - 0,0,430,428,1,0,0,0,430,431,1,0,0,0,431,433,1,0,0,0,432,430,1,0,0,0,433, - 434,5,72,0,0,434,447,1,0,0,0,435,436,5,71,0,0,436,441,3,100,50,0,437,438, - 5,39,0,0,438,440,3,100,50,0,439,437,1,0,0,0,440,443,1,0,0,0,441,439,1,0, - 0,0,441,442,1,0,0,0,442,444,1,0,0,0,443,441,1,0,0,0,444,445,5,72,0,0,445, - 447,1,0,0,0,446,404,1,0,0,0,446,405,1,0,0,0,446,408,1,0,0,0,446,409,1,0, - 0,0,446,410,1,0,0,0,446,411,1,0,0,0,446,412,1,0,0,0,446,413,1,0,0,0,446, - 424,1,0,0,0,446,435,1,0,0,0,447,65,1,0,0,0,448,451,5,54,0,0,449,451,5,70, - 0,0,450,448,1,0,0,0,450,449,1,0,0,0,451,67,1,0,0,0,452,453,5,10,0,0,453, - 454,5,32,0,0,454,69,1,0,0,0,455,456,5,18,0,0,456,461,3,72,36,0,457,458, - 5,39,0,0,458,460,3,72,36,0,459,457,1,0,0,0,460,463,1,0,0,0,461,459,1,0, - 0,0,461,462,1,0,0,0,462,71,1,0,0,0,463,461,1,0,0,0,464,466,3,10,5,0,465, - 467,7,4,0,0,466,465,1,0,0,0,466,467,1,0,0,0,467,470,1,0,0,0,468,469,5,52, - 0,0,469,471,7,5,0,0,470,468,1,0,0,0,470,471,1,0,0,0,471,73,1,0,0,0,472, - 473,5,9,0,0,473,474,3,58,29,0,474,75,1,0,0,0,475,476,5,2,0,0,476,477,3, - 58,29,0,477,77,1,0,0,0,478,479,5,15,0,0,479,484,3,80,40,0,480,481,5,39, - 0,0,481,483,3,80,40,0,482,480,1,0,0,0,483,486,1,0,0,0,484,482,1,0,0,0,484, - 485,1,0,0,0,485,79,1,0,0,0,486,484,1,0,0,0,487,488,3,56,28,0,488,489,5, - 86,0,0,489,490,3,56,28,0,490,81,1,0,0,0,491,492,5,1,0,0,492,493,3,20,10, - 0,493,495,3,100,50,0,494,496,3,88,44,0,495,494,1,0,0,0,495,496,1,0,0,0, - 496,83,1,0,0,0,497,498,5,7,0,0,498,499,3,20,10,0,499,500,3,100,50,0,500, - 85,1,0,0,0,501,502,5,14,0,0,502,503,3,54,27,0,503,87,1,0,0,0,504,509,3, - 90,45,0,505,506,5,39,0,0,506,508,3,90,45,0,507,505,1,0,0,0,508,511,1,0, - 0,0,509,507,1,0,0,0,509,510,1,0,0,0,510,89,1,0,0,0,511,509,1,0,0,0,512, - 513,3,60,30,0,513,514,5,37,0,0,514,515,3,64,32,0,515,91,1,0,0,0,516,517, - 7,6,0,0,517,93,1,0,0,0,518,521,3,96,48,0,519,521,3,98,49,0,520,518,1,0, - 0,0,520,519,1,0,0,0,521,95,1,0,0,0,522,524,7,0,0,0,523,522,1,0,0,0,523, - 524,1,0,0,0,524,525,1,0,0,0,525,526,5,33,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,32,0,0,531, - 99,1,0,0,0,532,533,5,31,0,0,533,101,1,0,0,0,534,535,7,7,0,0,535,103,1,0, - 0,0,536,537,5,5,0,0,537,538,3,106,53,0,538,105,1,0,0,0,539,540,5,71,0,0, - 540,541,3,2,1,0,541,542,5,72,0,0,542,107,1,0,0,0,543,544,5,17,0,0,544,545, - 5,108,0,0,545,109,1,0,0,0,546,547,5,12,0,0,547,548,5,112,0,0,548,111,1, - 0,0,0,549,550,5,3,0,0,550,553,5,92,0,0,551,552,5,90,0,0,552,554,3,56,28, - 0,553,551,1,0,0,0,553,554,1,0,0,0,554,564,1,0,0,0,555,556,5,91,0,0,556, - 561,3,114,57,0,557,558,5,39,0,0,558,560,3,114,57,0,559,557,1,0,0,0,560, - 563,1,0,0,0,561,559,1,0,0,0,561,562,1,0,0,0,562,565,1,0,0,0,563,561,1,0, - 0,0,564,555,1,0,0,0,564,565,1,0,0,0,565,113,1,0,0,0,566,567,3,56,28,0,567, - 568,5,37,0,0,568,570,1,0,0,0,569,566,1,0,0,0,569,570,1,0,0,0,570,571,1, - 0,0,0,571,572,3,56,28,0,572,115,1,0,0,0,573,574,5,11,0,0,574,575,3,34,17, - 0,575,576,5,90,0,0,576,577,3,58,29,0,577,117,1,0,0,0,578,579,5,21,0,0,579, - 580,3,120,60,0,580,119,1,0,0,0,581,582,5,31,0,0,582,121,1,0,0,0,54,133, - 142,159,172,181,189,193,201,203,208,215,220,231,237,245,247,258,265,276, - 279,293,301,309,313,320,328,336,349,353,357,364,368,374,381,389,397,419, - 430,441,446,450,461,466,470,484,495,509,520,523,528,553,561,564,569]; + 2,1,2,1,2,1,2,1,2,1,2,1,2,3,2,144,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,1,3,1,3,3,3,164,8,3,1,4,1,4,1,4,1,5,1,5,1, + 5,1,5,1,5,1,5,1,5,3,5,176,8,5,1,5,1,5,1,5,1,5,1,5,5,5,183,8,5,10,5,12,5, + 186,9,5,1,5,1,5,1,5,1,5,1,5,3,5,193,8,5,1,5,1,5,1,5,1,5,3,5,199,8,5,1,5, + 1,5,1,5,1,5,1,5,1,5,5,5,207,8,5,10,5,12,5,210,9,5,1,6,1,6,3,6,214,8,6,1, + 6,1,6,1,6,1,6,1,6,3,6,221,8,6,1,6,1,6,1,6,3,6,226,8,6,1,7,1,7,1,7,1,7,1, + 8,1,8,1,8,1,8,1,8,3,8,237,8,8,1,9,1,9,1,9,1,9,3,9,243,8,9,1,9,1,9,1,9,1, + 9,1,9,1,9,5,9,251,8,9,10,9,12,9,254,9,9,1,10,1,10,1,10,1,10,1,10,1,10,1, + 10,1,10,3,10,264,8,10,1,10,1,10,1,10,5,10,269,8,10,10,10,12,10,272,9,10, + 1,11,1,11,1,11,1,11,1,11,1,11,5,11,280,8,11,10,11,12,11,283,9,11,3,11,285, + 8,11,1,11,1,11,1,12,1,12,1,13,1,13,1,13,1,14,1,14,1,14,5,14,297,8,14,10, + 14,12,14,300,9,14,1,15,1,15,1,15,1,15,1,15,3,15,307,8,15,1,16,1,16,1,16, + 1,16,5,16,313,8,16,10,16,12,16,316,9,16,1,16,3,16,319,8,16,1,17,1,17,1, + 17,1,17,1,17,3,17,326,8,17,1,18,1,18,1,19,1,19,1,20,1,20,3,20,334,8,20, + 1,21,1,21,1,21,1,21,5,21,340,8,21,10,21,12,21,343,9,21,1,22,1,22,1,22,1, + 22,1,23,1,23,1,23,1,23,5,23,353,8,23,10,23,12,23,356,9,23,1,23,3,23,359, + 8,23,1,23,1,23,3,23,363,8,23,1,24,1,24,1,24,1,25,1,25,3,25,370,8,25,1,25, + 1,25,3,25,374,8,25,1,26,1,26,1,26,5,26,379,8,26,10,26,12,26,382,9,26,1, + 27,1,27,1,27,5,27,387,8,27,10,27,12,27,390,9,27,1,28,1,28,1,28,5,28,395, + 8,28,10,28,12,28,398,9,28,1,29,1,29,1,30,1,30,1,31,1,31,1,31,1,31,1,31, + 1,31,1,31,1,31,1,31,1,31,1,31,1,31,1,31,5,31,417,8,31,10,31,12,31,420,9, + 31,1,31,1,31,1,31,1,31,1,31,1,31,5,31,428,8,31,10,31,12,31,431,9,31,1,31, + 1,31,1,31,1,31,1,31,1,31,5,31,439,8,31,10,31,12,31,442,9,31,1,31,1,31,3, + 31,446,8,31,1,32,1,32,3,32,450,8,32,1,33,1,33,1,33,1,34,1,34,1,34,1,34, + 5,34,459,8,34,10,34,12,34,462,9,34,1,35,1,35,3,35,466,8,35,1,35,1,35,3, + 35,470,8,35,1,36,1,36,1,36,1,37,1,37,1,37,1,38,1,38,1,38,1,38,5,38,482, + 8,38,10,38,12,38,485,9,38,1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,3,40, + 495,8,40,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,43,1,43,1,43,5,43,507,8,43, + 10,43,12,43,510,9,43,1,44,1,44,1,44,1,44,1,45,1,45,1,46,1,46,3,46,520,8, + 46,1,47,3,47,523,8,47,1,47,1,47,1,48,3,48,528,8,48,1,48,1,48,1,49,1,49, + 1,50,1,50,1,51,1,51,1,51,1,52,1,52,1,52,1,52,1,53,1,53,1,53,1,54,1,54,1, + 54,1,55,1,55,1,55,1,55,3,55,553,8,55,1,55,1,55,1,55,1,55,5,55,559,8,55, + 10,55,12,55,562,9,55,3,55,564,8,55,1,56,1,56,1,56,3,56,569,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,582,8,58,1,59,1,59, + 1,59,1,60,1,60,1,60,0,4,2,10,18,20,61,0,2,4,6,8,10,12,14,16,18,20,22,24, + 26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, + 74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114, + 116,118,120,0,8,1,0,60,61,1,0,62,64,2,0,27,27,77,77,1,0,68,69,2,0,32,32, + 36,36,2,0,39,39,42,42,2,0,38,38,52,52,2,0,53,53,55,59,613,0,122,1,0,0,0, + 2,125,1,0,0,0,4,143,1,0,0,0,6,163,1,0,0,0,8,165,1,0,0,0,10,198,1,0,0,0, + 12,225,1,0,0,0,14,227,1,0,0,0,16,236,1,0,0,0,18,242,1,0,0,0,20,263,1,0, + 0,0,22,273,1,0,0,0,24,288,1,0,0,0,26,290,1,0,0,0,28,293,1,0,0,0,30,306, + 1,0,0,0,32,308,1,0,0,0,34,325,1,0,0,0,36,327,1,0,0,0,38,329,1,0,0,0,40, + 333,1,0,0,0,42,335,1,0,0,0,44,344,1,0,0,0,46,348,1,0,0,0,48,364,1,0,0,0, + 50,367,1,0,0,0,52,375,1,0,0,0,54,383,1,0,0,0,56,391,1,0,0,0,58,399,1,0, + 0,0,60,401,1,0,0,0,62,445,1,0,0,0,64,449,1,0,0,0,66,451,1,0,0,0,68,454, + 1,0,0,0,70,463,1,0,0,0,72,471,1,0,0,0,74,474,1,0,0,0,76,477,1,0,0,0,78, + 486,1,0,0,0,80,490,1,0,0,0,82,496,1,0,0,0,84,500,1,0,0,0,86,503,1,0,0,0, + 88,511,1,0,0,0,90,515,1,0,0,0,92,519,1,0,0,0,94,522,1,0,0,0,96,527,1,0, + 0,0,98,531,1,0,0,0,100,533,1,0,0,0,102,535,1,0,0,0,104,538,1,0,0,0,106, + 542,1,0,0,0,108,545,1,0,0,0,110,548,1,0,0,0,112,568,1,0,0,0,114,572,1,0, + 0,0,116,577,1,0,0,0,118,583,1,0,0,0,120,586,1,0,0,0,122,123,3,2,1,0,123, + 124,5,0,0,1,124,1,1,0,0,0,125,126,6,1,-1,0,126,127,3,4,2,0,127,133,1,0, + 0,0,128,129,10,1,0,0,129,130,5,26,0,0,130,132,3,6,3,0,131,128,1,0,0,0,132, + 135,1,0,0,0,133,131,1,0,0,0,133,134,1,0,0,0,134,3,1,0,0,0,135,133,1,0,0, + 0,136,144,3,102,51,0,137,144,3,32,16,0,138,144,3,108,54,0,139,144,3,26, + 13,0,140,144,3,106,53,0,141,142,4,2,1,0,142,144,3,46,23,0,143,136,1,0,0, + 0,143,137,1,0,0,0,143,138,1,0,0,0,143,139,1,0,0,0,143,140,1,0,0,0,143,141, + 1,0,0,0,144,5,1,0,0,0,145,164,3,48,24,0,146,164,3,8,4,0,147,164,3,72,36, + 0,148,164,3,66,33,0,149,164,3,50,25,0,150,164,3,68,34,0,151,164,3,74,37, + 0,152,164,3,76,38,0,153,164,3,80,40,0,154,164,3,82,41,0,155,164,3,110,55, + 0,156,164,3,84,42,0,157,158,4,3,2,0,158,164,3,116,58,0,159,160,4,3,3,0, + 160,164,3,114,57,0,161,162,4,3,4,0,162,164,3,118,59,0,163,145,1,0,0,0,163, + 146,1,0,0,0,163,147,1,0,0,0,163,148,1,0,0,0,163,149,1,0,0,0,163,150,1,0, + 0,0,163,151,1,0,0,0,163,152,1,0,0,0,163,153,1,0,0,0,163,154,1,0,0,0,163, + 155,1,0,0,0,163,156,1,0,0,0,163,157,1,0,0,0,163,159,1,0,0,0,163,161,1,0, + 0,0,164,7,1,0,0,0,165,166,5,17,0,0,166,167,3,10,5,0,167,9,1,0,0,0,168,169, + 6,5,-1,0,169,170,5,45,0,0,170,199,3,10,5,8,171,199,3,16,8,0,172,199,3,12, + 6,0,173,175,3,16,8,0,174,176,5,45,0,0,175,174,1,0,0,0,175,176,1,0,0,0,176, + 177,1,0,0,0,177,178,5,40,0,0,178,179,5,44,0,0,179,184,3,16,8,0,180,181, + 5,35,0,0,181,183,3,16,8,0,182,180,1,0,0,0,183,186,1,0,0,0,184,182,1,0,0, + 0,184,185,1,0,0,0,185,187,1,0,0,0,186,184,1,0,0,0,187,188,5,51,0,0,188, + 199,1,0,0,0,189,190,3,16,8,0,190,192,5,41,0,0,191,193,5,45,0,0,192,191, + 1,0,0,0,192,193,1,0,0,0,193,194,1,0,0,0,194,195,5,46,0,0,195,199,1,0,0, + 0,196,197,4,5,5,0,197,199,3,14,7,0,198,168,1,0,0,0,198,171,1,0,0,0,198, + 172,1,0,0,0,198,173,1,0,0,0,198,189,1,0,0,0,198,196,1,0,0,0,199,208,1,0, + 0,0,200,201,10,5,0,0,201,202,5,31,0,0,202,207,3,10,5,6,203,204,10,4,0,0, + 204,205,5,48,0,0,205,207,3,10,5,5,206,200,1,0,0,0,206,203,1,0,0,0,207,210, + 1,0,0,0,208,206,1,0,0,0,208,209,1,0,0,0,209,11,1,0,0,0,210,208,1,0,0,0, + 211,213,3,16,8,0,212,214,5,45,0,0,213,212,1,0,0,0,213,214,1,0,0,0,214,215, + 1,0,0,0,215,216,5,43,0,0,216,217,3,98,49,0,217,226,1,0,0,0,218,220,3,16, + 8,0,219,221,5,45,0,0,220,219,1,0,0,0,220,221,1,0,0,0,221,222,1,0,0,0,222, + 223,5,50,0,0,223,224,3,98,49,0,224,226,1,0,0,0,225,211,1,0,0,0,225,218, + 1,0,0,0,226,13,1,0,0,0,227,228,3,16,8,0,228,229,5,20,0,0,229,230,3,98,49, + 0,230,15,1,0,0,0,231,237,3,18,9,0,232,233,3,18,9,0,233,234,3,100,50,0,234, + 235,3,18,9,0,235,237,1,0,0,0,236,231,1,0,0,0,236,232,1,0,0,0,237,17,1,0, + 0,0,238,239,6,9,-1,0,239,243,3,20,10,0,240,241,7,0,0,0,241,243,3,18,9,3, + 242,238,1,0,0,0,242,240,1,0,0,0,243,252,1,0,0,0,244,245,10,2,0,0,245,246, + 7,1,0,0,246,251,3,18,9,3,247,248,10,1,0,0,248,249,7,0,0,0,249,251,3,18, + 9,2,250,244,1,0,0,0,250,247,1,0,0,0,251,254,1,0,0,0,252,250,1,0,0,0,252, + 253,1,0,0,0,253,19,1,0,0,0,254,252,1,0,0,0,255,256,6,10,-1,0,256,264,3, + 62,31,0,257,264,3,52,26,0,258,264,3,22,11,0,259,260,5,44,0,0,260,261,3, + 10,5,0,261,262,5,51,0,0,262,264,1,0,0,0,263,255,1,0,0,0,263,257,1,0,0,0, + 263,258,1,0,0,0,263,259,1,0,0,0,264,270,1,0,0,0,265,266,10,1,0,0,266,267, + 5,34,0,0,267,269,3,24,12,0,268,265,1,0,0,0,269,272,1,0,0,0,270,268,1,0, + 0,0,270,271,1,0,0,0,271,21,1,0,0,0,272,270,1,0,0,0,273,274,3,58,29,0,274, + 284,5,44,0,0,275,285,5,62,0,0,276,281,3,10,5,0,277,278,5,35,0,0,278,280, + 3,10,5,0,279,277,1,0,0,0,280,283,1,0,0,0,281,279,1,0,0,0,281,282,1,0,0, + 0,282,285,1,0,0,0,283,281,1,0,0,0,284,275,1,0,0,0,284,276,1,0,0,0,284,285, + 1,0,0,0,285,286,1,0,0,0,286,287,5,51,0,0,287,23,1,0,0,0,288,289,3,58,29, + 0,289,25,1,0,0,0,290,291,5,13,0,0,291,292,3,28,14,0,292,27,1,0,0,0,293, + 298,3,30,15,0,294,295,5,35,0,0,295,297,3,30,15,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,29,1,0,0,0,300,298,1,0,0,0, + 301,307,3,10,5,0,302,303,3,52,26,0,303,304,5,33,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,31,1,0,0,0,308,309,5,6, + 0,0,309,314,3,34,17,0,310,311,5,35,0,0,311,313,3,34,17,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,40,20,0,318,317,1,0,0,0,318,319,1,0,0,0,319,33,1,0,0, + 0,320,321,3,36,18,0,321,322,5,109,0,0,322,323,3,38,19,0,323,326,1,0,0,0, + 324,326,3,38,19,0,325,320,1,0,0,0,325,324,1,0,0,0,326,35,1,0,0,0,327,328, + 5,77,0,0,328,37,1,0,0,0,329,330,7,2,0,0,330,39,1,0,0,0,331,334,3,42,21, + 0,332,334,3,44,22,0,333,331,1,0,0,0,333,332,1,0,0,0,334,41,1,0,0,0,335, + 336,5,76,0,0,336,341,5,77,0,0,337,338,5,35,0,0,338,340,5,77,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,43,1,0,0,0, + 343,341,1,0,0,0,344,345,5,66,0,0,345,346,3,42,21,0,346,347,5,67,0,0,347, + 45,1,0,0,0,348,349,5,21,0,0,349,354,3,34,17,0,350,351,5,35,0,0,351,353, + 3,34,17,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,28,14,0,358,357,1,0,0,0,358, + 359,1,0,0,0,359,362,1,0,0,0,360,361,5,30,0,0,361,363,3,28,14,0,362,360, + 1,0,0,0,362,363,1,0,0,0,363,47,1,0,0,0,364,365,5,4,0,0,365,366,3,28,14, + 0,366,49,1,0,0,0,367,369,5,16,0,0,368,370,3,28,14,0,369,368,1,0,0,0,369, + 370,1,0,0,0,370,373,1,0,0,0,371,372,5,30,0,0,372,374,3,28,14,0,373,371, + 1,0,0,0,373,374,1,0,0,0,374,51,1,0,0,0,375,380,3,58,29,0,376,377,5,37,0, + 0,377,379,3,58,29,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,53,1,0,0,0,382,380,1,0,0,0,383,388,3,60,30,0,384,385,5, + 37,0,0,385,387,3,60,30,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,55,1,0,0,0,390,388,1,0,0,0,391,396,3,54,27,0,392, + 393,5,35,0,0,393,395,3,54,27,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,57,1,0,0,0,398,396,1,0,0,0,399,400,7,3,0,0, + 400,59,1,0,0,0,401,402,5,81,0,0,402,61,1,0,0,0,403,446,5,46,0,0,404,405, + 3,96,48,0,405,406,5,68,0,0,406,446,1,0,0,0,407,446,3,94,47,0,408,446,3, + 96,48,0,409,446,3,90,45,0,410,446,3,64,32,0,411,446,3,98,49,0,412,413,5, + 66,0,0,413,418,3,92,46,0,414,415,5,35,0,0,415,417,3,92,46,0,416,414,1,0, + 0,0,417,420,1,0,0,0,418,416,1,0,0,0,418,419,1,0,0,0,419,421,1,0,0,0,420, + 418,1,0,0,0,421,422,5,67,0,0,422,446,1,0,0,0,423,424,5,66,0,0,424,429,3, + 90,45,0,425,426,5,35,0,0,426,428,3,90,45,0,427,425,1,0,0,0,428,431,1,0, + 0,0,429,427,1,0,0,0,429,430,1,0,0,0,430,432,1,0,0,0,431,429,1,0,0,0,432, + 433,5,67,0,0,433,446,1,0,0,0,434,435,5,66,0,0,435,440,3,98,49,0,436,437, + 5,35,0,0,437,439,3,98,49,0,438,436,1,0,0,0,439,442,1,0,0,0,440,438,1,0, + 0,0,440,441,1,0,0,0,441,443,1,0,0,0,442,440,1,0,0,0,443,444,5,67,0,0,444, + 446,1,0,0,0,445,403,1,0,0,0,445,404,1,0,0,0,445,407,1,0,0,0,445,408,1,0, + 0,0,445,409,1,0,0,0,445,410,1,0,0,0,445,411,1,0,0,0,445,412,1,0,0,0,445, + 423,1,0,0,0,445,434,1,0,0,0,446,63,1,0,0,0,447,450,5,49,0,0,448,450,5,65, + 0,0,449,447,1,0,0,0,449,448,1,0,0,0,450,65,1,0,0,0,451,452,5,9,0,0,452, + 453,5,28,0,0,453,67,1,0,0,0,454,455,5,15,0,0,455,460,3,70,35,0,456,457, + 5,35,0,0,457,459,3,70,35,0,458,456,1,0,0,0,459,462,1,0,0,0,460,458,1,0, + 0,0,460,461,1,0,0,0,461,69,1,0,0,0,462,460,1,0,0,0,463,465,3,10,5,0,464, + 466,7,4,0,0,465,464,1,0,0,0,465,466,1,0,0,0,466,469,1,0,0,0,467,468,5,47, + 0,0,468,470,7,5,0,0,469,467,1,0,0,0,469,470,1,0,0,0,470,71,1,0,0,0,471, + 472,5,8,0,0,472,473,3,56,28,0,473,73,1,0,0,0,474,475,5,2,0,0,475,476,3, + 56,28,0,476,75,1,0,0,0,477,478,5,12,0,0,478,483,3,78,39,0,479,480,5,35, + 0,0,480,482,3,78,39,0,481,479,1,0,0,0,482,485,1,0,0,0,483,481,1,0,0,0,483, + 484,1,0,0,0,484,77,1,0,0,0,485,483,1,0,0,0,486,487,3,54,27,0,487,488,5, + 85,0,0,488,489,3,54,27,0,489,79,1,0,0,0,490,491,5,1,0,0,491,492,3,20,10, + 0,492,494,3,98,49,0,493,495,3,86,43,0,494,493,1,0,0,0,494,495,1,0,0,0,495, + 81,1,0,0,0,496,497,5,7,0,0,497,498,3,20,10,0,498,499,3,98,49,0,499,83,1, + 0,0,0,500,501,5,11,0,0,501,502,3,52,26,0,502,85,1,0,0,0,503,508,3,88,44, + 0,504,505,5,35,0,0,505,507,3,88,44,0,506,504,1,0,0,0,507,510,1,0,0,0,508, + 506,1,0,0,0,508,509,1,0,0,0,509,87,1,0,0,0,510,508,1,0,0,0,511,512,3,58, + 29,0,512,513,5,33,0,0,513,514,3,62,31,0,514,89,1,0,0,0,515,516,7,6,0,0, + 516,91,1,0,0,0,517,520,3,94,47,0,518,520,3,96,48,0,519,517,1,0,0,0,519, + 518,1,0,0,0,520,93,1,0,0,0,521,523,7,0,0,0,522,521,1,0,0,0,522,523,1,0, + 0,0,523,524,1,0,0,0,524,525,5,29,0,0,525,95,1,0,0,0,526,528,7,0,0,0,527, + 526,1,0,0,0,527,528,1,0,0,0,528,529,1,0,0,0,529,530,5,28,0,0,530,97,1,0, + 0,0,531,532,5,27,0,0,532,99,1,0,0,0,533,534,7,7,0,0,534,101,1,0,0,0,535, + 536,5,5,0,0,536,537,3,104,52,0,537,103,1,0,0,0,538,539,5,66,0,0,539,540, + 3,2,1,0,540,541,5,67,0,0,541,105,1,0,0,0,542,543,5,14,0,0,543,544,5,101, + 0,0,544,107,1,0,0,0,545,546,5,10,0,0,546,547,5,105,0,0,547,109,1,0,0,0, + 548,549,5,3,0,0,549,552,5,91,0,0,550,551,5,89,0,0,551,553,3,54,27,0,552, + 550,1,0,0,0,552,553,1,0,0,0,553,563,1,0,0,0,554,555,5,90,0,0,555,560,3, + 112,56,0,556,557,5,35,0,0,557,559,3,112,56,0,558,556,1,0,0,0,559,562,1, + 0,0,0,560,558,1,0,0,0,560,561,1,0,0,0,561,564,1,0,0,0,562,560,1,0,0,0,563, + 554,1,0,0,0,563,564,1,0,0,0,564,111,1,0,0,0,565,566,3,54,27,0,566,567,5, + 33,0,0,567,569,1,0,0,0,568,565,1,0,0,0,568,569,1,0,0,0,569,570,1,0,0,0, + 570,571,3,54,27,0,571,113,1,0,0,0,572,573,5,19,0,0,573,574,3,34,17,0,574, + 575,5,89,0,0,575,576,3,56,28,0,576,115,1,0,0,0,577,578,5,18,0,0,578,581, + 3,28,14,0,579,580,5,30,0,0,580,582,3,28,14,0,581,579,1,0,0,0,581,582,1, + 0,0,0,582,117,1,0,0,0,583,584,5,20,0,0,584,585,3,120,60,0,585,119,1,0,0, + 0,586,587,5,27,0,0,587,121,1,0,0,0,54,133,143,163,175,184,192,198,206,208, + 213,220,225,236,242,250,252,263,270,281,284,298,306,314,318,325,333,341, + 354,358,362,369,373,380,388,396,418,429,440,445,449,460,465,469,483,494, + 508,519,522,527,552,560,563,568,581]; private static __ATN: ATN; public static get _ATN(): ATN { @@ -3669,17 +3698,17 @@ export class SourceCommandContext extends ParserRuleContext { public fromCommand(): FromCommandContext { return this.getTypedRuleContext(FromCommandContext, 0) as FromCommandContext; } + public metaCommand(): MetaCommandContext { + return this.getTypedRuleContext(MetaCommandContext, 0) as MetaCommandContext; + } public rowCommand(): RowCommandContext { return this.getTypedRuleContext(RowCommandContext, 0) as RowCommandContext; } - public metricsCommand(): MetricsCommandContext { - return this.getTypedRuleContext(MetricsCommandContext, 0) as MetricsCommandContext; - } public showCommand(): ShowCommandContext { return this.getTypedRuleContext(ShowCommandContext, 0) as ShowCommandContext; } - public metaCommand(): MetaCommandContext { - return this.getTypedRuleContext(MetaCommandContext, 0) as MetaCommandContext; + public metricsCommand(): MetricsCommandContext { + return this.getTypedRuleContext(MetricsCommandContext, 0) as MetricsCommandContext; } public get ruleIndex(): number { return esql_parser.RULE_sourceCommand; @@ -3705,26 +3734,20 @@ export class ProcessingCommandContext extends ParserRuleContext { public evalCommand(): EvalCommandContext { return this.getTypedRuleContext(EvalCommandContext, 0) as EvalCommandContext; } - public inlinestatsCommand(): InlinestatsCommandContext { - return this.getTypedRuleContext(InlinestatsCommandContext, 0) as InlinestatsCommandContext; - } - public limitCommand(): LimitCommandContext { - return this.getTypedRuleContext(LimitCommandContext, 0) as LimitCommandContext; - } - public lookupCommand(): LookupCommandContext { - return this.getTypedRuleContext(LookupCommandContext, 0) as LookupCommandContext; + public whereCommand(): WhereCommandContext { + return this.getTypedRuleContext(WhereCommandContext, 0) as WhereCommandContext; } public keepCommand(): KeepCommandContext { return this.getTypedRuleContext(KeepCommandContext, 0) as KeepCommandContext; } - public sortCommand(): SortCommandContext { - return this.getTypedRuleContext(SortCommandContext, 0) as SortCommandContext; + public limitCommand(): LimitCommandContext { + return this.getTypedRuleContext(LimitCommandContext, 0) as LimitCommandContext; } public statsCommand(): StatsCommandContext { return this.getTypedRuleContext(StatsCommandContext, 0) as StatsCommandContext; } - public whereCommand(): WhereCommandContext { - return this.getTypedRuleContext(WhereCommandContext, 0) as WhereCommandContext; + public sortCommand(): SortCommandContext { + return this.getTypedRuleContext(SortCommandContext, 0) as SortCommandContext; } public dropCommand(): DropCommandContext { return this.getTypedRuleContext(DropCommandContext, 0) as DropCommandContext; @@ -3744,6 +3767,12 @@ export class ProcessingCommandContext extends ParserRuleContext { public mvExpandCommand(): MvExpandCommandContext { return this.getTypedRuleContext(MvExpandCommandContext, 0) as MvExpandCommandContext; } + public inlinestatsCommand(): InlinestatsCommandContext { + return this.getTypedRuleContext(InlinestatsCommandContext, 0) as InlinestatsCommandContext; + } + public lookupCommand(): LookupCommandContext { + return this.getTypedRuleContext(LookupCommandContext, 0) as LookupCommandContext; + } public matchCommand(): MatchCommandContext { return this.getTypedRuleContext(MatchCommandContext, 0) as MatchCommandContext; } @@ -4026,11 +4055,11 @@ export class MatchBooleanExpressionContext extends ParserRuleContext { super(parent, invokingState); this.parser = parser; } - public qualifiedName(): QualifiedNameContext { - return this.getTypedRuleContext(QualifiedNameContext, 0) as QualifiedNameContext; + public valueExpression(): ValueExpressionContext { + return this.getTypedRuleContext(ValueExpressionContext, 0) as ValueExpressionContext; } - public MATCH_OPERATOR(): TerminalNode { - return this.getToken(esql_parser.MATCH_OPERATOR, 0); + public DEV_MATCH(): TerminalNode { + return this.getToken(esql_parser.DEV_MATCH, 0); } public string_(): StringContext { return this.getTypedRuleContext(StringContext, 0) as StringContext; @@ -4719,8 +4748,8 @@ export class MetricsCommandContext extends ParserRuleContext { super(parent, invokingState); this.parser = parser; } - public METRICS(): TerminalNode { - return this.getToken(esql_parser.METRICS, 0); + public DEV_METRICS(): TerminalNode { + return this.getToken(esql_parser.DEV_METRICS, 0); } public indexPattern_list(): IndexPatternContext[] { return this.getTypedRuleContexts(IndexPatternContext) as IndexPatternContext[]; @@ -4821,41 +4850,6 @@ export class StatsCommandContext extends ParserRuleContext { } -export class InlinestatsCommandContext extends ParserRuleContext { - public _stats!: FieldsContext; - public _grouping!: FieldsContext; - constructor(parser?: esql_parser, parent?: ParserRuleContext, invokingState?: number) { - super(parent, invokingState); - this.parser = parser; - } - public INLINESTATS(): TerminalNode { - return this.getToken(esql_parser.INLINESTATS, 0); - } - public fields_list(): FieldsContext[] { - return this.getTypedRuleContexts(FieldsContext) as FieldsContext[]; - } - public fields(i: number): FieldsContext { - return this.getTypedRuleContext(FieldsContext, i) as FieldsContext; - } - public BY(): TerminalNode { - return this.getToken(esql_parser.BY, 0); - } - public get ruleIndex(): number { - return esql_parser.RULE_inlinestatsCommand; - } - public enterRule(listener: esql_parserListener): void { - if(listener.enterInlinestatsCommand) { - listener.enterInlinestatsCommand(this); - } - } - public exitRule(listener: esql_parserListener): void { - if(listener.exitInlinestatsCommand) { - listener.exitInlinestatsCommand(this); - } - } -} - - export class QualifiedNameContext extends ParserRuleContext { constructor(parser?: esql_parser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); @@ -6084,8 +6078,8 @@ export class LookupCommandContext extends ParserRuleContext { super(parent, invokingState); this.parser = parser; } - public LOOKUP(): TerminalNode { - return this.getToken(esql_parser.LOOKUP, 0); + public DEV_LOOKUP(): TerminalNode { + return this.getToken(esql_parser.DEV_LOOKUP, 0); } public ON(): TerminalNode { return this.getToken(esql_parser.ON, 0); @@ -6112,13 +6106,48 @@ export class LookupCommandContext extends ParserRuleContext { } +export class InlinestatsCommandContext extends ParserRuleContext { + public _stats!: FieldsContext; + public _grouping!: FieldsContext; + constructor(parser?: esql_parser, parent?: ParserRuleContext, invokingState?: number) { + super(parent, invokingState); + this.parser = parser; + } + public DEV_INLINESTATS(): TerminalNode { + return this.getToken(esql_parser.DEV_INLINESTATS, 0); + } + public fields_list(): FieldsContext[] { + return this.getTypedRuleContexts(FieldsContext) as FieldsContext[]; + } + public fields(i: number): FieldsContext { + return this.getTypedRuleContext(FieldsContext, i) as FieldsContext; + } + public BY(): TerminalNode { + return this.getToken(esql_parser.BY, 0); + } + public get ruleIndex(): number { + return esql_parser.RULE_inlinestatsCommand; + } + public enterRule(listener: esql_parserListener): void { + if(listener.enterInlinestatsCommand) { + listener.enterInlinestatsCommand(this); + } + } + public exitRule(listener: esql_parserListener): void { + if(listener.exitInlinestatsCommand) { + listener.exitInlinestatsCommand(this); + } + } +} + + export class MatchCommandContext extends ParserRuleContext { constructor(parser?: esql_parser, parent?: ParserRuleContext, invokingState?: number) { super(parent, invokingState); this.parser = parser; } - public MATCH(): TerminalNode { - return this.getToken(esql_parser.MATCH, 0); + public DEV_MATCH(): TerminalNode { + return this.getToken(esql_parser.DEV_MATCH, 0); } public matchQuery(): MatchQueryContext { return this.getTypedRuleContext(MatchQueryContext, 0) as MatchQueryContext; diff --git a/packages/kbn-esql-ast/src/antlr/esql_parser_listener.ts b/packages/kbn-esql-ast/src/antlr/esql_parser_listener.ts index 768ff5910602f..7beb89e1ddd0e 100644 --- a/packages/kbn-esql-ast/src/antlr/esql_parser_listener.ts +++ b/packages/kbn-esql-ast/src/antlr/esql_parser_listener.ts @@ -4,6 +4,14 @@ import {ParseTreeListener} from "antlr4"; +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + + import { SingleStatementContext } from "./esql_parser.js"; import { CompositeQueryContext } from "./esql_parser.js"; import { SingleCommandQueryContext } from "./esql_parser.js"; @@ -44,7 +52,6 @@ import { Deprecated_metadataContext } from "./esql_parser.js"; import { MetricsCommandContext } from "./esql_parser.js"; import { EvalCommandContext } from "./esql_parser.js"; import { StatsCommandContext } from "./esql_parser.js"; -import { InlinestatsCommandContext } from "./esql_parser.js"; import { QualifiedNameContext } from "./esql_parser.js"; import { QualifiedNamePatternContext } from "./esql_parser.js"; import { QualifiedNamePatternsContext } from "./esql_parser.js"; @@ -87,6 +94,7 @@ import { MetaFunctionsContext } from "./esql_parser.js"; import { EnrichCommandContext } from "./esql_parser.js"; import { EnrichWithClauseContext } from "./esql_parser.js"; import { LookupCommandContext } from "./esql_parser.js"; +import { InlinestatsCommandContext } from "./esql_parser.js"; import { MatchCommandContext } from "./esql_parser.js"; import { MatchQueryContext } from "./esql_parser.js"; @@ -536,16 +544,6 @@ export default class esql_parserListener extends ParseTreeListener { * @param ctx the parse tree */ exitStatsCommand?: (ctx: StatsCommandContext) => void; - /** - * Enter a parse tree produced by `esql_parser.inlinestatsCommand`. - * @param ctx the parse tree - */ - enterInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; - /** - * Exit a parse tree produced by `esql_parser.inlinestatsCommand`. - * @param ctx the parse tree - */ - exitInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; /** * Enter a parse tree produced by `esql_parser.qualifiedName`. * @param ctx the parse tree @@ -994,6 +992,16 @@ export default class esql_parserListener extends ParseTreeListener { * @param ctx the parse tree */ exitLookupCommand?: (ctx: LookupCommandContext) => void; + /** + * Enter a parse tree produced by `esql_parser.inlinestatsCommand`. + * @param ctx the parse tree + */ + enterInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; + /** + * Exit a parse tree produced by `esql_parser.inlinestatsCommand`. + * @param ctx the parse tree + */ + exitInlinestatsCommand?: (ctx: InlinestatsCommandContext) => void; /** * Enter a parse tree produced by `esql_parser.matchCommand`. * @param ctx the parse tree diff --git a/packages/kbn-esql-ast/src/antlr/lexer_config.js b/packages/kbn-esql-ast/src/antlr/lexer_config.js new file mode 100644 index 0000000000000..1618afa024cd4 --- /dev/null +++ b/packages/kbn-esql-ast/src/antlr/lexer_config.js @@ -0,0 +1,15 @@ +import { Lexer } from 'antlr4'; + +if (!Lexer) { + throw new Error('Failed to import Lexer from antlr4'); +} + +export default class lexer_config extends Lexer { + constructor(...args) { + super(...args); + } + + isDevVersion() { + return true; + } +} diff --git a/packages/kbn-esql-ast/src/antlr/parser_config.js b/packages/kbn-esql-ast/src/antlr/parser_config.js new file mode 100644 index 0000000000000..565829f0d1cba --- /dev/null +++ b/packages/kbn-esql-ast/src/antlr/parser_config.js @@ -0,0 +1,15 @@ +import { Parser } from 'antlr4'; + +if (!Parser) { + throw new Error('Failed to import Parser from antlr4'); +} + +export default class parser_config extends Parser { + constructor(...args) { + super(...args); + } + + isDevVersion() { + return true; + } +} diff --git a/packages/kbn-esql-ast/src/antlr_error_listener.ts b/packages/kbn-esql-ast/src/antlr_error_listener.ts index add9a7bcace0f..b11758aae0d2d 100644 --- a/packages/kbn-esql-ast/src/antlr_error_listener.ts +++ b/packages/kbn-esql-ast/src/antlr_error_listener.ts @@ -11,6 +11,7 @@ import { ErrorListener } from 'antlr4'; import type { EditorError } from './types'; import { getPosition } from './ast_position_utils'; +const REPLACE_DEV = /,*\s*DEV_\w+\s*/g; export class ESQLErrorListener extends ErrorListener { protected errors: EditorError[] = []; @@ -22,6 +23,9 @@ export class ESQLErrorListener extends ErrorListener { message: string, error: RecognitionException | undefined ): void { + // Remove any DEV_ tokens from the error message + message = message.replace(REPLACE_DEV, ''); + const textMessage = `SyntaxError: ${message}`; const tokenPosition = getPosition(offendingSymbol); diff --git a/packages/kbn-esql-ast/src/ast_helpers.ts b/packages/kbn-esql-ast/src/ast_helpers.ts index e338d2eacd4a4..563f221972493 100644 --- a/packages/kbn-esql-ast/src/ast_helpers.ts +++ b/packages/kbn-esql-ast/src/ast_helpers.ts @@ -269,13 +269,13 @@ export function computeLocationExtends(fn: ESQLFunction) { /* SCRIPT_MARKER_START */ function getQuotedText(ctx: ParserRuleContext) { - return [27 /* esql_parser.QUOTED_STRING */, 68 /* esql_parser.QUOTED_IDENTIFIER */] + return [27 /* esql_parser.QUOTED_STRING */, 69 /* esql_parser.QUOTED_IDENTIFIER */] .map((keyCode) => ctx.getToken(keyCode, 0)) .filter(nonNullable)[0]; } function getUnquotedText(ctx: ParserRuleContext) { - return [67 /* esql_parser.UNQUOTED_IDENTIFIER */, 73 /* esql_parser.FROM_UNQUOTED_IDENTIFIER */] + return [68 /* esql_parser.UNQUOTED_IDENTIFIER */, 77 /* esql_parser.UNQUOTED_SOURCE */] .map((keyCode) => ctx.getToken(keyCode, 0)) .filter(nonNullable)[0]; } diff --git a/packages/kbn-esql-ast/src/ast_parser.ts b/packages/kbn-esql-ast/src/ast_parser.ts index 44c5dfcd9353f..2f6ffb02928db 100644 --- a/packages/kbn-esql-ast/src/ast_parser.ts +++ b/packages/kbn-esql-ast/src/ast_parser.ts @@ -14,7 +14,7 @@ import type { ESQLAst, EditorError } from './types'; // These will need to be manually updated whenever the relevant grammar changes. const SYNTAX_ERRORS_TO_IGNORE = [ - `SyntaxError: mismatched input '' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}`, + `SyntaxError: mismatched input '' expecting {'explain', 'from', 'meta', 'row', 'show'}`, ]; export function getAstAndSyntaxErrors(text: string | undefined): { diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.stats.test.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.stats.test.ts index 1f6bd93359311..488453b9fad6f 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.stats.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.stats.test.ts @@ -7,7 +7,7 @@ */ import { ESQL_COMMON_NUMERIC_TYPES, ESQL_NUMBER_TYPES } from '../../shared/esql_types'; -import { ADD_DATE_HISTOGRAM_SNIPPET } from '../factories'; +import { getAddDateHistogramSnippet } from '../factories'; import { roundParameterTypes } from './constants'; import { setup, getFunctionSignaturesByReturnType, getFieldNamesByType } from './helpers'; @@ -214,7 +214,7 @@ describe('autocomplete.suggest', () => { const { assertSuggestions } = await setup(); const expected = [ 'var0 = ', - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...getFieldNamesByType('any').map((field) => `${field} `), ...allEvaFunctions, ...allGroupingFunctions, @@ -237,7 +237,7 @@ describe('autocomplete.suggest', () => { const fields = getFieldNamesByType('any').map((field) => `${field} `); await assertSuggestions('from a | stats a=c by d, /', [ 'var0 = ', - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...fields, ...allEvaFunctions, ...allGroupingFunctions, @@ -249,7 +249,7 @@ describe('autocomplete.suggest', () => { ]); await assertSuggestions('from a | stats avg(b) by c, /', [ 'var0 = ', - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...fields, ...getFunctionSignaturesByReturnType('eval', 'any', { scalar: true }), ...allGroupingFunctions, @@ -271,13 +271,13 @@ describe('autocomplete.suggest', () => { ...allGroupingFunctions, ]); await assertSuggestions('from a | stats avg(b) by var0 = /', [ - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...getFieldNamesByType('any').map((field) => `${field} `), ...allEvaFunctions, ...allGroupingFunctions, ]); await assertSuggestions('from a | stats avg(b) by c, var0 = /', [ - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...getFieldNamesByType('any').map((field) => `${field} `), ...allEvaFunctions, ...allGroupingFunctions, diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts index 9f558c7c17470..e0678aab0d9db 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts @@ -11,7 +11,8 @@ import { evalFunctionDefinitions } from '../definitions/functions'; import { timeUnitsToSuggest } from '../definitions/literals'; import { commandDefinitions as unmodifiedCommandDefinitions } from '../definitions/commands'; import { - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet, + getDateLiterals, getSafeInsertText, TIME_SYSTEM_PARAMS, TRIGGER_SUGGESTION_COMMAND, @@ -141,6 +142,19 @@ describe('autocomplete', () => { ['and', 'or', 'not'] ), ]); + + const expectedComparisonWithDateSuggestions = [ + ...getDateLiterals(), + ...getFieldNamesByType(['date']), + // all functions compatible with a keywordField type + ...getFunctionSignaturesByReturnType('where', ['date'], { scalar: true }), + ]; + testSuggestions('from a | where dateField == /', expectedComparisonWithDateSuggestions); + + testSuggestions('from a | where dateField < /', expectedComparisonWithDateSuggestions); + + testSuggestions('from a | where dateField >= /', expectedComparisonWithDateSuggestions); + const expectedComparisonWithTextFieldSuggestions = [ ...getFieldNamesByType(['text', 'keyword', 'ip', 'version']), ...getFunctionSignaturesByReturnType('where', ['text', 'keyword', 'ip', 'version'], { @@ -643,7 +657,7 @@ describe('autocomplete', () => { // STATS argument BY expression testSuggestions('FROM index1 | STATS field BY f/', [ 'var0 = ', - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...getFunctionSignaturesByReturnType('stats', 'any', { grouping: true, scalar: true }), ...getFieldNamesByType('any').map((field) => `${field} `), ]); @@ -856,7 +870,7 @@ describe('autocomplete', () => { 'by' ); testSuggestions('FROM a | STATS AVG(numberField) BY /', [ - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), attachTriggerCommand('var0 = '), ...getFieldNamesByType('any') .map((field) => `${field} `) @@ -866,7 +880,7 @@ describe('autocomplete', () => { // STATS argument BY assignment (checking field suggestions) testSuggestions('FROM a | STATS AVG(numberField) BY var0 = /', [ - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet(), ...getFieldNamesByType('any') .map((field) => `${field} `) .map(attachTriggerCommand), diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts index b2808ee2c1156..74a44e3f4aa3d 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts @@ -78,7 +78,7 @@ import { getDateLiterals, buildFieldsDefinitionsWithMetadata, TRIGGER_SUGGESTION_COMMAND, - ADD_DATE_HISTOGRAM_SNIPPET, + getAddDateHistogramSnippet, } from './factories'; import { EDITOR_MARKER, SINGLE_BACKTICK, METADATA_FIELDS } from '../shared/constants'; import { getAstContext, removeMarkerArgFromArgsList } from '../shared/context'; @@ -244,6 +244,7 @@ export async function suggest( buildQueryUntilPreviousCommand(ast, correctedQuery), ast ); + const { getFieldsByType, getFieldsMap } = getFieldsByTypeRetriever( queryForFields, resourceRetriever @@ -298,7 +299,8 @@ export async function suggest( { option, ...rest }, getFieldsByType, getFieldsMap, - getPolicyMetadata + getPolicyMetadata, + resourceRetriever?.getPreferences ); } } @@ -1102,6 +1104,7 @@ async function getBuiltinFunctionNextArgument( } else { const finalType = nestedType || nodeArgType || 'any'; const supportedTypes = getSupportedTypesForBinaryOperators(fnDef, finalType as string); + suggestions.push( ...(await getFieldsOrFunctionsSuggestions( // this is a special case with AND/OR @@ -1232,8 +1235,11 @@ async function getFieldsOrFunctionsSuggestions( } } } + // could also be in stats (bucket) but our autocomplete is not great yet + const displayDateSuggestions = types.includes('date') && ['where', 'eval'].includes(commandName); const suggestions = filteredFieldsByType.concat( + displayDateSuggestions ? getDateLiterals() : [], functions ? getCompatibleFunctionDefinition(commandName, optionName, types, ignoreFn) : [], variables ? pushItUpInTheList(buildVariablesDefinitions(filteredVariablesByType), functions) @@ -1569,8 +1575,14 @@ async function getOptionArgsSuggestions( }, getFieldsByType: GetFieldsByTypeFn, getFieldsMaps: GetFieldsMapFn, - getPolicyMetadata: GetPolicyMetadataFn + getPolicyMetadata: GetPolicyMetadataFn, + getPreferences?: () => Promise<{ histogramBarTarget: number } | undefined> ) { + let preferences: { histogramBarTarget: number } | undefined; + if (getPreferences) { + preferences = await getPreferences(); + } + const optionDef = getCommandOption(option.name); const { nodeArg, argIndex, lastArg } = extractArgMeta(option, node); const suggestions = []; @@ -1774,9 +1786,9 @@ async function getOptionArgsSuggestions( defaultMessage: 'Add date histogram', } ), - text: ADD_DATE_HISTOGRAM_SNIPPET, + text: getAddDateHistogramSnippet(preferences?.histogramBarTarget), asSnippet: true, - kind: 'Function', + kind: 'Issue', detail: i18n.translate( 'kbn-esql-validation-autocomplete.esql.autocomplete.addDateHistogramDetail', { diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts index ac405084bb253..739365095343b 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts @@ -30,7 +30,10 @@ const allFunctions = statsAggregationFunctionDefinitions .concat(groupingFunctionDefinitions); export const TIME_SYSTEM_PARAMS = ['?t_start', '?t_end']; -export const ADD_DATE_HISTOGRAM_SNIPPET = 'BUCKET($0, 10, ?t_start, ?t_end)'; + +export const getAddDateHistogramSnippet = (histogramBarTarget = 50) => { + return `BUCKET($0, ${histogramBarTarget}, ${TIME_SYSTEM_PARAMS.join(', ')})`; +}; export const TRIGGER_SUGGESTION_COMMAND = { title: 'Trigger Suggestion Dialog', diff --git a/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts b/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts index c627bc0a62176..b9ea4206dff74 100644 --- a/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts +++ b/packages/kbn-esql-validation-autocomplete/src/definitions/functions.ts @@ -2288,7 +2288,7 @@ const locateDefinition: FunctionDefinition = { name: 'locate', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.locate', { defaultMessage: - 'Returns an integer that indicates the position of a keyword substring within another string.', + 'Returns an integer that indicates the position of a keyword substring within another string.\nReturns `0` if the substring cannot be found.\nNote that string positions start from `1`.', }), alias: undefined, signatures: [ diff --git a/packages/kbn-esql-validation-autocomplete/src/shared/types.ts b/packages/kbn-esql-validation-autocomplete/src/shared/types.ts index 04a8365c5e51c..02d1cc72cb9c7 100644 --- a/packages/kbn-esql-validation-autocomplete/src/shared/types.ts +++ b/packages/kbn-esql-validation-autocomplete/src/shared/types.ts @@ -28,6 +28,7 @@ export interface ESQLCallbacks { {}, { name: string; sourceIndices: string[]; matchField: string; enrichFields: string[] } >; + getPreferences?: () => Promise<{ histogramBarTarget: number }>; } export type ReasonTypes = 'missingCommand' | 'unsupportedFunction' | 'unknownFunction'; diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.from.ts b/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.from.ts index 06d23a30c441d..c90ed14b102af 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.from.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.from.ts @@ -17,10 +17,10 @@ export const validationFromCommandTestSuite = (setup: helpers.Setup) => { const { expectErrors } = await setup(); await expectErrors('f', [ - "SyntaxError: mismatched input 'f' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}", + "SyntaxError: mismatched input 'f' expecting {'explain', 'from', 'meta', 'row', 'show'}", ]); await expectErrors('from ', [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); }); @@ -67,10 +67,10 @@ export const validationFromCommandTestSuite = (setup: helpers.Setup) => { const { expectErrors } = await setup(); await expectErrors('from index,', [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); await expectErrors(`FROM index\n, \tother_index\t,\n \t `, [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); await expectErrors(`from assignment = 1`, [ diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.metrics.ts b/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.metrics.ts index ea5df88553888..5359c670a498e 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.metrics.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/__tests__/test_suites/validation.command.metrics.ts @@ -16,10 +16,10 @@ export const validationMetricsCommandTestSuite = (setup: helpers.Setup) => { const { expectErrors } = await setup(); await expectErrors('m', [ - "SyntaxError: mismatched input 'm' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}", + "SyntaxError: mismatched input 'm' expecting {'explain', 'from', 'meta', 'row', 'show'}", ]); await expectErrors('metrics ', [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); }); @@ -61,10 +61,10 @@ export const validationMetricsCommandTestSuite = (setup: helpers.Setup) => { const { expectErrors } = await setup(); await expectErrors('metrics index,', [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); await expectErrors(`metrics index\n, \tother_index\t,\n \t `, [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}", + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}", ]); }); diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json index 75d45e85bd11a..fd04d1f5646d7 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json +++ b/packages/kbn-esql-validation-autocomplete/src/validation/esql_validation_meta_tests.json @@ -160,63 +160,63 @@ { "query": "eval", "error": [ - "SyntaxError: mismatched input 'eval' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'eval' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "stats", "error": [ - "SyntaxError: mismatched input 'stats' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'stats' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "rename", "error": [ - "SyntaxError: mismatched input 'rename' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'rename' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "limit", "error": [ - "SyntaxError: mismatched input 'limit' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'limit' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "keep", "error": [ - "SyntaxError: mismatched input 'keep' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'keep' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "drop", "error": [ - "SyntaxError: mismatched input 'drop' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'drop' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "mv_expand", "error": [ - "SyntaxError: mismatched input 'mv_expand' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'mv_expand' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "dissect", "error": [ - "SyntaxError: mismatched input 'dissect' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'dissect' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "grok", "error": [ - "SyntaxError: mismatched input 'grok' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'grok' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, @@ -2252,28 +2252,28 @@ { "query": "from index | project ", "error": [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}" + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}" ], "warning": [] }, { "query": "from index | project textField, doubleField, dateField", "error": [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}" + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}" ], "warning": [] }, { "query": "from index | PROJECT textField, doubleField, dateField", "error": [ - "SyntaxError: mismatched input 'PROJECT' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}" + "SyntaxError: mismatched input 'PROJECT' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}" ], "warning": [] }, { "query": "from index | project missingField, doubleField, dateField", "error": [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}" + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}" ], "warning": [] }, @@ -37672,14 +37672,14 @@ { "query": "f", "error": [ - "SyntaxError: mismatched input 'f' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}" + "SyntaxError: mismatched input 'f' expecting {'explain', 'from', 'meta', 'row', 'show'}" ], "warning": [] }, { "query": "from ", "error": [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}" + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}" ], "warning": [] }, @@ -37851,14 +37851,14 @@ { "query": "from index,", "error": [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}" + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}" ], "warning": [] }, { "query": "FROM index\n, \tother_index\t,\n \t ", "error": [ - "SyntaxError: mismatched input '' expecting {UNQUOTED_SOURCE, QUOTED_STRING}" + "SyntaxError: mismatched input '' expecting {QUOTED_STRING, UNQUOTED_SOURCE}" ], "warning": [] }, diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts index a4b097430851c..d4302fb9e66bd 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/validation.test.ts @@ -274,7 +274,7 @@ describe('validation logic', () => { ['eval', 'stats', 'rename', 'limit', 'keep', 'drop', 'mv_expand', 'dissect', 'grok'].map( (command) => testErrorsAndWarnings(command, [ - `SyntaxError: mismatched input '${command}' expecting {'explain', 'from', 'meta', 'metrics', 'row', 'show'}`, + `SyntaxError: mismatched input '${command}' expecting {'explain', 'from', 'meta', 'row', 'show'}`, ]) ); }); @@ -530,16 +530,16 @@ describe('validation logic', () => { ]); testErrorsAndWarnings('from index | keep `any#Char$Field`', []); testErrorsAndWarnings('from index | project ', [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}", + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}", ]); testErrorsAndWarnings('from index | project textField, doubleField, dateField', [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}", + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}", ]); testErrorsAndWarnings('from index | PROJECT textField, doubleField, dateField', [ - "SyntaxError: mismatched input 'PROJECT' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}", + "SyntaxError: mismatched input 'PROJECT' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}", ]); testErrorsAndWarnings('from index | project missingField, doubleField, dateField', [ - "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'inlinestats', 'keep', 'limit', 'lookup', 'mv_expand', 'rename', 'sort', 'stats', 'where', MATCH}", + "SyntaxError: mismatched input 'project' expecting {'dissect', 'drop', 'enrich', 'eval', 'grok', 'keep', 'limit', 'mv_expand', 'rename', 'sort', 'stats', 'where'}", ]); testErrorsAndWarnings('from index | keep k*', []); testErrorsAndWarnings('from index | keep *Field', []); @@ -16159,6 +16159,7 @@ describe('validation logic', () => { getSources: /Unknown index/, getPolicies: /Unknown policy/, getFieldsFor: /Unknown column|Argument of|it is unsupported or not indexed/, + getPreferences: /Unknown/, }; return excludedCallback.map((callback) => contentByCallback[callback]) || []; } diff --git a/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts b/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts index 5a06cf3f6a246..ffcb2d8cc226f 100644 --- a/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts +++ b/packages/kbn-esql-validation-autocomplete/src/validation/validation.ts @@ -1099,6 +1099,7 @@ export const ignoreErrorsMap: Record = { getFieldsFor: ['unknownColumn', 'wrongArgumentType', 'unsupportedFieldType'], getSources: ['unknownIndex'], getPolicies: ['unknownPolicy'], + getPreferences: [], }; /** diff --git a/packages/kbn-field-utils/src/components/field_description/field_description.tsx b/packages/kbn-field-utils/src/components/field_description/field_description.tsx index 74b9fa12ae7ca..d87a20fd45cd5 100644 --- a/packages/kbn-field-utils/src/components/field_description/field_description.tsx +++ b/packages/kbn-field-utils/src/components/field_description/field_description.tsx @@ -98,7 +98,7 @@ export const FieldDescriptionContent: React.FC< ); const truncateFieldDescription = useCallback( - (nextValue) => { + (nextValue: boolean) => { setIsTruncated(nextValue); setShouldTruncateByDefault(nextValue); }, diff --git a/packages/kbn-management/settings/components/field_input/input/code_editor_input.tsx b/packages/kbn-management/settings/components/field_input/input/code_editor_input.tsx index b20f51d208feb..d74edebf1d6ef 100644 --- a/packages/kbn-management/settings/components/field_input/input/code_editor_input.tsx +++ b/packages/kbn-management/settings/components/field_input/input/code_editor_input.tsx @@ -53,7 +53,7 @@ export const CodeEditorInput = ({ const onUpdate = useUpdate({ onInputChange, field }); const updateValue = useCallback( - async (newValue: string, onUpdateFn) => { + async (newValue: string, onUpdateFn: typeof onUpdate) => { let parsedValue; // Validate JSON syntax diff --git a/packages/kbn-monaco/src/esql/lib/esql_theme.test.ts b/packages/kbn-monaco/src/esql/lib/esql_theme.test.ts index f6b0fa740a790..99a1ab61fe3c4 100644 --- a/packages/kbn-monaco/src/esql/lib/esql_theme.test.ts +++ b/packages/kbn-monaco/src/esql/lib/esql_theme.test.ts @@ -45,9 +45,17 @@ describe('ESQL Theme', () => { // see packages/kbn-monaco/src/esql/lib/esql_token_helpers.ts const syntheticNames = ['functions', 'nulls_order', 'timespan_literal']; + const rulesWithNoName: string[] = []; for (const rule of theme.rules) { - expect([...lexicalNames, ...syntheticNames]).toContain( - rule.token.replace(ESQL_TOKEN_POSTFIX, '').toLowerCase() + const token = rule.token.replace(ESQL_TOKEN_POSTFIX, ''); + if (![...lexicalNames, ...syntheticNames].includes(token)) { + rulesWithNoName.push(token); + } + } + + if (rulesWithNoName.length) { + throw new Error( + `These rules have no corresponding lexical name: ${rulesWithNoName.join(', ')}` ); } }); @@ -87,19 +95,38 @@ describe('ESQL Theme', () => { 'setting_ws', 'metrics_ws', 'closing_metrics_ws', - 'match_operator', ]; // First, check that every valid exception is actually valid + const invalidExceptions: string[] = []; for (const name of validExceptions) { - expect(lexicalNames).toContain(name); + if (!lexicalNames.includes(name)) { + invalidExceptions.push(name); + } + } + + if (invalidExceptions.length) { + throw new Error( + `These rule requirement exceptions are not valid lexical names: ${invalidExceptions.join( + ', ' + )}` + ); } const namesToCheck = lexicalNames.filter((name) => !validExceptions.includes(name)); // Now, check that every lexical name has a corresponding rule + const missingRules: string[] = []; for (const name of namesToCheck) { - expect(tokenIDs).toContain(name); + if (!tokenIDs.includes(name)) { + missingRules.push(name); + } + } + + if (missingRules.length) { + throw new Error( + `These lexical names are missing corresponding rules: ${missingRules.join(', ')}` + ); } }); }); diff --git a/packages/kbn-monaco/src/esql/lib/esql_theme.ts b/packages/kbn-monaco/src/esql/lib/esql_theme.ts index 851aef18bbbb5..1a164e76780eb 100644 --- a/packages/kbn-monaco/src/esql/lib/esql_theme.ts +++ b/packages/kbn-monaco/src/esql/lib/esql_theme.ts @@ -44,13 +44,13 @@ export const buildESQlTheme = (): monaco.editor.IStandaloneThemeData => ({ // commands ...buildRuleGroup( [ - 'metrics', + 'dev_metrics', 'meta', 'metadata', - 'match', + 'dev_match', 'mv_expand', 'stats', - 'inlinestats', + 'dev_inlinestats', 'dissect', 'grok', 'keep', @@ -67,7 +67,7 @@ export const buildESQlTheme = (): monaco.editor.IStandaloneThemeData => ({ 'in', 'as', 'limit', - 'lookup', + 'dev_lookup', 'null', 'enrich', 'on', diff --git a/packages/kbn-test/src/kbn_client/kbn_client_version.ts b/packages/kbn-test/src/kbn_client/kbn_client_version.ts index a52e04a8ebd5d..710f627927260 100644 --- a/packages/kbn-test/src/kbn_client/kbn_client_version.ts +++ b/packages/kbn-test/src/kbn_client/kbn_client_version.ts @@ -19,6 +19,13 @@ export class KbnClientVersion { } const status = await this.status.get(); + + if (!status.version) { + throw new Error( + `Unable to get version from Kibana, invalid response from server: ${JSON.stringify(status)}` + ); + } + this.versionCache = status.version.number + (status.version.build_snapshot ? '-SNAPSHOT' : ''); return this.versionCache; } diff --git a/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx b/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx index 9976078804819..42a1402e4da38 100644 --- a/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx +++ b/packages/kbn-text-based-editor/src/esql_documentation_sections.tsx @@ -1722,6 +1722,8 @@ export const functions = { ### LOCATE Returns an integer that indicates the position of a keyword substring within another string. + Returns \`0\` if the substring cannot be found. + Note that string positions start from \`1\`. \`\`\` row a = "hello" diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 4fd0f994520d6..fc1f0839ea1a8 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -83,9 +83,17 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const datePickerOpenStatusRef = useRef(false); const { euiTheme } = useEuiTheme(); const kibana = useKibana(); - const { dataViews, expressions, indexManagementApiService, application, core, fieldsMetadata } = - kibana.services; + const { + dataViews, + expressions, + indexManagementApiService, + application, + core, + fieldsMetadata, + uiSettings, + } = kibana.services; const timeZone = core?.uiSettings?.get('dateFormat:tz'); + const histogramBarTarget = uiSettings?.get('histogram:barTarget') ?? 50; const [code, setCode] = useState(query.esql ?? ''); // To make server side errors less "sticky", register the state of the code when submitting const [codeWhenSubmitted, setCodeStateOnSubmission] = useState(code); @@ -245,10 +253,17 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const containerRef = useRef(null); // When the editor is on full size mode, the user can resize the height of the editor. - const onMouseDownResizeHandler = useCallback( + const onMouseDownResizeHandler = useCallback< + React.ComponentProps['onMouseDownResizeHandler'] + >( (mouseDownEvent) => { + function isMouseEvent(e: React.TouchEvent | React.MouseEvent): e is React.MouseEvent { + return e && 'pageY' in e; + } const startSize = editorHeight; - const startPosition = mouseDownEvent.pageY; + const startPosition = isMouseEvent(mouseDownEvent) + ? mouseDownEvent?.pageY + : mouseDownEvent?.touches[0].pageY; function onMouseMove(mouseMoveEvent: MouseEvent) { const height = startSize - startPosition + mouseMoveEvent.pageY; @@ -265,7 +280,9 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ [editorHeight] ); - const onKeyDownResizeHandler = useCallback( + const onKeyDownResizeHandler = useCallback< + React.ComponentProps['onKeyDownResizeHandler'] + >( (keyDownEvent) => { let height = editorHeight; if ( @@ -355,6 +372,11 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ } return policies.map(({ type, query: policyQuery, ...rest }) => rest); }, + getPreferences: async () => { + return { + histogramBarTarget, + }; + }, }; return callbacks; }, [ @@ -369,6 +391,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ abortController, indexManagementApiService, fieldsMetadata, + histogramBarTarget, ]); const queryRunButtonProperties = useMemo(() => { diff --git a/packages/kbn-unified-data-table/src/hooks/use_selected_docs.ts b/packages/kbn-unified-data-table/src/hooks/use_selected_docs.ts index c70e74f1abdaa..9f5cf398684f1 100644 --- a/packages/kbn-unified-data-table/src/hooks/use_selected_docs.ts +++ b/packages/kbn-unified-data-table/src/hooks/use_selected_docs.ts @@ -82,7 +82,7 @@ export const useSelectedDocs = (docMap: Map): UseSelect const selectedDocsCount = selectedDocIds.length; const getCountOfFilteredSelectedDocs = useCallback( - (docIds) => { + (docIds: string[]) => { if (!selectedDocsCount) { return 0; } diff --git a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx index 6a53239590d92..0d1814828369f 100644 --- a/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx +++ b/packages/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx @@ -342,7 +342,7 @@ function nodeToEuiCollapsibleNavProps( if (renderAs === 'panelOpener') { // Render as a panel opener (button to open a panel as a second navigation) return { - items: [...renderPanelOpener(navNode, deps)], + items: [...renderPanelOpener(navNode, { spaceBefore, ...deps })], isVisible: true, }; } diff --git a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts index 1a3708a3d5bcd..5233ca6ce481a 100644 --- a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts +++ b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts @@ -147,14 +147,14 @@ export const CreateDockerCloud: Task = { async run(config, log, build) { await runDockerGenerator(config, log, build, { architecture: 'x64', - baseImage: 'ubuntu', + baseImage: 'wolfi', context: false, cloud: true, image: true, }); await runDockerGenerator(config, log, build, { architecture: 'aarch64', - baseImage: 'ubuntu', + baseImage: 'wolfi', context: false, cloud: true, image: true, @@ -204,7 +204,7 @@ export const CreateDockerContexts: Task = { image: false, }); await runDockerGenerator(config, log, build, { - baseImage: 'ubuntu', + baseImage: 'wolfi', cloud: true, context: true, image: false, diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts index 46225c5266048..1d0e81526e9ba 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -54,7 +54,7 @@ export async function runDockerGenerator( let imageFlavor = ''; if (flags.baseImage === 'ubi') imageFlavor += `-ubi`; - if (flags.baseImage === 'wolfi' && !flags.serverless) imageFlavor += `-wolfi`; + if (flags.baseImage === 'wolfi' && !flags.serverless && !flags.cloud) imageFlavor += `-wolfi`; if (flags.ironbank) imageFlavor += '-ironbank'; if (flags.cloud) imageFlavor += '-cloud'; if (flags.serverless) imageFlavor += '-serverless'; diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index acd5b54a74f1b..ec5588b4c793e 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -134,7 +134,7 @@ RUN for iter in {1..10}; do \ (exit $exit_code) {{/ubuntu}} {{#wolfi}} -RUN apk --no-cache add bash curl fontconfig libstdc++ nss findutils shadow +RUN apk --no-cache add bash curl fontconfig libstdc++ libnss findutils shadow {{/wolfi}} # Bring in Kibana from the initial stage. @@ -152,8 +152,8 @@ WORKDIR /usr/share/kibana {{#fips}} # Enable FIPS for Kibana only. In the future we can override OS wide with ENV OPENSSL_CONF -RUN /usr/bin/echo -e '\n--enable-fips' >> config/node.options -RUN /usr/bin/echo '--openssl-config=/usr/share/kibana/config/nodejs.cnf' >> config/node.options +RUN /bin/echo -e '\n--enable-fips' >> config/node.options +RUN echo '--openssl-config=/usr/share/kibana/config/nodejs.cnf' >> config/node.options COPY --chown=1000:0 openssl/nodejs.cnf "/usr/share/kibana/config/nodejs.cnf" ENV OPENSSL_MODULES=/usr/share/kibana/openssl/lib/ossl-modules ENV XPACK_SECURITY_EXPERIMENTAL_FIPSMODE_ENABLED=true @@ -231,7 +231,7 @@ ENTRYPOINT ["/bin/tini", "--"] CMD ["/app/kibana.sh"] # Generate a stub command that will be overwritten at runtime RUN mkdir /app && \ - /usr/bin/echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ + /bin/echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ chmod 0555 /app/kibana.sh {{/cloud}} diff --git a/src/plugins/controls/common/control_group/control_group_persistence.ts b/src/plugins/controls/common/control_group/control_group_persistence.ts index 0de1238b9575c..8e9a795c2ec4c 100644 --- a/src/plugins/controls/common/control_group/control_group_persistence.ts +++ b/src/plugins/controls/common/control_group/control_group_persistence.ts @@ -9,6 +9,7 @@ import deepEqual from 'fast-deep-equal'; import { SerializableRecord } from '@kbn/utility-types'; +import { v4 } from 'uuid'; import { pick, omit, xor } from 'lodash'; import { @@ -22,6 +23,7 @@ import { } from './control_group_panel_diff_system'; import { ControlGroupInput } from '..'; import { + ControlsPanels, PersistableControlGroupInput, persistableControlGroupInputKeys, RawControlGroupAttributes, @@ -101,6 +103,32 @@ const getPanelsAreEqual = ( return true; }; +export const controlGroupInputToRawControlGroupAttributes = ( + controlGroupInput: Omit +): RawControlGroupAttributes => { + return { + controlStyle: controlGroupInput.controlStyle, + chainingSystem: controlGroupInput.chainingSystem, + showApplySelections: controlGroupInput.showApplySelections, + panelsJSON: JSON.stringify(controlGroupInput.panels), + ignoreParentSettingsJSON: JSON.stringify(controlGroupInput.ignoreParentSettings), + }; +}; + +export const generateNewControlIds = (controlGroupInput?: PersistableControlGroupInput) => { + if (!controlGroupInput?.panels) return; + + const newPanelsMap: ControlsPanels = {}; + for (const panel of Object.values(controlGroupInput.panels)) { + const newId = v4(); + newPanelsMap[newId] = { + ...panel, + explicitInput: { ...panel.explicitInput, id: newId }, + }; + } + return { ...controlGroupInput, panels: newPanelsMap }; +}; + export const rawControlGroupAttributesToControlGroupInput = ( rawControlGroupAttributes: RawControlGroupAttributes ): PersistableControlGroupInput | undefined => { diff --git a/src/plugins/controls/common/index.ts b/src/plugins/controls/common/index.ts index 6be0bc5818f57..69af581fc5fad 100644 --- a/src/plugins/controls/common/index.ts +++ b/src/plugins/controls/common/index.ts @@ -22,12 +22,14 @@ export { persistableControlGroupInputKeys, } from './control_group/types'; export { + controlGroupInputToRawControlGroupAttributes, rawControlGroupAttributesToControlGroupInput, rawControlGroupAttributesToSerializable, serializableToRawControlGroupAttributes, getDefaultControlGroupPersistableInput, persistableControlGroupInputIsEqual, getDefaultControlGroupInput, + generateNewControlIds, } from './control_group/control_group_persistence'; export { diff --git a/src/plugins/controls/public/react_controls/control_group/components/control_group.tsx b/src/plugins/controls/public/react_controls/control_group/components/control_group.tsx index 4a2a4c802272d..c825e9021b48d 100644 --- a/src/plugins/controls/public/react_controls/control_group/components/control_group.tsx +++ b/src/plugins/controls/public/react_controls/control_group/components/control_group.tsx @@ -121,7 +121,6 @@ export function ControlGroup({ paddingSize="none" color={draggingId ? 'success' : 'transparent'} className="controlsWrapper" - data-test-subj="controls-group-wrapper" > & { controlsInOrder: ControlsInOrder; }; @@ -34,7 +38,6 @@ export function initializeControlGroupUnsavedChanges( children$: PresentationContainer['children$'], comparators: StateComparators, snapshotControlsRuntimeState: () => ControlPanelsState, - resetControlsUnsavedChanges: () => void, parentApi: unknown, lastSavedRuntimeState: ControlGroupRuntimeState ) { @@ -44,6 +47,7 @@ export function initializeControlGroupUnsavedChanges( chainingSystem: lastSavedRuntimeState.chainingSystem, controlsInOrder: getControlsInOrder(lastSavedRuntimeState.initialChildControlState), ignoreParentSettings: lastSavedRuntimeState.ignoreParentSettings, + initialChildControlState: lastSavedRuntimeState.initialChildControlState, labelPosition: lastSavedRuntimeState.labelPosition, }, parentApi, @@ -68,7 +72,6 @@ export function initializeControlGroupUnsavedChanges( ), asyncResetUnsavedChanges: async () => { controlGroupUnsavedChanges.api.resetUnsavedChanges(); - resetControlsUnsavedChanges(); const filtersReadyPromises: Array> = []; Object.values(children$.value).forEach((controlApi) => { diff --git a/src/plugins/controls/public/react_controls/control_group/get_control_group_factory.tsx b/src/plugins/controls/public/react_controls/control_group/get_control_group_factory.tsx index 2e6519b69343f..45802689e81a1 100644 --- a/src/plugins/controls/public/react_controls/control_group/get_control_group_factory.tsx +++ b/src/plugins/controls/public/react_controls/control_group/get_control_group_factory.tsx @@ -34,19 +34,12 @@ import { chaining$, controlFetch$, controlGroupFetch$ } from './control_fetch'; import { initControlsManager } from './init_controls_manager'; import { openEditControlGroupFlyout } from './open_edit_control_group_flyout'; import { deserializeControlGroup } from './serialization_utils'; -import { - ControlGroupApi, - ControlGroupRuntimeState, - ControlGroupSerializedState, - ControlPanelsState, -} from './types'; +import { ControlGroupApi, ControlGroupRuntimeState, ControlGroupSerializedState } from './types'; import { ControlGroup } from './components/control_group'; import { initSelectionsManager } from './selections_manager'; import { initializeControlGroupUnsavedChanges } from './control_group_unsaved_changes_api'; import { openDataControlEditor } from '../controls/data_controls/open_data_control_editor'; -const DEFAULT_CHAINING_SYSTEM = 'HIERARCHICAL'; - export const getControlGroupEmbeddableFactory = (services: { core: CoreStart; dataViews: DataViewsPublicPluginStart; @@ -67,6 +60,7 @@ export const getControlGroupEmbeddableFactory = (services: { lastSavedRuntimeState ) => { const { + initialChildControlState, labelPosition: initialLabelPosition, chainingSystem, autoApplySelections, @@ -74,22 +68,19 @@ export const getControlGroupEmbeddableFactory = (services: { } = initialRuntimeState; const autoApplySelections$ = new BehaviorSubject(autoApplySelections); - const defaultDataViewId = await services.dataViews.getDefaultId(); - const lastSavedControlsState$ = new BehaviorSubject( - lastSavedRuntimeState.initialChildControlState - ); + const parentDataViewId = apiPublishesDataViews(parentApi) + ? parentApi.dataViews.value?.[0]?.id + : undefined; const controlsManager = initControlsManager( - initialRuntimeState.initialChildControlState, - lastSavedControlsState$ + initialChildControlState, + parentDataViewId ?? (await services.dataViews.getDefaultId()) ); const selectionsManager = initSelectionsManager({ ...controlsManager.api, autoApplySelections$, }); const dataViews = new BehaviorSubject(undefined); - const chainingSystem$ = new BehaviorSubject( - chainingSystem ?? DEFAULT_CHAINING_SYSTEM - ); + const chainingSystem$ = new BehaviorSubject(chainingSystem); const ignoreParentSettings$ = new BehaviorSubject( ignoreParentSettings ); @@ -113,7 +104,6 @@ export const getControlGroupEmbeddableFactory = (services: { chainingSystem: [ chainingSystem$, (next: ControlGroupChainingSystem) => chainingSystem$.next(next), - (a, b) => (a ?? DEFAULT_CHAINING_SYSTEM) === (b ?? DEFAULT_CHAINING_SYSTEM), ], ignoreParentSettings: [ ignoreParentSettings$, @@ -123,7 +113,6 @@ export const getControlGroupEmbeddableFactory = (services: { labelPosition: [labelPosition$, (next: ControlStyle) => labelPosition$.next(next)], }, controlsManager.snapshotControlsRuntimeState, - controlsManager.resetControlsUnsavedChanges, parentApi, lastSavedRuntimeState ); @@ -170,28 +159,20 @@ export const getControlGroupEmbeddableFactory = (services: { i18n.translate('controls.controlGroup.displayName', { defaultMessage: 'Controls', }), - openAddDataControlFlyout: (options) => { - const parentDataViewId = apiPublishesDataViews(parentApi) - ? parentApi.dataViews.value?.[0]?.id - : undefined; - const newControlState = controlsManager.getNewControlState(); + openAddDataControlFlyout: (settings) => { + const { controlInputTransform } = settings ?? { + controlInputTransform: (state) => state, + }; openDataControlEditor({ - initialState: { - ...newControlState, - dataViewId: - newControlState.dataViewId ?? parentDataViewId ?? defaultDataViewId ?? undefined, - }, + initialState: controlsManager.getNewControlState(), onSave: ({ type: controlType, state: initialState }) => { controlsManager.api.addNewPanel({ panelType: controlType, - initialState: options?.controlInputTransform - ? options.controlInputTransform( - initialState as Partial, - controlType - ) - : initialState, + initialState: controlInputTransform!( + initialState as Partial, + controlType + ), }); - options?.onSave?.(); }, controlGroupApi: api, services, @@ -226,20 +207,6 @@ export const getControlGroupEmbeddableFactory = (services: { dataViews.next(newDataViews) ); - const saveNotificationSubscription = apiHasSaveNotification(parentApi) - ? parentApi.saveNotification$.subscribe(() => { - lastSavedControlsState$.next(controlsManager.snapshotControlsRuntimeState()); - - if ( - typeof autoApplySelections$.value === 'boolean' && - !autoApplySelections$.value && - selectionsManager.hasUnappliedSelections$.value - ) { - selectionsManager.applySelections(); - } - }) - : undefined; - /** Fetch the allowExpensiveQuries setting for the children to use if necessary */ try { const { allowExpensiveQueries } = await services.core.http.get<{ @@ -268,7 +235,6 @@ export const getControlGroupEmbeddableFactory = (services: { return () => { selectionsManager.cleanup(); childrenDataViewsSubscription.unsubscribe(); - saveNotificationSubscription?.unsubscribe(); }; }, []); diff --git a/src/plugins/controls/public/react_controls/control_group/init_controls_manager.test.ts b/src/plugins/controls/public/react_controls/control_group/init_controls_manager.test.ts index fc729478ec770..3e381123ecd9a 100644 --- a/src/plugins/controls/public/react_controls/control_group/init_controls_manager.test.ts +++ b/src/plugins/controls/public/react_controls/control_group/init_controls_manager.test.ts @@ -6,26 +6,27 @@ * Side Public License, v 1. */ -import { BehaviorSubject } from 'rxjs'; import { DefaultDataControlState } from '../controls/data_controls/types'; import { DefaultControlApi } from '../controls/types'; import { initControlsManager, getLastUsedDataViewId } from './init_controls_manager'; -import { ControlPanelState, ControlPanelsState } from './types'; +import { ControlPanelState } from './types'; jest.mock('uuid', () => ({ v4: jest.fn().mockReturnValue('delta'), })); -describe('PresentationContainer api', () => { - const intialControlsState = { - alpha: { type: 'testControl', order: 0 }, - bravo: { type: 'testControl', order: 1 }, - charlie: { type: 'testControl', order: 2 }, - }; - const lastSavedControlsState$ = new BehaviorSubject(intialControlsState); +const DEFAULT_DATA_VIEW_ID = 'myDataView'; +describe('PresentationContainer api', () => { test('addNewPanel should add control at end of controls', async () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 0 }, + bravo: { type: 'testControl', order: 1 }, + charlie: { type: 'testControl', order: 2 }, + }, + DEFAULT_DATA_VIEW_ID + ); const addNewPanelPromise = controlsManager.api.addNewPanel({ panelType: 'testControl', initialState: {}, @@ -41,7 +42,14 @@ describe('PresentationContainer api', () => { }); test('removePanel should remove control', () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 0 }, + bravo: { type: 'testControl', order: 1 }, + charlie: { type: 'testControl', order: 2 }, + }, + DEFAULT_DATA_VIEW_ID + ); controlsManager.api.removePanel('bravo'); expect(controlsManager.controlsInOrder$.value.map((element) => element.id)).toEqual([ 'alpha', @@ -50,7 +58,14 @@ describe('PresentationContainer api', () => { }); test('replacePanel should replace control', async () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 0 }, + bravo: { type: 'testControl', order: 1 }, + charlie: { type: 'testControl', order: 2 }, + }, + DEFAULT_DATA_VIEW_ID + ); const replacePanelPromise = controlsManager.api.replacePanel('bravo', { panelType: 'testControl', initialState: {}, @@ -66,7 +81,13 @@ describe('PresentationContainer api', () => { describe('untilInitialized', () => { test('should not resolve until all controls are initialized', async () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 0 }, + bravo: { type: 'testControl', order: 1 }, + }, + DEFAULT_DATA_VIEW_ID + ); let isDone = false; controlsManager.api.untilInitialized().then(() => { isDone = true; @@ -80,18 +101,19 @@ describe('PresentationContainer api', () => { controlsManager.setControlApi('bravo', {} as unknown as DefaultControlApi); await new Promise((resolve) => setTimeout(resolve, 0)); - expect(isDone).toBe(false); - - controlsManager.setControlApi('charlie', {} as unknown as DefaultControlApi); - await new Promise((resolve) => setTimeout(resolve, 0)); expect(isDone).toBe(true); }); test('should resolve when all control already initialized ', async () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 0 }, + bravo: { type: 'testControl', order: 1 }, + }, + DEFAULT_DATA_VIEW_ID + ); controlsManager.setControlApi('alpha', {} as unknown as DefaultControlApi); controlsManager.setControlApi('bravo', {} as unknown as DefaultControlApi); - controlsManager.setControlApi('charlie', {} as unknown as DefaultControlApi); let isDone = false; controlsManager.api.untilInitialized().then(() => { @@ -105,14 +127,14 @@ describe('PresentationContainer api', () => { }); describe('snapshotControlsRuntimeState', () => { - const intialControlsState = { - alpha: { type: 'testControl', order: 1 }, - bravo: { type: 'testControl', order: 0 }, - }; - const lastSavedControlsState$ = new BehaviorSubject(intialControlsState); - test('should snapshot runtime state for all controls', async () => { - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); + const controlsManager = initControlsManager( + { + alpha: { type: 'testControl', order: 1 }, + bravo: { type: 'testControl', order: 0 }, + }, + DEFAULT_DATA_VIEW_ID + ); controlsManager.setControlApi('alpha', { snapshotRuntimeState: () => { return { key1: 'alpha value' }; @@ -168,120 +190,28 @@ describe('getLastUsedDataViewId', () => { }); }); -describe('resetControlsUnsavedChanges', () => { - test(`should remove previous sessions's unsaved changes on reset`, () => { - // last session's unsaved changes added 1 control - const intialControlsState = { - alpha: { type: 'testControl', order: 0 }, - }; - // last saved state is empty control group - const lastSavedControlsState$ = new BehaviorSubject({}); - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); - controlsManager.setControlApi('alpha', {} as unknown as DefaultControlApi); - - expect(controlsManager.controlsInOrder$.value).toEqual([ - { - id: 'alpha', - type: 'testControl', - }, - ]); - - controlsManager.resetControlsUnsavedChanges(); - expect(controlsManager.controlsInOrder$.value).toEqual([]); - }); - - test('should restore deleted control on reset', () => { - const intialControlsState = { - alpha: { type: 'testControl', order: 0 }, - }; - const lastSavedControlsState$ = new BehaviorSubject(intialControlsState); - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); - controlsManager.setControlApi('alpha', {} as unknown as DefaultControlApi); - - // delete control - controlsManager.api.removePanel('alpha'); - - // deleted control should exist on reset - controlsManager.resetControlsUnsavedChanges(); - expect(controlsManager.controlsInOrder$.value).toEqual([ - { - id: 'alpha', - type: 'testControl', - }, - ]); - }); - - test('should restore controls to last saved state', () => { - const intialControlsState = {}; - const lastSavedControlsState$ = new BehaviorSubject(intialControlsState); - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); - - // add control - controlsManager.api.addNewPanel({ panelType: 'testControl' }); - controlsManager.setControlApi('delta', { - snapshotRuntimeState: () => { - return {}; - }, - } as unknown as DefaultControlApi); - - // simulate save - lastSavedControlsState$.next(controlsManager.snapshotControlsRuntimeState()); - - // saved control should exist on reset - controlsManager.resetControlsUnsavedChanges(); - expect(controlsManager.controlsInOrder$.value).toEqual([ - { - id: 'delta', - type: 'testControl', - }, - ]); - }); - - // Test edge case where adding a panel and resetting left orphaned control in children$ - test('should remove orphaned children on reset', () => { - // baseline last saved state contains a single control - const intialControlsState = { - alpha: { type: 'testControl', order: 0 }, - }; - const lastSavedControlsState$ = new BehaviorSubject(intialControlsState); - const controlsManager = initControlsManager(intialControlsState, lastSavedControlsState$); - controlsManager.setControlApi('alpha', {} as unknown as DefaultControlApi); - - // add another control - controlsManager.api.addNewPanel({ panelType: 'testControl' }); - controlsManager.setControlApi('delta', {} as unknown as DefaultControlApi); - expect(Object.keys(controlsManager.api.children$.value).length).toBe(2); - - // reset to lastSavedControlsState - controlsManager.resetControlsUnsavedChanges(); - // children$ should no longer contain control removed by resetting back to original control baseline - expect(Object.keys(controlsManager.api.children$.value).length).toBe(1); - }); -}); - describe('getNewControlState', () => { test('should contain defaults when there are no existing controls', () => { - const controlsManager = initControlsManager({}, new BehaviorSubject({})); + const controlsManager = initControlsManager({}, DEFAULT_DATA_VIEW_ID); expect(controlsManager.getNewControlState()).toEqual({ grow: true, width: 'medium', - dataViewId: undefined, + dataViewId: DEFAULT_DATA_VIEW_ID, }); }); test('should start with defaults if there are existing controls', () => { - const intialControlsState = { - alpha: { - type: 'testControl', - order: 1, - dataViewId: 'myOtherDataViewId', - width: 'small', - grow: false, - } as ControlPanelState & Pick, - }; const controlsManager = initControlsManager( - intialControlsState, - new BehaviorSubject(intialControlsState) + { + alpha: { + type: 'testControl', + order: 1, + dataViewId: 'myOtherDataViewId', + width: 'small', + grow: false, + } as ControlPanelState & Pick, + }, + DEFAULT_DATA_VIEW_ID ); expect(controlsManager.getNewControlState()).toEqual({ grow: true, @@ -291,7 +221,7 @@ describe('getNewControlState', () => { }); test('should contain values of last added control', () => { - const controlsManager = initControlsManager({}, new BehaviorSubject({})); + const controlsManager = initControlsManager({}, DEFAULT_DATA_VIEW_ID); controlsManager.api.addNewPanel({ panelType: 'testControl', initialState: { diff --git a/src/plugins/controls/public/react_controls/control_group/init_controls_manager.ts b/src/plugins/controls/public/react_controls/control_group/init_controls_manager.ts index aaa5d41e492ae..07b533f329631 100644 --- a/src/plugins/controls/public/react_controls/control_group/init_controls_manager.ts +++ b/src/plugins/controls/public/react_controls/control_group/init_controls_manager.ts @@ -38,25 +38,22 @@ export function getControlsInOrder(initialControlPanelsState: ControlPanelsState } export function initControlsManager( - /** - * Composed from last saved controls state and previous sessions's unsaved changes to controls state - */ - initialControlsState: ControlPanelsState, - /** - * Observable that publishes last saved controls state only - */ - lastSavedControlsState$: PublishingSubject + initialControlPanelsState: ControlPanelsState, + defaultDataViewId: string | null ) { - const initialControlIds = Object.keys(initialControlsState); + const lastSavedControlsPanelState$ = new BehaviorSubject(initialControlPanelsState); + const initialControlIds = Object.keys(initialControlPanelsState); const children$ = new BehaviorSubject<{ [key: string]: DefaultControlApi }>({}); - let currentControlsState: { [panelId: string]: DefaultControlState } = { - ...initialControlsState, + let controlsPanelState: { [panelId: string]: DefaultControlState } = { + ...initialControlPanelsState, }; const controlsInOrder$ = new BehaviorSubject( - getControlsInOrder(initialControlsState) + getControlsInOrder(initialControlPanelsState) ); const lastUsedDataViewId$ = new BehaviorSubject( - getLastUsedDataViewId(controlsInOrder$.value, initialControlsState) + getLastUsedDataViewId(controlsInOrder$.value, initialControlPanelsState) ?? + defaultDataViewId ?? + undefined ); const lastUsedWidth$ = new BehaviorSubject(DEFAULT_CONTROL_WIDTH); const lastUsedGrow$ = new BehaviorSubject(DEFAULT_CONTROL_GROW); @@ -111,12 +108,12 @@ export function initControlsManager( type: panelType, }); controlsInOrder$.next(nextControlsInOrder); - currentControlsState[id] = initialState ?? {}; + controlsPanelState[id] = initialState ?? {}; return await untilControlLoaded(id); } function removePanel(panelId: string) { - delete currentControlsState[panelId]; + delete controlsPanelState[panelId]; controlsInOrder$.next(controlsInOrder$.value.filter(({ id }) => id !== panelId)); children$.next(omit(children$.value, panelId)); } @@ -164,7 +161,7 @@ export function initControlsManager( type: controlApi.type, width, /** Re-add the `explicitInput` layer on serialize so control group saved object retains shape */ - explicitInput: { id, ...rest }, + explicitInput: rest, }; }); @@ -187,30 +184,9 @@ export function initControlsManager( }); return controlsRuntimeState; }, - resetControlsUnsavedChanges: () => { - currentControlsState = { - ...lastSavedControlsState$.value, - }; - const nextControlsInOrder = getControlsInOrder(currentControlsState as ControlPanelsState); - controlsInOrder$.next(nextControlsInOrder); - - const nextControlIds = nextControlsInOrder.map(({ id }) => id); - const children = { ...children$.value }; - let modifiedChildren = false; - Object.keys(children).forEach((controlId) => { - if (!nextControlIds.includes(controlId)) { - // remove children that no longer exist after reset - delete children[controlId]; - modifiedChildren = true; - } - }); - if (modifiedChildren) { - children$.next(children); - } - }, api: { getSerializedStateForChild: (childId: string) => { - const controlPanelState = currentControlsState[childId]; + const controlPanelState = controlsPanelState[childId]; return controlPanelState ? { rawState: controlPanelState } : undefined; }, children$: children$ as PublishingSubject<{ @@ -254,10 +230,26 @@ export function initControlsManager( comparators: { controlsInOrder: [ controlsInOrder$, - (next: ControlsInOrder) => {}, // setter does nothing, controlsInOrder$ reset by resetControlsRuntimeState + (next: ControlsInOrder) => controlsInOrder$.next(next), fastIsEqual, ], - } as StateComparators>, + // Control state differences tracked by controlApi comparators + // Control ordering differences tracked by controlsInOrder comparator + // initialChildControlState comparatator exists to reset controls manager to last saved state + initialChildControlState: [ + lastSavedControlsPanelState$, + (lastSavedControlPanelsState: ControlPanelsState) => { + lastSavedControlsPanelState$.next(lastSavedControlPanelsState); + controlsPanelState = { + ...lastSavedControlPanelsState, + }; + controlsInOrder$.next(getControlsInOrder(lastSavedControlPanelsState)); + }, + () => true, + ], + } as StateComparators< + Pick + >, }; } diff --git a/src/plugins/controls/public/react_controls/control_group/open_edit_control_group_flyout.tsx b/src/plugins/controls/public/react_controls/control_group/open_edit_control_group_flyout.tsx index 98784f826090b..c636d37ade6b2 100644 --- a/src/plugins/controls/public/react_controls/control_group/open_edit_control_group_flyout.tsx +++ b/src/plugins/controls/public/react_controls/control_group/open_edit_control_group_flyout.tsx @@ -72,7 +72,7 @@ export const openEditControlGroupFlyout = ( Object.keys(controlGroupApi.children$.getValue()).forEach((childId) => { controlGroupApi.removePanel(childId); }); - closeOverlay(ref); + ref.close(); }); }; diff --git a/src/plugins/controls/public/react_controls/control_group/serialization_utils.ts b/src/plugins/controls/public/react_controls/control_group/serialization_utils.ts index 031dababa5ca1..eb3706c3913a1 100644 --- a/src/plugins/controls/public/react_controls/control_group/serialization_utils.ts +++ b/src/plugins/controls/public/react_controls/control_group/serialization_utils.ts @@ -9,7 +9,6 @@ import { SerializedPanelState } from '@kbn/presentation-containers'; import { omit } from 'lodash'; import { ControlGroupRuntimeState, ControlGroupSerializedState } from './types'; -import { parseReferenceName } from '../controls/data_controls/reference_name_utils'; export const deserializeControlGroup = ( state: SerializedPanelState @@ -21,9 +20,9 @@ export const deserializeControlGroup = ( const references = state.references ?? []; references.forEach((reference) => { const referenceName = reference.name; - const { controlId } = parseReferenceName(referenceName); - if (panels[controlId]) { - panels[controlId].dataViewId = reference.id; + const panelId = referenceName.substring('controlGroup_'.length, referenceName.lastIndexOf(':')); + if (panels[panelId]) { + panels[panelId].dataViewId = reference.id; } }); diff --git a/src/plugins/controls/public/react_controls/control_group/types.ts b/src/plugins/controls/public/react_controls/control_group/types.ts index 826a5fde393b1..d009712e52a5b 100644 --- a/src/plugins/controls/public/react_controls/control_group/types.ts +++ b/src/plugins/controls/public/react_controls/control_group/types.ts @@ -65,9 +65,8 @@ export type ControlGroupApi = PresentationContainer & ignoreParentSettings$: PublishingSubject; allowExpensiveQueries$: PublishingSubject; untilInitialized: () => Promise; - openAddDataControlFlyout: (options?: { + openAddDataControlFlyout: (settings?: { controlInputTransform?: ControlInputTransform; - onSave?: () => void; }) => void; labelPosition: PublishingSubject; }; diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.test.tsx b/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.test.tsx index 5baca7edfdaab..5dd6bf745feca 100644 --- a/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.test.tsx +++ b/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.test.tsx @@ -51,7 +51,6 @@ describe('initializeDataControl', () => { dataControl = initializeDataControl( 'myControlId', 'myControlType', - 'referenceNameSuffix', dataControlState, editorStateManager, controlGroupApi, @@ -83,7 +82,6 @@ describe('initializeDataControl', () => { dataControl = initializeDataControl( 'myControlId', 'myControlType', - 'referenceNameSuffix', { ...dataControlState, dataViewId: 'notGonnaFindMeDataViewId', @@ -122,7 +120,6 @@ describe('initializeDataControl', () => { dataControl = initializeDataControl( 'myControlId', 'myControlType', - 'referenceNameSuffix', { ...dataControlState, fieldName: 'notGonnaFindMeFieldName', diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.ts b/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.ts index d3b90e72bb7fa..312701dd22c32 100644 --- a/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.ts +++ b/src/plugins/controls/public/react_controls/controls/data_controls/initialize_data_control.ts @@ -26,12 +26,10 @@ import { initializeDefaultControlApi } from '../initialize_default_control_api'; import { ControlApiInitialization, ControlStateManager, DefaultControlState } from '../types'; import { openDataControlEditor } from './open_data_control_editor'; import { DataControlApi, DataControlFieldFormatter, DefaultDataControlState } from './types'; -import { getReferenceName } from './reference_name_utils'; export const initializeDataControl = ( controlId: string, controlType: string, - referenceNameSuffix: string, state: DefaultDataControlState, /** * `This state manager` should only include the state that the data control editor is @@ -244,7 +242,7 @@ export const initializeDataControl = ( }, references: [ { - name: getReferenceName(controlId, referenceNameSuffix), + name: `controlGroup_${controlId}:${controlType}DataView`, type: DATA_VIEW_SAVED_OBJECT_TYPE, id: dataViewId.getValue(), }, diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/components/options_list_popover_suggestions.tsx b/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/components/options_list_popover_suggestions.tsx index 4cf010f0473aa..2fa364a4c3ecf 100644 --- a/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/components/options_list_popover_suggestions.tsx +++ b/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/components/options_list_popover_suggestions.tsx @@ -155,7 +155,7 @@ export const OptionsListPopoverSuggestions = ({ }, [api.loadMoreSubject, stateManager.requestSize, totalCardinality]); const renderOption = useCallback( - (option, searchStringValue) => { + (option: EuiSelectableOption, searchStringValue: string) => { if (!allowExpensiveQueries || searchTechnique === 'exact') return option.label; return ( diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/get_options_list_control_factory.tsx b/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/get_options_list_control_factory.tsx index 4a16fcfe29b31..12d0de5a3d7d3 100644 --- a/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/get_options_list_control_factory.tsx +++ b/src/plugins/controls/public/react_controls/controls/data_controls/options_list_control/get_options_list_control_factory.tsx @@ -8,7 +8,6 @@ import React, { useEffect } from 'react'; import { BehaviorSubject, combineLatest, debounceTime, filter, skip } from 'rxjs'; -import fastIsEqual from 'fast-deep-equal'; import { buildExistsFilter, buildPhraseFilter, buildPhrasesFilter, Filter } from '@kbn/es-query'; import { useBatchedPublishingSubjects } from '@kbn/presentation-publishing'; @@ -88,7 +87,6 @@ export const getOptionsListControlFactory = ( >( uuid, OPTIONS_LIST_CONTROL, - 'optionsListDataView', initialState, { searchTechnique: searchTechnique$, singleSelect: singleSelect$ }, controlGroupApi, @@ -245,7 +243,7 @@ export const getOptionsListControlFactory = ( searchTechnique: searchTechnique$.getValue(), runPastTimeout: runPastTimeout$.getValue(), singleSelect: singleSelect$.getValue(), - selectedOptions: selections.selectedOptions$.getValue(), + selections: selections.selectedOptions$.getValue(), sort: sort$.getValue(), existsSelected: selections.existsSelected$.getValue(), exclude: selections.exclude$.getValue(), @@ -279,7 +277,7 @@ export const getOptionsListControlFactory = ( sort: [ sort$, (sort) => sort$.next(sort), - (a, b) => fastIsEqual(a ?? OPTIONS_LIST_DEFAULT_SORT, b ?? OPTIONS_LIST_DEFAULT_SORT), + (a, b) => (a ?? OPTIONS_LIST_DEFAULT_SORT) === (b ?? OPTIONS_LIST_DEFAULT_SORT), ], /** This state cannot currently be changed after the control is created */ diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/range_slider/get_range_slider_control_factory.tsx b/src/plugins/controls/public/react_controls/controls/data_controls/range_slider/get_range_slider_control_factory.tsx index 88f0497ac5cba..a2819460d05c9 100644 --- a/src/plugins/controls/public/react_controls/controls/data_controls/range_slider/get_range_slider_control_factory.tsx +++ b/src/plugins/controls/public/react_controls/controls/data_controls/range_slider/get_range_slider_control_factory.tsx @@ -63,7 +63,6 @@ export const getRangesliderControlFactory = ( const dataControl = initializeDataControl>( uuid, RANGE_SLIDER_CONTROL, - 'rangeSliderDataView', initialState, { step: step$, @@ -159,8 +158,8 @@ export const getRangesliderControlFactory = ( if (error) { dataControl.api.setBlockingError(error); } - max$.next(max !== undefined ? Math.ceil(max) : undefined); - min$.next(min !== undefined ? Math.floor(min) : undefined); + max$.next(max); + min$.next(min); } ); diff --git a/src/plugins/controls/public/react_controls/controls/data_controls/reference_name_utils.ts b/src/plugins/controls/public/react_controls/controls/data_controls/reference_name_utils.ts deleted file mode 100644 index 1a8a1e65f72de..0000000000000 --- a/src/plugins/controls/public/react_controls/controls/data_controls/reference_name_utils.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 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 or the Server - * Side Public License, v 1. - */ - -const REFERENCE_NAME_PREFIX = 'controlGroup_'; - -export function getReferenceName(controlId: string, referenceNameSuffix: string) { - return `${REFERENCE_NAME_PREFIX}${controlId}:${referenceNameSuffix}`; -} - -export function parseReferenceName(referenceName: string) { - return { - controlId: referenceName.substring( - REFERENCE_NAME_PREFIX.length, - referenceName.lastIndexOf(':') - ), - }; -} diff --git a/src/plugins/controls/public/react_controls/controls/timeslider_control/get_timeslider_control_factory.tsx b/src/plugins/controls/public/react_controls/controls/timeslider_control/get_timeslider_control_factory.tsx index ef8ea463a9f63..f3d1b43de8fa2 100644 --- a/src/plugins/controls/public/react_controls/controls/timeslider_control/get_timeslider_control_factory.tsx +++ b/src/plugins/controls/public/react_controls/controls/timeslider_control/get_timeslider_control_factory.tsx @@ -35,17 +35,16 @@ import './components/index.scss'; import { TimeSliderPrepend } from './components/time_slider_prepend'; import { TIME_SLIDER_CONTROL } from '../../../../common'; -const displayName = i18n.translate('controls.timesliderControl.displayName', { - defaultMessage: 'Time slider', -}); - export const getTimesliderControlFactory = ( services: Services ): ControlFactory => { return { type: TIME_SLIDER_CONTROL, getIconType: () => 'search', - getDisplayName: () => displayName, + getDisplayName: () => + i18n.translate('controls.timesliderControl.displayName', { + defaultMessage: 'Time slider', + }), buildControl: async (initialState, buildApi, uuid, controlGroupApi) => { const { timeRangeMeta$, formatDate, cleanupTimeRangeSubscription } = initTimeRangeSubscription(controlGroupApi, services); @@ -204,7 +203,6 @@ export const getTimesliderControlFactory = ( const api = buildApi( { ...defaultControl.api, - defaultPanelTitle: new BehaviorSubject(displayName), timeslice$, serializeState: () => { const { rawState: defaultControlState } = defaultControl.serialize(); diff --git a/src/plugins/controls/public/react_controls/controls/timeslider_control/types.ts b/src/plugins/controls/public/react_controls/controls/timeslider_control/types.ts index d7c837732cce4..bc5fcd67829c2 100644 --- a/src/plugins/controls/public/react_controls/controls/timeslider_control/types.ts +++ b/src/plugins/controls/public/react_controls/controls/timeslider_control/types.ts @@ -8,7 +8,7 @@ import { CoreStart } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { PublishesPanelTitle, PublishesTimeslice } from '@kbn/presentation-publishing'; +import type { PublishesTimeslice } from '@kbn/presentation-publishing'; import type { DefaultControlApi, DefaultControlState } from '../types'; export type Timeslice = [number, number]; @@ -20,9 +20,7 @@ export interface TimesliderControlState extends DefaultControlState { timesliceEndAsPercentageOfTimeRange?: number; } -export type TimesliderControlApi = DefaultControlApi & - Pick & - PublishesTimeslice; +export type TimesliderControlApi = DefaultControlApi & PublishesTimeslice; export interface Services { core: CoreStart; diff --git a/src/plugins/dashboard/common/dashboard_container/persistable_state/dashboard_container_references.ts b/src/plugins/dashboard/common/dashboard_container/persistable_state/dashboard_container_references.ts index 169af0ca27da4..f1f6efb0d6678 100644 --- a/src/plugins/dashboard/common/dashboard_container/persistable_state/dashboard_container_references.ts +++ b/src/plugins/dashboard/common/dashboard_container/persistable_state/dashboard_container_references.ts @@ -7,6 +7,7 @@ */ import type { Reference } from '@kbn/content-management-utils'; +import { CONTROL_GROUP_TYPE, PersistableControlGroupInput } from '@kbn/controls-plugin/common'; import { EmbeddableInput, EmbeddablePersistableStateService, @@ -22,10 +23,6 @@ export const getReferencesForPanelId = (id: string, references: Reference[]): Re return filteredReferences; }; -export const getReferencesForControls = (references: Reference[]): Reference[] => { - return references.filter((reference) => reference.name.startsWith(controlGroupReferencePrefix)); -}; - export const prefixReferencesFromPanel = (id: string, references: Reference[]): Reference[] => { const prefix = `${id}:`; return references @@ -37,6 +34,7 @@ export const prefixReferencesFromPanel = (id: string, references: Reference[]): }; const controlGroupReferencePrefix = 'controlGroup_'; +const controlGroupId = 'dashboard_control_group'; export const createInject = ( persistableStateService: EmbeddablePersistableStateService @@ -92,6 +90,27 @@ export const createInject = ( } } + // since the controlGroup is not part of the panels array, its references need to be injected separately + if ('controlGroupInput' in workingState && workingState.controlGroupInput) { + const controlGroupReferences = references + .filter((reference) => reference.name.indexOf(controlGroupReferencePrefix) === 0) + .map((reference) => ({ + ...reference, + name: reference.name.replace(controlGroupReferencePrefix, ''), + })); + + const { type, ...injectedControlGroupState } = persistableStateService.inject( + { + ...workingState.controlGroupInput, + type: CONTROL_GROUP_TYPE, + id: controlGroupId, + }, + controlGroupReferences + ); + workingState.controlGroupInput = + injectedControlGroupState as unknown as PersistableControlGroupInput; + } + return workingState as EmbeddableStateWithType; }; }; @@ -141,6 +160,23 @@ export const createExtract = ( } } + // since the controlGroup is not part of the panels array, its references need to be extracted separately + if ('controlGroupInput' in workingState && workingState.controlGroupInput) { + const { state: extractedControlGroupState, references: controlGroupReferences } = + persistableStateService.extract({ + ...workingState.controlGroupInput, + type: CONTROL_GROUP_TYPE, + id: controlGroupId, + }); + workingState.controlGroupInput = + extractedControlGroupState as unknown as PersistableControlGroupInput; + const prefixedControlGroupReferences = controlGroupReferences.map((reference) => ({ + ...reference, + name: `${controlGroupReferencePrefix}${reference.name}`, + })); + references.push(...prefixedControlGroupReferences); + } + return { state: workingState as EmbeddableStateWithType, references }; }; }; diff --git a/src/plugins/dashboard/common/dashboard_saved_object/persistable_state/dashboard_saved_object_references.ts b/src/plugins/dashboard/common/dashboard_saved_object/persistable_state/dashboard_saved_object_references.ts index d6a852807bea3..94e8582ebecae 100644 --- a/src/plugins/dashboard/common/dashboard_saved_object/persistable_state/dashboard_saved_object_references.ts +++ b/src/plugins/dashboard/common/dashboard_saved_object/persistable_state/dashboard_saved_object_references.ts @@ -8,6 +8,7 @@ import type { Reference } from '@kbn/content-management-utils'; import { EmbeddablePersistableStateService } from '@kbn/embeddable-plugin/common/types'; +import { rawControlGroupAttributesToControlGroupInput } from '@kbn/controls-plugin/common'; import { convertPanelMapToSavedPanels, @@ -32,6 +33,9 @@ function parseDashboardAttributesWithType( } return { + controlGroupInput: + attributes.controlGroupInput && + rawControlGroupAttributesToControlGroupInput(attributes.controlGroupInput), type: 'dashboard', panels: convertSavedPanelsToPanelMap(parsedPanels), } as ParsedDashboardAttributesWithType; @@ -55,6 +59,13 @@ export function injectReferences( panelsJSON: JSON.stringify(injectedPanels), } as DashboardAttributes; + if (attributes.controlGroupInput && injectedState.controlGroupInput) { + newAttributes.controlGroupInput = { + ...attributes.controlGroupInput, + panelsJSON: JSON.stringify(injectedState.controlGroupInput.panels), + }; + } + return newAttributes; } @@ -85,6 +96,13 @@ export function extractReferences( panelsJSON: JSON.stringify(extractedPanels), } as DashboardAttributes; + if (attributes.controlGroupInput && extractedState.controlGroupInput) { + newAttributes.controlGroupInput = { + ...attributes.controlGroupInput, + panelsJSON: JSON.stringify(extractedState.controlGroupInput.panels), + }; + } + return { references: [...references, ...extractedReferences], attributes: newAttributes, diff --git a/src/plugins/dashboard/common/types.ts b/src/plugins/dashboard/common/types.ts index fd434085b397b..b5492d62ea220 100644 --- a/src/plugins/dashboard/common/types.ts +++ b/src/plugins/dashboard/common/types.ts @@ -8,6 +8,8 @@ import type { Reference } from '@kbn/content-management-utils'; import { EmbeddableStateWithType } from '@kbn/embeddable-plugin/common'; +import { PersistableControlGroupInput } from '@kbn/controls-plugin/common'; + import { DashboardAttributes, SavedDashboardPanel } from './content_management'; import { DashboardContainerInput, DashboardPanelMap } from './dashboard_container/types'; @@ -38,6 +40,7 @@ export type SharedDashboardState = Partial< * A partially parsed version of the Dashboard Attributes used for inject and extract logic for both the Dashboard Container and the Dashboard Saved Object. */ export type ParsedDashboardAttributesWithType = EmbeddableStateWithType & { + controlGroupInput?: PersistableControlGroupInput; panels: DashboardPanelMap; type: 'dashboard'; }; diff --git a/src/plugins/dashboard/public/dashboard_app/locator/locator.test.ts b/src/plugins/dashboard/public/dashboard_app/locator/locator.test.ts index fd2f64828899f..2b56acc719158 100644 --- a/src/plugins/dashboard/public/dashboard_app/locator/locator.test.ts +++ b/src/plugins/dashboard/public/dashboard_app/locator/locator.test.ts @@ -9,7 +9,9 @@ import { DashboardAppLocatorDefinition } from './locator'; import { hashedItemStore } from '@kbn/kibana-utils-plugin/public'; import { mockStorage } from '@kbn/kibana-utils-plugin/public/storage/hashed_item_store/mock'; +import { mockControlGroupInput } from '@kbn/controls-plugin/common/mocks'; import { FilterStateStore } from '@kbn/es-query'; +import { SerializableControlGroupInput } from '@kbn/controls-plugin/common'; describe('dashboard locator', () => { beforeEach(() => { @@ -191,18 +193,16 @@ describe('dashboard locator', () => { useHashedUrl: false, getDashboardFilterFields: async (dashboardId: string) => [], }); - const controlGroupState = { - autoApplySelections: false, - }; + const controlGroupInput = mockControlGroupInput() as unknown as SerializableControlGroupInput; const location = await definition.getLocation({ - controlGroupState, + controlGroupInput, }); expect(location).toMatchObject({ app: 'dashboards', path: `#/create?_g=()`, state: { - controlGroupState, + controlGroupInput, }, }); }); diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/add_new_panel/dashboard_panel_selection_flyout.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/add_new_panel/dashboard_panel_selection_flyout.tsx index bb23fd6798b11..1fd99fed54c03 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/add_new_panel/dashboard_panel_selection_flyout.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/add_new_panel/dashboard_panel_selection_flyout.tsx @@ -186,9 +186,13 @@ export const DashboardPanelSelectionListFlyout: React.FC< > {panelsSearchResult?.some(({ isDisabled }) => !isDisabled) ? ( panelsSearchResult.map( - ({ id, title, items, isDisabled, ['data-test-subj']: dataTestSubj }) => + ({ id, title, items, isDisabled, ['data-test-subj']: dataTestSubj, order }) => !isDisabled ? ( - + {typeof title === 'string' ?

{title}

: title}
diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_data_control_button.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_data_control_button.tsx index b96f450e19bdc..e7c7daa2bcc27 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_data_control_button.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_data_control_button.tsx @@ -8,16 +8,16 @@ import React from 'react'; import { EuiContextMenuItem } from '@elastic/eui'; -import { ControlGroupApi } from '@kbn/controls-plugin/public'; +import { ControlGroupContainer } from '@kbn/controls-plugin/public'; import { getAddControlButtonTitle } from '../../_dashboard_app_strings'; import { useDashboardAPI } from '../../dashboard_app'; interface Props { closePopover: () => void; - controlGroupApi?: ControlGroupApi; + controlGroup: ControlGroupContainer; } -export const AddDataControlButton = ({ closePopover, controlGroupApi, ...rest }: Props) => { +export const AddDataControlButton = ({ closePopover, controlGroup, ...rest }: Props) => { const dashboard = useDashboardAPI(); const onSave = () => { dashboard.scrollToTop(); @@ -28,10 +28,9 @@ export const AddDataControlButton = ({ closePopover, controlGroupApi, ...rest }: {...rest} icon="plusInCircle" data-test-subj="controls-create-button" - disabled={!controlGroupApi} aria-label={getAddControlButtonTitle()} onClick={() => { - controlGroupApi?.openAddDataControlFlyout({ onSave }); + controlGroup.openAddDataControlFlyout({ onSave }); closePopover(); }} > diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_time_slider_control_button.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_time_slider_control_button.tsx index 9cb9b1b82f9da..a3a9cf7ce73d8 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_time_slider_control_button.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/add_time_slider_control_button.tsx @@ -7,12 +7,8 @@ */ import React, { useEffect, useState } from 'react'; -import { v4 as uuidv4 } from 'uuid'; import { EuiContextMenuItem } from '@elastic/eui'; -import type { ControlGroupApi } from '@kbn/controls-plugin/public'; -import { TIME_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; - -import { apiHasType } from '@kbn/presentation-publishing'; +import { ControlGroupContainer, TIME_SLIDER_CONTROL } from '@kbn/controls-plugin/public'; import { getAddTimeSliderControlButtonTitle, getOnlyOneTimeSliderControlMsg, @@ -21,47 +17,40 @@ import { useDashboardAPI } from '../../dashboard_app'; interface Props { closePopover: () => void; - controlGroupApi?: ControlGroupApi; + controlGroup: ControlGroupContainer; } -export const AddTimeSliderControlButton = ({ closePopover, controlGroupApi, ...rest }: Props) => { +export const AddTimeSliderControlButton = ({ closePopover, controlGroup, ...rest }: Props) => { const [hasTimeSliderControl, setHasTimeSliderControl] = useState(false); const dashboard = useDashboardAPI(); useEffect(() => { - if (!controlGroupApi) { - return; - } - - const subscription = controlGroupApi.children$.subscribe((children) => { - const nextHasTimeSliderControl = Object.values(children).some((controlApi) => { - return apiHasType(controlApi) && controlApi.type === TIME_SLIDER_CONTROL; + const subscription = controlGroup.getInput$().subscribe(() => { + const childIds = controlGroup.getChildIds(); + const nextHasTimeSliderControl = childIds.some((id: string) => { + const child = controlGroup.getChild(id); + return child.type === TIME_SLIDER_CONTROL; }); - setHasTimeSliderControl(nextHasTimeSliderControl); + if (nextHasTimeSliderControl !== hasTimeSliderControl) { + setHasTimeSliderControl(nextHasTimeSliderControl); + } }); return () => { subscription.unsubscribe(); }; - }, [controlGroupApi]); + }, [controlGroup, hasTimeSliderControl, setHasTimeSliderControl]); return ( { - controlGroupApi?.addNewPanel({ - panelType: TIME_SLIDER_CONTROL, - initialState: { - grow: true, - width: 'large', - id: uuidv4(), - }, - }); + await controlGroup.addTimeSliderControl(); dashboard.scrollToTop(); closePopover(); }} data-test-subj="controls-create-timeslider-button" - disabled={!controlGroupApi || hasTimeSliderControl} + disabled={hasTimeSliderControl} toolTipContent={hasTimeSliderControl ? getOnlyOneTimeSliderControlMsg() : null} > {getAddTimeSliderControlButtonTitle()} diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx index 6c6459266f7c3..ba90513a44c1d 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx @@ -10,18 +10,18 @@ import React from 'react'; import { EuiContextMenuPanel, useEuiTheme } from '@elastic/eui'; import { ToolbarPopover } from '@kbn/shared-ux-button-toolbar'; +import type { ControlGroupContainer } from '@kbn/controls-plugin/public'; -import { ControlGroupApi } from '@kbn/controls-plugin/public'; import { getControlButtonTitle } from '../../_dashboard_app_strings'; import { AddDataControlButton } from './add_data_control_button'; import { AddTimeSliderControlButton } from './add_time_slider_control_button'; import { EditControlGroupButton } from './edit_control_group_button'; export function ControlsToolbarButton({ - controlGroupApi, + controlGroup, isDisabled, }: { - controlGroupApi?: ControlGroupApi; + controlGroup: ControlGroupContainer; isDisabled?: boolean; }) { const { euiTheme } = useEuiTheme(); @@ -43,17 +43,17 @@ export function ControlsToolbarButton({ items={[ , , , ]} diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/edit_control_group_button.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/edit_control_group_button.tsx index 5f093b2967d39..3563d87f5cf81 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/edit_control_group_button.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/edit_control_group_button.tsx @@ -8,24 +8,23 @@ import React from 'react'; import { EuiContextMenuItem } from '@elastic/eui'; -import { ControlGroupApi } from '@kbn/controls-plugin/public'; +import { ControlGroupContainer } from '@kbn/controls-plugin/public'; import { getEditControlGroupButtonTitle } from '../../_dashboard_app_strings'; interface Props { closePopover: () => void; - controlGroupApi?: ControlGroupApi; + controlGroup: ControlGroupContainer; } -export const EditControlGroupButton = ({ closePopover, controlGroupApi, ...rest }: Props) => { +export const EditControlGroupButton = ({ closePopover, controlGroup, ...rest }: Props) => { return ( { - controlGroupApi?.onEdit(); + controlGroup.openEditControlGroupFlyout(); closePopover(); }} > diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx index 17d8ced554948..579d6d17d3a94 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx @@ -13,7 +13,6 @@ import { useEuiTheme } from '@elastic/eui'; import { AddFromLibraryButton, Toolbar, ToolbarButton } from '@kbn/shared-ux-button-toolbar'; import { BaseVisType, VisTypeAlias } from '@kbn/visualizations-plugin/public'; -import { useStateFromPublishingSubject } from '@kbn/presentation-publishing'; import { getCreateVisualizationButtonTitle } from '../_dashboard_app_strings'; import { EditorMenu } from './editor_menu'; import { useDashboardAPI } from '../dashboard_app'; @@ -83,7 +82,6 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean } * dismissNotification: Optional, if not passed a toast will appear in the dashboard */ - const controlGroupApi = useStateFromPublishingSubject(dashboard.controlGroupApi$); const extraButtons = [ , , - , ]; + if (dashboard.controlGroup) { + extraButtons.push( + + ); + } return (
void; showResetChange?: boolean; }) => { - const isMounted = useMountedState(); - const [isSaveInProgress, setIsSaveInProgress] = useState(false); /** @@ -102,7 +99,6 @@ export const useDashboardMenuItems = ({ * (1) reset the dashboard to the last saved state, and * (2) if `switchToViewMode` is `true`, set the dashboard to view mode. */ - const [isResetting, setIsResetting] = useState(false); const resetChanges = useCallback( (switchToViewMode: boolean = false) => { dashboard.clearOverlays(); @@ -117,17 +113,13 @@ export const useDashboardMenuItems = ({ return; } confirmDiscardUnsavedChanges(() => { - batch(async () => { - setIsResetting(true); - await dashboard.asyncResetToLastSavedState(); - if (isMounted()) { - setIsResetting(false); - switchModes?.(); - } + batch(() => { + dashboard.resetToLastSavedState(); + switchModes?.(); }); }, viewMode); }, - [dashboard, dashboardBackup, hasUnsavedChanges, viewMode, isMounted] + [dashboard, dashboardBackup, hasUnsavedChanges, viewMode] ); /** @@ -198,8 +190,7 @@ export const useDashboardMenuItems = ({ switchToViewMode: { ...topNavStrings.switchToViewMode, id: 'cancel', - disableButton: disableTopNav || !lastSavedId || isResetting, - isLoading: isResetting, + disableButton: disableTopNav || !lastSavedId, testId: 'dashboardViewOnlyMode', run: () => resetChanges(true), } as TopNavMenuData, @@ -235,7 +226,6 @@ export const useDashboardMenuItems = ({ dashboardBackup, quickSaveDashboard, resetChanges, - isResetting, ]); const resetChangesMenuItem = useMemo(() => { @@ -244,22 +234,12 @@ export const useDashboardMenuItems = ({ id: 'reset', testId: 'dashboardDiscardChangesMenuItem', disableButton: - isResetting || !hasUnsavedChanges || hasOverlays || (viewMode === ViewMode.EDIT && (isSaveInProgress || !lastSavedId)), - isLoading: isResetting, run: () => resetChanges(), }; - }, [ - hasOverlays, - lastSavedId, - resetChanges, - viewMode, - isSaveInProgress, - hasUnsavedChanges, - isResetting, - ]); + }, [hasOverlays, lastSavedId, resetChanges, viewMode, isSaveInProgress, hasUnsavedChanges]); /** * Build ordered menus for view and edit mode. diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx index 91fa453e7c5f9..93f25962a0916 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx @@ -44,7 +44,7 @@ jest.mock('./dashboard_grid_item', () => { }; }); -const createAndMountDashboardGrid = async () => { +const createAndMountDashboardGrid = () => { const dashboardContainer = buildMockDashboard({ overrides: { panels: { @@ -61,7 +61,6 @@ const createAndMountDashboardGrid = async () => { }, }, }); - await dashboardContainer.untilContainerInitialized(); const component = mountWithIntl( @@ -71,20 +70,20 @@ const createAndMountDashboardGrid = async () => { }; test('renders DashboardGrid', async () => { - const { component } = await createAndMountDashboardGrid(); + const { component } = createAndMountDashboardGrid(); const panelElements = component.find('GridItem'); expect(panelElements.length).toBe(2); }); test('renders DashboardGrid with no visualizations', async () => { - const { dashboardContainer, component } = await createAndMountDashboardGrid(); + const { dashboardContainer, component } = createAndMountDashboardGrid(); dashboardContainer.updateInput({ panels: {} }); component.update(); expect(component.find('GridItem').length).toBe(0); }); test('DashboardGrid removes panel when removed from container', async () => { - const { dashboardContainer, component } = await createAndMountDashboardGrid(); + const { dashboardContainer, component } = createAndMountDashboardGrid(); const originalPanels = dashboardContainer.getInput().panels; const filteredPanels = { ...originalPanels }; delete filteredPanels['1']; @@ -95,7 +94,7 @@ test('DashboardGrid removes panel when removed from container', async () => { }); test('DashboardGrid renders expanded panel', async () => { - const { dashboardContainer, component } = await createAndMountDashboardGrid(); + const { dashboardContainer, component } = createAndMountDashboardGrid(); dashboardContainer.setExpandedPanelId('1'); component.update(); // Both panels should still exist in the dom, so nothing needs to be re-fetched once minimized. @@ -113,7 +112,7 @@ test('DashboardGrid renders expanded panel', async () => { }); test('DashboardGrid renders focused panel', async () => { - const { dashboardContainer, component } = await createAndMountDashboardGrid(); + const { dashboardContainer, component } = createAndMountDashboardGrid(); dashboardContainer.setFocusedPanelId('2'); component.update(); // Both panels should still exist in the dom, so nothing needs to be re-fetched once minimized. diff --git a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx index a3ffb5bfcdd38..cc0397a5af1e3 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx @@ -9,19 +9,12 @@ import { debounce } from 'lodash'; import classNames from 'classnames'; import useResizeObserver from 'use-resize-observer/polyfilled'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { EuiPortal } from '@elastic/eui'; -import { ReactEmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public'; +import { ViewMode } from '@kbn/embeddable-plugin/public'; import { ExitFullScreenButton } from '@kbn/shared-ux-button-exit-full-screen'; -import { - ControlGroupApi, - ControlGroupRuntimeState, - ControlGroupSerializedState, -} from '@kbn/controls-plugin/public'; -import { CONTROL_GROUP_TYPE } from '@kbn/controls-plugin/common'; -import { useStateFromPublishingSubject } from '@kbn/presentation-publishing'; import { DashboardGrid } from '../grid'; import { useDashboardContainer } from '../../embeddable/dashboard_container'; import { DashboardEmptyScreen } from '../empty_screen/dashboard_empty_screen'; @@ -41,11 +34,23 @@ export const useDebouncedWidthObserver = (skipDebounce = false, wait = 100) => { }; export const DashboardViewportComponent = () => { + const controlsRoot = useRef(null); + const dashboard = useDashboardContainer(); - const controlGroupApi = useStateFromPublishingSubject(dashboard.controlGroupApi$); + /** + * Render Control group + */ + const controlGroup = dashboard.controlGroup; + useEffect(() => { + if (controlGroup && controlsRoot.current) controlGroup.render(controlsRoot.current); + }, [controlGroup]); + const panelCount = Object.keys(dashboard.select((state) => state.explicitInput.panels)).length; - const [hasControls, setHasControls] = useState(false); + const controlCount = Object.keys( + controlGroup?.select((state) => state.explicitInput.panels) ?? {} + ).length; + const viewMode = dashboard.select((state) => state.explicitInput.viewMode); const dashboardTitle = dashboard.select((state) => state.explicitInput.title); const useMargins = dashboard.select((state) => state.explicitInput.useMargins); @@ -60,59 +65,17 @@ export const DashboardViewportComponent = () => { 'dshDashboardViewport--panelExpanded': Boolean(expandedPanelId), }); - useEffect(() => { - if (!controlGroupApi) { - return; - } - const subscription = controlGroupApi.children$.subscribe((children) => { - setHasControls(Object.keys(children).length > 0); - }); - return () => { - subscription.unsubscribe(); - }; - }, [controlGroupApi]); - - const [dashboardInitialized, setDashboardInitialized] = useState(false); - useEffect(() => { - let ignore = false; - dashboard.untilContainerInitialized().then(() => { - if (!ignore) { - setDashboardInitialized(true); - } - }); - return () => { - ignore = true; - }; - }, [dashboard]); - return (
- {viewMode !== ViewMode.PRINT ? ( -
- - key={dashboard.getInput().id} - hidePanelChrome={true} - panelProps={{ hideLoader: true }} - type={CONTROL_GROUP_TYPE} - maybeId={'control_group'} - getParentApi={() => { - return { - ...dashboard, - getSerializedStateForChild: dashboard.getSerializedStateForControlGroup, - getRuntimeStateForChild: dashboard.getRuntimeStateForControlGroup, - }; - }} - onApiAvailable={(api) => dashboard.setControlGroupApi(api)} - /> -
+ {controlGroup && viewMode !== ViewMode.PRINT ? ( +
0 ? 'dshDashboardViewport-controls' : ''} + ref={controlsRoot} + /> ) : null} {panelCount === 0 && }
{ > {/* Wait for `viewportWidth` to actually be set before rendering the dashboard grid - otherwise, there is a race condition where the panels can end up being squashed */} - {viewportWidth !== 0 && dashboardInitialized && ( - - )} + {viewportWidth !== 0 && }
); diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx index b8ee1cca82156..215c3e7b99e7d 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/api/run_save_functions.tsx @@ -7,6 +7,7 @@ */ import type { Reference } from '@kbn/content-management-utils'; +import type { PersistableControlGroupInput } from '@kbn/controls-plugin/common'; import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { EmbeddableInput, @@ -88,17 +89,13 @@ export async function runQuickSave(this: DashboardContainer) { const { panels: nextPanels, references } = await serializeAllPanelState(this); const dashboardStateToSave: DashboardContainerInput = { ...currentState, panels: nextPanels }; let stateToSave: SavedDashboardInput = dashboardStateToSave; - const controlGroupApi = this.controlGroupApi$.value; - let controlGroupReferences: Reference[] | undefined; - if (controlGroupApi) { - const { rawState: controlGroupSerializedState, references: extractedReferences } = - await controlGroupApi.serializeState(); - controlGroupReferences = extractedReferences; - stateToSave = { ...stateToSave, controlGroupInput: controlGroupSerializedState }; + let persistableControlGroupInput: PersistableControlGroupInput | undefined; + if (this.controlGroup) { + persistableControlGroupInput = this.controlGroup.getPersistableInput(); + stateToSave = { ...stateToSave, controlGroupInput: persistableControlGroupInput }; } const saveResult = await saveDashboardState({ - controlGroupReferences, panelReferences: references, currentState: stateToSave, saveOptions: {}, @@ -108,6 +105,9 @@ export async function runQuickSave(this: DashboardContainer) { this.savedObjectReferences = saveResult.references ?? []; this.dispatch.setLastSavedInput(dashboardStateToSave); this.saveNotification$.next(); + if (this.controlGroup && persistableControlGroupInput) { + this.controlGroup.setSavedState(persistableControlGroupInput); + } return saveResult; } @@ -180,20 +180,19 @@ export async function runInteractiveSave(this: DashboardContainer, interactionMo stateFromSaveModal.tags = newTags; } - let dashboardStateToSave: SavedDashboardInput = { + let dashboardStateToSave: DashboardContainerInput & { + controlGroupInput?: PersistableControlGroupInput; + } = { ...currentState, ...stateFromSaveModal, }; - const controlGroupApi = this.controlGroupApi$.value; - let controlGroupReferences: Reference[] | undefined; - if (controlGroupApi) { - const { rawState: controlGroupSerializedState, references } = - await controlGroupApi.serializeState(); - controlGroupReferences = references; + let persistableControlGroupInput: PersistableControlGroupInput | undefined; + if (this.controlGroup) { + persistableControlGroupInput = this.controlGroup.getPersistableInput(); dashboardStateToSave = { ...dashboardStateToSave, - controlGroupInput: controlGroupSerializedState, + controlGroupInput: persistableControlGroupInput, }; } @@ -226,7 +225,6 @@ export async function runInteractiveSave(this: DashboardContainer, interactionMo const beforeAddTime = window.performance.now(); const saveResult = await saveDashboardState({ - controlGroupReferences, panelReferences: references, saveOptions, currentState: { @@ -253,6 +251,9 @@ export async function runInteractiveSave(this: DashboardContainer, interactionMo batch(() => { this.dispatch.setStateFromSaveModal(stateFromSaveModal); this.dispatch.setLastSavedInput(dashboardStateToSave); + if (this.controlGroup && persistableControlGroupInput) { + this.controlGroup.setSavedState(persistableControlGroupInput); + } }); } diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.test.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.test.ts index 84b9d8dbea7b0..148c409e8d702 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.test.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.test.ts @@ -6,9 +6,11 @@ * Side Public License, v 1. */ +import { mockControlGroupInput } from '@kbn/controls-plugin/common/mocks'; +import { ControlGroupContainer } from '@kbn/controls-plugin/public/control_group/embeddable/control_group_container'; import { Filter } from '@kbn/es-query'; +import { ReduxToolsPackage } from '@kbn/presentation-util-plugin/public'; import { combineDashboardFiltersWithControlGroupFilters } from './dashboard_control_group_integration'; -import { BehaviorSubject } from 'rxjs'; jest.mock('@kbn/controls-plugin/public/control_group/embeddable/control_group_container'); @@ -49,41 +51,46 @@ const testFilter3: Filter = { }, }; -describe('combineDashboardFiltersWithControlGroupFilters', () => { - it('Combined filter pills do not get overwritten', async () => { - const dashboardFilterPills = [testFilter1, testFilter2]; - const mockControlGroupApi = { - filters$: new BehaviorSubject([]), - }; - const combinedFilters = combineDashboardFiltersWithControlGroupFilters( - dashboardFilterPills, - mockControlGroupApi - ); - expect(combinedFilters).toEqual(dashboardFilterPills); - }); +const mockControlGroupContainer = new ControlGroupContainer( + { getTools: () => {} } as unknown as ReduxToolsPackage, + mockControlGroupInput() +); - it('Combined control filters do not get overwritten', async () => { - const controlGroupFilters = [testFilter1, testFilter2]; - const mockControlGroupApi = { - filters$: new BehaviorSubject(controlGroupFilters), - }; - const combinedFilters = combineDashboardFiltersWithControlGroupFilters( - [] as Filter[], - mockControlGroupApi - ); - expect(combinedFilters).toEqual(controlGroupFilters); - }); +describe('Test dashboard control group', () => { + describe('Combine dashboard filters with control group filters test', () => { + it('Combined filter pills do not get overwritten', async () => { + const dashboardFilterPills = [testFilter1, testFilter2]; + mockControlGroupContainer.getOutput = jest.fn().mockReturnValue({ filters: [] }); + const combinedFilters = combineDashboardFiltersWithControlGroupFilters( + dashboardFilterPills, + mockControlGroupContainer + ); + expect(combinedFilters).toEqual(dashboardFilterPills); + }); + + it('Combined control filters do not get overwritten', async () => { + const controlGroupFilters = [testFilter1, testFilter2]; + mockControlGroupContainer.getOutput = jest + .fn() + .mockReturnValue({ filters: controlGroupFilters }); + const combinedFilters = combineDashboardFiltersWithControlGroupFilters( + [] as Filter[], + mockControlGroupContainer + ); + expect(combinedFilters).toEqual(controlGroupFilters); + }); - it('Combined dashboard filter pills and control filters do not get overwritten', async () => { - const dashboardFilterPills = [testFilter1, testFilter2]; - const controlGroupFilters = [testFilter3]; - const mockControlGroupApi = { - filters$: new BehaviorSubject(controlGroupFilters), - }; - const combinedFilters = combineDashboardFiltersWithControlGroupFilters( - dashboardFilterPills, - mockControlGroupApi - ); - expect(combinedFilters).toEqual(dashboardFilterPills.concat(controlGroupFilters)); + it('Combined dashboard filter pills and control filters do not get overwritten', async () => { + const dashboardFilterPills = [testFilter1, testFilter2]; + const controlGroupFilters = [testFilter3]; + mockControlGroupContainer.getOutput = jest + .fn() + .mockReturnValue({ filters: controlGroupFilters }); + const combinedFilters = combineDashboardFiltersWithControlGroupFilters( + dashboardFilterPills, + mockControlGroupContainer + ); + expect(combinedFilters).toEqual(dashboardFilterPills.concat(controlGroupFilters)); + }); }); }); diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts index 6267f6a27a2cc..675ea42634506 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/controls/dashboard_control_group_integration.ts @@ -6,95 +6,114 @@ * Side Public License, v 1. */ -import { COMPARE_ALL_OPTIONS, compareFilters, type Filter } from '@kbn/es-query'; -import { - BehaviorSubject, - combineLatest, - distinctUntilChanged, - map, - of, - skip, - startWith, - switchMap, -} from 'rxjs'; -import { PublishesFilters, PublishingSubject } from '@kbn/presentation-publishing'; +import { ControlGroupInput } from '@kbn/controls-plugin/common'; +import { ControlGroupContainer } from '@kbn/controls-plugin/public'; +import { compareFilters, COMPARE_ALL_OPTIONS, type Filter } from '@kbn/es-query'; +import { combineCompatibleChildrenApis } from '@kbn/presentation-containers'; +import { apiPublishesDataLoading, PublishesDataLoading } from '@kbn/presentation-publishing'; +import deepEqual from 'fast-deep-equal'; +import { isEqual } from 'lodash'; +import { distinctUntilChanged, Observable, skip } from 'rxjs'; +import { DashboardContainerInput } from '../../../../../common'; import { DashboardContainer } from '../../dashboard_container'; -export function startSyncingDashboardControlGroup(dashboard: DashboardContainer) { - const controlGroupFilters$ = dashboard.controlGroupApi$.pipe( - switchMap((controlGroupApi) => (controlGroupApi ? controlGroupApi.filters$ : of(undefined))) - ); - const controlGroupTimeslice$ = dashboard.controlGroupApi$.pipe( - switchMap((controlGroupApi) => (controlGroupApi ? controlGroupApi.timeslice$ : of(undefined))) - ); +interface DiffChecks { + [key: string]: (a?: unknown, b?: unknown) => boolean; +} - // -------------------------------------------------------------------------------------- - // dashboard.unifiedSearchFilters$ - // -------------------------------------------------------------------------------------- - const unifiedSearchFilters$ = new BehaviorSubject( - dashboard.getInput().filters - ); - dashboard.unifiedSearchFilters$ = unifiedSearchFilters$ as PublishingSubject< - Filter[] | undefined - >; - dashboard.publishingSubscription.add( - dashboard - .getInput$() - .pipe( - startWith(dashboard.getInput()), - map((input) => input.filters), - distinctUntilChanged((previous, current) => { - return compareFilters(previous ?? [], current ?? [], COMPARE_ALL_OPTIONS); - }) - ) - .subscribe((unifiedSearchFilters) => { - unifiedSearchFilters$.next(unifiedSearchFilters); - }) - ); +const distinctUntilDiffCheck = (a: T, b: T, diffChecks: DiffChecks) => + !(Object.keys(diffChecks) as Array) + .map((key) => deepEqual(a[key], b[key])) + .includes(false); + +type DashboardControlGroupCommonKeys = keyof Pick< + DashboardContainerInput | ControlGroupInput, + 'filters' | 'lastReloadRequestTime' | 'timeRange' | 'query' +>; + +export function startSyncingDashboardControlGroup(this: DashboardContainer) { + if (!this.controlGroup) return; - // -------------------------------------------------------------------------------------- - // Set dashboard.filters$ to include unified search filters and control group filters - // -------------------------------------------------------------------------------------- - function getCombinedFilters() { - return combineDashboardFiltersWithControlGroupFilters( - dashboard.getInput().filters ?? [], - dashboard.controlGroupApi$.value - ); - } + const compareAllFilters = (a?: Filter[], b?: Filter[]) => + compareFilters(a ?? [], b ?? [], COMPARE_ALL_OPTIONS); - const filters$ = new BehaviorSubject(getCombinedFilters()); - dashboard.filters$ = filters$; + const dashboardRefetchDiff: DiffChecks = { + filters: (a, b) => compareAllFilters(a as Filter[], b as Filter[]), + timeRange: deepEqual, + query: deepEqual, + viewMode: deepEqual, + }; - dashboard.publishingSubscription.add( - combineLatest([dashboard.unifiedSearchFilters$, controlGroupFilters$]).subscribe(() => { - filters$.next(getCombinedFilters()); - }) + // pass down any pieces of input needed to refetch or force refetch data for the controls + this.integrationSubscriptions.add( + (this.getInput$() as Readonly>) + .pipe( + distinctUntilChanged((a, b) => + distinctUntilDiffCheck(a, b, dashboardRefetchDiff) + ) + ) + .subscribe(() => { + const newInput: { [key: string]: unknown } = {}; + (Object.keys(dashboardRefetchDiff) as DashboardControlGroupCommonKeys[]).forEach((key) => { + if ( + !dashboardRefetchDiff[key]?.(this.getInput()[key], this.controlGroup!.getInput()[key]) + ) { + newInput[key] = this.getInput()[key]; + } + }); + if (Object.keys(newInput).length > 0) { + this.controlGroup!.updateInput(newInput); + } + }) ); - // -------------------------------------------------------------------------------------- // when control group outputs filters, force a refresh! - // -------------------------------------------------------------------------------------- - dashboard.publishingSubscription.add( - controlGroupFilters$ + this.integrationSubscriptions.add( + this.controlGroup + .getOutput$() .pipe( + distinctUntilChanged(({ filters: filtersA }, { filters: filtersB }) => + compareAllFilters(filtersA, filtersB) + ), skip(1) // skip first filter output because it will have been applied in initialize ) - .subscribe(() => dashboard.forceRefresh(false)) // we should not reload the control group when the control group output changes - otherwise, performance is severely impacted + .subscribe(() => this.forceRefresh(false)) // we should not reload the control group when the control group output changes - otherwise, performance is severely impacted ); - // -------------------------------------------------------------------------------------- - // when control group outputs timeslice, dispatch timeslice - // -------------------------------------------------------------------------------------- - dashboard.publishingSubscription.add( - controlGroupTimeslice$.subscribe((timeslice) => { - dashboard.dispatch.setTimeslice(timeslice); - }) + this.integrationSubscriptions.add( + this.controlGroup + .getOutput$() + .pipe( + distinctUntilChanged(({ timeslice: timesliceA }, { timeslice: timesliceB }) => + isEqual(timesliceA, timesliceB) + ) + ) + .subscribe(({ timeslice }) => { + if (!isEqual(timeslice, this.getInput().timeslice)) { + this.dispatch.setTimeslice(timeslice); + } + }) + ); + + // the Control Group needs to know when any dashboard children are loading in order to know when to move on to the next time slice when playing. + this.integrationSubscriptions.add( + combineCompatibleChildrenApis( + this, + 'dataLoading', + apiPublishesDataLoading, + false, + (childrenLoading) => childrenLoading.some(Boolean) + ) + .pipe(skip(1)) // skip the initial output of "false" + .subscribe((anyChildLoading) => + this.controlGroup?.anyControlOutputConsumerLoading$.next(anyChildLoading) + ) ); } export const combineDashboardFiltersWithControlGroupFilters = ( dashboardFilters: Filter[], - controlGroupApi?: PublishesFilters + controlGroup: ControlGroupContainer ): Filter[] => { - return [...dashboardFilters, ...(controlGroupApi?.filters$.value ?? [])]; + return [...dashboardFilters, ...(controlGroup.getOutput().filters ?? [])]; }; diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts index 12f513c1f417f..b9d2ff286023d 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.test.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +import { BehaviorSubject, Observable } from 'rxjs'; + import { ContactCardEmbeddable, ContactCardEmbeddableFactory, @@ -13,6 +15,11 @@ import { ContactCardEmbeddableOutput, CONTACT_CARD_EMBEDDABLE, } from '@kbn/embeddable-plugin/public/lib/test_samples'; +import { + ControlGroupInput, + ControlGroupContainer, + ControlGroupContainerFactory, +} from '@kbn/controls-plugin/public'; import { Filter } from '@kbn/es-query'; import { EmbeddablePackageState, ViewMode } from '@kbn/embeddable-plugin/public'; import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; @@ -22,7 +29,6 @@ import { getSampleDashboardPanel } from '../../../mocks'; import { pluginServices } from '../../../services/plugin_services'; import { DashboardCreationOptions } from '../dashboard_container_factory'; import { DEFAULT_DASHBOARD_INPUT } from '../../../dashboard_constants'; -import { mockControlGroupApi } from '../../../mocks'; test("doesn't throw error when no data views are available", async () => { pluginServices.getServices().data.dataViews.defaultDataViewExists = jest @@ -410,7 +416,6 @@ test('creates new embeddable with incoming embeddable if id does not match exist }, }), }); - dashboard?.setControlGroupApi(mockControlGroupApi); // flush promises await new Promise((r) => setTimeout(r, 1)); @@ -471,7 +476,6 @@ test('creates new embeddable with specified size if size is provided', async () }, }), }); - dashboard?.setControlGroupApi(mockControlGroupApi); // flush promises await new Promise((r) => setTimeout(r, 1)); @@ -493,6 +497,42 @@ test('creates new embeddable with specified size if size is provided', async () expect(dashboard!.getState().explicitInput.panels.new_panel.gridData.h).toBe(1); }); +test('creates a control group from the control group factory', async () => { + const mockControlGroupContainer = { + destroy: jest.fn(), + render: jest.fn(), + updateInput: jest.fn(), + getInput: jest.fn().mockReturnValue({}), + getInput$: jest.fn().mockReturnValue(new Observable()), + getOutput: jest.fn().mockReturnValue({}), + getOutput$: jest.fn().mockReturnValue(new Observable()), + onFiltersPublished$: new Observable(), + unsavedChanges: new BehaviorSubject(undefined), + } as unknown as ControlGroupContainer; + const mockControlGroupFactory = { + create: jest.fn().mockReturnValue(mockControlGroupContainer), + } as unknown as ControlGroupContainerFactory; + pluginServices.getServices().embeddable.getEmbeddableFactory = jest + .fn() + .mockReturnValue(mockControlGroupFactory); + await createDashboard({ + useControlGroupIntegration: true, + getInitialInput: () => ({ + controlGroupInput: { controlStyle: 'twoLine' } as unknown as ControlGroupInput, + }), + }); + // flush promises + await new Promise((r) => setTimeout(r, 1)); + expect(pluginServices.getServices().embeddable.getEmbeddableFactory).toHaveBeenCalledWith( + 'control_group' + ); + expect(mockControlGroupFactory.create).toHaveBeenCalledWith( + expect.objectContaining({ controlStyle: 'twoLine' }), + undefined, + { lastSavedInput: expect.objectContaining({ controlStyle: 'oneLine' }) } + ); +}); + /* * dashboard.getInput$() subscriptions are used to update: * 1) dashboard instance searchSessionId state @@ -527,7 +567,6 @@ test('searchSessionId is updated prior to child embeddable parent subscription e createSessionRestorationDataProvider: () => {}, } as unknown as DashboardCreationOptions['searchSessionSettings'], }); - dashboard?.setControlGroupApi(mockControlGroupApi); expect(dashboard).toBeDefined(); const embeddable = await dashboard!.addNewEmbeddable< ContactCardEmbeddableInput, diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts index 8e23540479535..158fc638adc3d 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/create_dashboard.ts @@ -5,13 +5,38 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - +import { + ControlGroupInput, + CONTROL_GROUP_TYPE, + getDefaultControlGroupInput, + getDefaultControlGroupPersistableInput, +} from '@kbn/controls-plugin/common'; +import { + ControlGroupContainerFactory, + ControlGroupOutput, + type ControlGroupContainer, +} from '@kbn/controls-plugin/public'; import { GlobalQueryStateFromUrl, syncGlobalQueryStateWithUrl } from '@kbn/data-plugin/public'; -import { ViewMode } from '@kbn/embeddable-plugin/public'; -import { TimeRange } from '@kbn/es-query'; +import { EmbeddableFactory, isErrorEmbeddable, ViewMode } from '@kbn/embeddable-plugin/public'; +import { + AggregateQuery, + compareFilters, + COMPARE_ALL_OPTIONS, + Filter, + Query, + TimeRange, +} from '@kbn/es-query'; import { lazyLoadReduxToolsPackage } from '@kbn/presentation-util-plugin/public'; -import { cloneDeep, omit } from 'lodash'; -import { Subject } from 'rxjs'; +import deepEqual from 'fast-deep-equal'; +import { cloneDeep, identity, omit, pickBy } from 'lodash'; +import { + BehaviorSubject, + combineLatest, + distinctUntilChanged, + map, + startWith, + Subject, +} from 'rxjs'; import { v4 } from 'uuid'; import { DashboardContainerInput, @@ -35,11 +60,14 @@ import { startDiffingDashboardState } from '../../state/diffing/dashboard_diffin import { DashboardPublicState, UnsavedPanelState } from '../../types'; import { DashboardContainer } from '../dashboard_container'; import { DashboardCreationOptions } from '../dashboard_container_factory'; +import { + combineDashboardFiltersWithControlGroupFilters, + startSyncingDashboardControlGroup, +} from './controls/dashboard_control_group_integration'; import { startSyncingDashboardDataViews } from './data_views/sync_dashboard_data_views'; import { startQueryPerformanceTracking } from './performance/query_performance_tracking'; import { startDashboardSearchSessionIntegration } from './search_sessions/start_dashboard_search_session_integration'; import { syncUnifiedSearchState } from './unified_search/sync_dashboard_unified_search_state'; -import { PANELS_CONTROL_GROUP_KEY } from '../../../services/dashboard_backup/dashboard_backup_service'; /** * Builds a new Dashboard from scratch. @@ -134,13 +162,16 @@ export const initializeDashboard = async ({ loadDashboardReturn, untilDashboardReady, creationOptions, + controlGroup, }: { loadDashboardReturn: LoadDashboardReturn; untilDashboardReady: () => Promise; creationOptions?: DashboardCreationOptions; + controlGroup?: ControlGroupContainer; }) => { const { dashboardBackup, + embeddable: { getEmbeddableFactory }, dashboardCapabilities: { showWriteControls }, embeddable: { reactEmbeddableRegistryHasKey }, data: { @@ -160,6 +191,7 @@ export const initializeDashboard = async ({ searchSessionSettings, unifiedSearchSettings, validateLoadedSavedObject, + useControlGroupIntegration, useUnifiedSearchIntegration, useSessionStorageIntegration, } = creationOptions ?? {}; @@ -259,6 +291,11 @@ export const initializeDashboard = async ({ cloneDeep(combinedOverrideInput), 'controlGroupInput' ); + const initialControlGroupInput: ControlGroupInput | {} = { + ...(loadDashboardReturn?.dashboardInput?.controlGroupInput ?? {}), + ...(sessionStorageInput?.controlGroupInput ?? {}), + ...(overrideInput?.controlGroupInput ?? {}), + }; // Back up any view mode passed in explicitly. if (overrideInput?.viewMode) { @@ -275,7 +312,6 @@ export const initializeDashboard = async ({ // -------------------------------------------------------------------------------------- untilDashboardReady().then((dashboard) => { dashboard.savedObjectReferences = loadDashboardReturn?.references; - dashboard.controlGroupInput = loadDashboardReturn?.dashboardInput?.controlGroupInput; }); // -------------------------------------------------------------------------------------- @@ -438,13 +474,6 @@ export const initializeDashboard = async ({ // Set restored runtime state for react embeddables. // -------------------------------------------------------------------------------------- untilDashboardReady().then((dashboardContainer) => { - if (overrideInput?.controlGroupState) { - dashboardContainer.setRuntimeStateForChild( - PANELS_CONTROL_GROUP_KEY, - overrideInput.controlGroupState - ); - } - for (const idWithRuntimeState of Object.keys(runtimePanelsToRestore)) { const restoredRuntimeStateForChild = runtimePanelsToRestore[idWithRuntimeState]; if (!restoredRuntimeStateForChild) continue; @@ -452,6 +481,52 @@ export const initializeDashboard = async ({ } }); + // -------------------------------------------------------------------------------------- + // Start the control group integration. + // -------------------------------------------------------------------------------------- + if (useControlGroupIntegration) { + const controlsGroupFactory = getEmbeddableFactory< + ControlGroupInput, + ControlGroupOutput, + ControlGroupContainer + >(CONTROL_GROUP_TYPE) as EmbeddableFactory< + ControlGroupInput, + ControlGroupOutput, + ControlGroupContainer + > & { + create: ControlGroupContainerFactory['create']; + }; + const { filters, query, timeRange, viewMode, id } = initialDashboardInput; + const fullControlGroupInput = { + id: `control_group_${id ?? 'new_dashboard'}`, + ...getDefaultControlGroupInput(), + ...pickBy(initialControlGroupInput, identity), // undefined keys in initialInput should not overwrite defaults + timeRange, + viewMode, + filters, + query, + }; + + if (controlGroup) { + controlGroup.updateInputAndReinitialize(fullControlGroupInput); + } else { + const newControlGroup = await controlsGroupFactory?.create(fullControlGroupInput, this, { + lastSavedInput: + loadDashboardReturn?.dashboardInput?.controlGroupInput ?? + getDefaultControlGroupPersistableInput(), + }); + if (!newControlGroup || isErrorEmbeddable(newControlGroup)) { + throw new Error('Error in control group startup'); + } + controlGroup = newControlGroup; + } + + untilDashboardReady().then((dashboardContainer) => { + dashboardContainer.controlGroup = controlGroup; + startSyncingDashboardControlGroup.bind(dashboardContainer)(); + }); + } + // -------------------------------------------------------------------------------------- // Start the data views integration. // -------------------------------------------------------------------------------------- @@ -477,6 +552,63 @@ export const initializeDashboard = async ({ setTimeout(() => dashboard.dispatch.setAnimatePanelTransforms(true), 500) ); + // -------------------------------------------------------------------------------------- + // Set parentApi.filters$ to include dashboardContainer filters and control group filters + // -------------------------------------------------------------------------------------- + untilDashboardReady().then((dashboardContainer) => { + if (!dashboardContainer.controlGroup) { + return; + } + + function getCombinedFilters() { + return combineDashboardFiltersWithControlGroupFilters( + dashboardContainer.getInput().filters ?? [], + dashboardContainer.controlGroup! + ); + } + + const filters$ = new BehaviorSubject(getCombinedFilters()); + dashboardContainer.filters$ = filters$; + + const inputFilters$ = dashboardContainer.getInput$().pipe( + startWith(dashboardContainer.getInput()), + map((input) => input.filters), + distinctUntilChanged((previous, current) => { + return compareFilters(previous ?? [], current ?? [], COMPARE_ALL_OPTIONS); + }) + ); + + // Can not use onFiltersPublished$ directly since it does not have an intial value and + // combineLatest will not emit until each observable emits at least one value + const controlGroupFilters$ = dashboardContainer.controlGroup.onFiltersPublished$.pipe( + startWith(dashboardContainer.controlGroup.getOutput().filters) + ); + + dashboardContainer.integrationSubscriptions.add( + combineLatest([inputFilters$, controlGroupFilters$]).subscribe(() => { + filters$.next(getCombinedFilters()); + }) + ); + }); + + // -------------------------------------------------------------------------------------- + // Set up parentApi.query$ + // Can not use legacyEmbeddableToApi since query$ setting is delayed + // -------------------------------------------------------------------------------------- + untilDashboardReady().then((dashboardContainer) => { + const query$ = new BehaviorSubject( + dashboardContainer.getInput().query + ); + dashboardContainer.query$ = query$; + dashboardContainer.integrationSubscriptions.add( + dashboardContainer.getInput$().subscribe((input) => { + if (!deepEqual(query$.getValue() ?? [], input.query)) { + query$.next(input.query); + } + }) + ); + }); + // -------------------------------------------------------------------------------------- // Set up search sessions integration. // -------------------------------------------------------------------------------------- @@ -497,8 +629,7 @@ export const initializeDashboard = async ({ sessionIdToRestore ?? (existingSession && incomingEmbeddable ? existingSession : session.start()); - untilDashboardReady().then(async (container) => { - await container.untilContainerInitialized(); + untilDashboardReady().then((container) => { startDashboardSearchSessionIntegration.bind(container)( creationOptions?.searchSessionSettings ); diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts b/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts index 9de483bfb0376..3fd4c0df233cf 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/create/data_views/sync_dashboard_data_views.ts @@ -10,7 +10,7 @@ import { DataView } from '@kbn/data-views-plugin/common'; import { combineCompatibleChildrenApis } from '@kbn/presentation-containers'; import { apiPublishesDataViews, PublishesDataViews } from '@kbn/presentation-publishing'; import { uniqBy } from 'lodash'; -import { combineLatest, Observable, of, switchMap } from 'rxjs'; +import { combineLatest, map, Observable, of, switchMap } from 'rxjs'; import { pluginServices } from '../../../../services/plugin_services'; import { DashboardContainer } from '../../dashboard_container'; @@ -19,11 +19,19 @@ export function startSyncingDashboardDataViews(this: DashboardContainer) { data: { dataViews }, } = pluginServices.getServices(); - const controlGroupDataViewsPipe: Observable = this.controlGroupApi$.pipe( - switchMap((controlGroupApi) => { - return controlGroupApi ? controlGroupApi.dataViews : of([]); - }) - ); + const controlGroupDataViewsPipe: Observable = this.controlGroup + ? this.controlGroup.getOutput$().pipe( + map((output) => output.dataViewIds ?? []), + switchMap( + (dataViewIds) => + new Promise((resolve) => + Promise.all(dataViewIds.map((id) => dataViews.get(id))).then((nextDataViews) => + resolve(nextDataViews) + ) + ) + ) + ) + : of([]); const childDataViewsPipe = combineCompatibleChildrenApis( this, @@ -35,10 +43,7 @@ export function startSyncingDashboardDataViews(this: DashboardContainer) { return combineLatest([controlGroupDataViewsPipe, childDataViewsPipe]) .pipe( switchMap(([controlGroupDataViews, childDataViews]) => { - const allDataViews = [ - ...(controlGroupDataViews ? controlGroupDataViews : []), - ...childDataViews, - ]; + const allDataViews = controlGroupDataViews.concat(childDataViews); if (allDataViews.length === 0) { return (async () => { const defaultDataViewId = await dataViews.getDefaultId(); @@ -49,6 +54,7 @@ export function startSyncingDashboardDataViews(this: DashboardContainer) { }) ) .subscribe((newDataViews) => { + if (newDataViews[0].id) this.controlGroup?.setRelevantDataViewId(newDataViews[0].id); this.setAllDataViews(newDataViews); }); } diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.test.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.test.tsx index b6d77ac9b7822..ee2cc0dd961fd 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.test.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.test.tsx @@ -18,12 +18,7 @@ import { import type { TimeRange } from '@kbn/es-query'; import { mockedReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public/mocks'; -import { - buildMockDashboard, - getSampleDashboardInput, - getSampleDashboardPanel, - mockControlGroupApi, -} from '../../mocks'; +import { buildMockDashboard, getSampleDashboardInput, getSampleDashboardPanel } from '../../mocks'; import { pluginServices } from '../../services/plugin_services'; import { DashboardContainer } from './dashboard_container'; @@ -175,7 +170,6 @@ test('searchSessionId propagates to children', async () => { undefined, { lastSavedInput: sampleInput } ); - container?.setControlGroupApi(mockControlGroupApi); const embeddable = await container.addNewEmbeddable< ContactCardEmbeddableInput, ContactCardEmbeddableOutput, @@ -195,10 +189,11 @@ describe('getInheritedInput', () => { const dashboardTimeslice = [1688061910000, 1688062209000] as [number, number]; test('Should pass dashboard timeRange and timeslice to panel when panel does not have custom time range', async () => { - const container = buildMockDashboard(); - container.updateInput({ - timeRange: dashboardTimeRange, - timeslice: dashboardTimeslice, + const container = buildMockDashboard({ + overrides: { + timeRange: dashboardTimeRange, + timeslice: dashboardTimeslice, + }, }); const embeddable = await container.addNewEmbeddable( CONTACT_CARD_EMBEDDABLE, @@ -219,10 +214,11 @@ describe('getInheritedInput', () => { }); test('Should not pass dashboard timeRange and timeslice to panel when panel has custom time range', async () => { - const container = buildMockDashboard(); - container.updateInput({ - timeRange: dashboardTimeRange, - timeslice: dashboardTimeslice, + const container = buildMockDashboard({ + overrides: { + timeRange: dashboardTimeRange, + timeslice: dashboardTimeslice, + }, }); const embeddableTimeRange = { to: 'now', diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx index d1409a3a4b02e..585e0ff0b1ff6 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -8,6 +8,7 @@ import { METRIC_TYPE } from '@kbn/analytics'; import type { Reference } from '@kbn/content-management-utils'; +import type { ControlGroupContainer } from '@kbn/controls-plugin/public'; import type { I18nStart, KibanaExecutionContext, OverlayRef } from '@kbn/core/public'; import { type PublishingSubject, @@ -15,8 +16,6 @@ import { apiPublishesUnsavedChanges, getPanelTitle, PublishesViewMode, - PublishesDataLoading, - apiPublishesDataLoading, } from '@kbn/presentation-publishing'; import { RefreshInterval } from '@kbn/data-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/public'; @@ -33,7 +32,7 @@ import { type EmbeddableOutput, type IEmbeddable, } from '@kbn/embeddable-plugin/public'; -import type { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query'; +import type { Filter, Query, TimeRange } from '@kbn/es-query'; import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { HasRuntimeChildState, @@ -41,7 +40,6 @@ import { HasSerializedChildState, TrackContentfulRender, TracksQueryPerformance, - combineCompatibleChildrenApis, } from '@kbn/presentation-containers'; import { PanelPackage } from '@kbn/presentation-containers'; import { ReduxEmbeddableTools, ReduxToolsPackage } from '@kbn/presentation-util-plugin/public'; @@ -52,18 +50,14 @@ import { omit } from 'lodash'; import React, { createContext, useContext } from 'react'; import ReactDOM from 'react-dom'; import { batch } from 'react-redux'; -import { BehaviorSubject, Subject, Subscription, first, skipWhile, switchMap } from 'rxjs'; +import { BehaviorSubject, Subject, Subscription } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs'; import { v4 } from 'uuid'; import { PublishesSettings } from '@kbn/presentation-containers/interfaces/publishes_settings'; import { apiHasSerializableState } from '@kbn/presentation-containers/interfaces/serialized_state'; -import { ControlGroupApi, ControlGroupSerializedState } from '@kbn/controls-plugin/public'; import { DashboardLocatorParams, DASHBOARD_CONTAINER_TYPE } from '../..'; -import { DashboardAttributes, DashboardContainerInput, DashboardPanelState } from '../../../common'; -import { - getReferencesForControls, - getReferencesForPanelId, -} from '../../../common/dashboard_container/persistable_state/dashboard_container_references'; +import { DashboardContainerInput, DashboardPanelState } from '../../../common'; +import { getReferencesForPanelId } from '../../../common/dashboard_container/persistable_state/dashboard_container_references'; import { DASHBOARD_APP_ID, DASHBOARD_UI_METRIC_ID, @@ -90,10 +84,7 @@ import { showSettings, } from './api'; import { duplicateDashboardPanel } from './api/duplicate_dashboard_panel'; -import { - combineDashboardFiltersWithControlGroupFilters, - startSyncingDashboardControlGroup, -} from './create/controls/dashboard_control_group_integration'; +import { combineDashboardFiltersWithControlGroupFilters } from './create/controls/dashboard_control_group_integration'; import { initializeDashboard } from './create/create_dashboard'; import { DashboardCreationOptions, @@ -101,7 +92,6 @@ import { dashboardTypeDisplayName, } from './dashboard_container_factory'; import { getPanelAddedSuccessString } from '../../dashboard_app/_dashboard_app_strings'; -import { PANELS_CONTROL_GROUP_KEY } from '../../services/dashboard_backup/dashboard_backup_service'; export interface InheritedChildInput { filters: Filter[]; @@ -157,7 +147,7 @@ export class DashboardContainer public integrationSubscriptions: Subscription = new Subscription(); public publishingSubscription: Subscription = new Subscription(); public diffingSubscription: Subscription = new Subscription(); - public controlGroupApi$: PublishingSubject; + public controlGroup?: ControlGroupContainer; public settings: Record>; public searchSessionId?: string; @@ -166,7 +156,6 @@ export class DashboardContainer public reload$ = new Subject(); public timeRestore$: BehaviorSubject; public timeslice$: BehaviorSubject<[number, number] | undefined>; - public unifiedSearchFilters$?: PublishingSubject; public locator?: Pick, 'navigate' | 'getRedirectUrl'>; public readonly executionContext: KibanaExecutionContext; @@ -183,9 +172,6 @@ export class DashboardContainer private hadContentfulRender = false; private scrollPosition?: number; - // setup - public untilContainerInitialized: () => Promise; - // cleanup public stopSyncingWithUnifiedSearch?: () => void; private cleanupStateTools: () => void; @@ -211,7 +197,6 @@ export class DashboardContainer | undefined; // new embeddable framework public savedObjectReferences: Reference[] = []; - public controlGroupInput: DashboardAttributes['controlGroupInput'] | undefined; constructor( initialInput: DashboardContainerInput, @@ -222,43 +207,19 @@ export class DashboardContainer creationOptions?: DashboardCreationOptions, initialComponentState?: DashboardPublicState ) { - const controlGroupApi$ = new BehaviorSubject(undefined); - async function untilContainerInitialized(): Promise { - return new Promise((resolve) => { - controlGroupApi$ - .pipe( - skipWhile((controlGroupApi) => !controlGroupApi), - switchMap(async (controlGroupApi) => { - await controlGroupApi?.untilInitialized(); - }), - first() - ) - .subscribe(() => { - resolve(); - }); - }); - } - const { usageCollection, embeddable: { getEmbeddableFactory }, } = pluginServices.getServices(); - super( { ...initialInput, }, { embeddableLoaded: {} }, getEmbeddableFactory, - parent, - { - untilContainerInitialized, - } + parent ); - this.controlGroupApi$ = controlGroupApi$; - this.untilContainerInitialized = untilContainerInitialized; - this.trackPanelAddMetric = usageCollection.reportUiCounter?.bind( usageCollection, DASHBOARD_UI_METRIC_ID @@ -350,41 +311,7 @@ export class DashboardContainer DashboardContainerInput >(this.publishingSubscription, this, 'lastReloadRequestTime'); - startSyncingDashboardControlGroup(this); - this.executionContext = initialInput.executionContext; - - this.dataLoading = new BehaviorSubject(false); - this.publishingSubscription.add( - combineCompatibleChildrenApis( - this, - 'dataLoading', - apiPublishesDataLoading, - undefined, - // flatten method - (values) => { - return values.some((isLoading) => isLoading); - } - ).subscribe((isAtLeastOneChildLoading) => { - (this.dataLoading as BehaviorSubject).next(isAtLeastOneChildLoading); - }) - ); - - this.dataViews = new BehaviorSubject(this.getAllDataViews()); - - const query$ = new BehaviorSubject(this.getInput().query); - this.query$ = query$; - this.publishingSubscription.add( - this.getInput$().subscribe((input) => { - if (!deepEqual(query$.getValue() ?? [], input.query)) { - query$.next(input.query); - } - }) - ); - } - - public setControlGroupApi(controlGroupApi: ControlGroupApi) { - (this.controlGroupApi$ as BehaviorSubject).next(controlGroupApi); } public getAppContext() { @@ -470,10 +397,10 @@ export class DashboardContainer panels, } = this.input; - const combinedFilters = combineDashboardFiltersWithControlGroupFilters( - filters, - this.controlGroupApi$?.value - ); + let combinedFilters = filters; + if (this.controlGroup) { + combinedFilters = combineDashboardFiltersWithControlGroupFilters(filters, this.controlGroup); + } const hasCustomTimeRange = Boolean( (panels[id]?.explicitInput as Partial)?.timeRange ); @@ -502,6 +429,7 @@ export class DashboardContainer public destroy() { super.destroy(); this.cleanupStateTools(); + this.controlGroup?.destroy(); this.diffingSubscription.unsubscribe(); this.publishingSubscription.unsubscribe(); this.integrationSubscriptions.unsubscribe(); @@ -687,12 +615,16 @@ export class DashboardContainer public forceRefresh(refreshControlGroup: boolean = true) { this.dispatch.setLastReloadRequestTimeToNow({}); if (refreshControlGroup) { + this.controlGroup?.reload(); + // only reload all panels if this refresh does not come from the control group. this.reload$.next(); } } - public async asyncResetToLastSavedState() { + public onDataViewsUpdate$ = new Subject(); + + public resetToLastSavedState() { this.dispatch.resetToLastSavedInput({}); const { explicitInput: { timeRange, refreshInterval }, @@ -701,8 +633,8 @@ export class DashboardContainer }, } = this.getState(); - if (this.controlGroupApi$.value) { - await this.controlGroupApi$.value.asyncResetUnsavedChanges(); + if (this.controlGroup) { + this.controlGroup.resetToLastSavedState(); } // if we are using the unified search integration, we need to force reset the time picker. @@ -747,6 +679,7 @@ export class DashboardContainer const initializeResult = await initializeDashboard({ creationOptions: this.creationOptions, + controlGroup: this.controlGroup, untilDashboardReady, loadDashboardReturn, }); @@ -761,6 +694,9 @@ export class DashboardContainer omit(loadDashboardReturn?.dashboardInput, 'controlGroupInput') ); this.dispatch.setManaged(loadDashboardReturn?.managed); + if (this.controlGroup) { + this.controlGroup.setSavedState(loadDashboardReturn.dashboardInput?.controlGroupInput); + } this.dispatch.setAnimatePanelTransforms(false); // prevents panels from animating on navigate. this.dispatch.setLastSavedId(newSavedObjectId); this.setExpandedPanelId(undefined); @@ -784,7 +720,7 @@ export class DashboardContainer */ public setAllDataViews = (newDataViews: DataView[]) => { this.allDataViews = newDataViews; - (this.dataViews as BehaviorSubject).next(newDataViews); + this.onDataViewsUpdate$.next(newDataViews); }; public getExpandedPanelId = () => { @@ -807,6 +743,7 @@ export class DashboardContainer public clearOverlays = () => { this.dispatch.setHasOverlays(false); this.dispatch.setFocusedPanelId(undefined); + this.controlGroup?.closeAllFlyouts(); this.overlayRef?.close(); }; @@ -911,22 +848,6 @@ export class DashboardContainer }; }; - public getSerializedStateForControlGroup = () => { - return { - rawState: this.controlGroupInput - ? (this.controlGroupInput as ControlGroupSerializedState) - : ({ - controlStyle: 'oneLine', - chainingSystem: 'HIERARCHICAL', - showApplySelections: false, - panelsJSON: '{}', - ignoreParentSettingsJSON: - '{"ignoreFilters":false,"ignoreQuery":false,"ignoreTimerange":false,"ignoreValidations":false}', - } as ControlGroupSerializedState), - references: getReferencesForControls(this.savedObjectReferences), - }; - }; - private restoredRuntimeState: UnsavedPanelState | undefined = undefined; public setRuntimeStateForChild = (childId: string, state: object) => { const runtimeState = this.restoredRuntimeState ?? {}; @@ -937,10 +858,6 @@ export class DashboardContainer return this.restoredRuntimeState?.[childId]; }; - public getRuntimeStateForControlGroup = () => { - return this.getRuntimeStateForChild(PANELS_CONTROL_GROUP_KEY); - }; - public removePanel(id: string) { const { embeddable: { reactEmbeddableRegistryHasKey }, diff --git a/src/plugins/dashboard/public/dashboard_container/state/diffing/dashboard_diffing_integration.ts b/src/plugins/dashboard/public/dashboard_container/state/diffing/dashboard_diffing_integration.ts index 6d73e59856e28..89f71c074d9fd 100644 --- a/src/plugins/dashboard/public/dashboard_container/state/diffing/dashboard_diffing_integration.ts +++ b/src/plugins/dashboard/public/dashboard_container/state/diffing/dashboard_diffing_integration.ts @@ -5,10 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ +import { PersistableControlGroupInput } from '@kbn/controls-plugin/common'; import { childrenUnsavedChanges$ } from '@kbn/presentation-containers'; import { omit } from 'lodash'; import { AnyAction, Middleware } from 'redux'; -import { combineLatest, debounceTime, skipWhile, startWith, switchMap } from 'rxjs'; +import { combineLatest, debounceTime, Observable, of, startWith, switchMap } from 'rxjs'; import { DashboardContainer, DashboardCreationOptions } from '../..'; import { DashboardContainerInput } from '../../../../common'; import { CHANGE_CHECK_DEBOUNCE } from '../../../dashboard_constants'; @@ -16,7 +17,6 @@ import { pluginServices } from '../../../services/plugin_services'; import { UnsavedPanelState } from '../../types'; import { dashboardContainerReducers } from '../dashboard_container_reducers'; import { isKeyEqualAsync, unsavedChangesDiffingFunctions } from './dashboard_diffing_functions'; -import { PANELS_CONTROL_GROUP_KEY } from '../../../services/dashboard_backup/dashboard_backup_service'; /** * An array of reducers which cannot cause unsaved changes. Unsaved changes only compares the explicit input @@ -111,12 +111,8 @@ export function startDiffingDashboardState( combineLatest([ dashboardUnsavedChanges, childrenUnsavedChanges$(this.children$), - this.controlGroupApi$.pipe( - skipWhile((controlGroupApi) => !controlGroupApi), - switchMap((controlGroupApi) => { - return controlGroupApi!.unsavedChanges; - }) - ), + this.controlGroup?.unsavedChanges ?? + (of(undefined) as Observable), ]).subscribe(([dashboardChanges, unsavedPanelState, controlGroupChanges]) => { // calculate unsaved changes const hasUnsavedChanges = @@ -129,11 +125,11 @@ export function startDiffingDashboardState( // backup unsaved changes if configured to do so if (creationOptions?.useSessionStorageIntegration) { - const reactEmbeddableChanges = unsavedPanelState ? { ...unsavedPanelState } : {}; - if (controlGroupChanges) { - reactEmbeddableChanges[PANELS_CONTROL_GROUP_KEY] = controlGroupChanges; - } - backupUnsavedChanges.bind(this)(dashboardChanges, reactEmbeddableChanges); + backupUnsavedChanges.bind(this)( + dashboardChanges, + unsavedPanelState ? unsavedPanelState : {}, + controlGroupChanges + ); } }) ); @@ -185,7 +181,8 @@ export async function getDashboardUnsavedChanges( function backupUnsavedChanges( this: DashboardContainer, dashboardChanges: Partial, - reactEmbeddableChanges: UnsavedPanelState + reactEmbeddableChanges: UnsavedPanelState, + controlGroupChanges: PersistableControlGroupInput | undefined ) { const { dashboardBackup } = pluginServices.getServices(); const dashboardStateToBackup = omit(dashboardChanges, keysToOmitFromSessionStorage); @@ -195,6 +192,7 @@ function backupUnsavedChanges( { ...dashboardStateToBackup, panels: dashboardChanges.panels, + controlGroupInput: controlGroupChanges, }, reactEmbeddableChanges ); diff --git a/src/plugins/dashboard/public/dashboard_container/types.ts b/src/plugins/dashboard/public/dashboard_container/types.ts index f3ca588aa20b1..c2c7cfb8aa083 100644 --- a/src/plugins/dashboard/public/dashboard_container/types.ts +++ b/src/plugins/dashboard/public/dashboard_container/types.ts @@ -6,11 +6,11 @@ * Side Public License, v 1. */ +import { SerializableControlGroupInput } from '@kbn/controls-plugin/common'; import type { ContainerOutput } from '@kbn/embeddable-plugin/public'; import type { ReduxEmbeddableState } from '@kbn/presentation-util-plugin/public'; import { SerializableRecord } from '@kbn/utility-types'; -import { ControlGroupRuntimeState } from '@kbn/controls-plugin/public'; import type { DashboardContainerInput, DashboardOptions } from '../../common'; import { SavedDashboardPanel } from '../../common/content_management'; @@ -125,7 +125,7 @@ export type DashboardLocatorParams = Partial< panels?: Array; // used SerializableRecord here to force the GridData type to be read as serializable /** - * Control group changes + * Control group input */ - controlGroupState?: Partial & SerializableRecord; // used SerializableRecord here to force the GridData type to be read as serializable + controlGroupInput?: SerializableControlGroupInput; }; diff --git a/src/plugins/dashboard/public/dashboard_top_nav/internal_dashboard_top_nav.tsx b/src/plugins/dashboard/public/dashboard_top_nav/internal_dashboard_top_nav.tsx index 86682acb4287f..5f6edc138aa13 100644 --- a/src/plugins/dashboard/public/dashboard_top_nav/internal_dashboard_top_nav.tsx +++ b/src/plugins/dashboard/public/dashboard_top_nav/internal_dashboard_top_nav.tsx @@ -15,6 +15,7 @@ import { getContextProvider as getPresentationUtilContextProvider, } from '@kbn/presentation-util-plugin/public'; import { ViewMode } from '@kbn/embeddable-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/public'; import { TopNavMenuBadgeProps, TopNavMenuProps } from '@kbn/navigation-plugin/public'; import { EuiBreadcrumb, @@ -28,7 +29,6 @@ import { import { MountPoint } from '@kbn/core/public'; import { getManagedContentBadge } from '@kbn/managed-content-badge'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useStateFromPublishingSubject } from '@kbn/presentation-publishing'; import { getDashboardTitle, leaveConfirmStrings, @@ -113,8 +113,16 @@ export function InternalDashboardTopNav({ const query = dashboard.select((state) => state.explicitInput.query); const title = dashboard.select((state) => state.explicitInput.title); + // store data views in state & subscribe to dashboard data view changes. + const [allDataViews, setAllDataViews] = useState([]); const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const allDataViews = useStateFromPublishingSubject(dashboard.dataViews); + useEffect(() => { + setAllDataViews(dashboard.getAllDataViews()); + const subscription = dashboard.onDataViewsUpdate$.subscribe((dataViews) => + setAllDataViews(dataViews) + ); + return () => subscription.unsubscribe(); + }, [dashboard]); const dashboardTitle = useMemo(() => { return getDashboardTitle(title, viewMode, !lastSavedId); @@ -403,7 +411,7 @@ export function InternalDashboardTopNav({ screenTitle={title} useDefaultBehaviors={true} savedQueryId={savedQueryId} - indexPatterns={allDataViews ?? []} + indexPatterns={allDataViews} saveQueryMenuVisibility={allowSaveQuery ? 'allowed_by_app_privilege' : 'globally_managed'} appName={LEGACY_DASHBOARD_APP_ID} visible={viewMode !== ViewMode.PRINT} diff --git a/src/plugins/dashboard/public/mocks.tsx b/src/plugins/dashboard/public/mocks.tsx index 4a75d1a08b996..d447015b2b1a6 100644 --- a/src/plugins/dashboard/public/mocks.tsx +++ b/src/plugins/dashboard/public/mocks.tsx @@ -9,8 +9,6 @@ import { EmbeddableInput, ViewMode } from '@kbn/embeddable-plugin/public'; import { mockedReduxEmbeddablePackage } from '@kbn/presentation-util-plugin/public/mocks'; -import { ControlGroupApi } from '@kbn/controls-plugin/public'; -import { BehaviorSubject } from 'rxjs'; import { DashboardContainerInput, DashboardPanelState } from '../common'; import { DashboardContainer } from './dashboard_container/embeddable/dashboard_container'; import { DashboardStart } from './plugin'; @@ -74,15 +72,6 @@ export function setupIntersectionObserverMock({ }); } -export const mockControlGroupApi = { - untilInitialized: async () => {}, - filters$: new BehaviorSubject(undefined), - query$: new BehaviorSubject(undefined), - timeslice$: new BehaviorSubject(undefined), - dataViews: new BehaviorSubject(undefined), - unsavedChanges: new BehaviorSubject(undefined), -} as unknown as ControlGroupApi; - export function buildMockDashboard({ overrides, savedObjectId, @@ -100,7 +89,6 @@ export function buildMockDashboard({ undefined, { lastSavedInput: initialInput, lastSavedId: savedObjectId } ); - dashboardContainer?.setControlGroupApi(mockControlGroupApi); return dashboardContainer; } diff --git a/src/plugins/dashboard/public/services/dashboard_backup/dashboard_backup_service.ts b/src/plugins/dashboard/public/services/dashboard_backup/dashboard_backup_service.ts index 54486ece0970a..f97d88fd1c4fe 100644 --- a/src/plugins/dashboard/public/services/dashboard_backup/dashboard_backup_service.ts +++ b/src/plugins/dashboard/public/services/dashboard_backup/dashboard_backup_service.ts @@ -23,7 +23,6 @@ import { backupServiceStrings } from '../../dashboard_container/_dashboard_conta import { UnsavedPanelState } from '../../dashboard_container/types'; export const DASHBOARD_PANELS_UNSAVED_ID = 'unsavedDashboard'; -export const PANELS_CONTROL_GROUP_KEY = 'controlGroup'; const DASHBOARD_PANELS_SESSION_KEY = 'dashboardPanels'; const DASHBOARD_VIEWMODE_LOCAL_KEY = 'dashboardViewMode'; @@ -113,7 +112,6 @@ class DashboardBackupService implements DashboardBackupServiceType { const panels = this.sessionStorage.get(DASHBOARD_PANELS_SESSION_KEY)?.[this.activeSpaceId]?.[ id ] as UnsavedPanelState | undefined; - return { dashboardState, panels }; } catch (e) { this.notifications.toasts.addDanger({ diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts index eccd68b6952c0..2b2835e2a2420 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts @@ -56,15 +56,8 @@ export const dashboardContentManagementServiceFactory: DashboardContentManagemen contentManagement, savedObjectsTagging, }), - saveDashboardState: ({ - controlGroupReferences, - currentState, - saveOptions, - lastSavedId, - panelReferences, - }) => + saveDashboardState: ({ currentState, saveOptions, lastSavedId, panelReferences }) => saveDashboardState({ - controlGroupReferences, data, embeddable, saveOptions, diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/load_dashboard_state.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/load_dashboard_state.ts index 55ee72c5abbef..cabd1542efbb2 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/load_dashboard_state.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/load_dashboard_state.ts @@ -12,6 +12,7 @@ import { Filter, Query } from '@kbn/es-query'; import { ViewMode } from '@kbn/embeddable-plugin/public'; import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/public'; import { cleanFiltersForSerialize } from '@kbn/presentation-util-plugin/public'; +import { rawControlGroupAttributesToControlGroupInput } from '@kbn/controls-plugin/common'; import { parseSearchSourceJSON, injectSearchSourceReferences } from '@kbn/data-plugin/public'; import { @@ -186,7 +187,9 @@ export const loadDashboardState = async ({ viewMode: ViewMode.VIEW, // dashboards loaded from saved object default to view mode. If it was edited recently, the view mode from session storage will override this. tags: savedObjectsTagging.getTagIdsFromReferences?.(references) ?? [], - controlGroupInput: attributes.controlGroupInput, + controlGroupInput: + attributes.controlGroupInput && + rawControlGroupAttributesToControlGroupInput(attributes.controlGroupInput), version: convertNumberToDashboardVersion(version), }, diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts index 0487f14e699c6..1878344b630fc 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.test.ts @@ -6,6 +6,9 @@ * Side Public License, v 1. */ +import { ControlGroupInput } from '@kbn/controls-plugin/common'; +import { controlGroupInputBuilder } from '@kbn/controls-plugin/public'; + import { getSampleDashboardInput, getSampleDashboardPanel } from '../../../mocks'; import { DashboardEmbeddableService } from '../../embeddable/types'; import { SavedDashboardInput } from '../types'; @@ -29,6 +32,23 @@ describe('Migrate dashboard input', () => { panel3: getSampleDashboardPanel({ type: 'ultraDiscover', explicitInput: { id: 'panel3' } }), panel4: getSampleDashboardPanel({ type: 'ultraDiscover', explicitInput: { id: 'panel4' } }), }; + const controlGroupInput = { chainingSystem: 'NONE', panels: {} } as ControlGroupInput; + controlGroupInputBuilder.addOptionsListControl(controlGroupInput, { + dataViewId: 'positions-remain-fixed', + title: 'Results can be mixed', + fieldName: 'theres-a-stasis', + width: 'medium', + grow: false, + }); + controlGroupInputBuilder.addRangeSliderControl(controlGroupInput, { + dataViewId: 'an-object-set-in-motion', + title: 'The arbiter of time', + fieldName: 'unexpressed-emotion', + width: 'medium', + grow: false, + }); + controlGroupInputBuilder.addTimeSliderControl(controlGroupInput); + dashboardInput.controlGroupInput = controlGroupInput; const embeddableService: DashboardEmbeddableService = { getEmbeddableFactory: jest.fn(() => ({ @@ -42,8 +62,11 @@ describe('Migrate dashboard input', () => { // migration run should be true because the runEmbeddableFactoryMigrations mock above returns true. expect(result.anyMigrationRun).toBe(true); - expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledTimes(4); // should be called 4 times for the panels, and 3 times for the controls + expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledTimes(7); // should be called 4 times for the panels, and 3 times for the controls expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledWith('superLens'); expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledWith('ultraDiscover'); + expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledWith('optionsListControl'); + expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledWith('rangeSliderControl'); + expect(embeddableService.getEmbeddableFactory).toHaveBeenCalledWith('timeSlider'); }); }); diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts index 70a6df30303dd..46e57588a2c95 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/migrate_dashboard_input.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { ControlGroupInput } from '@kbn/controls-plugin/common'; import { EmbeddableFactoryNotFoundError, runEmbeddableFactoryMigrations, @@ -30,7 +31,28 @@ export const migrateDashboardInput = ( } = pluginServices.getServices(); let anyMigrationRun = false; if (!dashboardInput) return dashboardInput; + if (dashboardInput.controlGroupInput) { + /** + * If any Control Group migrations are required, we will need to start storing a Control Group Input version + * string in Dashboard Saved Objects and then running the whole Control Group input through the embeddable + * factory migrations here. + */ + // Migrate all of the Control children as well. + const migratedControls: ControlGroupInput['panels'] = {}; + + Object.entries(dashboardInput.controlGroupInput.panels).forEach(([id, panel]) => { + const factory = embeddable.getEmbeddableFactory(panel.type); + if (!factory) throw new EmbeddableFactoryNotFoundError(panel.type); + const { input: newInput, migrationRun: controlMigrationRun } = runEmbeddableFactoryMigrations( + panel.explicitInput, + factory + ); + if (controlMigrationRun) anyMigrationRun = true; + panel.explicitInput = newInput as DashboardPanelState['explicitInput']; + migratedControls[id] = panel; + }); + } const migratedPanels: DashboardContainerInput['panels'] = {}; for (const [id, panel] of Object.entries(dashboardInput.panels)) { // if the panel type is registered in the new embeddable system, we do not need to run migrations for it. diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/save_dashboard_state.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/save_dashboard_state.ts index 94ebcd0702f2c..c69f7fa065a7b 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/save_dashboard_state.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/save_dashboard_state.ts @@ -9,6 +9,12 @@ import { pick } from 'lodash'; import moment, { Moment } from 'moment'; +import { + controlGroupInputToRawControlGroupAttributes, + generateNewControlIds, + getDefaultControlGroupInput, + persistableControlGroupInputIsEqual, +} from '@kbn/controls-plugin/common'; import { extractSearchSourceReferences, RefreshInterval } from '@kbn/data-plugin/public'; import { isFilterPinned } from '@kbn/es-query'; @@ -23,10 +29,24 @@ import { DashboardContentManagementRequiredServices, SaveDashboardProps, SaveDashboardReturn, + SavedDashboardInput, } from '../types'; import { convertDashboardVersionToNumber } from './dashboard_versioning'; import { generateNewPanelIds } from '../../../../common/lib/dashboard_panel_converters'; +export const serializeControlGroupInput = ( + controlGroupInput: SavedDashboardInput['controlGroupInput'] +) => { + // only save to saved object if control group is not default + if ( + !controlGroupInput || + persistableControlGroupInputIsEqual(controlGroupInput, getDefaultControlGroupInput()) + ) { + return undefined; + } + return controlGroupInputToRawControlGroupAttributes(controlGroupInput); +}; + export const convertTimeToUTCString = (time?: string | Moment): undefined | string => { if (moment(time).isValid()) { return moment(time).utc().format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'); @@ -48,7 +68,6 @@ type SaveDashboardStateProps = SaveDashboardProps & { }; export const saveDashboardState = async ({ - controlGroupReferences, data, embeddable, lastSavedId, @@ -81,10 +100,9 @@ export const saveDashboardState = async ({ syncCursor, syncTooltips, hidePanelTitles, - controlGroupInput, } = currentState; - let { panels } = currentState; + let { panels, controlGroupInput } = currentState; let prefixedPanelReferences = panelReferences; if (saveOptions.saveAsCopy) { const { panels: newPanels, references: newPanelReferences } = generateNewPanelIds( @@ -93,10 +111,7 @@ export const saveDashboardState = async ({ ); panels = newPanels; prefixedPanelReferences = newPanelReferences; - // - // do not need to generate new ids for controls. - // ControlGroup Component is keyed on dashboard id so changing dashboard id mounts new ControlGroup Component. - // + controlGroupInput = generateNewControlIds(controlGroupInput); } /** @@ -144,7 +159,7 @@ export const saveDashboardState = async ({ const rawDashboardAttributes: DashboardAttributes = { version: convertDashboardVersionToNumber(LATEST_DASHBOARD_CONTAINER_VERSION), - controlGroupInput, + controlGroupInput: serializeControlGroupInput(controlGroupInput), kibanaSavedObjectMeta: { searchSourceJSON }, description: description ?? '', refreshInterval, @@ -171,11 +186,7 @@ export const saveDashboardState = async ({ ? savedObjectsTagging.updateTagsReferences(dashboardReferences, tags) : dashboardReferences; - const allReferences = [ - ...references, - ...(prefixedPanelReferences ?? []), - ...(controlGroupReferences ?? []), - ]; + const allReferences = [...references, ...(prefixedPanelReferences ?? [])]; /** * Save the saved object using the content management diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/types.ts b/src/plugins/dashboard/public/services/dashboard_content_management/types.ts index 3caa5f73e65b2..ac8b921672e2d 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/types.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/types.ts @@ -7,11 +7,11 @@ */ import type { Reference } from '@kbn/content-management-utils'; +import { PersistableControlGroupInput } from '@kbn/controls-plugin/common'; import { SavedObjectSaveOpts } from '@kbn/saved-objects-plugin/public'; -import { ControlGroupRuntimeState } from '@kbn/controls-plugin/public'; import { DashboardContainerInput } from '../../../common'; -import { DashboardAttributes, DashboardCrudTypes } from '../../../common/content_management'; +import { DashboardCrudTypes } from '../../../common/content_management'; import { DashboardStartDependencies } from '../../plugin'; import { DashboardBackupServiceType } from '../dashboard_backup/types'; import { DashboardDataService } from '../data/types'; @@ -64,17 +64,7 @@ export interface LoadDashboardFromSavedObjectProps { type DashboardResolveMeta = DashboardCrudTypes['GetOut']['meta']; export type SavedDashboardInput = DashboardContainerInput & { - /** - * Serialized control group state. - * Contains state loaded from dashboard saved object - */ - controlGroupInput?: DashboardAttributes['controlGroupInput'] | undefined; - /** - * Runtime control group state. - * Contains state passed from dashboard locator - * Use runtime state when building input for portable dashboards - */ - controlGroupState?: Partial; + controlGroupInput?: PersistableControlGroupInput; }; export interface LoadDashboardReturn { @@ -99,7 +89,6 @@ export interface LoadDashboardReturn { export type SavedDashboardSaveOpts = SavedObjectSaveOpts & { saveAsCopy?: boolean }; export interface SaveDashboardProps { - controlGroupReferences?: Reference[]; currentState: SavedDashboardInput; saveOptions: SavedDashboardSaveOpts; panelReferences?: Reference[]; diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts index 3a847ce939981..3cdf2428bf389 100644 --- a/src/plugins/data_views/public/plugin.ts +++ b/src/plugins/data_views/public/plugin.ts @@ -41,8 +41,11 @@ export class DataViewsPublicPlugin { private readonly hasData = new HasData(); private rollupsEnabled: boolean = false; + private readonly callResolveCluster: boolean; - constructor(private readonly initializerContext: PluginInitializerContext) {} + constructor(private readonly initializerContext: PluginInitializerContext) { + this.callResolveCluster = initializerContext.env.packageInfo.buildFlavor === 'traditional'; + } public setup( core: CoreSetup, @@ -83,7 +86,7 @@ export class DataViewsPublicPlugin const config = this.initializerContext.config.get(); return new DataViewsServicePublic({ - hasData: this.hasData.start(core), + hasData: this.hasData.start(core, this.callResolveCluster), uiSettings: new UiSettingsPublicToCommon(uiSettings), savedObjectsClient: new ContentMagementWrapper(contentManagement.client), apiClient: new DataViewsApiClient(http, async () => { diff --git a/src/plugins/data_views/public/services/has_data.test.ts b/src/plugins/data_views/public/services/has_data.test.ts index b2ccf3828af6b..7118aa5cceaf5 100644 --- a/src/plugins/data_views/public/services/has_data.test.ts +++ b/src/plugins/data_views/public/services/has_data.test.ts @@ -11,241 +11,288 @@ import { coreMock } from '@kbn/core/public/mocks'; import { HasData } from './has_data'; describe('when calling hasData service', () => { - it('should return true for hasESData when indices exist', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - aliases: [], - data_streams: [], - indices: [ - { - aliases: [], - attributes: ['open'], - name: 'sample_data_logs', - }, - ], - }) - ); - - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasESData(); - - expect(spy).toHaveBeenCalledTimes(1); - - expect(await response).toBe(true); - }); - - it('should return false for hasESData when no indices exist', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - aliases: [], - data_streams: [], - indices: [], - }) - ); - - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasESData(); - - expect(spy).toHaveBeenCalledTimes(1); - - expect(await response).toBe(false); - }); - - it('should return false for hasESData when only automatically created sources exist', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation((path: any) => - Promise.resolve({ - aliases: [], - data_streams: path.includes('*:*') - ? [] // return empty on remote cluster call - : [ - { - name: 'logs-enterprise_search.api-default', - timestamp_field: '@timestamp', - backing_indices: ['.ds-logs-enterprise_search.api-default-2022.03.07-000001'], - }, - ], - indices: [], - }) - ); - - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasESData(); - - expect(spy).toHaveBeenCalledTimes(1); - - expect(await response).toBe(false); - }); - - it('should hit search api in case resolve api throws', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - const spyGetIndices = jest - .spyOn(http, 'get') - .mockImplementation(() => Promise.reject(new Error('oops'))); - - const spySearch = jest - .spyOn(http, 'post') - .mockImplementation(() => Promise.resolve({ total: 10 })); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = await hasDataService.hasESData(); + describe('hasDataView', () => { + it('should return true for hasDataView when server returns true', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation(() => + Promise.resolve({ + hasDataView: true, + hasUserDataView: true, + }) + ); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasDataView(); + + expect(spy).toHaveBeenCalledTimes(1); - expect(response).toBe(true); + expect(await response).toBe(true); + }); + + it('should return false for hasDataView when server returns false', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation(() => + Promise.resolve({ + hasDataView: false, + hasUserDataView: true, + }) + ); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasDataView(); + + expect(spy).toHaveBeenCalledTimes(1); + + expect(await response).toBe(false); + }); + + it('should return true for hasDataView when server throws an error', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + // Mock getIndices + const spy = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.reject(new Error('Oops'))); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasDataView(); + + expect(spy).toHaveBeenCalledTimes(1); + + expect(await response).toBe(true); + }); + + it('should return false for hasUserDataView when server returns false', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation(() => + Promise.resolve({ + hasDataView: true, + hasUserDataView: false, + }) + ); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasUserDataView(); + + expect(spy).toHaveBeenCalledTimes(1); + + expect(await response).toBe(false); + }); + + it('should return true for hasUserDataView when server returns true', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation(() => + Promise.resolve({ + hasDataView: true, + hasUserDataView: true, + }) + ); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasUserDataView(); + + expect(spy).toHaveBeenCalledTimes(1); + + expect(await response).toBe(true); + }); - expect(spyGetIndices).toHaveBeenCalledTimes(1); - expect(spySearch).toHaveBeenCalledTimes(1); - }); - - it('should return false in case search api throws', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; + it('should return true for hasUserDataView when server throws an error', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - const spyGetIndices = jest - .spyOn(http, 'get') - .mockImplementation(() => Promise.reject(new Error('oops'))); + // Mock getIndices + const spy = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.reject(new Error('Oops'))); - const spySearch = jest - .spyOn(http, 'post') - .mockImplementation(() => Promise.reject(new Error('oops'))); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = await hasDataService.hasESData(); + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasUserDataView(); - expect(response).toBe(true); + expect(spy).toHaveBeenCalledTimes(1); - expect(spyGetIndices).toHaveBeenCalledTimes(1); - expect(spySearch).toHaveBeenCalledTimes(1); + expect(await response).toBe(true); + }); }); + describe('hasESData', () => { + describe('resolve/cluster is available', () => { + it('should return true for hasESData when indices exist', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - it('should return true for hasDataView when server returns true', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - hasDataView: true, - hasUserDataView: true, - }) - ); - - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasDataView(); - - expect(spy).toHaveBeenCalledTimes(1); - - expect(await response).toBe(true); - }); - - it('should return false for hasDataView when server returns false', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; - - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - hasDataView: false, - hasUserDataView: true, - }) - ); - - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasDataView(); - - expect(spy).toHaveBeenCalledTimes(1); + // Mock getIndices + const spy = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.resolve({ hasEsData: true })); - expect(await response).toBe(false); - }); - - it('should return true for hasDataView when server throws an error', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasESData(); - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => Promise.reject(new Error('Oops'))); + expect(spy).toHaveBeenCalledTimes(1); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasDataView(); + expect(await response).toBe(true); + }); - expect(spy).toHaveBeenCalledTimes(1); + it('should return false for hasESData when no indices exist', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - expect(await response).toBe(true); - }); + // Mock getIndices + const spy = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.resolve({ hasEsData: false })); - it('should return false for hasUserDataView when server returns false', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, true); + const response = hasDataService.hasESData(); - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - hasDataView: true, - hasUserDataView: false, - }) - ); + expect(spy).toHaveBeenCalledTimes(1); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasUserDataView(); + expect(await response).toBe(false); + }); + }); - expect(spy).toHaveBeenCalledTimes(1); + describe('resolve/cluster not available', () => { + it('should return true for hasESData when indices exist', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - expect(await response).toBe(false); - }); + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementationOnce(() => + Promise.resolve({ + aliases: [], + data_streams: [], + indices: [ + { + aliases: [], + attributes: ['open'], + name: 'sample_data_logs', + }, + ], + }) + ); - it('should return true for hasUserDataView when server returns true', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, false); + const response = hasDataService.hasESData(); - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => - Promise.resolve({ - hasDataView: true, - hasUserDataView: true, - }) - ); + expect(spy).toHaveBeenCalledTimes(1); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasUserDataView(); + expect(await response).toBe(true); + }); - expect(spy).toHaveBeenCalledTimes(1); + it('should return false for hasESData when no indices exist', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - expect(await response).toBe(true); - }); + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation(() => + Promise.resolve({ + aliases: [], + data_streams: [], + indices: [], + }) + ); - it('should return true for hasUserDataView when server throws an error', async () => { - const coreStart = coreMock.createStart(); - const http = coreStart.http; + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, false); + const response = hasDataService.hasESData(); - // Mock getIndices - const spy = jest.spyOn(http, 'get').mockImplementation(() => Promise.reject(new Error('Oops'))); + expect(spy).toHaveBeenCalledTimes(1); - const hasData = new HasData(); - const hasDataService = hasData.start(coreStart); - const response = hasDataService.hasUserDataView(); + expect(await response).toBe(false); + }); - expect(spy).toHaveBeenCalledTimes(1); + it('should return false for hasESData when only automatically created sources exist', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; - expect(await response).toBe(true); + // Mock getIndices + const spy = jest.spyOn(http, 'get').mockImplementation((path: any) => + Promise.resolve({ + aliases: [], + data_streams: path.includes('*:*') + ? [] // return empty on remote cluster call + : [ + { + name: 'logs-enterprise_search.api-default', + timestamp_field: '@timestamp', + backing_indices: ['.ds-logs-enterprise_search.api-default-2022.03.07-000001'], + }, + ], + indices: [], + }) + ); + + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, false); + const response = hasDataService.hasESData(); + + expect(spy).toHaveBeenCalledTimes(1); + + expect(await response).toBe(false); + }); + + it('should hit search api in case resolve api throws', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + const spyGetIndices = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.reject(new Error('oops'))); + + const spySearch = jest + .spyOn(http, 'post') + .mockImplementation(() => Promise.resolve({ total: 10 })); + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, false); + const response = await hasDataService.hasESData(); + + expect(response).toBe(true); + + expect(spyGetIndices).toHaveBeenCalledTimes(1); + expect(spySearch).toHaveBeenCalledTimes(1); + }); + + it('should return false in case search api throws', async () => { + const coreStart = coreMock.createStart(); + const http = coreStart.http; + + const spyGetIndices = jest + .spyOn(http, 'get') + .mockImplementation(() => Promise.reject(new Error('oops'))); + + const spySearch = jest + .spyOn(http, 'post') + .mockImplementation(() => Promise.reject(new Error('oops'))); + const hasData = new HasData(); + const hasDataService = hasData.start(coreStart, false); + const response = await hasDataService.hasESData(); + + expect(response).toBe(true); + + expect(spyGetIndices).toHaveBeenCalledTimes(1); + expect(spySearch).toHaveBeenCalledTimes(1); + }); + }); }); }); diff --git a/src/plugins/data_views/public/services/has_data.ts b/src/plugins/data_views/public/services/has_data.ts index 1e32825ec498b..a33e330bdb0ac 100644 --- a/src/plugins/data_views/public/services/has_data.ts +++ b/src/plugins/data_views/public/services/has_data.ts @@ -24,19 +24,43 @@ export class HasData { return true; }; - start(core: CoreStart) { + start(core: CoreStart, callResolveCluster: boolean) { const { http } = core; + + const hasESDataViaResolveIndex = async () => { + // fallback to previous implementation + const hasLocalESData = await this.checkLocalESData(http); + if (!hasLocalESData) { + const hasRemoteESData = await this.checkRemoteESData(http); + return hasRemoteESData; + } + return hasLocalESData; + }; + + const hasESDataViaResolveCluster = async () => { + try { + const { hasEsData } = await http.get<{ hasEsData: boolean }>( + '/internal/data_views/has_es_data', + { + version: '1', + } + ); + return hasEsData; + } catch (e) { + // fallback to previous implementation + return hasESDataViaResolveIndex(); + } + }; + return { /** * Check to see if ES data exists */ hasESData: async (): Promise => { - const hasLocalESData = await this.checkLocalESData(http); - if (!hasLocalESData) { - const hasRemoteESData = await this.checkRemoteESData(http); - return hasRemoteESData; + if (callResolveCluster) { + return hasESDataViaResolveCluster(); } - return hasLocalESData; + return hasESDataViaResolveIndex(); }, /** * Check to see if a data view exists diff --git a/src/plugins/data_views/server/rest_api_routes/internal/has_es_data.ts b/src/plugins/data_views/server/rest_api_routes/internal/has_es_data.ts new file mode 100644 index 0000000000000..6cd3e96ddfae6 --- /dev/null +++ b/src/plugins/data_views/server/rest_api_routes/internal/has_es_data.ts @@ -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 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 or the Server + * Side Public License, v 1. + */ + +import { IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { VersionedRoute } from '@kbn/core-http-server'; +import { schema } from '@kbn/config-schema'; +import { DEFAULT_ASSETS_TO_IGNORE } from '../../../common'; + +type Handler = Parameters['addVersion']>[1]; + +const patterns = ['*', '-.*'].concat( + DEFAULT_ASSETS_TO_IGNORE.DATA_STREAMS_TO_IGNORE.map((ds) => `-${ds}`) +); + +const crossClusterPatterns = patterns.map((ds) => `*:${ds}`); + +export const handler: Handler = async (ctx: RequestHandlerContext, req, res) => { + const core = await ctx.core; + const elasticsearchClient = core.elasticsearch.client.asCurrentUser; + const response = await elasticsearchClient.indices.resolveCluster({ + name: patterns.concat(crossClusterPatterns), + allow_no_indices: true, + ignore_unavailable: true, + }); + + const hasEsData = !!Object.values(response).find((cluster) => cluster.matching_indices); + + return res.ok({ body: { hasEsData } }); +}; + +export const registerHasEsDataRoute = (router: IRouter): void => { + router.versioned + .get({ + path: '/internal/data_views/has_es_data', + access: 'internal', + }) + .addVersion( + { + version: '1', + validate: { + response: { + 200: { + body: () => + schema.object({ + hasEsData: schema.boolean(), + }), + }, + }, + }, + }, + handler + ); +}; diff --git a/src/plugins/data_views/server/routes.ts b/src/plugins/data_views/server/routes.ts index d6ee36927ff80..54adfb0cf628d 100644 --- a/src/plugins/data_views/server/routes.ts +++ b/src/plugins/data_views/server/routes.ts @@ -14,6 +14,7 @@ import type { DataViewsServerPluginStart, DataViewsServerPluginStartDependencies import { registerExistingIndicesPath } from './rest_api_routes/internal/existing_indices'; import { registerFieldForWildcard } from './rest_api_routes/internal/fields_for'; import { registerHasDataViewsRoute } from './rest_api_routes/internal/has_data_views'; +import { registerHasEsDataRoute } from './rest_api_routes/internal/has_es_data'; import { registerFields } from './rest_api_routes/internal/fields'; interface RegisterRoutesArgs { @@ -40,4 +41,5 @@ export function registerRoutes({ registerFieldForWildcard(router, getStartServices, isRollupsEnabled); registerFields(router, getStartServices, isRollupsEnabled); registerHasDataViewsRoute(router); + registerHasEsDataRoute(router); } diff --git a/src/plugins/discover/public/application/doc/components/doc.tsx b/src/plugins/discover/public/application/doc/components/doc.tsx index eb706e59e2a34..a10cd4b8a14f9 100644 --- a/src/plugins/discover/public/application/doc/components/doc.tsx +++ b/src/plugins/discover/public/application/doc/components/doc.tsx @@ -14,6 +14,7 @@ import { i18n } from '@kbn/i18n'; import { ElasticRequestState } from '@kbn/unified-doc-viewer'; import { useEsDocSearch } from '@kbn/unified-doc-viewer-plugin/public'; import type { EsDocSearchProps } from '@kbn/unified-doc-viewer-plugin/public/types'; +import type { DataTableRecord } from '@kbn/discover-utils/types'; import { setBreadcrumbs } from '../../../utils/breadcrumbs'; import { useDiscoverServices } from '../../../hooks/use_discover_services'; import { SingleDocViewer } from './single_doc_viewer'; @@ -43,7 +44,7 @@ export function Doc(props: DocProps) { }, [profilesManager, core, dataView]); const onProcessRecord = useCallback( - (record) => { + (record: DataTableRecord) => { return profilesManager.resolveDocumentProfile({ record }); }, [profilesManager] diff --git a/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx b/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx index 800b143213227..2be1f3fe26984 100644 --- a/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx +++ b/src/plugins/discover/public/application/main/components/field_stats_table/field_stats_table.tsx @@ -20,6 +20,7 @@ import { SmartFieldFallbackTooltip, } from '@kbn/unified-field-list'; import type { DataVisualizerTableItem } from '@kbn/data-visualizer-plugin/public/application/common/components/stats_table/types'; +import type { DataVisualizerTableState } from '@kbn/data-visualizer-plugin/common/types'; import { isOfAggregateQueryType } from '@kbn/es-query'; import { useDiscoverServices } from '../../../../hooks/use_discover_services'; import { FIELD_STATISTICS_LOADED } from './constants'; @@ -146,7 +147,7 @@ export const FieldStatisticsTable = React.memo((props: FieldStatisticsTableProps ); const updateState = useCallback( - (changes) => { + (changes: Partial) => { if (changes.showDistributions !== undefined && stateContainer) { stateContainer.appState.update({ hideAggregatedPreview: !changes.showDistributions }, true); } diff --git a/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx b/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx index 481647e18c156..87d354b2cbac4 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/esql_dataview_transition/esql_dataview_transition_modal.tsx @@ -34,7 +34,7 @@ export default function ESQLToDataViewTransitionModal({ onClose, }: ESQLToDataViewTransitionModalProps) { const [dismissModalChecked, setDismissModalChecked] = useState(false); - const onTransitionModalDismiss = useCallback((e) => { + const onTransitionModalDismiss = useCallback((e: React.ChangeEvent) => { setDismissModalChecked(e.target.checked); }, []); diff --git a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx index cbb93c413af8e..6bf68afa912c7 100644 --- a/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx +++ b/src/plugins/discover/public/embeddable/get_search_embeddable_factory.tsx @@ -27,6 +27,7 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { VIEW_MODE } from '@kbn/saved-search-plugin/common'; import { SearchResponseIncompleteWarning } from '@kbn/search-response-warnings/src/types'; +import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; import { getValidViewMode } from '../application/main/utils/get_valid_view_mode'; import { DiscoverServices } from '../build_services'; import { SearchEmbeddablFieldStatsTableComponent } from './components/search_embeddable_field_stats_table_component'; @@ -242,9 +243,9 @@ export const getSearchEmbeddableFactory = ({ return dataViews![0]; }, [dataViews]); - const onAddFilter = useCallback( + const onAddFilter = useCallback( async (field, value, operator) => { - if (!dataView) return; + if (!dataView || !field) return; let newFilters = generateFilters( discoverServices.filterManager, diff --git a/src/plugins/embeddable/public/lib/containers/container.ts b/src/plugins/embeddable/public/lib/containers/container.ts index e4ce579104bb5..cac385dd2c86d 100644 --- a/src/plugins/embeddable/public/lib/containers/container.ts +++ b/src/plugins/embeddable/public/lib/containers/container.ts @@ -82,9 +82,6 @@ export abstract class Container< const init$ = this.getInput$().pipe( take(1), mergeMap(async (currentInput) => { - if (settings?.untilContainerInitialized) { - await settings.untilContainerInitialized(); - } const initPromise = this.initializeChildEmbeddables(currentInput, settings); if (awaitingInitialize) await initPromise; }) diff --git a/src/plugins/embeddable/public/lib/containers/i_container.ts b/src/plugins/embeddable/public/lib/containers/i_container.ts index 5ee9b0a250adc..53226e7d15146 100644 --- a/src/plugins/embeddable/public/lib/containers/i_container.ts +++ b/src/plugins/embeddable/public/lib/containers/i_container.ts @@ -37,8 +37,6 @@ export interface EmbeddableContainerSettings { * Initialise children in the order specified. If an ID does not match it will be skipped and if a child is not included it will be initialized in the default order after the list of provided IDs. */ childIdInitializeOrder?: string[]; - - untilContainerInitialized?: () => Promise; } export interface IContainer< diff --git a/src/plugins/embeddable/public/lib/embeddables/common/constants.ts b/src/plugins/embeddable/public/lib/embeddables/common/constants.ts index 78228ec370a0e..3a47125a039c5 100644 --- a/src/plugins/embeddable/public/lib/embeddables/common/constants.ts +++ b/src/plugins/embeddable/public/lib/embeddables/common/constants.ts @@ -10,20 +10,13 @@ import { i18n } from '@kbn/i18n'; import { UiActionsPresentableGroup } from '@kbn/ui-actions-plugin/public'; export const COMMON_EMBEDDABLE_GROUPING: { [key: string]: UiActionsPresentableGroup } = { - legacy: { - id: 'legacy', - getDisplayName: () => - i18n.translate('embeddableApi.common.constants.grouping.legacy', { - defaultMessage: 'Legacy', - }), - order: -2, - }, annotation: { id: 'annotation-and-navigation', getDisplayName: () => i18n.translate('embeddableApi.common.constants.grouping.annotations', { defaultMessage: 'Annotations and Navigation', }), + order: 900, // This is the order of the group in the context menu }, other: { id: 'other', @@ -32,6 +25,14 @@ export const COMMON_EMBEDDABLE_GROUPING: { [key: string]: UiActionsPresentableGr defaultMessage: 'Other', }), getIconType: () => 'empty', - order: -1, + order: -1, // Given an item that doesn't specify a group is assigned zero, this forces other to come after all intentionally grouped section + }, + legacy: { + id: 'legacy', + getDisplayName: () => + i18n.translate('embeddableApi.common.constants.grouping.legacy', { + defaultMessage: 'Legacy', + }), + order: -2, // Given an item that doesn't specify a group is assigned zero, this forces it to the bottom of the list }, }; diff --git a/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts b/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts index e34fc02acd6be..57cfe3350420a 100644 --- a/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts +++ b/src/plugins/embeddable/public/lib/embeddables/compatibility/embeddable_compatibility_utils.ts @@ -51,11 +51,7 @@ export const embeddableInputToSubject = < subscription.add( embeddable .getInput$() - .pipe( - distinctUntilKeyChanged(key, (prev, current) => { - return deepEqual(prev, current); - }) - ) + .pipe(distinctUntilKeyChanged(key)) .subscribe(() => subject.next(embeddable.getInput()?.[key] as ValueType)) ); } diff --git a/src/plugins/embeddable/public/lib/embeddables/diff_embeddable_input.ts b/src/plugins/embeddable/public/lib/embeddables/diff_embeddable_input.ts index 79e7b5b99bc60..16b41ec9cc23c 100644 --- a/src/plugins/embeddable/public/lib/embeddables/diff_embeddable_input.ts +++ b/src/plugins/embeddable/public/lib/embeddables/diff_embeddable_input.ts @@ -58,19 +58,16 @@ export const genericEmbeddableInputIsEqual = ( const { title: currentTitle, hidePanelTitles: currentHidePanelTitles, - enhancements: currentEnhancements, ...current } = pick(currentInput as GenericEmbedableInputToCompare, genericInputKeysToCompare); const { title: lastTitle, hidePanelTitles: lastHidePanelTitles, - enhancements: lastEnhancements, ...last } = pick(lastInput as GenericEmbedableInputToCompare, genericInputKeysToCompare); if (currentTitle !== lastTitle) return false; if (Boolean(currentHidePanelTitles) !== Boolean(lastHidePanelTitles)) return false; - if (!fastIsEqual(currentEnhancements ?? {}, lastEnhancements ?? {})) return false; if (!fastIsEqual(current, last)) return false; return true; }; diff --git a/src/plugins/esql_datagrid/public/data_grid.tsx b/src/plugins/esql_datagrid/public/data_grid.tsx index a53cb1b28f351..2ad4b2d63aa7d 100644 --- a/src/plugins/esql_datagrid/public/data_grid.tsx +++ b/src/plugins/esql_datagrid/public/data_grid.tsx @@ -13,6 +13,7 @@ import { DataLoadingState, type SortOrder, renderCustomToolbar, + UnifiedDataTableRenderCustomToolbarProps, } from '@kbn/unified-data-table'; import { i18n } from '@kbn/i18n'; import { EuiLink, EuiText, EuiIcon } from '@elastic/eui'; @@ -67,7 +68,7 @@ const DataGrid: React.FC = (props) => { ); const [rowsPerPage, setRowsPerPage] = useState(DEFAULT_ROWS_PER_PAGE); - const onSetColumns = useCallback((columns) => { + const onSetColumns = useCallback((columns: string[]) => { setActiveColumns(columns); }, []); @@ -146,7 +147,7 @@ const DataGrid: React.FC = (props) => { }, [props.share?.url.locators]); const renderToolbar = useCallback( - (customToolbarProps) => { + (customToolbarProps: UnifiedDataTableRenderCustomToolbarProps) => { const discoverLink = discoverLocator?.getRedirectUrl({ dataViewSpec: props.dataView.toSpec(), timeRange: props.data.query.timefilter.timefilter.getTime(), diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx index 008149966c49d..c5cb3bec36951 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_table/table.tsx @@ -24,6 +24,7 @@ import { useResizeObserver, EuiSwitch, useEuiTheme, + EuiSwitchEvent, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { css } from '@emotion/react'; @@ -367,7 +368,7 @@ export const DocViewerTable = ({ ); const onHideNullValuesChange = useCallback( - (e) => { + (e: EuiSwitchEvent) => { setAreNullValuesHidden(e.target.checked); }, [setAreNullValuesHidden] diff --git a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx index b49f4e33fbb58..d1ae920d46d82 100644 --- a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx +++ b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx @@ -19,6 +19,7 @@ import { Placement, Tooltip, LegendValue, + BrushEndListener, } from '@elastic/charts'; import { EuiTitle } from '@elastic/eui'; import { RangeFilterParams } from '@kbn/es-query'; @@ -120,7 +121,7 @@ export const TimelionVisComponent = ({ isDateHistogram: true, }); - const brushEndListener = useCallback( + const brushEndListener = useCallback( ({ x }) => { if (!x) { return; diff --git a/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts b/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts index f0e4cce0c8adb..683d6a6e7cc22 100644 --- a/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts +++ b/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../ftr_provider_context'; @@ -13,25 +14,77 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const pieChart = getService('pieChart'); const elasticChart = getService('elasticChart'); + const testSubjects = getService('testSubjects'); + const dashboardAddPanel = getService('dashboardAddPanel'); - const { dashboard, header, dashboardControls } = getPageObjects([ + const { dashboard, header, dashboardControls, timePicker } = getPageObjects([ 'dashboardControls', + 'timePicker', 'dashboard', 'header', ]); describe('Dashboard control group apply button', () => { - const optionsListId = '41827e70-5285-4d44-8375-4c498449b9a7'; - const rangeSliderId = '515e7b9f-4f1b-4a06-beec-763810e4951a'; + let controlIds: string[]; before(async () => { await dashboard.navigateToApp(); - await dashboard.loadSavedDashboard('Test Control Group Apply Button'); - await dashboard.switchToEditMode(); + await dashboard.gotoDashboardLandingPage(); + await dashboard.clickNewDashboard(); + await timePicker.setDefaultDataRange(); + await elasticChart.setNewChartUiDebugFlag(); + await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); + + // save the dashboard before adding controls + await dashboard.saveDashboard('Test Control Group Apply Button', { + exitFromEditMode: false, + saveAsNew: true, + }); + await header.waitUntilLoadingHasFinished(); + await dashboard.waitForRenderComplete(); + await dashboard.expectMissingUnsavedChangesBadge(); + + // populate an initial set of controls and get their ids. + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'animal.keyword', + title: 'Animal', + }); + await dashboardControls.createControl({ + controlType: RANGE_SLIDER_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'weightLbs', + title: 'Animal Name', + }); + await dashboardControls.createTimeSliderControl(); + + // wait for all controls to finish loading before saving + controlIds = await dashboardControls.getAllControlIds(); + await dashboardControls.optionsListWaitForLoading(controlIds[0]); + await dashboardControls.rangeSliderWaitForLoading(controlIds[1]); + + // re-save the dashboard + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + await dashboard.waitForRenderComplete(); + await dashboard.expectMissingUnsavedChangesBadge(); + }); + + it('able to set apply button setting', async () => { + await dashboardControls.updateShowApplyButtonSetting(true); + await testSubjects.existOrFail('controlGroup--applyFiltersButton'); + await dashboard.expectUnsavedChangesBadge(); + + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + await dashboard.expectMissingUnsavedChangesBadge(); }); it('renabling auto-apply forces filters to be published', async () => { + const optionsListId = controlIds[0]; + await dashboardControls.verifyApplyButtonEnabled(false); await dashboardControls.optionsListOpenPopover(optionsListId); await dashboardControls.optionsListPopoverSelectOption('cat'); await dashboardControls.optionsListEnsurePopoverIsClosed(optionsListId); @@ -48,7 +101,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); describe('options list selections', () => { + let optionsListId: string; + + before(async () => { + optionsListId = controlIds[0]; + }); + it('making selection enables apply button', async () => { + await dashboardControls.verifyApplyButtonEnabled(false); await dashboardControls.optionsListOpenPopover(optionsListId); await dashboardControls.optionsListPopoverSelectOption('cat'); await dashboardControls.optionsListEnsurePopoverIsClosed(optionsListId); @@ -57,6 +117,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('waits to apply filters until button is pressed', async () => { + await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); await dashboardControls.clickApplyButton(); @@ -78,19 +139,27 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await header.waitUntilLoadingHasFinished(); await dashboard.waitForRenderComplete(); - await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); + await dashboardControls.verifyApplyButtonEnabled(false); expect(await dashboardControls.optionsListGetSelectionsString(optionsListId)).to.be('Any'); }); }); describe('range slider selections', () => { + let rangeSliderId: string; + + before(async () => { + rangeSliderId = controlIds[1]; + }); + it('making selection enables apply button', async () => { + await dashboardControls.verifyApplyButtonEnabled(false); await dashboardControls.rangeSliderSetUpperBound(rangeSliderId, '30'); await dashboardControls.verifyApplyButtonEnabled(); }); it('waits to apply filters until apply button is pressed', async () => { + await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); await dashboardControls.clickApplyButton(); @@ -111,8 +180,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await header.waitUntilLoadingHasFinished(); await dashboard.waitForRenderComplete(); - await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); + await dashboardControls.verifyApplyButtonEnabled(false); expect( await dashboardControls.rangeSliderGetLowerBoundAttribute(rangeSliderId, 'value') ).to.be(''); @@ -130,6 +199,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('making selection enables apply button', async () => { + await dashboardControls.verifyApplyButtonEnabled(false); await dashboardControls.gotoNextTimeSlice(); await dashboardControls.gotoNextTimeSlice(); // go to an empty timeslice await header.waitUntilLoadingHasFinished(); @@ -137,6 +207,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('waits to apply timeslice until apply button is pressed', async () => { + await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); await dashboardControls.clickApplyButton(); @@ -155,8 +226,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await header.waitUntilLoadingHasFinished(); await dashboard.waitForRenderComplete(); - await dashboard.expectMissingUnsavedChangesBadge(); expect(await pieChart.getPieSliceCount()).to.be(5); + await dashboardControls.verifyApplyButtonEnabled(false); const valueNow = await dashboardControls.getTimeSliceFromTimeSlider(); expect(valueNow).to.equal(valueBefore); }); diff --git a/test/functional/apps/dashboard_elements/controls/common/multiple_data_views.ts b/test/functional/apps/dashboard_elements/controls/common/multiple_data_views.ts index f20052add7243..5a07e60d45695 100644 --- a/test/functional/apps/dashboard_elements/controls/common/multiple_data_views.ts +++ b/test/functional/apps/dashboard_elements/controls/common/multiple_data_views.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../ftr_provider_context'; @@ -16,29 +17,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const filterBar = getService('filterBar'); const testSubjects = getService('testSubjects'); - const { dashboard, dashboardControls } = getPageObjects([ + const dashboardAddPanel = getService('dashboardAddPanel'); + const { common, dashboard, dashboardControls } = getPageObjects([ 'dashboardControls', 'dashboard', 'console', + 'common', 'header', ]); describe('Dashboard control group with multiple data views', () => { - // Controls from flights data view - const carrierControlId = '265b6a28-9ccb-44ae-83c9-3d7a7cac1961'; - const ticketPriceControlId = 'ed2b93e2-da37-482b-ae43-586a41cc2399'; - // Controls from logstash-* data view - const osControlId = '5e1b146b-8a8b-4117-9218-c4aeaee7bc9a'; - const bytesControlId = 'c4760951-e793-45d5-a6b7-c72c145af7f9'; - - async function waitForAllConrolsLoading() { - await Promise.all([ - dashboardControls.optionsListWaitForLoading(carrierControlId), - dashboardControls.rangeSliderWaitForLoading(ticketPriceControlId), - dashboardControls.optionsListWaitForLoading(osControlId), - dashboardControls.rangeSliderWaitForLoading(bytesControlId), - ]); - } + let controlIds: string[]; before(async () => { await security.testUser.setRoles(['kibana_admin', 'kibana_sample_admin']); @@ -50,12 +39,50 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.load( 'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern' ); - await kibanaServer.importExport.load( - 'test/functional/fixtures/kbn_archiver/dashboard/current/multi_data_view_kibana' - ); await kibanaServer.uiSettings.replace({ defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c', + 'courier:ignoreFilterIfFieldNotInIndex': true, + }); + + await common.setTime({ + from: 'Apr 10, 2018 @ 00:00:00.000', + to: 'Nov 15, 2018 @ 00:00:00.000', + }); + + await dashboard.navigateToApp(); + await dashboard.clickNewDashboard(); + + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'kibana_sample_data_flights', + fieldName: 'Carrier', + title: 'Carrier', + }); + + await dashboardControls.createControl({ + controlType: RANGE_SLIDER_CONTROL, + dataViewTitle: 'kibana_sample_data_flights', + fieldName: 'AvgTicketPrice', + title: 'Average Ticket Price', }); + + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'logstash-*', + fieldName: 'machine.os.raw', + title: 'Operating System', + }); + + await dashboardControls.createControl({ + controlType: RANGE_SLIDER_CONTROL, + dataViewTitle: 'logstash-*', + fieldName: 'bytes', + title: 'Bytes', + }); + + await dashboardAddPanel.addSavedSearch('logstash hits'); + + controlIds = await dashboardControls.getAllControlIds(); }); after(async () => { @@ -66,169 +93,96 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await kibanaServer.importExport.unload( 'test/functional/fixtures/kbn_archiver/kibana_sample_data_flights_index_pattern' ); - await kibanaServer.importExport.unload( - 'test/functional/fixtures/kbn_archiver/dashboard/current/multi_data_view_kibana' - ); await security.testUser.restoreDefaults(); + await kibanaServer.uiSettings.unset('courier:ignoreFilterIfFieldNotInIndex'); await kibanaServer.uiSettings.unset('defaultIndex'); }); - describe('courier:ignoreFilterIfFieldNotInIndex enabled', () => { - before(async () => { - await kibanaServer.uiSettings.replace({ - 'courier:ignoreFilterIfFieldNotInIndex': true, - }); + it('ignores global filters on controls using a data view without the filter field', async () => { + await filterBar.addFilter({ field: 'Carrier', operation: 'exists' }); - await dashboard.navigateToApp(); - await dashboard.loadSavedDashboard('Test Control Group With Multiple Data Views'); - }); + await dashboardControls.optionsListOpenPopover(controlIds[0]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('4'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); - after(async () => { - await kibanaServer.uiSettings.unset('courier:ignoreFilterIfFieldNotInIndex'); - }); + await dashboardControls.validateRange('placeholder', controlIds[1], '100', '1200'); - describe('global filters', () => { - before(async () => { - await filterBar.addFilter({ - field: 'Carrier', - operation: 'is', - value: 'Kibana Airlines', - }); - await waitForAllConrolsLoading(); - }); - - after(async () => { - await dashboard.clickDiscardChanges(); - }); - - it('applies global filters to controls with data view of filter field', async () => { - await dashboardControls.optionsListOpenPopover(carrierControlId); - expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('1'); - await dashboardControls.optionsListEnsurePopoverIsClosed(carrierControlId); - - await dashboardControls.validateRange('placeholder', ticketPriceControlId, '100', '1196'); - }); - - it('ignores global filters to controls without data view of filter field', async () => { - await dashboardControls.optionsListOpenPopover(osControlId); - expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('5'); - await dashboardControls.optionsListEnsurePopoverIsClosed(osControlId); - - await dashboardControls.validateRange('placeholder', bytesControlId, '0', '19979'); - }); - }); + await dashboardControls.optionsListOpenPopover(controlIds[2]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('5'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[2]); - describe('control filters', () => { - before(async () => { - await dashboardControls.optionsListOpenPopover(carrierControlId); - await dashboardControls.optionsListPopoverSelectOption('Kibana Airlines'); - await dashboardControls.optionsListEnsurePopoverIsClosed(carrierControlId); - await waitForAllConrolsLoading(); - }); - - after(async () => { - await dashboard.clickDiscardChanges(); - }); - - it('applies control filters to controls with data view of control filter', async () => { - await dashboardControls.validateRange('placeholder', ticketPriceControlId, '100', '1196'); - }); - - it('ignores control filters on controls without data view of control filter', async () => { - await dashboardControls.optionsListOpenPopover(osControlId); - expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('5'); - await dashboardControls.optionsListEnsurePopoverIsClosed(osControlId); - - await dashboardControls.validateRange('placeholder', bytesControlId, '0', '19979'); - }); - - it('ignores control filters on panels without data view of control filter', async () => { - const logstashSavedSearchPanel = await testSubjects.find('embeddedSavedSearchDocTable'); - expect( - await ( - await logstashSavedSearchPanel.findByCssSelector('[data-document-number]') - ).getAttribute('data-document-number') - ).to.not.be('0'); - }); - }); + await dashboardControls.validateRange('placeholder', controlIds[3], '0', '19979'); }); - describe('courier:ignoreFilterIfFieldNotInIndex disabled', () => { - before(async () => { - await kibanaServer.uiSettings.replace({ - 'courier:ignoreFilterIfFieldNotInIndex': false, - }); + it('ignores controls on other controls and panels using a data view without the control field by default', async () => { + await filterBar.removeFilter('Carrier'); + await dashboardControls.optionsListOpenPopover(controlIds[0]); + await dashboardControls.optionsListPopoverSelectOption('Kibana Airlines'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); - await dashboard.navigateToApp(); - await dashboard.loadSavedDashboard('Test Control Group With Multiple Data Views'); - }); + await dashboardControls.validateRange('placeholder', controlIds[1], '100', '1196'); - after(async () => { - await kibanaServer.uiSettings.unset('courier:ignoreFilterIfFieldNotInIndex'); - }); + await dashboardControls.optionsListOpenPopover(controlIds[2]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('5'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[2]); - describe('global filters', () => { - before(async () => { - await filterBar.addFilter({ - field: 'Carrier', - operation: 'is', - value: 'Kibana Airlines', - }); - await waitForAllConrolsLoading(); - }); - - after(async () => { - await dashboard.clickDiscardChanges(); - }); - - it('applies global filters to controls without data view of filter field', async () => { - await dashboardControls.optionsListOpenPopover(osControlId); - expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('0'); - await dashboardControls.optionsListEnsurePopoverIsClosed(osControlId); - - await dashboardControls.validateRange( - 'placeholder', - bytesControlId, - '-Infinity', - 'Infinity' - ); - }); - }); + await dashboardControls.validateRange('placeholder', controlIds[3], '0', '19979'); - describe('control filters', () => { - before(async () => { - await dashboardControls.optionsListOpenPopover(carrierControlId); - await dashboardControls.optionsListPopoverSelectOption('Kibana Airlines'); - await dashboardControls.optionsListEnsurePopoverIsClosed(carrierControlId); - await waitForAllConrolsLoading(); - }); - - after(async () => { - await dashboard.clickDiscardChanges(); - }); - - it('applies control filters on controls without data view of control filter', async () => { - await dashboardControls.optionsListOpenPopover(osControlId); - expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('0'); - await dashboardControls.optionsListEnsurePopoverIsClosed(osControlId); - - await dashboardControls.validateRange( - 'placeholder', - bytesControlId, - '-Infinity', - 'Infinity' - ); - }); - - it('applies control filters on panels without data view of control filter', async () => { - const logstashSavedSearchPanel = await testSubjects.find('embeddedSavedSearchDocTable'); - expect( - await ( - await logstashSavedSearchPanel.findByCssSelector('[data-document-number]') - ).getAttribute('data-document-number') - ).to.be('0'); - }); - }); + const logstashSavedSearchPanel = await testSubjects.find('embeddedSavedSearchDocTable'); + expect( + await ( + await logstashSavedSearchPanel.findByCssSelector('[data-document-number]') + ).getAttribute('data-document-number') + ).to.not.be('0'); + }); + + it('applies global filters on controls using data view a without the filter field', async () => { + await kibanaServer.uiSettings.update({ 'courier:ignoreFilterIfFieldNotInIndex': false }); + await common.navigateToApp('dashboard'); + await testSubjects.click('edit-unsaved-New-Dashboard'); + await filterBar.addFilter({ field: 'Carrier', operation: 'exists' }); + + await Promise.all([ + dashboardControls.optionsListWaitForLoading(controlIds[0]), + dashboardControls.rangeSliderWaitForLoading(controlIds[1]), + dashboardControls.optionsListWaitForLoading(controlIds[2]), + dashboardControls.rangeSliderWaitForLoading(controlIds[3]), + ]); + + await dashboardControls.clearControlSelections(controlIds[0]); + await dashboardControls.optionsListOpenPopover(controlIds[0]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('4'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); + + await dashboardControls.validateRange('placeholder', controlIds[1], '100', '1200'); + + await dashboardControls.optionsListOpenPopover(controlIds[2]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('0'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[2]); + + await dashboardControls.validateRange('placeholder', controlIds[3], '0', '0'); + }); + + it('applies global filters on controls using a data view without the filter field', async () => { + await filterBar.removeFilter('Carrier'); + await dashboardControls.optionsListOpenPopover(controlIds[0]); + await dashboardControls.optionsListPopoverSelectOption('Kibana Airlines'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[0]); + + await dashboardControls.validateRange('placeholder', controlIds[1], '100', '1196'); + + await dashboardControls.optionsListOpenPopover(controlIds[2]); + expect(await dashboardControls.optionsListGetCardinalityValue()).to.be('0'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlIds[2]); + + await dashboardControls.validateRange('placeholder', controlIds[3], '0', '0'); + + const logstashSavedSearchPanel = await testSubjects.find('embeddedSavedSearchDocTable'); + expect( + await ( + await logstashSavedSearchPanel.findByCssSelector('[data-document-number]') + ).getAttribute('data-document-number') + ).to.be('0'); }); }); } diff --git a/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts b/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts index 5d0199fc248e4..22980eb6423a2 100644 --- a/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts +++ b/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts @@ -35,17 +35,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const replaceWithOptionsList = async (controlId: string, field: string) => { await changeFieldType(controlId, field, OPTIONS_LIST_CONTROL); - const newControlId: string = (await dashboardControls.getAllControlIds())[0]; - await testSubjects.waitForEnabled(`optionsList-control-${newControlId}`); - await dashboardControls.verifyControlType(newControlId, 'optionsList-control'); + await testSubjects.waitForEnabled(`optionsList-control-${controlId}`); + await dashboardControls.verifyControlType(controlId, 'optionsList-control'); }; const replaceWithRangeSlider = async (controlId: string, field: string) => { await changeFieldType(controlId, field, RANGE_SLIDER_CONTROL); await retry.try(async () => { - const newControlId: string = (await dashboardControls.getAllControlIds())[0]; - await dashboardControls.rangeSliderWaitForLoading(newControlId); - await dashboardControls.verifyControlType(newControlId, 'range-slider-control'); + await dashboardControls.rangeSliderWaitForLoading(controlId); + await dashboardControls.verifyControlType(controlId, 'range-slider-control'); }); }; @@ -70,6 +68,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Replace options list', () => { beforeEach(async () => { + await dashboardControls.clearAllControls(); await dashboardControls.createControl({ controlType: OPTIONS_LIST_CONTROL, dataViewTitle: 'animals-*', @@ -79,7 +78,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); afterEach(async () => { - await dashboardControls.clearAllControls(); + await dashboard.clearUnsavedChanges(); }); it('with range slider - default title', async () => { @@ -101,6 +100,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Replace range slider', () => { beforeEach(async () => { + await dashboardControls.clearAllControls(); await dashboardControls.createControl({ controlType: RANGE_SLIDER_CONTROL, dataViewTitle: 'animals-*', @@ -111,7 +111,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); afterEach(async () => { - await dashboardControls.clearAllControls(); + await dashboard.clearUnsavedChanges(); }); it('with options list - default title', async () => { diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts index 87d754b053301..220b9819f4466 100644 --- a/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts @@ -17,7 +17,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const { dashboardControls, dashboard, header } = getPageObjects([ 'dashboardControls', + 'timePicker', 'dashboard', + 'settings', + 'console', + 'common', 'header', ]); @@ -48,7 +52,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); - await dashboard.clickDiscardChanges(); }); it('sort alphabetically - descending', async () => { @@ -130,6 +133,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { for (let i = 0; i < sortedSuggestions.length - 1; i++) { expect(sortedSuggestions[i]).to.be.lessThan(sortedSuggestions[i + 1]); } + + // revert to the old field name to keep state consistent for other tests + await dashboardControls.editExistingControl(controlId); + await dashboardControls.controlsEditorSetfield('sound.keyword'); + await dashboardControls.optionsListSetAdditionalSettings({ searchTechnique: 'prefix' }); + await dashboardControls.controlEditorSave(); }); }); diff --git a/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts b/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts index bff1e069b2ff0..fa4322963381c 100644 --- a/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts +++ b/test/functional/apps/dashboard_elements/controls/options_list/options_list_validation.ts @@ -9,6 +9,7 @@ import { pick } from 'lodash'; import expect from '@kbn/expect'; +import { OPTIONS_LIST_CONTROL } from '@kbn/controls-plugin/common'; import { FtrProviderContext } from '../../../../ftr_provider_context'; import { OPTIONS_LIST_ANIMAL_SOUND_SUGGESTIONS } from '../../../../page_objects/dashboard_page_controls'; @@ -17,6 +18,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const queryBar = getService('queryBar'); const pieChart = getService('pieChart'); const filterBar = getService('filterBar'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const dashboardPanelActions = getService('dashboardPanelActions'); const { dashboardControls, dashboard, header } = getPageObjects([ 'dashboardControls', @@ -29,18 +32,41 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ]); describe('Dashboard options list validation', () => { - const controlId = 'cd881630-fd28-4e9c-aec5-ae9711d48369'; + let controlId: string; before(async () => { - await dashboard.loadSavedDashboard('Test Options List Validation'); await dashboard.ensureDashboardIsInEditMode(); + await dashboardControls.createControl({ + controlType: OPTIONS_LIST_CONTROL, + dataViewTitle: 'animals-*', + fieldName: 'sound.keyword', + title: 'Animal Sounds', + }); + controlId = (await dashboardControls.getAllControlIds())[0]; + await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie'); + await dashboard.clickQuickSave(); + await header.waitUntilLoadingHasFinished(); + }); + + after(async () => { + await filterBar.removeAllFilters(); + await dashboardControls.deleteAllControls(); + await dashboardPanelActions.removePanelByTitle('Rendering Test: animal sounds pie'); + await dashboard.clickQuickSave(); }); describe('Options List dashboard validation', () => { + before(async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('meow'); + await dashboardControls.optionsListPopoverSelectOption('bark'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); + }); + after(async () => { - // Instead of reset, filter must be manually deleted to avoid - // https://github.com/elastic/kibana/issues/191675 + await dashboardControls.clearControlSelections(controlId); await filterBar.removeAllFilters(); + await queryBar.clickQuerySubmitButton(); }); it('Can mark selections invalid with Query', async () => { @@ -92,13 +118,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Options List dashboard no validation', () => { before(async () => { + await dashboardControls.optionsListOpenPopover(controlId); + await dashboardControls.optionsListPopoverSelectOption('meow'); + await dashboardControls.optionsListPopoverSelectOption('bark'); + await dashboardControls.optionsListEnsurePopoverIsClosed(controlId); await dashboardControls.updateValidationSetting(false); }); - after(async () => { - await dashboard.clickDiscardChanges(); - }); - it('Does not mark selections invalid with Query', async () => { await queryBar.setQuery('NOT animal.keyword : "dog" '); await queryBar.submitQuery(); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts b/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts index 0bd0523365d83..d290777c9008f 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_cell_renderers.ts @@ -8,6 +8,7 @@ import kbnRison from '@kbn/rison'; import expect from '@kbn/expect'; +import type { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services'; import type { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { @@ -18,6 +19,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dataViews = getService('dataViews'); const queryBar = getService('queryBar'); const browser = getService('browser'); + const retry = getService('retry'); describe('extension getCellRenderers', () => { before(async () => { @@ -39,8 +41,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, { ensureCurrentUrl: false, }); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0); const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-'); expect(await logLevelBadge.getVisibleText()).to.be('debug'); @@ -59,11 +65,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, { ensureCurrentUrl: false, }); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level'); - const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0); - expect(await firstCell.getVisibleText()).to.be('debug'); - await testSubjects.missingOrFail('*logLevelBadgeCell-'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + await retry.try(async () => { + const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0); + expect(await firstCell.getVisibleText()).to.be('debug'); + await testSubjects.missingOrFail('*logLevelBadgeCell-'); + }); }); }); @@ -72,17 +84,28 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-logs,logstash*'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-logs,logstash*'); await queryBar.setQuery('log.level:*'); await queryBar.submitQuery(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level'); - let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); - let logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-'); - expect(await logLevelBadge.getVisibleText()).to.be('debug'); - expect(await logLevelBadge.getComputedStyle('background-color')).to.be( - 'rgba(190, 207, 227, 1)' - ); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + let firstCell: WebElementWrapper; + let logLevelBadge: WebElementWrapper; + + await retry.try(async () => { + firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); + logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-'); + expect(await logLevelBadge.getVisibleText()).to.be('debug'); + expect(await logLevelBadge.getComputedStyle('background-color')).to.be( + 'rgba(190, 207, 227, 1)' + ); + }); // check Surrounding docs page await dataGrid.clickRowToggle(); @@ -92,26 +115,38 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await browser.refresh(); await PageObjects.header.waitUntilLoadingHasFinished(); - firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); - logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-'); - expect(await logLevelBadge.getVisibleText()).to.be('debug'); - expect(await logLevelBadge.getComputedStyle('background-color')).to.be( - 'rgba(190, 207, 227, 1)' - ); + await retry.try(async () => { + firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); + logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-'); + expect(await logLevelBadge.getVisibleText()).to.be('debug'); + expect(await logLevelBadge.getComputedStyle('background-color')).to.be( + 'rgba(190, 207, 227, 1)' + ); + }); }); it("should not render log.level badge cell if it's not a logs data source", async () => { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-*'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-*'); await queryBar.setQuery('log.level:*'); await queryBar.submitQuery(); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level'); - let firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); - expect(await firstCell.getVisibleText()).to.be('debug'); - await testSubjects.missingOrFail('*logLevelBadgeCell-'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + + let firstCell: WebElementWrapper; + + await retry.try(async () => { + firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1); + expect(await firstCell.getVisibleText()).to.be('debug'); + await testSubjects.missingOrFail('*logLevelBadgeCell-'); + }); // check Surrounding docs page await dataGrid.clickRowToggle(); @@ -121,9 +156,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await browser.refresh(); await PageObjects.header.waitUntilLoadingHasFinished(); - firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1); - expect(await firstCell.getVisibleText()).to.be('debug'); - await testSubjects.missingOrFail('*logLevelBadgeCell-'); + await retry.try(async () => { + firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1); + expect(await firstCell.getVisibleText()).to.be('debug'); + await testSubjects.missingOrFail('*logLevelBadgeCell-'); + }); }); }); }); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_default_app_state.ts b/test/functional/apps/discover/context_awareness/extensions/_get_default_app_state.ts index 7e057da66b764..477c268a2f186 100644 --- a/test/functional/apps/discover/context_awareness/extensions/_get_default_app_state.ts +++ b/test/functional/apps/discover/context_awareness/extensions/_get_default_app_state.ts @@ -89,6 +89,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, { ensureCurrentUrl: false, }); + await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemRemove('log.level'); await PageObjects.unifiedFieldList.clickFieldListItemRemove('message'); @@ -128,7 +129,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-logs'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-logs'); await expectColumns(['@timestamp', 'log.level', 'message']); await dataGrid.clickGridSettings(); const rowHeightValue = await dataGrid.getCurrentRowHeightValue(); @@ -141,14 +144,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-*'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-*'); await expectColumns(['@timestamp', 'Document']); await dataGrid.clickGridSettings(); let rowHeightValue = await dataGrid.getCurrentRowHeightValue(); expect(rowHeightValue).to.be('Custom'); let rowHeightNumber = await dataGrid.getCustomRowHeightNumber(); expect(rowHeightNumber).to.be(3); - await dataViews.switchTo('my-example-logs'); + await dataViews.switchToAndValidate('my-example-logs'); await expectColumns(['@timestamp', 'log.level', 'message']); await dataGrid.clickGridSettings(); rowHeightValue = await dataGrid.getCurrentRowHeightValue(); @@ -161,7 +166,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-logs'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-logs'); await PageObjects.discover.waitUntilSearchingHasFinished(); await PageObjects.unifiedFieldList.clickFieldListItemRemove('log.level'); await PageObjects.unifiedFieldList.clickFieldListItemRemove('message'); @@ -186,7 +193,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.navigateToActualUrl('discover', undefined, { ensureCurrentUrl: false, }); - await dataViews.switchTo('my-example-logs'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataViews.switchToAndValidate('my-example-logs'); await expectColumns(['@timestamp', 'log.level', 'message', 'data_stream.type']); }); }); diff --git a/test/functional/fixtures/kbn_archiver/dashboard/current/kibana.json b/test/functional/fixtures/kbn_archiver/dashboard/current/kibana.json index c4c2b4ab2d025..a89dcf714dfc3 100644 --- a/test/functional/fixtures/kbn_archiver/dashboard/current/kibana.json +++ b/test/functional/fixtures/kbn_archiver/dashboard/current/kibana.json @@ -3225,108 +3225,3 @@ "coreMigrationVersion": "8.8.0", "typeMigrationVersion": "10.2.0" } - -{ - "id": "55bc0b4b-a50f-46bf-b154-dd156067eea5", - "type": "dashboard", - "namespaces": [ - "default" - ], - "updated_at": "2024-08-26T13:30:47.442Z", - "created_at": "2024-08-26T13:29:23.580Z", - "version": "WzEwNiwxXQ==", - "attributes": { - "version": 2, - "controlGroupInput": { - "chainingSystem": "HIERARCHICAL", - "controlStyle": "oneLine", - "showApplySelections": true, - "ignoreParentSettingsJSON": "{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}", - "panelsJSON": "{\"41827e70-5285-4d44-8375-4c498449b9a7\":{\"grow\":true,\"order\":0,\"type\":\"optionsListControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"a0f483a0-3dc9-11e8-8660-4d65aa086b3c\",\"fieldName\":\"animal.keyword\",\"searchTechnique\":\"prefix\",\"selectedOptions\":[],\"sort\":{\"by\":\"_count\",\"direction\":\"desc\"}}},\"515e7b9f-4f1b-4a06-beec-763810e4951a\":{\"grow\":true,\"order\":1,\"type\":\"rangeSliderControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"a0f483a0-3dc9-11e8-8660-4d65aa086b3c\",\"fieldName\":\"weightLbs\",\"step\":1}},\"b33b103a-84e2-4c2f-b4bd-be143dbd7e8a\":{\"grow\":true,\"order\":2,\"type\":\"timeSlider\",\"width\":\"large\",\"explicitInput\":{}}}" - }, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" - }, - "description": "", - "refreshInterval": { - "pause": true, - "value": 60000 - }, - "timeRestore": true, - "optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}", - "panelsJSON": "[{\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"ffc13252-56b4-4e3f-847e-61373fa0be86\"},\"panelIndex\":\"ffc13252-56b4-4e3f-847e-61373fa0be86\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_ffc13252-56b4-4e3f-847e-61373fa0be86\"}]", - "timeFrom": "2018-01-01T00:00:00.000Z", - "title": "Test Control Group Apply Button", - "timeTo": "2018-04-13T00:00:00.000Z" - }, - "references": [ - { - "name": "ffc13252-56b4-4e3f-847e-61373fa0be86:panel_ffc13252-56b4-4e3f-847e-61373fa0be86", - "type": "visualization", - "id": "50643b60-3dd3-11e8-b2b9-5d5dc1715159" - }, - { - "name": "controlGroup_41827e70-5285-4d44-8375-4c498449b9a7:optionsListControlDataView", - "type": "index-pattern", - "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c" - }, - { - "name": "controlGroup_515e7b9f-4f1b-4a06-beec-763810e4951a:rangeSliderControlDataView", - "type": "index-pattern", - "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c" - } - ], - "managed": false, - "coreMigrationVersion": "8.8.0", - "typeMigrationVersion": "10.2.0" -} - -{ - "id": "0b61857d-b7d3-4b4b-aa6b-773808361cd6", - "type": "dashboard", - "namespaces": [ - "default" - ], - "updated_at": "2024-08-26T15:23:33.053Z", - "created_at": "2024-08-26T15:22:39.194Z", - "version": "WzE1MTksMV0=", - "attributes": { - "version": 2, - "controlGroupInput": { - "chainingSystem": "HIERARCHICAL", - "controlStyle": "oneLine", - "showApplySelections": false, - "ignoreParentSettingsJSON": "{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}", - "panelsJSON": "{\"cd881630-fd28-4e9c-aec5-ae9711d48369\":{\"grow\":true,\"order\":0,\"type\":\"optionsListControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"a0f483a0-3dc9-11e8-8660-4d65aa086b3c\",\"fieldName\":\"sound.keyword\",\"searchTechnique\":\"prefix\",\"selectedOptions\":[\"meow\",\"bark\"],\"sort\":{\"by\":\"_count\",\"direction\":\"desc\"}}}}" - }, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" - }, - "description": "", - "refreshInterval": { - "pause": true, - "value": 60000 - }, - "timeRestore": true, - "optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}", - "panelsJSON": "[{\"type\":\"visualization\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"12415efc-008a-4f02-bad4-5c1f0d9ba1c6\"},\"panelIndex\":\"12415efc-008a-4f02-bad4-5c1f0d9ba1c6\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_12415efc-008a-4f02-bad4-5c1f0d9ba1c6\"}]", - "timeFrom": "2018-01-01T00:00:00.000Z", - "title": "Test Options List Validation", - "timeTo": "2018-04-13T00:00:00.000Z" - }, - "references": [ - { - "name": "12415efc-008a-4f02-bad4-5c1f0d9ba1c6:panel_12415efc-008a-4f02-bad4-5c1f0d9ba1c6", - "type": "visualization", - "id": "50643b60-3dd3-11e8-b2b9-5d5dc1715159" - }, - { - "name": "controlGroup_cd881630-fd28-4e9c-aec5-ae9711d48369:optionsListControlDataView", - "type": "index-pattern", - "id": "a0f483a0-3dc9-11e8-8660-4d65aa086b3c" - } - ], - "managed": false, - "coreMigrationVersion": "8.8.0", - "typeMigrationVersion": "10.2.0" -} \ No newline at end of file diff --git a/test/functional/fixtures/kbn_archiver/dashboard/current/multi_data_view_kibana.json b/test/functional/fixtures/kbn_archiver/dashboard/current/multi_data_view_kibana.json deleted file mode 100644 index 7a5de78d372aa..0000000000000 --- a/test/functional/fixtures/kbn_archiver/dashboard/current/multi_data_view_kibana.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "id": "2af8906f-143b-4152-9f74-4994fb9c7b3e", - "type": "dashboard", - "namespaces": [ - "default" - ], - "updated_at": "2024-08-27T16:43:33.847Z", - "created_at": "2024-08-27T16:43:33.847Z", - "version": "WzIwNSwxXQ==", - "attributes": { - "version": 2, - "controlGroupInput": { - "chainingSystem": "HIERARCHICAL", - "controlStyle": "oneLine", - "showApplySelections": false, - "ignoreParentSettingsJSON": "{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}", - "panelsJSON": "{\"265b6a28-9ccb-44ae-83c9-3d7a7cac1961\":{\"grow\":true,\"order\":0,\"type\":\"optionsListControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"d3d7af60-4c81-11e8-b3d7-01146121b73d\",\"fieldName\":\"Carrier\",\"searchTechnique\":\"prefix\",\"selectedOptions\":[],\"sort\":{\"by\":\"_count\",\"direction\":\"desc\"}}},\"ed2b93e2-da37-482b-ae43-586a41cc2399\":{\"grow\":true,\"order\":1,\"type\":\"rangeSliderControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"d3d7af60-4c81-11e8-b3d7-01146121b73d\",\"fieldName\":\"AvgTicketPrice\",\"title\":\"Average Ticket Price\",\"step\":1}},\"5e1b146b-8a8b-4117-9218-c4aeaee7bc9a\":{\"grow\":true,\"order\":2,\"type\":\"optionsListControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"0bf35f60-3dc9-11e8-8660-4d65aa086b3c\",\"fieldName\":\"machine.os.raw\",\"title\":\"Operating System\",\"searchTechnique\":\"prefix\",\"selectedOptions\":[],\"sort\":{\"by\":\"_count\",\"direction\":\"desc\"}}},\"c4760951-e793-45d5-a6b7-c72c145af7f9\":{\"grow\":true,\"order\":3,\"type\":\"rangeSliderControl\",\"width\":\"medium\",\"explicitInput\":{\"dataViewId\":\"0bf35f60-3dc9-11e8-8660-4d65aa086b3c\",\"fieldName\":\"bytes\",\"title\":\"Bytes\",\"step\":1}}}" - }, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}" - }, - "description": "", - "refreshInterval": { - "pause": true, - "value": 60000 - }, - "timeRestore": true, - "optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}", - "panelsJSON": "[{\"type\":\"search\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"d75a68e9-67d9-4bed-9dba-85490d3eec37\"},\"panelIndex\":\"d75a68e9-67d9-4bed-9dba-85490d3eec37\",\"embeddableConfig\":{\"description\":\"\",\"enhancements\":{}},\"title\":\"logstash hits\",\"panelRefName\":\"panel_d75a68e9-67d9-4bed-9dba-85490d3eec37\"}]", - "timeFrom": "2018-04-10T00:00:00.000Z", - "title": "Test Control Group With Multiple Data Views", - "timeTo": "2018-11-15T00:00:00.000Z" - }, - "references": [ - { - "name": "d75a68e9-67d9-4bed-9dba-85490d3eec37:panel_d75a68e9-67d9-4bed-9dba-85490d3eec37", - "type": "search", - "id": "2b9247e0-6458-11ed-9957-e76caeeb9f75" - }, - { - "name": "controlGroup_265b6a28-9ccb-44ae-83c9-3d7a7cac1961:optionsListControlDataView", - "type": "index-pattern", - "id": "d3d7af60-4c81-11e8-b3d7-01146121b73d" - }, - { - "name": "controlGroup_ed2b93e2-da37-482b-ae43-586a41cc2399:rangeSliderControlDataView", - "type": "index-pattern", - "id": "d3d7af60-4c81-11e8-b3d7-01146121b73d" - }, - { - "name": "controlGroup_5e1b146b-8a8b-4117-9218-c4aeaee7bc9a:optionsListControlDataView", - "type": "index-pattern", - "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c" - }, - { - "name": "controlGroup_c4760951-e793-45d5-a6b7-c72c145af7f9:rangeSliderControlDataView", - "type": "index-pattern", - "id": "0bf35f60-3dc9-11e8-8660-4d65aa086b3c" - } - ], - "managed": false, - "coreMigrationVersion": "8.8.0", - "typeMigrationVersion": "10.2.0" -} \ No newline at end of file diff --git a/test/functional/page_objects/dashboard_page_controls.ts b/test/functional/page_objects/dashboard_page_controls.ts index dcc43432dab28..a3573438124e5 100644 --- a/test/functional/page_objects/dashboard_page_controls.ts +++ b/test/functional/page_objects/dashboard_page_controls.ts @@ -475,11 +475,7 @@ export class DashboardPageControls extends FtrService { await this.optionsListWaitForLoading(controlId); if (!skipOpen) await this.optionsListOpenPopover(controlId); await this.retry.try(async () => { - const availableOptions = await this.optionsListPopoverGetAvailableOptions(); - expect(availableOptions.suggestions).to.eql(expectation.suggestions); - expect(availableOptions.invalidSelections.sort()).to.eql( - expectation.invalidSelections.sort() - ); + expect(await this.optionsListPopoverGetAvailableOptions()).to.eql(expectation); }); if (await this.testSubjects.exists('optionsList-cardinality-label')) { expect(await this.optionsListGetCardinalityValue()).to.be( @@ -500,9 +496,7 @@ export class DashboardPageControls extends FtrService { public async optionsListPopoverSearchForOption(search: string) { this.log.debug(`searching for ${search} in options list`); await this.optionsListPopoverAssertOpen(); - await this.testSubjects.setValue(`optionsList-control-search-input`, search, { - typeCharByChar: true, - }); + await this.testSubjects.setValue(`optionsList-control-search-input`, search); await this.optionsListPopoverWaitForLoading(); } diff --git a/x-pack/packages/kbn-cloud-security-posture-common/index.ts b/x-pack/packages/kbn-cloud-security-posture-common/index.ts index 66a98d5e398c3..b5211af3342a3 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/index.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/index.ts @@ -20,4 +20,8 @@ export type { export type { CspFinding } from './types/findings'; export type { BenchmarksCisId } from './types/benchmark'; export * from './constants'; -export { extractErrorMessage, buildMutedRulesFilter } from './utils/helpers'; +export { + extractErrorMessage, + buildMutedRulesFilter, + buildEntityFlyoutPreviewQuery, +} from './utils/helpers'; diff --git a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts index 7e5f4f1d8120a..d920a8dc25165 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.test.ts @@ -5,7 +5,12 @@ * 2.0. */ -import { extractErrorMessage, defaultErrorMessage, buildMutedRulesFilter } from './helpers'; +import { + extractErrorMessage, + defaultErrorMessage, + buildMutedRulesFilter, + buildEntityFlyoutPreviewQuery, +} from './helpers'; const fallbackMessage = 'thisIsAFallBackMessage'; @@ -138,4 +143,43 @@ describe('test helper methods', () => { expect(buildMutedRulesFilter(rulesStates)).toEqual(expectedQuery); }); }); + + describe('buildEntityFlyoutPreviewQueryTest', () => { + it('should return the correct query when given field and query', () => { + const field = 'host.name'; + const query = 'exampleHost'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': { value: 'exampleHost' } } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildEntityFlyoutPreviewQuery(field, query)).toEqual(expectedQuery); + }); + + it('should return the correct query when given field and empty query', () => { + const field = 'host.name'; + const expectedQuery = { + bool: { + filter: [ + { + bool: { + should: [{ term: { 'host.name': { value: '' } } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; + + expect(buildEntityFlyoutPreviewQuery(field)).toEqual(expectedQuery); + }); + }); }); diff --git a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts index 7c26c61778137..1c593fcebf545 100644 --- a/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts +++ b/x-pack/packages/kbn-cloud-security-posture-common/utils/helpers.ts @@ -41,3 +41,18 @@ export const buildMutedRulesFilter = ( return mutedRulesFilterQuery; }; + +export const buildEntityFlyoutPreviewQuery = (field: string, queryValue?: string) => { + return { + bool: { + filter: [ + { + bool: { + should: [{ term: { [field]: { value: `${queryValue || ''}` } } }], + minimum_should_match: 1, + }, + }, + ], + }, + }; +}; diff --git a/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_misconfiguration_preview.ts b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_misconfiguration_preview.ts new file mode 100644 index 0000000000000..af7371da95301 --- /dev/null +++ b/x-pack/packages/kbn-cloud-security-posture/src/hooks/use_misconfiguration_preview.ts @@ -0,0 +1,149 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useQuery } from '@tanstack/react-query'; +import { lastValueFrom } from 'rxjs'; +import type { IKibanaSearchResponse, IKibanaSearchRequest } from '@kbn/search-types'; +import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { + CDR_MISCONFIGURATIONS_INDEX_PATTERN, + LATEST_FINDINGS_RETENTION_POLICY, + CspFinding, +} from '@kbn/cloud-security-posture-common'; +import type { CspBenchmarkRulesStates } from '@kbn/cloud-security-posture-common/schema/rules/latest'; +import { buildMutedRulesFilter } from '@kbn/cloud-security-posture-common'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import type { CoreStart } from '@kbn/core/public'; +import { showErrorToast } from '../..'; +import type { CspClientPluginStartDeps } from '../../type'; +import { useGetCspBenchmarkRulesStatesApi } from './use_get_benchmark_rules_state_api'; + +interface MisconfigurationPreviewBaseEsQuery { + query?: { + bool: { + filter: estypes.QueryDslQueryContainer[]; + }; + }; +} + +interface UseMisconfigurationPreviewOptions extends MisconfigurationPreviewBaseEsQuery { + sort: string[][]; + enabled: boolean; + pageSize: number; +} + +type LatestFindingsRequest = IKibanaSearchRequest; +type LatestFindingsResponse = IKibanaSearchResponse< + estypes.SearchResponse +>; + +interface FindingsAggs { + count: estypes.AggregationsMultiBucketAggregateBase; +} + +const RESULT_EVALUATION = { + PASSED: 'passed', + FAILED: 'failed', + UNKNOWN: 'unknown', +}; + +export const getFindingsCountAggQueryMisconfigurationPreview = () => ({ + count: { + filters: { + other_bucket_key: RESULT_EVALUATION.UNKNOWN, + filters: { + [RESULT_EVALUATION.PASSED]: { match: { 'result.evaluation': RESULT_EVALUATION.PASSED } }, + [RESULT_EVALUATION.FAILED]: { match: { 'result.evaluation': RESULT_EVALUATION.FAILED } }, + }, + }, + }, +}); + +export const getMisconfigurationAggregationCount = ( + buckets: estypes.AggregationsBuckets +) => { + return Object.entries(buckets).reduce( + (evaluation, [key, value]) => { + evaluation[key] = (evaluation[key] || 0) + (value.doc_count || 0); + return evaluation; + }, + { + [RESULT_EVALUATION.PASSED]: 0, + [RESULT_EVALUATION.FAILED]: 0, + [RESULT_EVALUATION.UNKNOWN]: 0, + } + ); +}; + +export const buildMisconfigurationsFindingsQuery = ( + { query }: UseMisconfigurationPreviewOptions, + rulesStates: CspBenchmarkRulesStates +) => { + const mutedRulesFilterQuery = buildMutedRulesFilter(rulesStates); + + return { + index: CDR_MISCONFIGURATIONS_INDEX_PATTERN, + size: 0, + aggs: getFindingsCountAggQueryMisconfigurationPreview(), + ignore_unavailable: false, + query: buildMisconfigurationsFindingsQueryWithFilters(query, mutedRulesFilterQuery), + }; +}; + +const buildMisconfigurationsFindingsQueryWithFilters = ( + query: UseMisconfigurationPreviewOptions['query'], + mutedRulesFilterQuery: estypes.QueryDslQueryContainer[] +) => { + return { + ...query, + bool: { + ...query?.bool, + filter: [ + ...(query?.bool?.filter ?? []), + { + range: { + '@timestamp': { + gte: `now-${LATEST_FINDINGS_RETENTION_POLICY}`, + lte: 'now', + }, + }, + }, + ], + must_not: [...mutedRulesFilterQuery], + }, + }; +}; + +export const useMisconfigurationPreview = (options: UseMisconfigurationPreviewOptions) => { + const { + data, + notifications: { toasts }, + } = useKibana().services; + const { data: rulesStates } = useGetCspBenchmarkRulesStatesApi(); + + return useQuery( + ['csp_misconfiguration_preview', { params: options }, rulesStates], + async () => { + const { + rawResponse: { aggregations }, + } = await lastValueFrom( + data.search.search({ + params: buildMisconfigurationsFindingsQuery(options, rulesStates!), + }) + ); + if (!aggregations) throw new Error('expected aggregations to be defined'); + + return { + count: getMisconfigurationAggregationCount(aggregations.count.buckets), + }; + }, + { + enabled: options.enabled && !!rulesStates, + keepPreviousData: true, + onError: (err: Error) => showErrorToast(toasts, err), + } + ); +}; diff --git a/x-pack/packages/kbn-cloud-security-posture/tsconfig.json b/x-pack/packages/kbn-cloud-security-posture/tsconfig.json index 152c3fe8a8b29..fec5d21b8aa79 100644 --- a/x-pack/packages/kbn-cloud-security-posture/tsconfig.json +++ b/x-pack/packages/kbn-cloud-security-posture/tsconfig.json @@ -36,5 +36,6 @@ "@kbn/kibana-react-plugin", "@kbn/cloud-security-posture-common", "@kbn/i18n", + "@kbn/search-types", ] } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_header/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_header/index.tsx index 7c63c59ee58b9..d81a56fb97eef 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_header/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/assistant_header/index.tsx @@ -110,7 +110,7 @@ export const AssistantHeader: React.FC = ({ const showDestroyModal = useCallback(() => setIsResetConversationModalVisible(true), []); const onConversationChange = useCallback( - (updatedConversation) => { + (updatedConversation: Conversation) => { onConversationSelected({ cId: updatedConversation.id, cTitle: updatedConversation.title, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/pagination/use_session_pagination.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/pagination/use_session_pagination.ts index daaccc1fc6992..3bf0a5e792089 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/pagination/use_session_pagination.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/common/components/assistant_settings_management/pagination/use_session_pagination.ts @@ -48,7 +48,11 @@ export const useSessionPagination = ({ ); const onTableChange = useCallback( - ({ page, sort }) => { + ({ + page, + sort, + }: // eslint-disable-next-line @typescript-eslint/no-explicit-any + any) => { setSessionStorageTableOptions({ page, sort, diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx index dabba11805eae..cf30f5ea935e9 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_selector_settings/index.tsx @@ -100,7 +100,8 @@ export const ConversationSelectorSettings: React.FC = React.memo( // Callback for when user types to create a new conversation const onCreateOption = useCallback( - (searchValue, flattenedOptions = []) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (searchValue: any, flattenedOptions: any = []) => { if (!searchValue || !searchValue.trim().toLowerCase()) { return; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings_editor.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings_editor.tsx index af6ac01fb18a4..f5c74cf77ee85 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings_editor.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings/conversation_settings_editor.tsx @@ -18,7 +18,7 @@ import { Conversation } from '../../../..'; import * as i18n from './translations'; import * as i18nModel from '../../../connectorland/models/model_selector/translations'; -import { ConnectorSelector } from '../../../connectorland/connector_selector'; +import { AIConnector, ConnectorSelector } from '../../../connectorland/connector_selector'; import { SelectSystemPrompt } from '../../prompt_editor/system_prompt/select_system_prompt'; import { ModelSelector } from '../../../connectorland/models/model_selector/model_selector'; import { useLoadConnectors } from '../../../connectorland/use_load_connectors'; @@ -140,7 +140,7 @@ export const ConversationSettingsEditor: React.FC { + (connector: AIConnector) => { if (selectedConversation != null) { const config = getGenAiConfig(connector); const updatedConversation = { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/index.tsx index be7afdfb007f3..10c0867cafb38 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/index.tsx @@ -121,7 +121,8 @@ const ConversationSettingsManagementComponent: React.FC = ({ ); const setAssistantStreamingEnabled = useCallback( - (value) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (value: any) => { setHasPendingChanges(true); setUpdatedAssistantStreamingEnabled(value); }, @@ -259,11 +260,10 @@ const ConversationSettingsManagementComponent: React.FC = ({ const columns = useMemo( () => getColumns({ - conversations: conversationSettings, onDeleteActionClicked, onEditActionClicked, }), - [conversationSettings, getColumns, onDeleteActionClicked, onEditActionClicked] + [getColumns, onDeleteActionClicked, onEditActionClicked] ); const confirmationTitle = useMemo( diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/use_conversations_table.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/use_conversations_table.tsx index 0d253be5d2651..e9c1cead27d66 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/use_conversations_table.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/conversations/conversation_settings_management/use_conversations_table.tsx @@ -40,6 +40,9 @@ export const useConversationsTable = () => { ({ onDeleteActionClicked, onEditActionClicked, + }: { + onDeleteActionClicked: (conversation: ConversationTableItem) => void; + onEditActionClicked: (conversation: ConversationTableItem) => void; }): Array> => { return [ { diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.tsx index 08a6888b30626..2fa4f0d210055 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/select_system_prompt/index.tsx @@ -128,7 +128,7 @@ const SelectSystemPromptComponent: React.FC = ({ ); const onChange = useCallback( - async (selectedSystemPromptId) => { + async (selectedSystemPromptId: string) => { if (selectedSystemPromptId === ADD_NEW_SYSTEM_PROMPT) { setIsSettingsModalVisible(true); setSelectedSettingsTab(SYSTEM_PROMPTS_TAB); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_editor.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_editor.tsx index 2036b1114b79c..5c0e7f8aa3e56 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_editor.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_editor.tsx @@ -292,7 +292,7 @@ export const SystemPromptEditorComponent: React.FC = ({ ); const handleNewConversationDefaultChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const isChecked = e.target.checked; const defaultNewSystemPrompts = systemPromptSettings.filter( (p) => p.isNewConversationDefault diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx index 4e97ca36f1198..15e047c599727 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_modal/system_prompt_selector/system_prompt_selector.tsx @@ -95,7 +95,8 @@ export const SystemPromptSelector: React.FC = React.memo( // Callback for when user types to create a new system prompt const onCreateOption = useCallback( - (searchValue, flattenedOptions = []) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (searchValue: any, flattenedOptions: any[] = []) => { if (!searchValue || !searchValue.trim().toLowerCase()) { return; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_settings_management/default_conversations_column.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_settings_management/default_conversations_column.tsx index 7567775909a09..fbb27c7888b21 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_settings_management/default_conversations_column.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_editor/system_prompt/system_prompt_settings_management/default_conversations_column.tsx @@ -24,9 +24,9 @@ export const DefaultConversationsColumn: React.FC = React.memo( : Math.min(maxConversationsToShow, defaultConversations.length); const itemsToDisplay = defaultConversations.slice(0, currentDisplaying - 1); - const toggleContent = useCallback((prev) => { - setIsExpanded(!prev); - }, []); + const toggleContent = useCallback(() => { + setIsExpanded(!isExpanded); + }, [isExpanded]); if (!defaultConversations || defaultConversations?.length === 0) { return null; diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_textarea/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_textarea/index.tsx index 72cf691837d04..4cccc288a1832 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_textarea/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/prompt_textarea/index.tsx @@ -28,13 +28,13 @@ export const PromptTextArea = forwardRef( ); const onKeyDown = useCallback( - (event) => { + (event: React.KeyboardEvent) => { // keyCode 13 is needed in case of IME input if (event.keyCode === 13 && !event.shiftKey) { event.preventDefault(); if (value.trim().length) { - onPromptSubmit(event.target.value?.trim()); + onPromptSubmit(event.currentTarget.value?.trim()); setUserPrompt(''); } else { event.stopPropagation(); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/quick_prompt_selector.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/quick_prompt_selector.tsx index f0adee73ddb25..256e54836e9e2 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/quick_prompt_selector.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/quick_prompts/quick_prompt_selector/quick_prompt_selector.tsx @@ -94,7 +94,8 @@ export const QuickPromptSelector: React.FC = React.memo( // Callback for when user types to create a new quick prompt const onCreateOption = useCallback( - (searchValue, flattenedOptions = []) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (searchValue: any, flattenedOptions: any[] = []) => { if (!searchValue || !searchValue.trim().toLowerCase()) { return; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/evaluation_settings/evaluation_settings.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/evaluation_settings/evaluation_settings.tsx index a06c28ed360f5..319ee812a3cf3 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/evaluation_settings/evaluation_settings.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/settings/evaluation_settings/evaluation_settings.tsx @@ -55,9 +55,9 @@ export const EvaluationSettings: React.FC = React.memo(() => { // Run Details // Run Name - const [runName, setRunName] = useState(); + const [runName, setRunName] = useState(); const onRunNameChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setRunName(e.target.value); }, [setRunName] @@ -65,19 +65,19 @@ export const EvaluationSettings: React.FC = React.memo(() => { /** Trace Options **/ const [showTraceOptions, setShowTraceOptions] = useState(false); const onApmUrlChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setTraceOptions({ ...traceOptions, apmUrl: e.target.value }); }, [setTraceOptions, traceOptions] ); const onLangSmithProjectChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setTraceOptions({ ...traceOptions, langSmithProject: e.target.value }); }, [setTraceOptions, traceOptions] ); const onLangSmithApiKeyChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setTraceOptions({ ...traceOptions, langSmithApiKey: e.target.value }); }, [setTraceOptions, traceOptions] diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/use_anonymization_list_update.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/use_anonymization_list_update.tsx index e6b405f162d05..b2836c16a50ac 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/use_anonymization_list_update.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings/use_anonymization_list_update.tsx @@ -11,7 +11,7 @@ import { PerformAnonymizationFieldsBulkActionRequestBody } from '@kbn/elastic-as import { BatchUpdateListItem } from '../../../data_anonymization_editor/context_editor/types'; -interface Props { +export interface UseAnonymizationListUpdateProps { anonymizationFields: FindAnonymizationFieldsResponse; anonymizationFieldsBulkActions: PerformAnonymizationFieldsBulkActionRequestBody; setAnonymizationFieldsBulkActions: React.Dispatch< @@ -27,7 +27,7 @@ export const useAnonymizationListUpdate = ({ anonymizationFieldsBulkActions, setAnonymizationFieldsBulkActions, setUpdatedAnonymizationData, -}: Props) => { +}: UseAnonymizationListUpdateProps) => { const onListUpdated = useCallback( async (updates: BatchUpdateListItem[]) => { const updatedFieldsKeys = updates.map((u) => u.field); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_management/index.tsx b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_management/index.tsx index 420f570834cce..5fca3c6996d2f 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_management/index.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/data_anonymization/settings/anonymization_settings_management/index.tsx @@ -12,7 +12,10 @@ import { euiThemeVars } from '@kbn/ui-theme'; import { Stats } from '../../../data_anonymization_editor/stats'; import { ContextEditor } from '../../../data_anonymization_editor/context_editor'; import * as i18n from '../anonymization_settings/translations'; -import { useAnonymizationListUpdate } from '../anonymization_settings/use_anonymization_list_update'; +import { + useAnonymizationListUpdate, + UseAnonymizationListUpdateProps, +} from '../anonymization_settings/use_anonymization_list_update'; import { DEFAULT_ANONYMIZATION_FIELDS, DEFAULT_CONVERSATIONS, @@ -70,7 +73,9 @@ const AnonymizationSettingsManagementComponent: React.FC = ({ defaultPage handleSave(); }, [handleSave]); - const handleAnonymizationFieldsBulkActions = useCallback( + const handleAnonymizationFieldsBulkActions = useCallback< + UseAnonymizationListUpdateProps['setAnonymizationFieldsBulkActions'] + >( (value) => { setHasPendingChanges(true); setAnonymizationFieldsBulkActions(value); @@ -78,7 +83,9 @@ const AnonymizationSettingsManagementComponent: React.FC = ({ defaultPage [setAnonymizationFieldsBulkActions] ); - const handleUpdatedAnonymizationData = useCallback( + const handleUpdatedAnonymizationData = useCallback< + UseAnonymizationListUpdateProps['setUpdatedAnonymizationData'] + >( (value) => { setHasPendingChanges(true); setUpdatedAnonymizationData(value); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings_management.tsx b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings_management.tsx index e2c9c07aee4c3..0f0a90b05b0de 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings_management.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/knowledge_base/knowledge_base_settings_management.tsx @@ -68,7 +68,8 @@ export const KnowledgeBaseSettingsManagement: React.FC = React.memo(() => { ); const handleUpdateKnowledgeBaseSettings = useCallback( - (updatedKnowledgebase) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (updatedKnowledgebase: any) => { setHasPendingChanges(true); setUpdatedKnowledgeBaseSettings(updatedKnowledgebase); }, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx index fc3c698c7a460..b5688f9c98a33 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/data_quality_details/indices_details/pattern/index.tsx @@ -115,7 +115,7 @@ const PatternComponent: React.FC = ({ }, []); const handleFlyoutIndexExpandAction = useCallback( - (indexName) => { + (indexName: string) => { checkIndex({ abortController: flyoutIndexExpandActionAbortControllerRef.current, indexName, @@ -130,7 +130,7 @@ const PatternComponent: React.FC = ({ ); const handleTableRowIndexCheckNowAction = useCallback( - (indexName) => { + (indexName: string) => { checkIndex({ abortController: tableRowIndexCheckNowActionAbortControllerRef.current, indexName, diff --git a/x-pack/plugins/cases/public/components/case_form_fields/assignees.tsx b/x-pack/plugins/cases/public/components/case_form_fields/assignees.tsx index 6e56e7d154a2a..d3a6363d33a3c 100644 --- a/x-pack/plugins/cases/public/components/case_form_fields/assignees.tsx +++ b/x-pack/plugins/cases/public/components/case_form_fields/assignees.tsx @@ -113,45 +113,48 @@ const AssigneesFieldComponent: React.FC = React.memo( setValue([...selectedAssignees, { uid: currentUserProfile.uid }]); }, [currentUserProfile, selectedAssignees, setValue]); - const renderOption = useCallback((option, searchValue: string, contentClassName: string) => { - const { user, data } = option as UserProfileComboBoxOption; - - const displayName = getUserDisplayName(user); - - return ( - - - - + const renderOption = useCallback( + (option: EuiComboBoxOptionOption, searchValue: string, contentClassName: string) => { + const { user, data } = option as UserProfileComboBoxOption; + + const displayName = getUserDisplayName(user); + + return ( - - - {displayName} - + + - {user.email && user.email !== displayName ? ( - - - - {user.email} - - + + + + {displayName} + - ) : null} + {user.email && user.email !== displayName ? ( + + + + {user.email} + + + + ) : null} + - - ); - }, []); + ); + }, + [] + ); const isCurrentUserSelected = Boolean( selectedAssignees?.find((assignee) => assignee.uid === currentUserProfile?.uid) diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.tsx index 2eadd6ccbe79a..d26fe1ee185f8 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.tsx @@ -28,6 +28,7 @@ import type { CustomFieldConfiguration, TemplateConfiguration, CustomFieldTypes, + ActionConnector, } from '../../../common/types/domain'; import { useKibana } from '../../common/lib/kibana'; import { useGetActionTypes } from '../../containers/configure/use_action_types'; @@ -159,8 +160,8 @@ export const ConfigureCases: React.FC = React.memo(() => { } = useGetActionTypes(); const onConnectorUpdated = useCallback( - async (updatedConnector) => { - setEditedConnectorItem(updatedConnector); + async (updatedConnector: ActionConnector) => { + setEditedConnectorItem(updatedConnector as ActionConnectorTableItem); refetchConnectors(); refetchActionTypes(); refetchCaseConfigure(); @@ -169,7 +170,7 @@ export const ConfigureCases: React.FC = React.memo(() => { ); const onConnectorCreated = useCallback( - async (createdConnector) => { + async (createdConnector: ActionConnector) => { const caseConnector = normalizeActionConnector(createdConnector); await persistCaseConfigureAsync({ diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index 54198f8510e5e..184154d177a9b 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -52,7 +52,7 @@ export const FormContext: React.FC = ({ const { startTransaction } = useCreateCaseWithAttachmentsTransaction(); const submitCase = useCallback( - async (data: CasePostRequest, isValid) => { + async (data: CasePostRequest, isValid: boolean) => { if (isValid) { startTransaction({ appId, attachments }); diff --git a/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx b/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx index 455163f225a2b..2cb7618f7f18a 100644 --- a/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx +++ b/x-pack/plugins/cases/public/components/custom_fields/text/configure.test.tsx @@ -44,7 +44,8 @@ describe('Configure ', () => { }); }); - it('updates field options with default value correctly when not required', async () => { + // Flaky: https://github.com/elastic/kibana/issues/178001 + it.skip('updates field options with default value correctly when not required', async () => { render( diff --git a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/plugin.tsx b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/plugin.tsx index b55957c4b7ce0..364ccfd220faf 100644 --- a/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/plugin.tsx +++ b/x-pack/plugins/cases/public/components/markdown_editor/plugins/lens/plugin.tsx @@ -26,9 +26,11 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { useLocation } from 'react-router-dom'; import { css } from '@emotion/react'; -import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { TypedLensByValueInput, LensSavedObjectAttributes } from '@kbn/lens-plugin/public'; import type { EmbeddablePackageState } from '@kbn/embeddable-plugin/public'; import { SavedObjectFinder } from '@kbn/saved-objects-finder-plugin/public'; +import type { SavedObjectCommon } from '@kbn/saved-objects-finder-plugin/common'; +import type { TimeRange } from '@kbn/data-plugin/common'; import { useKibana } from '../../../../common/lib/kibana'; import { DRAFT_COMMENT_STORAGE_ID, ID } from './constants'; import { CommentEditorContext } from '../../context'; @@ -37,7 +39,7 @@ import { VISUALIZATION } from './translations'; import { useIsMainApplication } from '../../../../common/hooks'; import { convertToAbsoluteTimeRange } from '../../../visualizations/actions/convert_to_absolute_time_range'; -const DEFAULT_TIMERANGE = { +const DEFAULT_TIMERANGE: TimeRange = { from: 'now-7d', to: 'now', mode: 'relative', @@ -87,7 +89,7 @@ const LensEditorComponent: LensEuiMarkdownEditorUiPlugin['editor'] = ({ }, [clearDraftComment, currentAppId, embeddable, onCancel]); const handleAdd = useCallback( - (attributes, timeRange) => { + (attributes: Record, timeRange?: TimeRange) => { onSave( `!{${ID}${JSON.stringify({ timeRange: convertToAbsoluteTimeRange(timeRange), @@ -104,7 +106,11 @@ const LensEditorComponent: LensEuiMarkdownEditorUiPlugin['editor'] = ({ ); const handleUpdate = useCallback( - (attributes, timeRange, position) => { + ( + attributes: Record, + timeRange: TimeRange | undefined, + position: EuiMarkdownAstNodePosition + ) => { markdownContext.replaceNode( position, `!{${ID}${JSON.stringify({ @@ -152,7 +158,7 @@ const LensEditorComponent: LensEuiMarkdownEditorUiPlugin['editor'] = ({ ]); const handleEditInLensClick = useCallback( - (lensAttributes?, timeRange = DEFAULT_TIMERANGE) => { + (lensAttributes?: Record, timeRange: TimeRange = DEFAULT_TIMERANGE) => { storage.set(DRAFT_COMMENT_STORAGE_ID, { commentId: commentEditorContext?.editorId, comment: commentEditorContext?.value, @@ -166,7 +172,7 @@ const LensEditorComponent: LensEuiMarkdownEditorUiPlugin['editor'] = ({ ? { id: '', timeRange, - attributes: lensAttributes || node?.attributes, + attributes: (lensAttributes || node?.attributes) as LensSavedObjectAttributes, } : undefined, { @@ -190,7 +196,12 @@ const LensEditorComponent: LensEuiMarkdownEditorUiPlugin['editor'] = ({ ); const handleChooseLensSO = useCallback( - (savedObjectId, savedObjectType, fullName, savedObject) => { + ( + savedObjectId: string, + savedObjectType: string, + fullName: string, + savedObject: SavedObjectCommon + ) => { handleEditInLensClick({ ...savedObject.attributes, title: '', diff --git a/x-pack/plugins/cloud/server/plugin.ts b/x-pack/plugins/cloud/server/plugin.ts index 362a69b4ac0a6..4d77cae8d870f 100644 --- a/x-pack/plugins/cloud/server/plugin.ts +++ b/x-pack/plugins/cloud/server/plugin.ts @@ -202,7 +202,7 @@ export class CloudPlugin implements Plugin { organizationId, instanceSizeMb: readInstanceSizeMb(), deploymentId, - elasticsearchUrl: decodedId?.elasticsearchUrl, + elasticsearchUrl: core.elasticsearch.publicBaseUrl || decodedId?.elasticsearchUrl, kibanaUrl: decodedId?.kibanaUrl, cloudHost: decodedId?.host, cloudDefaultPort: decodedId?.defaultPort, diff --git a/x-pack/plugins/data_quality/server/plugin.ts b/x-pack/plugins/data_quality/server/plugin.ts index 088905b8975d4..1b7e9cface597 100644 --- a/x-pack/plugins/data_quality/server/plugin.ts +++ b/x-pack/plugins/data_quality/server/plugin.ts @@ -39,6 +39,13 @@ export class DataQualityPlugin implements Plugin { ['metrics-*-*']: ['read'], }, }, + { + ui: [], + requiredClusterPrivileges: [], + requiredIndexPrivileges: { + ['synthetics-*-*']: ['read'], + }, + }, ], }); } diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_esql_editor.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_esql_editor.tsx index f9e22c71aaf4f..51bc74bb52d4a 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_esql_editor.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_esql_editor.tsx @@ -13,7 +13,7 @@ interface FieldStatsESQLEditorProps { canEditTextBasedQuery?: boolean; query: AggregateQuery; setQuery: (query: AggregateQuery) => void; - onQuerySubmit: (query: AggregateQuery, abortController: AbortController) => Promise; + onQuerySubmit: (query: AggregateQuery, abortController?: AbortController) => Promise; } export const FieldStatsESQLEditor = ({ canEditTextBasedQuery = true, @@ -25,7 +25,7 @@ export const FieldStatsESQLEditor = ({ const [isVisualizationLoading, setIsVisualizationLoading] = useState(false); const onTextLangQuerySubmit = useCallback( - async (q, abortController) => { + async (q?: AggregateQuery, abortController?: AbortController) => { if (q && onQuerySubmit) { setIsVisualizationLoading(true); await onQuerySubmit(q, abortController); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_initializer.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_initializer.tsx index e1959e039f863..4635b38956479 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_initializer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/embeddables/field_stats/field_stats_initializer.tsx @@ -95,7 +95,7 @@ export const FieldStatisticsInitializer: FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [dataViewId, viewType, esqlQuery.esql, isEsqlMode]); const onESQLQuerySubmit = useCallback( - async (query: AggregateQuery, abortController: AbortController) => { + async (query: AggregateQuery, abortController?: AbortController) => { const adhocDataView = await getESQLAdHocDataview(query.esql, dataViews); if (adhocDataView && adhocDataView.id) { setDataViewId(adhocDataView.id); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/custom_fields/global_data_tags_table.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/custom_fields/global_data_tags_table.test.tsx index dffe682bcc452..b16b6fc0c14cf 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/custom_fields/global_data_tags_table.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_advanced_fields/custom_fields/global_data_tags_table.test.tsx @@ -44,8 +44,11 @@ describe('GlobalDataTagsTable', () => { global_data_tags: tags, }); - const updateAgentPolicy = React.useCallback((policy) => { + const updateAgentPolicy = React.useCallback< + React.ComponentProps['updateAgentPolicy'] + >((policy) => { mockUpdateAgentPolicy(policy); + // @ts-expect-error - TODO: fix this, types do not match _updateAgentPolicy(policy); }, []); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx index 3d1e29240c733..dc055cec7fceb 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/hooks/use_package_policy_steps.tsx @@ -84,7 +84,7 @@ export function usePackagePolicySteps({ ); const updateSelectedPolicyTab = useCallback( - (currentTab) => { + (currentTab: SelectedPolicyTab) => { setSelectedPolicyTab(currentTab); setPolicyValidation(currentTab, newAgentPolicy); }, diff --git a/x-pack/plugins/fleet/server/services/output.test.ts b/x-pack/plugins/fleet/server/services/output.test.ts index 0951657fae6dd..581bd2d8882dd 100644 --- a/x-pack/plugins/fleet/server/services/output.test.ts +++ b/x-pack/plugins/fleet/server/services/output.test.ts @@ -261,6 +261,18 @@ describe('Output Service', () => { ], } as unknown as ReturnType; + const mockedPackagePolicyWithFleetServerResolvedValue = { + items: [ + { + name: 'fleet-server-123', + policy_ids: ['fleet_server_policy'], + package: { + name: 'fleet_server', + }, + }, + ], + } as unknown as ReturnType; + const mockedAgentPolicyWithSyntheticsResolvedValue = { items: [ { @@ -291,9 +303,22 @@ describe('Output Service', () => { ], } as unknown as ReturnType; + const mockedPackagePolicyWithSyntheticsResolvedValue = { + items: [ + { + name: 'synthetics-123', + policy_ids: ['synthetics_policy'], + package: { + name: 'synthetics', + }, + }, + ], + } as unknown as ReturnType; + beforeEach(() => { mockedAgentPolicyService.getByIDs.mockResolvedValue([]); mockedAgentPolicyService.list.mockClear(); + mockedPackagePolicyService.list.mockReset(); mockedAgentPolicyService.hasAPMIntegration.mockClear(); mockedAgentPolicyService.hasFleetServerIntegration.mockClear(); mockedAgentPolicyService.hasSyntheticsIntegration.mockClear(); @@ -303,6 +328,9 @@ describe('Output Service', () => { mockedAppContextService.getEncryptedSavedObjectsSetup.mockReset(); mockedAuditLoggingService.writeCustomSoAuditLog.mockReset(); mockedAgentPolicyService.update.mockReset(); + mockedPackagePolicyService.list.mockResolvedValue({ + items: [], + } as any); }); afterEach(() => { @@ -657,6 +685,12 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); + mockedAgentPolicyService.getByIDs.mockResolvedValue( + (await mockedAgentPolicyWithFleetServerResolvedValue).items + ); await outputService.create( soClient, @@ -690,6 +724,12 @@ describe('Output Service', () => { mockedAgentPolicyWithSyntheticsResolvedValue ); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); + mockedAgentPolicyService.getByIDs.mockResolvedValue( + (await mockedAgentPolicyWithSyntheticsResolvedValue).items + ); await outputService.create( soClient, @@ -802,6 +842,12 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); + mockedAgentPolicyService.getByIDs.mockResolvedValue( + (await mockedAgentPolicyWithFleetServerResolvedValue).items + ); await outputService.create( soClient, @@ -835,6 +881,12 @@ describe('Output Service', () => { mockedAgentPolicyWithSyntheticsResolvedValue ); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); + mockedAgentPolicyService.getByIDs.mockResolvedValue( + (await mockedAgentPolicyWithSyntheticsResolvedValue).items + ); await outputService.create( soClient, @@ -911,6 +963,7 @@ describe('Output Service', () => { const soClient = getMockedSoClient({ defaultOutputId: 'existing-default-output', }); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'output-test', { is_default: true, @@ -931,6 +984,7 @@ describe('Output Service', () => { const soClient = getMockedSoClient({ defaultOutputId: 'existing-default-output', }); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-default-output', { is_default: true, @@ -1036,6 +1090,7 @@ describe('Output Service', () => { it('Allow to update preconfigured output allowed to edit field from preconfiguration', async () => { const soClient = getMockedSoClient(); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update( soClient, esClientMock, @@ -1055,6 +1110,7 @@ describe('Output Service', () => { const soClient = getMockedSoClient({ defaultOutputId: 'existing-preconfigured-default-output', }); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await expect( outputService.update(soClient, esClientMock, 'output-test', { @@ -1072,6 +1128,7 @@ describe('Output Service', () => { const soClient = getMockedSoClient({ defaultOutputId: 'existing-default-output', }); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update( soClient, @@ -1101,6 +1158,7 @@ describe('Output Service', () => { items: [{}], } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-logstash-output', { type: 'elasticsearch', @@ -1121,6 +1179,7 @@ describe('Output Service', () => { items: [{}], } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-kafka-output', { type: 'elasticsearch', @@ -1162,6 +1221,7 @@ describe('Output Service', () => { items: [{}], } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-logstash-output', { is_default: true, @@ -1176,6 +1236,7 @@ describe('Output Service', () => { items: [{}], } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-logstash-output', { is_default: true, @@ -1201,6 +1262,7 @@ describe('Output Service', () => { items: [{}], } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await expect( outputService.update(soClient, esClientMock, 'existing-logstash-output', { @@ -1214,6 +1276,7 @@ describe('Output Service', () => { mockedAgentPolicyService.list.mockResolvedValue({ items: [{}], } as unknown as ReturnType); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(false); @@ -1238,6 +1301,7 @@ describe('Output Service', () => { } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false); + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); await outputService.update(soClient, esClientMock, 'existing-kafka-output', { type: 'logstash', @@ -1280,6 +1344,9 @@ describe('Output Service', () => { mockedAgentPolicyService.list.mockResolvedValue( mockedAgentPolicyWithFleetServerResolvedValue ); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); await outputService.update(soClient, esClientMock, 'output-test', { @@ -1312,6 +1379,9 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); await outputService.update( soClient, @@ -1349,6 +1419,9 @@ describe('Output Service', () => { }); mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); await outputService.update(soClient, esClientMock, 'output-test', { type: 'logstash', @@ -1378,6 +1451,9 @@ describe('Output Service', () => { }); mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); await outputService.update( soClient, @@ -1415,6 +1491,9 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); await expect( outputService.update(soClient, esClientMock, 'existing-es-output', { @@ -1431,6 +1510,9 @@ describe('Output Service', () => { mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); await expect( outputService.update(soClient, esClientMock, 'existing-es-output', { @@ -1465,6 +1547,9 @@ describe('Output Service', () => { mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(false); + mockedAgentPolicyService.list.mockResolvedValue({ + items: [], + } as any); await outputService.update(soClient, esClientMock, 'existing-es-output', { type: 'kafka', @@ -1498,6 +1583,9 @@ describe('Output Service', () => { } as unknown as ReturnType); mockedAgentPolicyService.hasAPMIntegration.mockReturnValue(false); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(false); + mockedAgentPolicyService.list.mockResolvedValue({ + items: [], + } as any); await outputService.update(soClient, esClientMock, 'existing-logstash-output', { type: 'kafka', @@ -1532,6 +1620,9 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); await outputService.update(soClient, esClientMock, 'output-test', { type: 'kafka', @@ -1575,6 +1666,9 @@ describe('Output Service', () => { mockedAgentPolicyWithFleetServerResolvedValue ); mockedAgentPolicyService.hasFleetServerIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithFleetServerResolvedValue + ); await outputService.update( soClient, @@ -1624,6 +1718,9 @@ describe('Output Service', () => { }); mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); await outputService.update(soClient, esClientMock, 'output-test', { type: 'kafka', @@ -1665,6 +1762,9 @@ describe('Output Service', () => { }); mockedAgentPolicyService.list.mockResolvedValue(mockedAgentPolicyWithSyntheticsResolvedValue); mockedAgentPolicyService.hasSyntheticsIntegration.mockReturnValue(true); + mockedPackagePolicyService.list.mockResolvedValue( + mockedPackagePolicyWithSyntheticsResolvedValue + ); await outputService.update( soClient, @@ -1975,6 +2075,7 @@ describe('Output Service', () => { describe('backfillAllOutputPresets', () => { it('should update non-preconfigured output', async () => { + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); const soClient = getMockedSoClient({}); soClient.find.mockResolvedValue({ @@ -2005,6 +2106,7 @@ describe('Output Service', () => { }); it('should update preconfigured output', async () => { + mockedPackagePolicyService.list.mockResolvedValue({ items: [] } as any); const soClient = getMockedSoClient({}); soClient.find.mockResolvedValue({ diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts index 57a641ed44d6f..bd5066d3ffc43 100644 --- a/x-pack/plugins/fleet/server/services/output.ts +++ b/x-pack/plugins/fleet/server/services/output.ts @@ -8,6 +8,7 @@ import { v5 as uuidv5 } from 'uuid'; import { omit } from 'lodash'; import { safeLoad } from 'js-yaml'; import deepEqual from 'fast-deep-equal'; +import { indexBy } from 'lodash/fp'; import type { ElasticsearchClient, @@ -52,6 +53,9 @@ import { kafkaCompressionType, kafkaAcknowledgeReliabilityLevel, RESERVED_CONFIG_YML_KEYS, + FLEET_APM_PACKAGE, + FLEET_SYNTHETICS_PACKAGE, + FLEET_SERVER_PACKAGE, } from '../../common/constants'; import { normalizeHostsForAgents } from '../../common/services'; import { @@ -149,7 +153,6 @@ async function getAgentPoliciesPerOutput(outputId?: string, isDefault?: boolean) const directAgentPolicies = await agentPolicyService.list(internalSoClientWithoutSpaceExtension, { kuery: agentPoliciesKuery, perPage: SO_SEARCH_LIMIT, - withPackagePolicies: true, }); const directAgentPolicyIds = directAgentPolicies?.items.map((policy) => policy.id); @@ -172,13 +175,38 @@ async function getAgentPoliciesPerOutput(outputId?: string, isDefault?: boolean) ]; const agentPoliciesFromPackagePolicies = await agentPolicyService.getByIDs( internalSoClientWithoutSpaceExtension, - agentPolicyIdsFromPackagePolicies, - { - withPackagePolicies: true, - } + agentPolicyIdsFromPackagePolicies ); - return [...directAgentPolicies.items, ...agentPoliciesFromPackagePolicies]; + const agentPoliciesIndexedById = indexBy( + (policy) => policy.id, + [...directAgentPolicies.items, ...agentPoliciesFromPackagePolicies] + ); + + // Bulk fetch package policies with only needed fields + if (Object.keys(agentPoliciesIndexedById).length) { + const { items: packagePolicies } = await packagePolicyService.list( + internalSoClientWithoutSpaceExtension, + { + fields: ['policy_ids', 'package.name'], + kuery: [FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE, FLEET_SERVER_PACKAGE] + .map((packageName) => `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${packageName}`) + .join(' or '), + } + ); + for (const packagePolicy of packagePolicies) { + for (const policyId of packagePolicy.policy_ids) { + if (agentPoliciesIndexedById[policyId]) { + if (!agentPoliciesIndexedById[policyId].package_policies) { + agentPoliciesIndexedById[policyId].package_policies = []; + } + agentPoliciesIndexedById[policyId].package_policies?.push(packagePolicy); + } + } + } + } + + return Object.values(agentPoliciesIndexedById); } async function validateLogstashOutputNotUsedInAPMPolicy(outputId?: string, isDefault?: boolean) { @@ -198,15 +226,38 @@ async function findPoliciesWithFleetServerOrSynthetics(outputId?: string, isDefa const internalSoClientWithoutSpaceExtension = appContextService.getInternalUserSOClientWithoutSpaceExtension(); - // find agent policies by outputId - // otherwise query all the policies - const agentPolicies = outputId - ? await getAgentPoliciesPerOutput(outputId, isDefault) - : ( - await agentPolicyService.list(internalSoClientWithoutSpaceExtension, { - withPackagePolicies: true, - }) - )?.items; + let agentPolicies: AgentPolicy[] | undefined; + if (outputId) { + agentPolicies = await getAgentPoliciesPerOutput(outputId, isDefault); + } else { + const { items: packagePolicies } = await packagePolicyService.list( + internalSoClientWithoutSpaceExtension, + { + fields: ['policy_ids', 'package.name'], + kuery: [FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE, FLEET_SERVER_PACKAGE] + .map((packageName) => `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:${packageName}`) + .join(' or '), + } + ); + const agentPolicyIds = _.uniq(packagePolicies.flatMap((p) => p.policy_ids)); + if (agentPolicyIds.length) { + agentPolicies = await agentPolicyService.getByIDs( + internalSoClientWithoutSpaceExtension, + agentPolicyIds + ); + for (const packagePolicy of packagePolicies) { + for (const policyId of packagePolicy.policy_ids) { + const agentPolicy = agentPolicies.find((p) => p.id === policyId); + if (agentPolicy) { + if (!agentPolicy.package_policies) { + agentPolicy.package_policies = []; + } + agentPolicy.package_policies?.push(packagePolicy); + } + } + } + } + } const policiesWithFleetServer = agentPolicies?.filter((policy) => agentPolicyService.hasFleetServerIntegration(policy)) || []; @@ -844,15 +895,18 @@ class OutputService { } const mergedType = data.type ?? originalOutput.type; + const mergedIsDefault = data.is_default ?? originalOutput.is_default; const defaultDataOutputId = await this.getDefaultDataOutputId(soClient); - await validateTypeChanges( - esClient, - id, - updateData, - originalOutput, - defaultDataOutputId, - fromPreconfiguration - ); + if (mergedType !== originalOutput.type || originalOutput.is_default !== mergedIsDefault) { + await validateTypeChanges( + esClient, + id, + updateData, + originalOutput, + defaultDataOutputId, + fromPreconfiguration + ); + } const removeKafkaFields = (target: Nullable>) => { target.version = null; diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_filter_fields.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_filter_fields.tsx index 41c4e4e95c186..74a3bdf6896bd 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_filter_fields.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_filter_fields.tsx @@ -39,7 +39,7 @@ export const MappingsFilter: React.FC = ({ const [isFilterByPopoverVisible, setIsFilterPopoverVisible] = useState(false); const dispatch = useDispatch(); const setSelectedOptions = useCallback( - (options) => { + (options: EuiSelectableOption[]) => { dispatch({ type: 'filter:update', value: { diff --git a/x-pack/plugins/inference/server/chat_complete/utils/generate_fake_tool_call_id.ts b/x-pack/plugins/inference/common/chat_complete/generate_fake_tool_call_id.ts similarity index 100% rename from x-pack/plugins/inference/server/chat_complete/utils/generate_fake_tool_call_id.ts rename to x-pack/plugins/inference/common/chat_complete/generate_fake_tool_call_id.ts diff --git a/x-pack/plugins/inference/common/chat_complete/index.ts b/x-pack/plugins/inference/common/chat_complete/index.ts index abad6a4372595..b42c2217c0177 100644 --- a/x-pack/plugins/inference/common/chat_complete/index.ts +++ b/x-pack/plugins/inference/common/chat_complete/index.ts @@ -6,7 +6,7 @@ */ import type { Observable } from 'rxjs'; -import type { InferenceTaskEventBase } from '../tasks'; +import type { InferenceTaskEventBase } from '../inference_task'; import type { ToolCall, ToolCallsOf, ToolOptions } from './tools'; export enum MessageRole { @@ -34,7 +34,7 @@ export type ToolMessage | unknown> = export type Message = UserMessage | AssistantMessage | ToolMessage; -export type ChatCompletionMessageEvent = +export type ChatCompletionMessageEvent = InferenceTaskEventBase & { content: string; } & { toolCalls: ToolCallsOf['toolCalls'] }; @@ -87,7 +87,7 @@ export type ChatCompletionEvent * @param {ToolChoice} [options.toolChoice] Force the LLM to call a (specific) tool, or no tool * @param {Record} [options.tools] A map of tools that can be called by the LLM */ -export type ChatCompleteAPI = ( +export type ChatCompleteAPI = ( options: { connectorId: string; system?: string; diff --git a/x-pack/plugins/inference/common/chat_complete/is_chat_completion_chunk_event.ts b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_chunk_event.ts new file mode 100644 index 0000000000000..1630d765ab81e --- /dev/null +++ b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_chunk_event.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ChatCompletionChunkEvent, ChatCompletionEvent, ChatCompletionEventType } from '.'; + +export function isChatCompletionChunkEvent( + event: ChatCompletionEvent +): event is ChatCompletionChunkEvent { + return event.type === ChatCompletionEventType.ChatCompletionChunk; +} diff --git a/x-pack/plugins/inference/common/chat_complete/is_chat_completion_event.ts b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_event.ts new file mode 100644 index 0000000000000..d4d9305cac94b --- /dev/null +++ b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_event.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ChatCompletionEvent, ChatCompletionEventType } from '.'; +import { InferenceTaskEvent } from '../inference_task'; + +export function isChatCompletionEvent(event: InferenceTaskEvent): event is ChatCompletionEvent { + return ( + event.type === ChatCompletionEventType.ChatCompletionChunk || + event.type === ChatCompletionEventType.ChatCompletionMessage || + event.type === ChatCompletionEventType.ChatCompletionTokenCount + ); +} diff --git a/x-pack/plugins/inference/common/chat_complete/is_chat_completion_message_event.ts b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_message_event.ts new file mode 100644 index 0000000000000..172e55df9e4b4 --- /dev/null +++ b/x-pack/plugins/inference/common/chat_complete/is_chat_completion_message_event.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ChatCompletionEvent, ChatCompletionEventType, ChatCompletionMessageEvent } from '.'; +import type { ToolOptions } from './tools'; + +export function isChatCompletionMessageEvent>( + event: ChatCompletionEvent +): event is ChatCompletionMessageEvent { + return event.type === ChatCompletionEventType.ChatCompletionMessage; +} diff --git a/x-pack/plugins/inference/common/chat_complete/tool_schema.ts b/x-pack/plugins/inference/common/chat_complete/tool_schema.ts index b23c03aaad775..2a2c61f8e9b70 100644 --- a/x-pack/plugins/inference/common/chat_complete/tool_schema.ts +++ b/x-pack/plugins/inference/common/chat_complete/tool_schema.ts @@ -13,7 +13,7 @@ interface ToolSchemaFragmentBase { interface ToolSchemaTypeObject extends ToolSchemaFragmentBase { type: 'object'; - properties: Record; + properties?: Record; required?: string[] | readonly string[]; } @@ -47,16 +47,19 @@ export type ToolSchemaType = | ToolSchemaTypeNumber | ToolSchemaTypeArray; -type FromToolSchemaObject = Required< - { - [key in keyof TToolSchemaObject['properties']]?: FromToolSchema< - TToolSchemaObject['properties'][key] - >; - }, - TToolSchemaObject['required'] extends string[] | readonly string[] - ? ValuesType - : never ->; +type FromToolSchemaObject = + TToolSchemaObject extends { properties: Record } + ? Required< + { + [key in keyof TToolSchemaObject['properties']]?: FromToolSchema< + TToolSchemaObject['properties'][key] + >; + }, + TToolSchemaObject['required'] extends string[] | readonly string[] + ? ValuesType + : never + > + : never; type FromToolSchemaArray = Array< FromToolSchema diff --git a/x-pack/plugins/inference/common/chat_complete/tools.ts b/x-pack/plugins/inference/common/chat_complete/tools.ts index 85fb4cd9d7020..a5db86c7c996d 100644 --- a/x-pack/plugins/inference/common/chat_complete/tools.ts +++ b/x-pack/plugins/inference/common/chat_complete/tools.ts @@ -48,11 +48,9 @@ export type ToolCallsOf = TToolOptions extends ? TToolOptions extends { toolChoice: ToolChoiceType.none } ? { toolCalls: [] } : { - toolCalls: ToolResponsesOf< - Assert, Record | undefined> - >; + toolCalls: ToolResponsesOf>; } - : { toolCalls: never[] }; + : { toolCalls: never }; export enum ToolChoiceType { none = 'none', @@ -70,7 +68,7 @@ export interface UnvalidatedToolCall { export interface ToolCall< TName extends string = string, - TArguments extends Record | undefined = undefined + TArguments extends Record | undefined = Record | undefined > { toolCallId: string; function: { diff --git a/x-pack/plugins/inference/common/ensure_multi_turn.ts b/x-pack/plugins/inference/common/ensure_multi_turn.ts new file mode 100644 index 0000000000000..8d222564f3e72 --- /dev/null +++ b/x-pack/plugins/inference/common/ensure_multi_turn.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Message, MessageRole } from './chat_complete'; + +function isUserMessage(message: Message): boolean { + return message.role !== MessageRole.Assistant; +} + +export function ensureMultiTurn(messages: Message[]): Message[] { + const next: Message[] = []; + + messages.forEach((message) => { + const prevMessage = next[next.length - 1]; + + if (prevMessage && isUserMessage(prevMessage) === isUserMessage(message)) { + next.push({ + content: '-', + role: isUserMessage(message) ? MessageRole.Assistant : MessageRole.User, + }); + } + + next.push(message); + }); + + return next; +} diff --git a/x-pack/plugins/inference/common/errors.ts b/x-pack/plugins/inference/common/errors.ts index fa063e1669936..e8bcd4cf60aaf 100644 --- a/x-pack/plugins/inference/common/errors.ts +++ b/x-pack/plugins/inference/common/errors.ts @@ -5,7 +5,7 @@ * 2.0. */ import { i18n } from '@kbn/i18n'; -import { InferenceTaskEventBase, InferenceTaskEventType } from './tasks'; +import { InferenceTaskEventBase, InferenceTaskEventType } from './inference_task'; export enum InferenceTaskErrorCode { internalError = 'internalError', @@ -42,7 +42,7 @@ export type InferenceTaskErrorEvent = InferenceTaskEventBase >; export type InferenceTaskRequestError = InferenceTaskError< @@ -53,9 +53,10 @@ export type InferenceTaskRequestError = InferenceTaskError< export function createInferenceInternalError( message: string = i18n.translate('xpack.inference.internalError', { defaultMessage: 'An internal error occurred', - }) + }), + meta?: Record ): InferenceTaskInternalError { - return new InferenceTaskError(InferenceTaskErrorCode.internalError, message, {}); + return new InferenceTaskError(InferenceTaskErrorCode.internalError, message, meta ?? {}); } export function createInferenceRequestError( diff --git a/x-pack/plugins/inference/common/index.ts b/x-pack/plugins/inference/common/index.ts new file mode 100644 index 0000000000000..58c84a47c1804 --- /dev/null +++ b/x-pack/plugins/inference/common/index.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +export { + correctCommonEsqlMistakes, + splitIntoCommands, +} from './tasks/nl_to_esql/correct_common_esql_mistakes'; + +export { isChatCompletionChunkEvent } from './chat_complete/is_chat_completion_chunk_event'; +export { isChatCompletionMessageEvent } from './chat_complete/is_chat_completion_message_event'; +export { isChatCompletionEvent } from './chat_complete/is_chat_completion_event'; + +export { isOutputUpdateEvent } from './output/is_output_update_event'; +export { isOutputCompleteEvent } from './output/is_output_complete_event'; +export { isOutputEvent } from './output/is_output_event'; + +export type { ToolSchema } from './chat_complete/tool_schema'; + +export { + type Message, + MessageRole, + type ToolMessage, + type AssistantMessage, + type UserMessage, +} from './chat_complete'; + +export { generateFakeToolCallId } from './chat_complete/generate_fake_tool_call_id'; diff --git a/x-pack/plugins/inference/common/tasks.ts b/x-pack/plugins/inference/common/inference_task.ts similarity index 100% rename from x-pack/plugins/inference/common/tasks.ts rename to x-pack/plugins/inference/common/inference_task.ts diff --git a/x-pack/plugins/inference/common/output/create_output_api.ts b/x-pack/plugins/inference/common/output/create_output_api.ts index 9842f9635dea8..0da2a84c53c5b 100644 --- a/x-pack/plugins/inference/common/output/create_output_api.ts +++ b/x-pack/plugins/inference/common/output/create_output_api.ts @@ -9,22 +9,29 @@ import { map } from 'rxjs'; import { ChatCompleteAPI, ChatCompletionEventType, MessageRole } from '../chat_complete'; import { withoutTokenCountEvents } from '../chat_complete/without_token_count_events'; import { OutputAPI, OutputEvent, OutputEventType } from '.'; +import { ensureMultiTurn } from '../ensure_multi_turn'; export function createOutputApi(chatCompleteApi: ChatCompleteAPI): OutputAPI { - return (id, { connectorId, input, schema, system }) => { + return (id, { connectorId, input, schema, system, previousMessages }) => { return chatCompleteApi({ connectorId, system, - messages: [ + messages: ensureMultiTurn([ + ...(previousMessages || []), { role: MessageRole.User, content: input, }, - ], + ]), ...(schema ? { - tools: { output: { description: `Output your response in the this format`, schema } }, - toolChoice: { function: 'output' }, + tools: { + output: { + description: `Use the following schema to respond to the user's request in structured data, so it can be parsed and handled.`, + schema, + }, + }, + toolChoice: { function: 'output' as const }, } : {}), }).pipe( @@ -37,10 +44,15 @@ export function createOutputApi(chatCompleteApi: ChatCompleteAPI): OutputAPI { content: event.content, }; } + return { id, type: OutputEventType.OutputComplete, - output: event.toolCalls[0].function.arguments, + output: + event.toolCalls.length && 'arguments' in event.toolCalls[0].function + ? event.toolCalls[0].function.arguments + : undefined, + content: event.content, }; }) ); diff --git a/x-pack/plugins/inference/common/output/index.ts b/x-pack/plugins/inference/common/output/index.ts index 69df7fb3ecd9d..12636498ab925 100644 --- a/x-pack/plugins/inference/common/output/index.ts +++ b/x-pack/plugins/inference/common/output/index.ts @@ -7,14 +7,15 @@ import { Observable } from 'rxjs'; import { FromToolSchema, ToolSchema } from '../chat_complete/tool_schema'; -import { InferenceTaskEventBase } from '../tasks'; +import { InferenceTaskEventBase } from '../inference_task'; +import { Message } from '../chat_complete'; export enum OutputEventType { OutputUpdate = 'output', OutputComplete = 'complete', } -type Output = Record | undefined; +type Output = Record | undefined | unknown; export type OutputUpdateEvent = InferenceTaskEventBase & { @@ -28,6 +29,7 @@ export type OutputCompleteEvent< > = InferenceTaskEventBase & { id: TId; output: TOutput; + content?: string; }; export type OutputEvent = @@ -39,7 +41,8 @@ export type OutputEvent Observable< OutputEvent : undefined> @@ -59,11 +63,13 @@ export type OutputAPI = < export function createOutputCompleteEvent( id: TId, - output: TOutput + output: TOutput, + content?: string ): OutputCompleteEvent { return { id, type: OutputEventType.OutputComplete, output, + content, }; } diff --git a/x-pack/plugins/inference/common/output/is_output_complete_event.ts b/x-pack/plugins/inference/common/output/is_output_complete_event.ts new file mode 100644 index 0000000000000..bac3443b8258c --- /dev/null +++ b/x-pack/plugins/inference/common/output/is_output_complete_event.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { OutputEvent, OutputEventType, OutputUpdateEvent } from '.'; + +export function isOutputCompleteEvent( + event: TOutputEvent +): event is Exclude { + return event.type === OutputEventType.OutputComplete; +} diff --git a/x-pack/plugins/inference/common/output/is_output_event.ts b/x-pack/plugins/inference/common/output/is_output_event.ts new file mode 100644 index 0000000000000..dad2b0967a6ac --- /dev/null +++ b/x-pack/plugins/inference/common/output/is_output_event.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { OutputEvent, OutputEventType } from '.'; +import type { InferenceTaskEvent } from '../inference_task'; + +export function isOutputEvent(event: InferenceTaskEvent): event is OutputEvent { + return ( + event.type === OutputEventType.OutputComplete || event.type === OutputEventType.OutputUpdate + ); +} diff --git a/x-pack/plugins/inference/common/output/is_output_update_event.ts b/x-pack/plugins/inference/common/output/is_output_update_event.ts new file mode 100644 index 0000000000000..459436e64014e --- /dev/null +++ b/x-pack/plugins/inference/common/output/is_output_update_event.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { OutputEvent, OutputEventType, OutputUpdateEvent } from '.'; + +export function isOutputUpdateEvent( + event: OutputEvent +): event is OutputUpdateEvent { + return event.type === OutputEventType.OutputComplete; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/constants.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/constants.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/constants.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/constants.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/correct_common_esql_mistakes.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/correct_common_esql_mistakes.test.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.test.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/correct_common_esql_mistakes.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/correct_common_esql_mistakes.ts rename to x-pack/plugins/inference/common/tasks/nl_to_esql/correct_common_esql_mistakes.ts diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts new file mode 100644 index 0000000000000..818f4854e038d --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.test.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { correctQueryWithActions } from './correct_query_with_actions'; + +describe('correctQueryWithActions', () => { + it(`fixes errors correctly for a query with one syntax error for stats`, async () => { + const fixedQuery = await correctQueryWithActions('from logstash-* | stats aveg(bytes)'); + expect(fixedQuery).toBe('from logstash-* | stats avg(bytes)'); + }); + + it(`fixes errors correctly for a query with 2 syntax errors for stats`, async () => { + const fixedQuery = await correctQueryWithActions( + 'from logstash-* | stats aveg(bytes), max2(bytes)' + ); + expect(fixedQuery).toBe('from logstash-* | stats avg(bytes), max(bytes)'); + }); + + it(`fixes errors correctly for a query with one syntax error for eval`, async () => { + const fixedQuery = await correctQueryWithActions( + 'from logstash-* | stats var0 = max(bytes) | eval ab(var0) | limit 1' + ); + expect(fixedQuery).toBe('from logstash-* | stats var0 = max(bytes) | eval abs(var0) | limit 1'); + }); + + it(`fixes errors correctly for a query with two syntax error for eval`, async () => { + const fixedQuery = await correctQueryWithActions( + 'from logstash-* | stats var0 = max2(bytes) | eval ab(var0) | limit 1' + ); + expect(fixedQuery).toBe('from logstash-* | stats var0 = max(bytes) | eval abs(var0) | limit 1'); + }); + + it(`doesnt complain for @timestamp column`, async () => { + const queryWithTimestamp = `FROM logstash-* + | WHERE @timestamp >= NOW() - 15 minutes + | EVAL bucket = DATE_TRUNC(1 minute, @timestamp) + | STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY service.name, bucket + | SORT avg_cpu DESC + | LIMIT 10`; + const fixedQuery = await correctQueryWithActions(queryWithTimestamp); + expect(fixedQuery).toBe(queryWithTimestamp); + }); +}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts new file mode 100644 index 0000000000000..15b050c3a3897 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/correct_query_with_actions.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { validateQuery, getActions } from '@kbn/esql-validation-autocomplete'; +import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; + +const fixedQueryByOneAction = async (queryString: string) => { + const { errors } = await validateQuery(queryString, getAstAndSyntaxErrors, { + ignoreOnMissingCallbacks: true, + }); + + const actions = await getActions(queryString, errors, getAstAndSyntaxErrors, { + relaxOnMissingCallbacks: true, + }); + + if (actions.length) { + const [firstAction] = actions; + const range = firstAction.edits[0].range; + const correctText = firstAction.edits[0].text; + const problematicString = queryString.substring(range.startColumn - 1, range.endColumn - 1); + const fixedQuery = queryString.replace(problematicString, correctText); + + return { + query: fixedQuery, + shouldRunAgain: Boolean(actions.length), + }; + } + return { + query: queryString, + shouldRunAgain: false, + }; +}; + +/** + * @param queryString + * @returns corrected queryString + * The cases that are handled are: + * - Query stats / eval functions have typos e.g. aveg instead of avg + * - Unquoted fields e.g. keep field-1 instead of keep `field-1` + * - Unquoted fields in stats or eval e.g. stats avg(field-1) instead of stats avg(`field-1`) + * - Combination of the above + */ + +export const correctQueryWithActions = async (queryString: string) => { + let shouldCorrectQuery = true; + let fixedQuery = queryString; + // this is an escape hatch, the loop will end automatically if the ast doesnt return more actions + // in case it goes wrong, we allow it to loop 10 times + let limit = 10; + + while (shouldCorrectQuery && limit >= 0) { + const { query, shouldRunAgain } = await fixedQueryByOneAction(fixedQuery); + shouldCorrectQuery = shouldRunAgain; + fixedQuery = query; + limit--; + } + + return fixedQuery; +}; diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts new file mode 100644 index 0000000000000..04d99aede62b8 --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.test.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getErrorsWithCommands } from './get_errors_with_commands'; + +describe('getErrorsWithCommands', () => { + it('returns the command associated with the error', () => { + expect( + getErrorsWithCommands(`FROM logs-* | WHERE @timestamp <= NOW() | STATS BY host.name`, [ + { + type: 'error', + text: 'Syntax error', + code: '', + location: { + min: 24, + max: 36, + }, + }, + ]) + ).toEqual(['Error in `| WHERE @timestamp <= NOW()`:\n Syntax error']); + }); +}); diff --git a/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts new file mode 100644 index 0000000000000..b25c79161f79b --- /dev/null +++ b/x-pack/plugins/inference/common/tasks/nl_to_esql/get_errors_with_commands.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EditorError, ESQLMessage } from '@kbn/esql-ast'; +import { splitIntoCommands } from './correct_common_esql_mistakes'; + +export function getErrorsWithCommands(query: string, errors: Array) { + const asCommands = splitIntoCommands(query); + + const errorMessages = errors.map((error) => { + if ('location' in error) { + const commandsUntilEndOfError = splitIntoCommands(query.substring(0, error.location.max)); + const lastCompleteCommand = asCommands[commandsUntilEndOfError.length - 1]; + if (lastCompleteCommand) { + return `Error in \`| ${lastCompleteCommand.command}\`:\n ${error.text}`; + } + } + return 'text' in error ? error.text : error.message; + }); + + return errorMessages; +} diff --git a/x-pack/plugins/inference/jest.config.js b/x-pack/plugins/inference/jest.config.js index 3bc2142bcdfc3..8b20bd72f17b2 100644 --- a/x-pack/plugins/inference/jest.config.js +++ b/x-pack/plugins/inference/jest.config.js @@ -8,7 +8,11 @@ module.exports = { preset: '@kbn/test', rootDir: '../../..', - roots: ['/x-pack/plugins/inference/public', '/x-pack/plugins/inference/server'], + roots: [ + '/x-pack/plugins/inference/public', + '/x-pack/plugins/inference/server', + '/x-pack/plugins/inference/common', + ], setupFiles: [], collectCoverage: true, collectCoverageFrom: [ diff --git a/x-pack/plugins/inference/public/util/http_response_into_observable.test.ts b/x-pack/plugins/inference/public/util/http_response_into_observable.test.ts index f50ec402bdd77..2b99b6f1db6f5 100644 --- a/x-pack/plugins/inference/public/util/http_response_into_observable.test.ts +++ b/x-pack/plugins/inference/public/util/http_response_into_observable.test.ts @@ -9,7 +9,7 @@ import { lastValueFrom, of, toArray } from 'rxjs'; import { httpResponseIntoObservable } from './http_response_into_observable'; import type { StreamedHttpResponse } from './create_observable_from_http_response'; import { ChatCompletionEventType } from '../../common/chat_complete'; -import { InferenceTaskEventType } from '../../common/tasks'; +import { InferenceTaskEventType } from '../../common/inference_task'; import { InferenceTaskErrorCode } from '../../common/errors'; function toSse(...events: Array>) { diff --git a/x-pack/plugins/inference/public/util/http_response_into_observable.ts b/x-pack/plugins/inference/public/util/http_response_into_observable.ts index 5b0929762e25d..53fdf302076a9 100644 --- a/x-pack/plugins/inference/public/util/http_response_into_observable.ts +++ b/x-pack/plugins/inference/public/util/http_response_into_observable.ts @@ -6,7 +6,7 @@ */ import { map, OperatorFunction, pipe, switchMap, tap } from 'rxjs'; -import { InferenceTaskEvent, InferenceTaskEventType } from '../../common/tasks'; +import { InferenceTaskEvent, InferenceTaskEventType } from '../../common/inference_task'; import { createObservableFromHttpResponse, StreamedHttpResponse, diff --git a/x-pack/plugins/inference/scripts/evaluation/.eslintrc.json b/x-pack/plugins/inference/scripts/evaluation/.eslintrc.json new file mode 100644 index 0000000000000..4eef2a5557280 --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/.eslintrc.json @@ -0,0 +1,17 @@ +{ + "overrides": [ + { + "files": [ + "**/*.spec.ts" + ], + "rules": { + "@kbn/imports/require_import": [ + "error", + "@kbn/ambient-ftr-types" + ], + "@typescript-eslint/triple-slash-reference": "off", + "spaced-comment": "off" + } + } + ] +} diff --git a/x-pack/plugins/inference/scripts/evaluation/README.md b/x-pack/plugins/inference/scripts/evaluation/README.md new file mode 100644 index 0000000000000..39ba3426ba0d4 --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/README.md @@ -0,0 +1,31 @@ +# Evaluation Framework + +## Overview + +This tool is developed for the teams working on anything related to inference. It simplifies scripting and evaluating various scenarios with the Large Language Model (LLM) integration. + +## Setup requirements + +- An Elasticsearch instance +- A Kibana instance +- At least one generative AI connector set up + +## Running evaluations + +Run the tool using: + +`$ node x-pack/plugins/inference/scripts/evaluation/index.js` + +This will evaluate all existing scenarios, and write the evaluation results to the terminal. + +### Configuration + +#### Kibana and Elasticsearch + +By default, the tool will look for a Kibana instance running locally (at `http://localhost:5601`, which is the default address for running Kibana in development mode). It will also attempt to read the Kibana config file for the Elasticsearch address & credentials. If you want to override these settings, use `--kibana` and `--es`. Only basic auth is supported, e.g. `--kibana http://username:password@localhost:5601`. If you want to use a specific space, use `--spaceId` + +#### Connector + +Use `--connectorId` to specify a generative AI connector to use. If none are given, it will prompt you to select a connector based on the ones that are available. If only a single supported connector is found, it will be used without prompting. + +Use `--evaluateWith` to specify the gen AI connector to use for evaluating the output of the task. By default, the same connector will be used. \ No newline at end of file diff --git a/x-pack/plugins/inference/scripts/evaluation/cli.ts b/x-pack/plugins/inference/scripts/evaluation/cli.ts new file mode 100644 index 0000000000000..d1cf133b0c4c0 --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/cli.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Argv } from 'yargs'; +import { connectorIdOption, elasticsearchOption, kibanaOption } from '../util/cli_options'; + +export enum EvaluateWith { + same = 'same', + other = 'other', +} + +export function options(y: Argv) { + return y + .option('files', { + string: true as const, + array: true, + describe: 'A file or list of files containing the scenarios to evaluate. Defaults to all', + }) + .option('grep', { + string: true, + array: false, + describe: 'A string or regex to filter scenarios by', + }) + .option('kibana', kibanaOption) + .option('spaceId', { + describe: 'The space to use.', + string: true, + array: false, + }) + .option('elasticsearch', elasticsearchOption) + .option('connectorId', connectorIdOption) + .option('logLevel', { + describe: 'Log level', + default: 'info', + }) + .option('evaluateWith', { + describe: + 'The connector ID to evaluate with. Leave empty for the same connector, use "other" to get a selection menu', + default: EvaluateWith.same, + }); +} diff --git a/x-pack/plugins/inference/scripts/evaluation/evaluation.ts b/x-pack/plugins/inference/scripts/evaluation/evaluation.ts new file mode 100644 index 0000000000000..0c70bf81eddad --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/evaluation.ts @@ -0,0 +1,190 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Client } from '@elastic/elasticsearch'; +import { run } from '@kbn/dev-cli-runner'; +import * as fastGlob from 'fast-glob'; +import yargs from 'yargs'; +import { castArray } from 'lodash'; +// @ts-expect-error +import Mocha from 'mocha'; +import Path from 'path'; +import { EvaluateWith, options } from './cli'; +import { getServiceUrls } from '../util/get_service_urls'; +import { KibanaClient } from '../util/kibana_client'; +import { initServices } from './services'; +import { EvaluationResult } from './types'; +import { selectConnector } from '../util/select_connector'; +import { createInferenceEvaluationClient } from './evaluation_client'; +import { createResultRenderer, renderFailedScenarios } from './table_renderer'; + +function runEvaluations() { + yargs(process.argv.slice(2)) + .command('*', 'Run Inference evaluations', options, (argv) => { + run( + async ({ log }) => { + const serviceUrls = await getServiceUrls({ + log, + elasticsearch: argv.elasticsearch, + kibana: argv.kibana, + }); + + const kibanaClient = new KibanaClient(log, serviceUrls.kibanaUrl, argv.spaceId); + const esClient = new Client({ + node: serviceUrls.esUrl, + }); + + await kibanaClient.createSpaceIfNeeded(); + + const connectors = await kibanaClient.getConnectors(); + if (!connectors.length) { + throw new Error('No connectors found'); + } + + const connector = await selectConnector({ + connectors, + preferredId: argv.connectorId, + log, + }); + + log.info(`Using connector ${connector.connectorId}`); + + const evaluationConnector = + argv.evaluateWith === EvaluateWith.same + ? connector + : await selectConnector({ + connectors, + preferredId: + argv.evaluateWith === EvaluateWith.other ? undefined : argv.evaluateWith, + log, + message: 'Select a connector for evaluation', + }); + + log.info(`Using connector ${evaluationConnector.connectorId} for evaluation`); + + const scenarios = + (argv.files !== undefined && + castArray(argv.files).map((file) => Path.join(process.cwd(), file))) || + fastGlob.sync(Path.join(__dirname, './scenarios/**/*.spec.ts')); + + if (!scenarios.length) { + throw new Error('No scenarios to run'); + } + + const mocha = new Mocha({ + grep: argv.grep, + timeout: '10m', + }); + + const chatClient = kibanaClient.createInferenceClient({ + connectorId: connector.connectorId, + }); + + const evaluationConnectorId = evaluationConnector.connectorId || connector.connectorId; + + const evaluationClient = createInferenceEvaluationClient({ + connectorId: connector.connectorId, + evaluationConnectorId, + outputApi: (id, parameters) => + chatClient.output(id, { + ...parameters, + connectorId: evaluationConnectorId, + }) as any, + suite: mocha.suite, + }); + + const renderer = createResultRenderer(); + const results: EvaluationResult[] = []; + const failedResults: EvaluationResult[] = []; + + evaluationClient.onResult((result) => { + results.push(result); + if (result.scores.filter((score) => score.score < 1).length) { + failedResults.push(result); + } + + log.write(renderer.render({ result })); + }); + + initServices({ + kibanaClient, + esClient, + chatClient, + evaluationClient, + logger: log, + }); + + for (const filename of scenarios) { + mocha.addFile(filename); + } + + return new Promise((resolve, reject) => { + mocha.run((failures: any) => { + if (failures) { + log.write(renderFailedScenarios(failedResults)); + reject(new Error(`Some tests failed`)); + return; + } + resolve(); + }); + }).finally(() => { + const modelScore = results + .flatMap((result) => result.scores) + .reduce( + (prev, result) => { + prev.score += result.score; + prev.total += 1; + return prev; + }, + { score: 0, total: 0 } + ); + + log.write('-------------------------------------------'); + log.write( + `Model ${connector.connectorId} scored ${modelScore.score} out of ${modelScore.total}` + ); + log.write('-------------------------------------------'); + + const scoresByCategory = results.reduce<{ + [key: string]: { + score: number; + total: number; + }; + }>((acc, result) => { + const category = result.category; + if (!acc[category]) { + acc[category] = { score: 0, total: 0 }; + } + result.scores.forEach((score) => { + acc[category].score += score.score; + acc[category].total += 1; + }); + return acc; + }, {}); + + log.write('-------------------------------------------'); + log.write(`Model ${connector.connectorId} scores per category`); + Object.entries(scoresByCategory).forEach(([category, { score, total }]) => { + log.write(`- category: ${category} - scored ${score} out of ${total}`); + }); + log.write('-------------------------------------------'); + }); + }, + { + log: { + defaultLevel: argv.logLevel as any, + }, + flags: { + allowUnexpected: true, + }, + } + ); + }) + .parse(); +} + +runEvaluations(); diff --git a/x-pack/plugins/inference/scripts/evaluation/evaluation_client.ts b/x-pack/plugins/inference/scripts/evaluation/evaluation_client.ts new file mode 100644 index 0000000000000..acf2fece1d0ff --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/evaluation_client.ts @@ -0,0 +1,181 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { remove } from 'lodash'; +import { lastValueFrom } from 'rxjs'; +import type { OutputAPI } from '../../common/output'; +import { withoutOutputUpdateEvents } from '../../common/output/without_output_update_events'; +import type { EvaluationResult } from './types'; + +export interface InferenceEvaluationClient { + getEvaluationConnectorId: () => string; + evaluate: (options: { + input: string; + criteria?: string[]; + system?: string; + }) => Promise; + getResults: () => EvaluationResult[]; + onResult: (cb: (result: EvaluationResult) => void) => () => void; + output: OutputAPI; +} + +export function createInferenceEvaluationClient({ + connectorId, + evaluationConnectorId, + suite, + outputApi, +}: { + connectorId: string; + evaluationConnectorId: string; + suite?: Mocha.Suite; + outputApi: OutputAPI; +}): InferenceEvaluationClient { + let currentTitle: string = ''; + let firstSuiteName: string = ''; + + // get the suite name + if (suite) { + suite.beforeEach(function () { + const currentTest: Mocha.Test = this.currentTest!; + const titles: string[] = []; + titles.push(this.currentTest!.title); + let parent = currentTest.parent; + while (parent) { + titles.push(parent.title); + parent = parent.parent; + } + currentTitle = titles.reverse().join(' '); + firstSuiteName = titles.filter((item) => item !== '')[0]; + }); + + suite.afterEach(function () { + currentTitle = ''; + }); + } + + const onResultCallbacks: Array<{ + callback: (result: EvaluationResult) => void; + unregister: () => void; + }> = []; + + const results: EvaluationResult[] = []; + + return { + output: outputApi, + getEvaluationConnectorId: () => evaluationConnectorId, + evaluate: async ({ input, criteria = [], system }) => { + const evaluation = await lastValueFrom( + outputApi('evaluate', { + connectorId, + system: withAdditionalSystemContext( + `You are a helpful, respected assistant for evaluating task + inputs and outputs in the Elastic Platform. + + Your goal is to verify whether the output of a task + succeeded, given the criteria. + + For each criterion, calculate a *score* between 0 (criterion fully failed) + and 1 (criterion fully succeeded), Fractional results (e.g. 0.5) are allowed, + if only part of the criterion succeeded. Explain your *reasoning* for the score, by + describing what the assistant did right, and describing and + quoting what the assistant did wrong, where it could improve, + and what the root cause was in case of a failure. + `, + system + ), + + input: ` + ## Criteria + + ${criteria + .map((criterion, index) => { + return `${index}: ${criterion}`; + }) + .join('\n')} + + ## Input + + ${input}`, + schema: { + type: 'object', + properties: { + criteria: { + type: 'array', + items: { + type: 'object', + properties: { + index: { + type: 'number', + description: 'The number of the criterion', + }, + score: { + type: 'number', + description: + 'The score you calculated for the criterion, between 0 (criterion fully failed) and 1 (criterion fully succeeded).', + }, + reasoning: { + type: 'string', + description: + 'Your reasoning for the score. Explain your score by mentioning what you expected to happen and what did happen.', + }, + }, + required: ['index', 'score', 'reasoning'], + }, + }, + }, + required: ['criteria'], + } as const, + }).pipe(withoutOutputUpdateEvents()) + ); + + const scoredCriteria = evaluation.output.criteria; + + const scores = scoredCriteria.map(({ index, score, reasoning }) => { + return { + criterion: criteria[index], + score, + reasoning, + }; + }); + + const result: EvaluationResult = { + name: currentTitle, + category: firstSuiteName, + input, + passed: scoredCriteria.every(({ score }) => score >= 1), + scores, + }; + + results.push(result); + + onResultCallbacks.forEach(({ callback }) => { + callback(result); + }); + + return result; + }, + getResults: () => results, + onResult: (callback) => { + const unregister = () => { + remove(onResultCallbacks, { callback }); + }; + onResultCallbacks.push({ callback, unregister }); + return unregister; + }, + }; +} + +const withAdditionalSystemContext = (system: string, additionalContext?: string): string => { + if (!additionalContext) { + return system; + } + + return [ + system, + `Here is some additional context that should help you for your evaluation:` + additionalContext, + ].join('\n\n'); +}; diff --git a/x-pack/plugins/inference/scripts/evaluation/index.js b/x-pack/plugins/inference/scripts/evaluation/index.js new file mode 100644 index 0000000000000..963e1a2ecfbed --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/index.js @@ -0,0 +1,10 @@ +/* + * 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. + */ + +require('@kbn/babel-register').install(); + +require('./evaluation'); diff --git a/x-pack/plugins/inference/scripts/evaluation/scenarios/esql/index.spec.ts b/x-pack/plugins/inference/scripts/evaluation/scenarios/esql/index.spec.ts new file mode 100644 index 0000000000000..dffca52b10836 --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/scenarios/esql/index.spec.ts @@ -0,0 +1,409 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/// + +import expect from '@kbn/expect'; +import { mapValues, pick } from 'lodash'; +import { firstValueFrom, lastValueFrom, filter } from 'rxjs'; +import { naturalLanguageToEsql } from '../../../../server/tasks/nl_to_esql'; +import { chatClient, evaluationClient, logger } from '../../services'; +import { loadDocuments } from '../../../../server/tasks/nl_to_esql/load_documents'; +import { isOutputCompleteEvent } from '../../../../common'; + +interface TestCase { + title: string; + question: string; + expected?: string; + criteria?: string[]; + only?: boolean; +} + +interface Section { + title: string; + tests: TestCase[]; +} + +const callNaturalLanguageToEsql = async (question: string) => { + return await lastValueFrom( + naturalLanguageToEsql({ + client: { + output: chatClient.output, + chatComplete: chatClient.chatComplete, + }, + connectorId: chatClient.getConnectorId(), + input: question, + logger: { + debug: (source) => { + logger.debug(typeof source === 'function' ? source() : source); + }, + }, + }) + ); +}; + +const expectedQueryCriteria = (expected: string) => { + return `The answer provides a ES|QL query that is functionally equivalent to: + + \`\`\`esql + ${expected} + \`\`\` + + It's OK if column names are slightly different, or if the used functions or operators are different, + as long as the expected end result is the same.`; +}; + +const retrieveUsedCommands = async ({ + question, + answer, + esqlDescription, +}: { + question: string; + answer: string; + esqlDescription: string; +}) => { + const commandsListOutput = await firstValueFrom( + evaluationClient + .output('retrieve_commands', { + connectorId: evaluationClient.getEvaluationConnectorId(), + system: ` + You are a helpful, respected Elastic ES|QL assistant. + + Your role is to enumerate the list of ES|QL commands and functions that were used + on a question and its answer. + + Only return each command or function once, even if they were used multiple times. + + The following extract of the ES|QL documentation lists all the commands and functions available: + + ${esqlDescription} + `, + input: ` + # Question + ${question} + + # Answer + ${answer} + `, + schema: { + type: 'object', + properties: { + commands: { + description: + 'The list of commands that were used in the provided ES|QL question and answer', + type: 'array', + items: { type: 'string' }, + }, + functions: { + description: + 'The list of functions that were used in the provided ES|QL question and answer', + type: 'array', + items: { type: 'string' }, + }, + }, + required: ['commands', 'functions'], + } as const, + }) + .pipe(filter(isOutputCompleteEvent)) + ); + + const output = commandsListOutput.output; + + const keywords = [ + ...(output.commands ?? []), + ...(output.functions ?? []), + 'SYNTAX', + 'OVERVIEW', + 'OPERATORS', + ].map((keyword) => keyword.toUpperCase()); + + return keywords; +}; + +async function evaluateEsqlQuery({ + question, + expected, + criteria = [], +}: { + question: string; + expected?: string; + criteria?: string[]; +}): Promise { + logger.debug(`Evaluation: ${question}`); + + const generateEvent = await callNaturalLanguageToEsql(question); + const answer = generateEvent.content!; + + logger.debug(`Received response: ${answer}`); + + const [systemMessage, esqlDocs] = await loadDocuments(); + + const usedCommands = await retrieveUsedCommands({ + question, + answer, + esqlDescription: systemMessage, + }); + + const requestedDocumentation = mapValues(pick(esqlDocs, usedCommands), ({ data }) => data); + + const evaluation = await evaluationClient.evaluate({ + input: ` + # Question + + ${question} + + # Answer + + ${generateEvent.content} + + `, + criteria: [...(expected ? [expectedQueryCriteria(expected)] : []), ...criteria], + system: ` + The assistant was asked to generate an ES|QL query based on the question from the user. + + Here is the documentation about the commands and function that are being used + in the ES|QL queries present in the question and the answer. + + ${Object.values(requestedDocumentation).join('\n\n')} + `, + }); + + expect(evaluation.passed).to.be(true); +} + +const buildTestDefinitions = (): Section[] => { + const testDefinitions: Section[] = [ + { + title: 'ES|QL query generation', + tests: [ + { + title: 'Generates a query to show the volume of logs over time', + question: `From the "kibana_sample_data_logs" index, show me the volume of logs per day over the last 10 days + Assume the following fields: + - @timestamp`, + expected: `FROM kibana_sample_data_logs + | WHERE @timestamp > NOW() - 10 days + | STATS volume = COUNT(*) BY BUCKET(@timestamp, 1 day)`, + }, + { + title: 'Generates a query to show employees filtered by name and grouped by hire_date', + question: `From the employees index, I want to see how many employees with a "B" in their first name + where hired each month over the past 2 years. + Assume the following fields: + - hire_date + - first_name + - last_name`, + expected: `FROM employees + | WHERE first_name LIKE "*B*" AND hire_date >= NOW() - 2 years + | STATS COUNT(*) BY BUCKET(hire_date, 1 month) + | SORT hire_date`, + }, + { + title: 'Generates a query to show employees which have a palindrome as last name', + question: `From the employees index, I want to find all employees with a palindrome as last name + (which can be read the same backward and forward), and then return their last name and first name + - last_name + - first_name`, + expected: `FROM employees + | EVAL reversed_last_name = REVERSE(last_name) + | WHERE TO_LOWER(last_name) == TO_LOWER(reversed_last_name) + | KEEP last_name, first_name`, + }, + { + title: 'Generates a query to show the top 10 domains by doc count', + question: `For standard Elastic ECS compliant packetbeat data view (\`packetbeat-*\`), + show me the top 10 unique destination.domain with the most docs. + Assume the following fields: + - destination.domain`, + expected: `FROM packetbeat-* + | STATS doc_count = COUNT(*) BY destination.domain + | SORT doc_count DESC + | LIMIT 10`, + }, + { + title: 'Generates a query to show the top 5 employees sorted ascending by hire date', + question: `From employees, I want to see the 5 earliest employees (hire_date), I want to display + only the month and the year that they were hired in and their employee number (emp_no). + Format the date as e.g. "September 2019".`, + expected: `FROM employees + | EVAL hire_date_formatted = DATE_FORMAT("MMMM YYYY", hire_date) + | SORT hire_date + | KEEP emp_no, hire_date_formatted + | LIMIT 5`, + }, + { + title: 'Explains that pagination is not supported when requested', + question: `From employees, I want to sort the documents by \`salary\`, + and then return 10 results per page, and then see the second page`, + criteria: [ + `The assistant should clearly mention that pagination is currently not supported in ES|QL. + It might provide a workaround, even if this should not be considered mandatory for this criteria.`, + ], + }, + { + title: + 'Generates a query to extract the year and shows 10 employees that were hired in 2024', + question: `From employees, extract the year from hire_date and show 10 employees hired in 2024`, + expected: `FROM employees + | WHERE DATE_EXTRACT("year", hire_date) == 2024 + | LIMIT 10`, + }, + { + title: 'Generates a query to calculate the avg cpu usage over the last 15m per service', + question: `Assume my metrics data is in \`metrics-*\`. I want to see what + a query would look like that gets the average CPU per service, + limit it to the top 10 results, in 1m buckets, and only the last 15m. + Assume the following fields: + - @timestamp + - system.cpu.total.norm.pct + - service.name`, + expected: `FROM metrics-* + | WHERE @timestamp >= NOW() - 15 minutes + | STATS avg_cpu = AVG(system.cpu.total.norm.pct) BY BUCKET(@timestamp, 1m), service.name + | SORT avg_cpu DESC + | LIMIT 10`, + }, + { + title: 'Generates a query to show logs volume with some complex multi-field filter', + question: `From the "sample_logs" index, show me the volume of daily logs + from source "foo" or "bar", with message longer than 62 chars and not containing "dolly", and with INFO level. + Assume the following fields: + - source + - message + - level + - @timestamp`, + expected: `│ FROM sample_logs + | WHERE source IN ("foo", "bar") AND LENGTH(message) > 62 AND message NOT LIKE "*dolly*" AND level == "INFO" + | STATS COUNT(*) BY day = BUCKET(@timestamp, 1d) + | SORT day ASC`, + }, + { + title: 'Generates a query to show normalized CPU per host', + question: `My data is in \`metricbeat*\`. Show me a query to see the percentage + of CPU time (system.cpu.system.pct) normalized by the number of CPU cores + (system.cpu.cores), broken down by host name. + Assume the following fields: + - system.cpu.system.pct + - system.cpu.cores + - host.name`, + expected: `FROM metricbeat* + | EVAL system_pct_normalized = TO_DOUBLE(system.cpu.system.pct) / system.cpu.cores + | STATS avg_system_pct_normalized = AVG(system_pct_normalized) BY host.name + | SORT host.name ASC`, + }, + { + title: 'Generates a query to show normalized CPU per host', + question: `From the access_logs index, I want to see the 50, 95 and 99 percentile + of response_time, break down by month over the past year. + Assume the following fields: + - @timestamp + - response_time + - status_code`, + expected: ` FROM access_logs + | WHERE @timestamp > NOW() - 1 year + | STATS p50 = PERCENTILE(response_time, 50), p95 = PERCENTILE(response_time, 95), p99 = PERCENTILE(response_time, 99) + BY month = BUCKET(@timestamp, 1 month) + | SORT month`, + }, + { + title: 'Generates a query using DISSECT to parse a postgres log message', + question: `Show me an example ESQL query to extract the query duration + from postgres log messages in postgres-logs*, with this format: + \`2021-01-01 00:00:00 UTC [12345]: [1-1] user=postgres,db=mydb,app=[unknown],client=127.0.0.1 LOG: duration: 123.456 ms statement: SELECT * FROM my_table\`. + Calculate the average. + Assume the following fields: + - message`, + expected: `FROM postgres-logs* + | DISSECT message "%{}: duration: %{query_duration} ms %{}" + | EVAL duration_double = TO_DOUBLE(duration) + | STATS AVG(duration_double)`, + }, + { + title: 'Generates a query using GROK to parse a postgres log message', + question: `Consider the postgres-logs index, with the message field having the following format: + \`2023-01-23T12:15:00.000Z ip=127.0.0.1 email=some.email@foo.com userid=42 [some message]\`. + Using GROK, please count the number of log entries for the email "test@org.com" for each month over last year + Assume the following fields: + - message`, + expected: `FROM postgres-logs + | GROK message "%{TIMESTAMP_ISO8601:timestamp} ip=%{IP:ip} email=%{EMAILADDRESS:email} userid=%{NUMBER:userid} [%{GREEDYDATA:log_message}]" + | WHERE email == "test@org.com" AND timestamp > NOW() - 1 year + | STATS COUNT(*) BY month = BUCKET(@timestamp, 1m) + | SORT month`, + }, + ], + }, + { + title: 'SPL to ESQL', + tests: [ + { + title: 'Converts a simple count query', + question: `Can you convert this SPL query to ESQL? \`index=network_firewall "SYN Timeout" | stats count by dest\``, + expected: `FROM network_firewall + | WHERE _raw == "SYN Timeout" + | STATS count = count(*) by dest`, + }, + { + title: 'Converts if/len to CASE/LENGTH', + question: `Can you convert this SPL query to ESQL? + \`index=prod_web + | eval length=len(message) + | eval k255=if((length>255),1,0) + | eval k2=if((length>2048),1,0) + | eval k4=if((length>4096),1,0) + | eval k16=if((length>16384),1,0) + | stats count, sum(k255), sum(k2),sum(k4),sum(k16), sum(length)\``, + expected: `FROM prod_web + | EVAL length = length(message), k255 = CASE(length > 255, 1, 0), k2 = CASE(length > 2048, 1, 0), k4 = CASE(length > 4096, 1, 0), k16 = CASE(length > 16384, 1, 0) + | STATS COUNT(*), SUM(k255), SUM(k2), SUM(k4), SUM(k16), SUM(length)`, + criteria: [ + 'The query provided by the Assistant uses the ESQL functions LENGTH and CASE, not the SPL functions len and if', + ], + }, + { + title: 'Converts matchers to NOT LIKE', + question: `Can you convert this SPL query to ESQL? + \`index=prod_web NOT "Connection reset" NOT "[acm-app] created a ThreadLocal" + sourcetype!=prod_urlf_east_logs sourcetype!=prod_urlf_west_logs + host!="dbs-tools-*" NOT "Public] in context with path [/global]" + host!="*dev*" host!="*qa*" host!="*uat*"\``, + expected: `FROM prod_web + | WHERE _raw NOT LIKE "Connection reset" + AND _raw NOT LIKE "[acm-app] created a ThreadLocal" + AND sourcetype != "prod_urlf_east_logs" + AND sourcetype != "prod_urlf_west_logs" + AND host NOT LIKE "dbs-tools-*" + AND _raw NOT LIKE "Public] in context with path [/global]" + AND host NOT LIKE "*dev*" + AND host NOT LIKE "*qa*" + AND host NOT LIKE "*uat*"`, + }, + ], + }, + ]; + + return testDefinitions; +}; + +const generateTestSuite = () => { + const testDefinitions = buildTestDefinitions(); + for (const section of testDefinitions) { + describe(`${section.title}`, () => { + for (const test of section.tests) { + (test.only ? it.only : it)(`${test.title}`, async () => { + await evaluateEsqlQuery({ + question: test.question, + expected: test.expected, + criteria: test.criteria, + }); + }); + } + }); + } +}; + +generateTestSuite(); diff --git a/x-pack/plugins/inference/scripts/evaluation/services/index.ts b/x-pack/plugins/inference/scripts/evaluation/services/index.ts new file mode 100644 index 0000000000000..5685a24e0df8b --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/services/index.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Client } from '@elastic/elasticsearch'; +import type { ToolingLog } from '@kbn/tooling-log'; +import type { ScriptInferenceClient, KibanaClient } from '../../util/kibana_client'; +import type { InferenceEvaluationClient } from '../evaluation_client'; + +// make services globals so they can more easily be used in the tests + +function createErrorThrowingProxy(name: string): any { + return new Proxy( + {}, + { + get: () => { + throw new Error(`${name} has not been instantiated yet`); + }, + set: () => { + throw new Error(`${name} has not been instantiated yet`); + }, + } + ); +} + +export let chatClient: ScriptInferenceClient = createErrorThrowingProxy('evaluationClient'); +export let evaluationClient: InferenceEvaluationClient = + createErrorThrowingProxy('evaluationClient'); + +export let esClient: Client = createErrorThrowingProxy('esClient'); +export let kibanaClient: KibanaClient = createErrorThrowingProxy('kibanaClient'); +export let logger: ToolingLog = createErrorThrowingProxy('logger'); + +export const initServices = (services: { + chatClient: ScriptInferenceClient; + evaluationClient: InferenceEvaluationClient; + esClient: Client; + kibanaClient: KibanaClient; + logger: ToolingLog; +}) => { + chatClient = services.chatClient; + evaluationClient = services.evaluationClient; + esClient = services.esClient; + kibanaClient = services.kibanaClient; + logger = services.logger; +}; diff --git a/x-pack/plugins/inference/scripts/evaluation/table_renderer.ts b/x-pack/plugins/inference/scripts/evaluation/table_renderer.ts new file mode 100644 index 0000000000000..48e09b96457dc --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/table_renderer.ts @@ -0,0 +1,100 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as table from 'table'; +import chalk from 'chalk'; +import type { TableUserConfig } from 'table'; +import type { EvaluationResult } from './types'; + +interface ResultRenderer { + render: (params: { result: EvaluationResult }) => string; +} + +export const createResultRenderer = (): ResultRenderer => { + const config = { + ...baseConfig, + spanningCells: [ + { row: 0, col: 0, colSpan: 3 }, + { row: 1, col: 0, colSpan: 3 }, + ], + columns: [{ wrapWord: true, width: 60 }, { wrapWord: true }, { wrapWord: true, width: 60 }], + }; + const header = [chalk.bold('Criterion'), chalk.bold('Result'), chalk.bold('Reasoning')]; + + return { + render: ({ result }) => { + const rows: string[][] = [[sanitize(result.input), '', ''], ['', '', ''], header]; + result.scores.forEach((score) => { + rows.push([ + sanitize(score.criterion), + score.score < 1 + ? chalk.redBright(String(score.score)) + : chalk.greenBright(String(score.score)), + sanitize(score.reasoning), + ]); + }); + return table.table(rows, config); + }, + }; +}; + +export const renderFailedScenarios = (failedScenario: EvaluationResult[]): string => { + const config = { + ...baseConfig, + spanningCells: [], + columns: [{ wrapWord: true, width: 60 }, { wrapWord: true }, { wrapWord: true, width: 60 }], + }; + const rows: string[][] = [ + ['Failed Tests', '', ''], + ['Scenario', 'Scores', 'Reasoning'], + ]; + + failedScenario.forEach((result) => { + const totalResults = result.scores.length; + const failedResults = result.scores.filter((score) => score.score < 1).length; + + const reasoningConcat = result.scores.map((score) => sanitize(score.reasoning)).join(' '); + rows.push([ + `${result.name}`, + `Average score ${Math.round( + (result.scores.reduce((total, next) => total + next.score, 0) * 100) / totalResults + )}. Failed ${failedResults} tests out of ${totalResults}`, + `Reasoning: ${reasoningConcat}`, + ]); + }); + + return table.table(rows, config); +}; + +const baseConfig: TableUserConfig = { + singleLine: false, + border: { + topBody: `─`, + topJoin: `┬`, + topLeft: `┌`, + topRight: `┐`, + + bottomBody: `─`, + bottomJoin: `┴`, + bottomLeft: `└`, + bottomRight: `┘`, + + bodyLeft: `│`, + bodyRight: `│`, + bodyJoin: `│`, + + joinBody: `─`, + joinLeft: `├`, + joinRight: `┤`, + joinJoin: `┼`, + }, +}; + +const sanitize = (text: string) => { + // table really doesn't like leading whitespaces and empty lines... + return text.replace(/^ +/gm, '').replace(/ +$/gm, '').replace(/^\n+/g, '').replace(/\n+$/g, ''); +}; diff --git a/x-pack/plugins/inference/scripts/evaluation/types.ts b/x-pack/plugins/inference/scripts/evaluation/types.ts new file mode 100644 index 0000000000000..cd6485306344e --- /dev/null +++ b/x-pack/plugins/inference/scripts/evaluation/types.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Client } from '@elastic/elasticsearch'; +import type { ScriptInferenceClient, KibanaClient } from '../util/kibana_client'; +import type { InferenceEvaluationClient } from './evaluation_client'; + +export interface ScenarioOptions { + esClient: Client; + kibanaClient: KibanaClient; + chatClient: ScriptInferenceClient; + evaluationClient: InferenceEvaluationClient; +} + +export interface EvaluationResult { + name: string; + category: string; + input: string; + passed: boolean; + scores: Array<{ + criterion: string; + reasoning: string; + score: number; + }>; +} + +export type EvaluationFunction = (options: ScenarioOptions) => Promise; diff --git a/x-pack/plugins/inference/scripts/load_esql_docs/README.md b/x-pack/plugins/inference/scripts/load_esql_docs/README.md new file mode 100644 index 0000000000000..06b6cf22aa49d --- /dev/null +++ b/x-pack/plugins/inference/scripts/load_esql_docs/README.md @@ -0,0 +1,10 @@ +# Load ES|QL docs + +This script loads ES|QL documentation from the `built-docs` repo, and rewrites it with help of the LLM. +The generated documentation is validated and will emit warnings when invalid queries have been generated. + +## Requirements + +- checked out `built-docs` repo in the same folder as the `kibana` repository +- a running Kibana instance +- an installed Generative AI connector diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/extract_sections.ts b/x-pack/plugins/inference/scripts/load_esql_docs/extract_sections.ts similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/extract_sections.ts rename to x-pack/plugins/inference/scripts/load_esql_docs/extract_sections.ts diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/index.js b/x-pack/plugins/inference/scripts/load_esql_docs/index.js similarity index 100% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/index.js rename to x-pack/plugins/inference/scripts/load_esql_docs/index.js diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/load_esql_docs.ts b/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts similarity index 91% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/load_esql_docs.ts rename to x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts index b8a90c2b62e46..3250d06906905 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/load_esql_docs/load_esql_docs.ts +++ b/x-pack/plugins/inference/scripts/load_esql_docs/load_esql_docs.ts @@ -5,30 +5,31 @@ * 2.0. */ import { run } from '@kbn/dev-cli-runner'; +import { ESQLMessage, EditorError, getAstAndSyntaxErrors } from '@kbn/esql-ast'; +import { validateQuery } from '@kbn/esql-validation-autocomplete'; import $, { load } from 'cheerio'; import { SingleBar } from 'cli-progress'; import FastGlob from 'fast-glob'; import Fs from 'fs/promises'; -import { once, partition, compact } from 'lodash'; +import { compact, once, partition } from 'lodash'; import pLimit from 'p-limit'; import Path from 'path'; import git, { SimpleGitProgressEvent } from 'simple-git'; import yargs, { Argv } from 'yargs'; -import { MessageRole } from '@kbn/observability-ai-assistant-plugin/common'; -import { validateQuery } from '@kbn/esql-validation-autocomplete'; -import { EditorError, ESQLMessage, getAstAndSyntaxErrors } from '@kbn/esql-ast'; -import { connectorIdOption, elasticsearchOption, kibanaOption } from '../evaluation/cli'; -import { getServiceUrls } from '../evaluation/get_service_urls'; -import { KibanaClient } from '../evaluation/kibana_client'; -import { selectConnector } from '../evaluation/select_connector'; +import { lastValueFrom } from 'rxjs'; +import { REPO_ROOT } from '@kbn/repo-info'; +import { INLINE_ESQL_QUERY_REGEX } from '../../common/tasks/nl_to_esql/constants'; +import { correctCommonEsqlMistakes } from '../../common/tasks/nl_to_esql/correct_common_esql_mistakes'; +import { connectorIdOption, elasticsearchOption, kibanaOption } from '../util/cli_options'; +import { getServiceUrls } from '../util/get_service_urls'; +import { KibanaClient } from '../util/kibana_client'; +import { selectConnector } from '../util/select_connector'; import { extractSections } from './extract_sections'; -import { correctCommonEsqlMistakes } from '../../server/functions/query/correct_common_esql_mistakes'; -import { INLINE_ESQL_QUERY_REGEX } from '../../server/functions/query/constants'; yargs(process.argv.slice(2)) .command( '*', - 'Extract ES|QL documentation for the Observability AI Assistant', + 'Extract ES|QL documentation', (y: Argv) => y .option('logLevel', { @@ -73,15 +74,13 @@ yargs(process.argv.slice(2)) log, }); - const chatClient = kibanaClient.createChatClient({ - connectorId: connector.id, - evaluationConnectorId: connector.id, - persist: false, + const chatClient = kibanaClient.createInferenceClient({ + connectorId: connector.connectorId, }); - log.info(`Using connector ${connector.id}`); + log.info(`Using connector ${connector.connectorId}`); - const builtDocsDir = Path.join(__dirname, '../../../../../../../built-docs'); + const builtDocsDir = Path.join(REPO_ROOT, '../built-docs'); log.debug(`Looking in ${builtDocsDir} for built-docs repository`); @@ -329,10 +328,7 @@ yargs(process.argv.slice(2)) return !isOverviewArticle; }); - const outDir = Path.join( - __dirname, - '../../../observability_ai_assistant_app/server/functions/query/esql_docs' - ); + const outDir = Path.join(__dirname, '../../server/tasks/nl_to_esql/esql_docs'); if (!argv.dryRun) { log.info(`Writing ${flattened.length} documents to disk to ${outDir}`); @@ -341,9 +337,12 @@ yargs(process.argv.slice(2)) if (!argv.only && !argv.dryRun) { log.debug(`Clearing ${outDir}`); - await Fs.rm(outDir, { recursive: true }).catch((error) => - error.code === 'ENOENT' ? Promise.resolve() : error - ); + await Fs.readdir(outDir, { recursive: true }) + .then((filesInDir) => { + const limiter = pLimit(10); + return Promise.all(filesInDir.map((file) => limiter(() => Fs.unlink(file)))); + }) + .catch((error) => (error.code === 'ENOENT' ? Promise.resolve() : error)); } if (!argv.dryRun) { @@ -428,10 +427,10 @@ yargs(process.argv.slice(2)) return chatLimiter(async () => { try { - const response = await chatClient.chat([ - { - role: MessageRole.System, - content: `## System instructions + const response = await lastValueFrom( + chatClient.output('generate_markdown', { + connectorId: chatClient.getConnectorId(), + system: `## System instructions Your job is to generate Markdown documentation off of content that is scraped from the Elasticsearch website. @@ -462,10 +461,7 @@ yargs(process.argv.slice(2)) ${allContent} `, - }, - { - role: MessageRole.User, - content: `Generate Markdown for the following document: + input: `Generate Markdown for the following document: ## ${doc.title} @@ -476,8 +472,8 @@ yargs(process.argv.slice(2)) ### Content of file ${doc.content}`, - }, - ]); + }) + ); return fsLimiter(() => writeFile({ title: doc.title, content: response.content! }) diff --git a/x-pack/plugins/inference/scripts/util/cli_options.ts b/x-pack/plugins/inference/scripts/util/cli_options.ts new file mode 100644 index 0000000000000..13bac131922ff --- /dev/null +++ b/x-pack/plugins/inference/scripts/util/cli_options.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { format, parse } from 'url'; +import { readKibanaConfig } from './read_kibana_config'; + +const config = readKibanaConfig(); + +export const kibanaOption = { + describe: 'Where Kibana is running', + string: true as const, + default: process.env.KIBANA_HOST || 'http://localhost:5601', +}; +export const elasticsearchOption = { + alias: 'es', + describe: 'Where Elasticsearch is running', + string: true as const, + default: format({ + ...parse(config['elasticsearch.hosts']), + auth: `${config['elasticsearch.username']}:${config['elasticsearch.password']}`, + }), +}; + +export const connectorIdOption = { + describe: 'The ID of the connector', + string: true as const, +}; diff --git a/x-pack/plugins/inference/scripts/util/get_service_urls.ts b/x-pack/plugins/inference/scripts/util/get_service_urls.ts new file mode 100644 index 0000000000000..859b47987a470 --- /dev/null +++ b/x-pack/plugins/inference/scripts/util/get_service_urls.ts @@ -0,0 +1,148 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ToolingLog } from '@kbn/tooling-log'; +import { omit } from 'lodash'; +import fetch from 'node-fetch'; +import { format, parse, Url } from 'url'; + +async function discoverAuth(parsedTarget: Url, log: ToolingLog) { + const possibleCredentials = [`admin:changeme`, `elastic:changeme`]; + for (const auth of possibleCredentials) { + const url = format({ + ...parsedTarget, + auth, + }); + let status: number; + try { + log.debug(`Fetching ${url}`); + const response = await fetch(url); + status = response.status; + } catch (err) { + log.debug(`${url} resulted in ${err.message}`); + status = 0; + } + + if (status === 200) { + return auth; + } + } + + throw new Error(`Failed to authenticate user for ${format(parsedTarget)}`); +} + +async function getKibanaUrl({ kibana, log }: { kibana: string; log: ToolingLog }) { + try { + const isCI = process.env.CI?.toLowerCase() === 'true'; + + const parsedKibanaUrl = parse(kibana); + + const kibanaUrlWithoutAuth = format(omit(parsedKibanaUrl, 'auth')); + + log.debug(`Checking Kibana URL ${kibanaUrlWithoutAuth} for a redirect`); + + const unredirectedResponse = await fetch(kibanaUrlWithoutAuth, { + headers: { + ...(parsedKibanaUrl.auth + ? { Authorization: `Basic ${Buffer.from(parsedKibanaUrl.auth).toString('base64')}` } + : {}), + }, + method: 'HEAD', + follow: 1, + redirect: 'manual', + }); + + log.debug('Unredirected response', unredirectedResponse.headers.get('location')); + + const discoveredKibanaUrl = + unredirectedResponse.headers + .get('location') + ?.replace('/spaces/enter', '') + ?.replace('spaces/space_selector', '') || kibanaUrlWithoutAuth; + + log.debug(`Discovered Kibana URL at ${discoveredKibanaUrl}`); + + const parsedTarget = parse(kibana); + + const parsedDiscoveredUrl = parse(discoveredKibanaUrl); + + const discoveredKibanaUrlWithAuth = format({ + ...parsedDiscoveredUrl, + auth: parsedTarget.auth, + }); + + const redirectedResponse = await fetch(discoveredKibanaUrlWithAuth, { + method: 'HEAD', + }); + + if (redirectedResponse.status !== 200) { + throw new Error( + `Expected HTTP 200 from ${discoveredKibanaUrlWithAuth}, got ${redirectedResponse.status}` + ); + } + + const discoveredKibanaUrlWithoutAuth = format({ + ...parsedDiscoveredUrl, + auth: undefined, + }); + + log.info( + `Discovered kibana running at: ${ + isCI ? discoveredKibanaUrlWithoutAuth : discoveredKibanaUrlWithAuth + }` + ); + + return discoveredKibanaUrlWithAuth.replace(/\/$/, ''); + } catch (error) { + throw new Error(`Could not connect to Kibana: ` + error.message); + } +} + +export async function getServiceUrls({ + log, + elasticsearch, + kibana, +}: { + elasticsearch: string; + kibana: string; + log: ToolingLog; +}) { + if (!elasticsearch) { + // assume things are running locally + kibana = kibana || 'http://127.0.0.1:5601'; + elasticsearch = 'http://127.0.0.1:9200'; + } + + const parsedTarget = parse(elasticsearch); + + let auth = parsedTarget.auth; + + if (!parsedTarget.auth) { + auth = await discoverAuth(parsedTarget, log); + } + + const formattedEsUrl = format({ + ...parsedTarget, + auth, + }); + + const suspectedKibanaUrl = kibana || elasticsearch.replace('.es', '.kb'); + + const parsedKibanaUrl = parse(suspectedKibanaUrl); + + const kibanaUrlWithAuth = format({ + ...parsedKibanaUrl, + auth: parsedKibanaUrl.auth || auth, + }); + + const validatedKibanaUrl = await getKibanaUrl({ kibana: kibanaUrlWithAuth, log }); + + return { + kibanaUrl: validatedKibanaUrl, + esUrl: formattedEsUrl, + }; +} diff --git a/x-pack/plugins/inference/scripts/util/kibana_client.ts b/x-pack/plugins/inference/scripts/util/kibana_client.ts new file mode 100644 index 0000000000000..f8e96cfcf4ae3 --- /dev/null +++ b/x-pack/plugins/inference/scripts/util/kibana_client.ts @@ -0,0 +1,226 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ToolingLog } from '@kbn/tooling-log'; +import axios, { AxiosInstance, AxiosResponse, isAxiosError } from 'axios'; +import { IncomingMessage } from 'http'; +import { omit, pick } from 'lodash'; +import { from, map, switchMap, throwError } from 'rxjs'; +import { UrlObject, format, parse } from 'url'; +import { inspect } from 'util'; +import { isReadable } from 'stream'; +import type { ChatCompleteAPI, ChatCompletionEvent } from '../../common/chat_complete'; +import { ChatCompleteRequestBody } from '../../common/chat_complete/request'; +import type { InferenceConnector } from '../../common/connectors'; +import { + InferenceTaskError, + InferenceTaskErrorEvent, + createInferenceInternalError, +} from '../../common/errors'; +import { InferenceTaskEventType } from '../../common/inference_task'; +import type { OutputAPI } from '../../common/output'; +import { createOutputApi } from '../../common/output/create_output_api'; +import { withoutOutputUpdateEvents } from '../../common/output/without_output_update_events'; +import { eventSourceStreamIntoObservable } from '../../server/util/event_source_stream_into_observable'; + +// eslint-disable-next-line spaced-comment +/// + +export interface ScriptInferenceClient { + getConnectorId: () => string; + chatComplete: ChatCompleteAPI; + output: OutputAPI; +} + +export class KibanaClient { + axios: AxiosInstance; + constructor( + private readonly log: ToolingLog, + private readonly url: string, + private readonly spaceId?: string + ) { + this.axios = axios.create({ + headers: { + 'kbn-xsrf': 'foo', + }, + }); + } + + private getUrl(props: { query?: UrlObject['query']; pathname: string; ignoreSpaceId?: boolean }) { + const parsed = parse(this.url); + + const baseUrl = parsed.pathname?.replaceAll('/', '') ?? ''; + + const url = format({ + ...parsed, + pathname: `/${[ + ...(baseUrl ? [baseUrl] : []), + ...(props.ignoreSpaceId || !this.spaceId ? [] : ['s', this.spaceId]), + props.pathname.startsWith('/') ? props.pathname.substring(1) : props.pathname, + ].join('/')}`, + query: props.query, + }); + + return url; + } + + callKibana( + method: string, + props: { query?: UrlObject['query']; pathname: string; ignoreSpaceId?: boolean }, + data?: any + ) { + const url = this.getUrl(props); + return this.axios({ + method, + url, + data: data || {}, + headers: { + 'kbn-xsrf': 'true', + 'x-elastic-internal-origin': 'foo', + }, + }).catch((error) => { + if (isAxiosError(error)) { + const interestingPartsOfError = { + ...omit(error, 'request', 'response', 'config'), + ...pick( + error, + 'response.data', + 'response.headers', + 'response.status', + 'response.statusText' + ), + }; + this.log.error(inspect(interestingPartsOfError, { depth: 10 })); + } + throw error; + }); + } + + async createSpaceIfNeeded() { + if (!this.spaceId) { + return; + } + + this.log.debug(`Checking if space ${this.spaceId} exists`); + + const spaceExistsResponse = await this.callKibana<{ + id?: string; + }>('GET', { + pathname: `/api/spaces/space/${this.spaceId}`, + ignoreSpaceId: true, + }).catch((error) => { + if (isAxiosError(error) && error.response?.status === 404) { + return { + status: 404, + data: { + id: undefined, + }, + }; + } + throw error; + }); + + if (spaceExistsResponse.data.id) { + this.log.debug(`Space id ${this.spaceId} found`); + return; + } + + this.log.info(`Creating space ${this.spaceId}`); + + const spaceCreatedResponse = await this.callKibana<{ id: string }>( + 'POST', + { + pathname: '/api/spaces/space', + ignoreSpaceId: true, + }, + { + id: this.spaceId, + name: this.spaceId, + } + ); + + if (spaceCreatedResponse.status === 200) { + this.log.info(`Created space ${this.spaceId}`); + } else { + throw new Error( + `Error creating space: ${spaceCreatedResponse.status} - ${spaceCreatedResponse.data}` + ); + } + } + + createInferenceClient({ connectorId }: { connectorId: string }): ScriptInferenceClient { + function stream(responsePromise: Promise) { + return from(responsePromise).pipe( + switchMap((response) => { + if (isReadable(response.data)) { + return eventSourceStreamIntoObservable(response.data as IncomingMessage); + } + return throwError(() => createInferenceInternalError('Unexpected error', response.data)); + }), + map((line) => { + return JSON.parse(line) as ChatCompletionEvent | InferenceTaskErrorEvent; + }), + map((line) => { + if (line.type === InferenceTaskEventType.error) { + throw new InferenceTaskError(line.error.code, line.error.message, line.error.meta); + } + return line; + }) + ); + } + + const chatCompleteApi: ChatCompleteAPI = ({ + connectorId: chatCompleteConnectorId, + messages, + system, + toolChoice, + tools, + }) => { + const body: ChatCompleteRequestBody = { + connectorId: chatCompleteConnectorId, + system, + messages, + toolChoice, + tools, + }; + + return stream( + this.axios.post( + this.getUrl({ + pathname: `/internal/inference/chat_complete`, + }), + body, + { responseType: 'stream', timeout: NaN } + ) + ); + }; + + const outputApi: OutputAPI = createOutputApi(chatCompleteApi); + + return { + getConnectorId: () => connectorId, + chatComplete: (options) => { + return chatCompleteApi({ + ...options, + }); + }, + output: (id, options) => { + return outputApi(id, { ...options }).pipe(withoutOutputUpdateEvents()); + }, + }; + } + + async getConnectors() { + const connectors: AxiosResponse<{ connectors: InferenceConnector[] }> = await axios.get( + this.getUrl({ + pathname: '/internal/inference/connectors', + }) + ); + + return connectors.data.connectors; + } +} diff --git a/x-pack/plugins/inference/scripts/util/read_kibana_config.ts b/x-pack/plugins/inference/scripts/util/read_kibana_config.ts new file mode 100644 index 0000000000000..5b64bb2f56189 --- /dev/null +++ b/x-pack/plugins/inference/scripts/util/read_kibana_config.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import path from 'path'; +import fs from 'fs'; +import yaml from 'js-yaml'; +import { identity, pickBy } from 'lodash'; + +export type KibanaConfig = ReturnType; + +export const readKibanaConfig = () => { + const kibanaConfigDir = path.join(__filename, '../../../../../../config'); + const kibanaDevConfig = path.join(kibanaConfigDir, 'kibana.dev.yml'); + const kibanaConfig = path.join(kibanaConfigDir, 'kibana.yml'); + + const loadedKibanaConfig = (yaml.safeLoad( + fs.readFileSync(fs.existsSync(kibanaDevConfig) ? kibanaDevConfig : kibanaConfig, 'utf8') + ) || {}) as {}; + + const cliEsCredentials = pickBy( + { + 'elasticsearch.username': process.env.ELASTICSEARCH_USERNAME, + 'elasticsearch.password': process.env.ELASTICSEARCH_PASSWORD, + 'elasticsearch.hosts': process.env.ELASTICSEARCH_HOST, + }, + identity + ) as { + 'elasticsearch.username'?: string; + 'elasticsearch.password'?: string; + 'elasticsearch.hosts'?: string; + }; + + return { + 'elasticsearch.hosts': 'http://localhost:9200', + 'elasticsearch.username': 'elastic', + 'elasticsearch.password': 'changeme', + ...loadedKibanaConfig, + ...cliEsCredentials, + }; +}; diff --git a/x-pack/plugins/inference/scripts/util/select_connector.ts b/x-pack/plugins/inference/scripts/util/select_connector.ts new file mode 100644 index 0000000000000..b5dc8ae2d4549 --- /dev/null +++ b/x-pack/plugins/inference/scripts/util/select_connector.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import inquirer from 'inquirer'; +import { ToolingLog } from '@kbn/tooling-log'; +import { KibanaClient } from './kibana_client'; + +export async function selectConnector({ + connectors, + preferredId, + log, + message = 'Select a connector', +}: { + connectors: Awaited>; + preferredId?: string; + log: ToolingLog; + message?: string; +}) { + let connector = connectors.find((item) => item.connectorId === preferredId); + + if (!connector && preferredId) { + log.warning(`Could not find connector ${preferredId}`); + } + + if (!connector && connectors.length === 1) { + connector = connectors[0]; + log.debug('Using the only connector found'); + } else if (!connector) { + const connectorChoice = await inquirer.prompt({ + type: 'list', + name: 'connector', + message, + choices: connectors.map((item) => ({ + name: `${item.name} (${item.connectorId})`, + value: item.connectorId, + })), + }); + + connector = connectors.find((item) => item.connectorId === connectorChoice.connector)!; + } + + return connector; +} diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.test.ts b/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.test.ts index 1d25f09dce3bc..d34b8693cb85f 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.test.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.test.ts @@ -6,6 +6,7 @@ */ import { PassThrough } from 'stream'; +import { loggerMock } from '@kbn/logging-mocks'; import type { InferenceExecutor } from '../../utils/inference_executor'; import { MessageRole } from '../../../../common/chat_complete'; import { ToolChoiceType } from '../../../../common/chat_complete/tools'; @@ -13,6 +14,7 @@ import { bedrockClaudeAdapter } from './bedrock_claude_adapter'; import { addNoToolUsageDirective } from './prompts'; describe('bedrockClaudeAdapter', () => { + const logger = loggerMock.create(); const executorMock = { invoke: jest.fn(), } as InferenceExecutor & { invoke: jest.MockedFn }; @@ -41,6 +43,7 @@ describe('bedrockClaudeAdapter', () => { describe('#chatComplete()', () => { it('calls `executor.invoke` with the right fixed parameters', () => { bedrockClaudeAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -62,6 +65,16 @@ describe('bedrockClaudeAdapter', () => { ], temperature: 0, stopSequences: ['\n\nHuman:'], + tools: [ + { + description: 'Do not call this tool, it is strictly forbidden', + input_schema: { + properties: {}, + type: 'object', + }, + name: 'do_not_call_this_tool', + }, + ], }, }); }); @@ -69,6 +82,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly format tools', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, messages: [ { role: MessageRole.User, @@ -127,6 +141,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly format messages', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, messages: [ { role: MessageRole.User, @@ -225,6 +240,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly format system message', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, system: 'Some system message', messages: [ { @@ -243,6 +259,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly format tool choice', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, messages: [ { role: MessageRole.User, @@ -263,6 +280,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly format tool choice for named function', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, messages: [ { role: MessageRole.User, @@ -284,6 +302,7 @@ describe('bedrockClaudeAdapter', () => { it('correctly adapt the request for ToolChoiceType.None', () => { bedrockClaudeAdapter.chatComplete({ executor: executorMock, + logger, system: 'some system instruction', messages: [ { diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.ts b/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.ts index 5a03dc04347b1..a0b48e6fc8631 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/bedrock/bedrock_claude_adapter.ts @@ -7,7 +7,6 @@ import { filter, from, map, switchMap, tap } from 'rxjs'; import { Readable } from 'stream'; -import type { InvokeAIActionParams } from '@kbn/stack-connectors-plugin/common/bedrock/types'; import { parseSerdeChunkMessage } from './serde_utils'; import { Message, MessageRole } from '../../../../common/chat_complete'; import { createInferenceInternalError } from '../../../../common/errors'; @@ -20,15 +19,16 @@ import { } from './serde_eventstream_into_observable'; import { processCompletionChunks } from './process_completion_chunks'; import { addNoToolUsageDirective } from './prompts'; +import { ToolSchemaType } from '../../../../common/chat_complete/tool_schema'; export const bedrockClaudeAdapter: InferenceConnectorAdapter = { chatComplete: ({ executor, system, messages, toolChoice, tools }) => { const noToolUsage = toolChoice === ToolChoiceType.none; - const connectorInvokeRequest: InvokeAIActionParams = { + const subActionParams = { system: noToolUsage ? addNoToolUsageDirective(system) : system, messages: messagesToBedrock(messages), - tools: noToolUsage ? [] : toolsToBedrock(tools), + tools: noToolUsage ? [] : toolsToBedrock(tools, messages), toolChoice: toolChoiceToBedrock(toolChoice), temperature: 0, stopSequences: ['\n\nHuman:'], @@ -37,7 +37,7 @@ export const bedrockClaudeAdapter: InferenceConnectorAdapter = { return from( executor.invoke({ subAction: 'invokeStream', - subActionParams: connectorInvokeRequest, + subActionParams, }) ).pipe( switchMap((response) => { @@ -82,19 +82,64 @@ const toolChoiceToBedrock = ( return undefined; }; -const toolsToBedrock = (tools: ToolOptions['tools']) => { - return tools - ? Object.entries(tools).map(([toolName, toolDef]) => { - return { - name: toolName, - description: toolDef.description, - input_schema: toolDef.schema ?? { +const toolsToBedrock = (tools: ToolOptions['tools'], messages: Message[]) => { + function walkSchema(schemaPart: T): T { + if (schemaPart.type === 'object' && schemaPart.properties) { + return { + ...schemaPart, + properties: Object.fromEntries( + Object.entries(schemaPart.properties).map(([key, childSchemaPart]) => { + return [key, walkSchema(childSchemaPart)]; + }) + ), + }; + } + + if (schemaPart.type === 'array') { + return { + ...schemaPart, + // Claude is prone to ignoring the "array" part of an array type + description: schemaPart.description + '. Must be provided as a JSON array', + items: walkSchema(schemaPart.items), + }; + } + + return schemaPart; + } + + if (tools) { + return Object.entries(tools).map(([toolName, toolDef]) => { + return { + name: toolName, + description: toolDef.description, + input_schema: walkSchema( + toolDef.schema ?? { type: 'object' as const, properties: {}, - }, - }; - }) - : undefined; + } + ), + }; + }); + } + + const hasToolUse = messages.filter( + (message) => + message.role === MessageRole.Tool || + (message.role === MessageRole.Assistant && message.toolCalls?.length) + ); + + if (hasToolUse) { + return [ + { + name: 'do_not_call_this_tool', + description: 'Do not call this tool, it is strictly forbidden', + input_schema: { + type: 'object', + properties: {}, + }, + }, + ]; + } }; const messagesToBedrock = (messages: Message[]): BedRockMessage[] => { diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.test.ts b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.test.ts index 3fe8c917c0015..a9f4305a3c532 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.test.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.test.ts @@ -8,6 +8,7 @@ import { processVertexStreamMock } from './gemini_adapter.test.mocks'; import { PassThrough } from 'stream'; import { noop, tap, lastValueFrom, toArray, Subject } from 'rxjs'; +import { loggerMock } from '@kbn/logging-mocks'; import type { InferenceExecutor } from '../../utils/inference_executor'; import { observableIntoEventSourceStream } from '../../../util/observable_into_event_source_stream'; import { MessageRole } from '../../../../common/chat_complete'; @@ -15,6 +16,7 @@ import { ToolChoiceType } from '../../../../common/chat_complete/tools'; import { geminiAdapter } from './gemini_adapter'; describe('geminiAdapter', () => { + const logger = loggerMock.create(); const executorMock = { invoke: jest.fn(), } as InferenceExecutor & { invoke: jest.MockedFn }; @@ -47,6 +49,7 @@ describe('geminiAdapter', () => { it('calls `executor.invoke` with the right fixed parameters', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -75,6 +78,7 @@ describe('geminiAdapter', () => { it('correctly format tools', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -138,6 +142,7 @@ describe('geminiAdapter', () => { it('correctly format messages', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -236,6 +241,7 @@ describe('geminiAdapter', () => { it('groups messages from the same user', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -304,6 +310,7 @@ describe('geminiAdapter', () => { it('correctly format system message', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, system: 'Some system message', messages: [ @@ -322,6 +329,7 @@ describe('geminiAdapter', () => { it('correctly format tool choice', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -340,6 +348,7 @@ describe('geminiAdapter', () => { it('correctly format tool choice for named function', () => { geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { @@ -366,11 +375,12 @@ describe('geminiAdapter', () => { return { actionId: '', status: 'ok', - data: observableIntoEventSourceStream(source$), + data: observableIntoEventSourceStream(source$, logger), }; }); const response$ = geminiAdapter.chatComplete({ + logger, executor: executorMock, messages: [ { diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.ts b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.ts index 8f6d02da0e3f8..2e86adcc82a85 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/gemini_adapter.ts @@ -106,12 +106,16 @@ function toolSchemaToGemini({ schema }: { schema: ToolSchema }): Gemini.Function type: Gemini.FunctionDeclarationSchemaType.OBJECT, description: def.description, required: def.required as string[], - properties: Object.entries(def.properties).reduce< - Record - >((properties, [key, prop]) => { - properties[key] = convertSchemaType({ def: prop }) as Gemini.FunctionDeclarationSchema; - return properties; - }, {}), + properties: def.properties + ? Object.entries(def.properties).reduce< + Record + >((properties, [key, prop]) => { + properties[key] = convertSchemaType({ + def: prop, + }) as Gemini.FunctionDeclarationSchema; + return properties; + }, {}) + : undefined, }; case 'string': return { @@ -137,7 +141,7 @@ function toolSchemaToGemini({ schema }: { schema: ToolSchema }): Gemini.Function return { type: Gemini.FunctionDeclarationSchemaType.OBJECT, required: schema.required as string[], - properties: Object.entries(schema.properties).reduce< + properties: Object.entries(schema.properties ?? {}).reduce< Record >((properties, [key, def]) => { properties[key] = convertSchemaType({ def }); diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/process_vertex_stream.ts b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/process_vertex_stream.ts index ec3fa8e82eed6..e2a6c74a0447f 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/gemini/process_vertex_stream.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/gemini/process_vertex_stream.ts @@ -11,7 +11,7 @@ import { ChatCompletionTokenCountEvent, ChatCompletionEventType, } from '../../../../common/chat_complete'; -import { generateFakeToolCallId } from '../../utils'; +import { generateFakeToolCallId } from '../../../../common'; import type { GenerateContentResponseChunk } from './types'; export function processVertexStream() { diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.ts b/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.ts index d72ceb2020e8a..9aa1d94e01a52 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.ts @@ -5,181 +5,4 @@ * 2.0. */ -import OpenAI from 'openai'; -import type { - ChatCompletionAssistantMessageParam, - ChatCompletionMessageParam, - ChatCompletionSystemMessageParam, - ChatCompletionToolMessageParam, - ChatCompletionUserMessageParam, -} from 'openai/resources'; -import { filter, from, map, switchMap, tap } from 'rxjs'; -import { Readable } from 'stream'; -import { - ChatCompletionChunkEvent, - ChatCompletionEventType, - Message, - MessageRole, -} from '../../../../common/chat_complete'; -import type { ToolOptions } from '../../../../common/chat_complete/tools'; -import { createTokenLimitReachedError } from '../../../../common/chat_complete/errors'; -import { createInferenceInternalError } from '../../../../common/errors'; -import { eventSourceStreamIntoObservable } from '../../../util/event_source_stream_into_observable'; -import type { InferenceConnectorAdapter } from '../../types'; - -export const openAIAdapter: InferenceConnectorAdapter = { - chatComplete: ({ executor, system, messages, toolChoice, tools }) => { - const stream = true; - - const request: Omit & { model?: string } = { - stream, - messages: messagesToOpenAI({ system, messages }), - tool_choice: toolChoiceToOpenAI(toolChoice), - tools: toolsToOpenAI(tools), - temperature: 0, - }; - - return from( - executor.invoke({ - subAction: 'stream', - subActionParams: { - body: JSON.stringify(request), - stream, - }, - }) - ).pipe( - switchMap((response) => { - const readable = response.data as Readable; - return eventSourceStreamIntoObservable(readable); - }), - filter((line) => !!line && line !== '[DONE]'), - map( - (line) => JSON.parse(line) as OpenAI.ChatCompletionChunk | { error: { message: string } } - ), - tap((line) => { - if ('error' in line) { - throw createInferenceInternalError(line.error.message); - } - if ( - 'choices' in line && - line.choices.length && - line.choices[0].finish_reason === 'length' - ) { - throw createTokenLimitReachedError(); - } - }), - filter( - (line): line is OpenAI.ChatCompletionChunk => - 'object' in line && line.object === 'chat.completion.chunk' - ), - map((chunk): ChatCompletionChunkEvent => { - const delta = chunk.choices[0].delta; - - return { - type: ChatCompletionEventType.ChatCompletionChunk, - content: delta.content ?? '', - tool_calls: - delta.tool_calls?.map((toolCall) => { - return { - function: { - name: toolCall.function?.name ?? '', - arguments: toolCall.function?.arguments ?? '', - }, - toolCallId: toolCall.id ?? '', - index: toolCall.index, - }; - }) ?? [], - }; - }) - ); - }, -}; - -function toolsToOpenAI(tools: ToolOptions['tools']): OpenAI.ChatCompletionCreateParams['tools'] { - return tools - ? Object.entries(tools).map(([toolName, { description, schema }]) => { - return { - type: 'function', - function: { - name: toolName, - description, - parameters: (schema ?? { - type: 'object' as const, - properties: {}, - }) as unknown as Record, - }, - }; - }) - : undefined; -} - -function toolChoiceToOpenAI( - toolChoice: ToolOptions['toolChoice'] -): OpenAI.ChatCompletionCreateParams['tool_choice'] { - return typeof toolChoice === 'string' - ? toolChoice - : toolChoice - ? { - function: { - name: toolChoice.function, - }, - type: 'function' as const, - } - : undefined; -} - -function messagesToOpenAI({ - system, - messages, -}: { - system?: string; - messages: Message[]; -}): OpenAI.ChatCompletionMessageParam[] { - const systemMessage: ChatCompletionSystemMessageParam | undefined = system - ? { role: 'system', content: system } - : undefined; - - return [ - ...(systemMessage ? [systemMessage] : []), - ...messages.map((message): ChatCompletionMessageParam => { - const role = message.role; - - switch (role) { - case MessageRole.Assistant: - const assistantMessage: ChatCompletionAssistantMessageParam = { - role: 'assistant', - content: message.content, - tool_calls: message.toolCalls?.map((toolCall) => { - return { - function: { - name: toolCall.function.name, - arguments: - 'arguments' in toolCall.function - ? JSON.stringify(toolCall.function.arguments) - : '{}', - }, - id: toolCall.toolCallId, - type: 'function', - }; - }), - }; - return assistantMessage; - - case MessageRole.User: - const userMessage: ChatCompletionUserMessageParam = { - role: 'user', - content: message.content, - }; - return userMessage; - - case MessageRole.Tool: - const toolMessage: ChatCompletionToolMessageParam = { - role: 'tool', - content: JSON.stringify(message.response), - tool_call_id: message.toolCallId, - }; - return toolMessage; - } - }), - ]; -} +export { openAIAdapter } from './openai_adapter'; diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.test.ts b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.test.ts similarity index 96% rename from x-pack/plugins/inference/server/chat_complete/adapters/openai/index.test.ts rename to x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.test.ts index f3b7c423ea42f..813e88760de8c 100644 --- a/x-pack/plugins/inference/server/chat_complete/adapters/openai/index.test.ts +++ b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.test.ts @@ -10,6 +10,8 @@ import { v4 } from 'uuid'; import { PassThrough } from 'stream'; import { pick } from 'lodash'; import { lastValueFrom, Subject, toArray } from 'rxjs'; +import type { Logger } from '@kbn/logging'; +import { loggerMock } from '@kbn/logging-mocks'; import { ChatCompletionEventType, MessageRole } from '../../../../common/chat_complete'; import { observableIntoEventSourceStream } from '../../../util/observable_into_event_source_stream'; import { InferenceExecutor } from '../../utils/inference_executor'; @@ -43,12 +45,18 @@ describe('openAIAdapter', () => { invoke: jest.fn(), } as InferenceExecutor & { invoke: jest.MockedFn }; + const logger = { + debug: jest.fn(), + error: jest.fn(), + } as unknown as Logger; + beforeEach(() => { executorMock.invoke.mockReset(); }); const defaultArgs = { executor: executorMock, + logger: loggerMock.create(), }; describe('when creating the request', () => { @@ -255,7 +263,7 @@ describe('openAIAdapter', () => { return { actionId: '', status: 'ok', - data: observableIntoEventSourceStream(source$), + data: observableIntoEventSourceStream(source$, logger), }; }); }); diff --git a/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts new file mode 100644 index 0000000000000..3a89f100f2879 --- /dev/null +++ b/x-pack/plugins/inference/server/chat_complete/adapters/openai/openai_adapter.ts @@ -0,0 +1,189 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import OpenAI from 'openai'; +import type { + ChatCompletionAssistantMessageParam, + ChatCompletionMessageParam, + ChatCompletionSystemMessageParam, + ChatCompletionToolMessageParam, + ChatCompletionUserMessageParam, +} from 'openai/resources'; +import { filter, from, map, switchMap, tap, throwError } from 'rxjs'; +import { Readable, isReadable } from 'stream'; +import { + ChatCompletionChunkEvent, + ChatCompletionEventType, + Message, + MessageRole, +} from '../../../../common/chat_complete'; +import type { ToolOptions } from '../../../../common/chat_complete/tools'; +import { createTokenLimitReachedError } from '../../../../common/chat_complete/errors'; +import { createInferenceInternalError } from '../../../../common/errors'; +import { eventSourceStreamIntoObservable } from '../../../util/event_source_stream_into_observable'; +import type { InferenceConnectorAdapter } from '../../types'; + +export const openAIAdapter: InferenceConnectorAdapter = { + chatComplete: ({ executor, system, messages, toolChoice, tools }) => { + const stream = true; + + const request: Omit & { model?: string } = { + stream, + messages: messagesToOpenAI({ system, messages }), + tool_choice: toolChoiceToOpenAI(toolChoice), + tools: toolsToOpenAI(tools), + temperature: 0, + }; + + return from( + executor.invoke({ + subAction: 'stream', + subActionParams: { + body: JSON.stringify(request), + stream, + }, + }) + ).pipe( + switchMap((response) => { + if (isReadable(response.data as any)) { + return eventSourceStreamIntoObservable(response.data as Readable); + } + return throwError(() => + createInferenceInternalError('Unexpected error', response.data as Record) + ); + }), + filter((line) => !!line && line !== '[DONE]'), + map( + (line) => JSON.parse(line) as OpenAI.ChatCompletionChunk | { error: { message: string } } + ), + tap((line) => { + if ('error' in line) { + throw createInferenceInternalError(line.error.message); + } + if ( + 'choices' in line && + line.choices.length && + line.choices[0].finish_reason === 'length' + ) { + throw createTokenLimitReachedError(); + } + }), + filter( + (line): line is OpenAI.ChatCompletionChunk => + 'object' in line && line.object === 'chat.completion.chunk' + ), + map((chunk): ChatCompletionChunkEvent => { + const delta = chunk.choices[0].delta; + + return { + type: ChatCompletionEventType.ChatCompletionChunk, + content: delta.content ?? '', + tool_calls: + delta.tool_calls?.map((toolCall) => { + return { + function: { + name: toolCall.function?.name ?? '', + arguments: toolCall.function?.arguments ?? '', + }, + toolCallId: toolCall.id ?? '', + index: toolCall.index, + }; + }) ?? [], + }; + }) + ); + }, +}; + +function toolsToOpenAI(tools: ToolOptions['tools']): OpenAI.ChatCompletionCreateParams['tools'] { + return tools + ? Object.entries(tools).map(([toolName, { description, schema }]) => { + return { + type: 'function', + function: { + name: toolName, + description, + parameters: (schema ?? { + type: 'object' as const, + properties: {}, + }) as unknown as Record, + }, + }; + }) + : undefined; +} + +function toolChoiceToOpenAI( + toolChoice: ToolOptions['toolChoice'] +): OpenAI.ChatCompletionCreateParams['tool_choice'] { + return typeof toolChoice === 'string' + ? toolChoice + : toolChoice + ? { + function: { + name: toolChoice.function, + }, + type: 'function' as const, + } + : undefined; +} + +function messagesToOpenAI({ + system, + messages, +}: { + system?: string; + messages: Message[]; +}): OpenAI.ChatCompletionMessageParam[] { + const systemMessage: ChatCompletionSystemMessageParam | undefined = system + ? { role: 'system', content: system } + : undefined; + + return [ + ...(systemMessage ? [systemMessage] : []), + ...messages.map((message): ChatCompletionMessageParam => { + const role = message.role; + + switch (role) { + case MessageRole.Assistant: + const assistantMessage: ChatCompletionAssistantMessageParam = { + role: 'assistant', + content: message.content, + tool_calls: message.toolCalls?.map((toolCall) => { + return { + function: { + name: toolCall.function.name, + arguments: + 'arguments' in toolCall.function + ? JSON.stringify(toolCall.function.arguments) + : '{}', + }, + id: toolCall.toolCallId, + type: 'function', + }; + }), + }; + return assistantMessage; + + case MessageRole.User: + const userMessage: ChatCompletionUserMessageParam = { + role: 'user', + content: message.content, + }; + return userMessage; + + case MessageRole.Tool: + const toolMessage: ChatCompletionToolMessageParam = { + role: 'tool', + content: JSON.stringify(message.response), + tool_call_id: message.toolCallId, + }; + return toolMessage; + } + }), + ]; +} diff --git a/x-pack/plugins/inference/server/chat_complete/api.ts b/x-pack/plugins/inference/server/chat_complete/api.ts index 17bf0e5214300..fe879392cd4de 100644 --- a/x-pack/plugins/inference/server/chat_complete/api.ts +++ b/x-pack/plugins/inference/server/chat_complete/api.ts @@ -5,8 +5,10 @@ * 2.0. */ -import type { KibanaRequest } from '@kbn/core-http-server'; +import { last } from 'lodash'; import { defer, switchMap, throwError } from 'rxjs'; +import type { Logger } from '@kbn/logging'; +import type { KibanaRequest } from '@kbn/core-http-server'; import type { ChatCompleteAPI, ChatCompletionResponse } from '../../common/chat_complete'; import { createInferenceRequestError } from '../../common/errors'; import type { InferenceStartDependencies } from '../types'; @@ -17,9 +19,11 @@ import { createInferenceExecutor, chunksIntoMessage } from './utils'; export function createChatCompleteApi({ request, actions, + logger, }: { request: KibanaRequest; actions: InferenceStartDependencies['actions']; + logger: Logger; }) { const chatCompleteAPI: ChatCompleteAPI = ({ connectorId, @@ -44,17 +48,24 @@ export function createChatCompleteApi({ ); } + logger.debug(() => `Sending request: ${JSON.stringify(last(messages))}`); + logger.trace(() => JSON.stringify({ messages, toolChoice, tools, system })); + return inferenceAdapter.chatComplete({ system, executor, messages, toolChoice, tools, + logger, }); }), chunksIntoMessage({ - toolChoice, - tools, + toolOptions: { + toolChoice, + tools, + }, + logger, }) ); }; diff --git a/x-pack/plugins/inference/server/chat_complete/types.ts b/x-pack/plugins/inference/server/chat_complete/types.ts index fff902f7e885e..5ef28fdbdc808 100644 --- a/x-pack/plugins/inference/server/chat_complete/types.ts +++ b/x-pack/plugins/inference/server/chat_complete/types.ts @@ -6,6 +6,7 @@ */ import type { Observable } from 'rxjs'; +import type { Logger } from '@kbn/logging'; import type { ChatCompletionChunkEvent, ChatCompletionTokenCountEvent, @@ -26,6 +27,7 @@ export interface InferenceConnectorAdapter { messages: Message[]; system?: string; executor: InferenceExecutor; + logger: Logger; } & ToolOptions ) => Observable; } diff --git a/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.test.ts b/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.test.ts index a3fdcd33bee94..0c5552a0113b8 100644 --- a/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.test.ts +++ b/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.test.ts @@ -12,15 +12,21 @@ import { } from '../../../common/chat_complete'; import { ToolChoiceType } from '../../../common/chat_complete/tools'; import { chunksIntoMessage } from './chunks_into_message'; +import type { Logger } from '@kbn/logging'; describe('chunksIntoMessage', () => { function fromEvents(...events: Array) { return of(...events); } + const logger = { + debug: jest.fn(), + error: jest.fn(), + } as unknown as Logger; + it('concatenates content chunks into a single message', async () => { const message = await lastValueFrom( - chunksIntoMessage({})( + chunksIntoMessage({ logger, toolOptions: {} })( fromEvents( { content: 'Hey', @@ -51,21 +57,24 @@ describe('chunksIntoMessage', () => { it('parses tool calls', async () => { const message = await lastValueFrom( chunksIntoMessage({ - toolChoice: ToolChoiceType.auto, - tools: { - myFunction: { - description: 'myFunction', - schema: { - type: 'object', - properties: { - foo: { - type: 'string', - const: 'bar', + toolOptions: { + toolChoice: ToolChoiceType.auto, + tools: { + myFunction: { + description: 'myFunction', + schema: { + type: 'object', + properties: { + foo: { + type: 'string', + const: 'bar', + }, }, }, }, }, }, + logger, })( fromEvents( { @@ -135,21 +144,24 @@ describe('chunksIntoMessage', () => { async function getMessage() { return await lastValueFrom( chunksIntoMessage({ - toolChoice: ToolChoiceType.auto, - tools: { - myFunction: { - description: 'myFunction', - schema: { - type: 'object', - properties: { - foo: { - type: 'string', - const: 'bar', + toolOptions: { + toolChoice: ToolChoiceType.auto, + tools: { + myFunction: { + description: 'myFunction', + schema: { + type: 'object', + properties: { + foo: { + type: 'string', + const: 'bar', + }, }, }, }, }, }, + logger, })( fromEvents({ content: '', @@ -177,20 +189,23 @@ describe('chunksIntoMessage', () => { it('concatenates multiple tool calls into a single message', async () => { const message = await lastValueFrom( chunksIntoMessage({ - toolChoice: ToolChoiceType.auto, - tools: { - myFunction: { - description: 'myFunction', - schema: { - type: 'object', - properties: { - foo: { - type: 'string', + toolOptions: { + toolChoice: ToolChoiceType.auto, + tools: { + myFunction: { + description: 'myFunction', + schema: { + type: 'object', + properties: { + foo: { + type: 'string', + }, }, }, }, }, }, + logger, })( fromEvents( { diff --git a/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.ts b/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.ts index 786a4c4ff7fb3..902289182a37a 100644 --- a/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.ts +++ b/x-pack/plugins/inference/server/chat_complete/utils/chunks_into_message.ts @@ -6,6 +6,7 @@ */ import { last, map, merge, OperatorFunction, scan, share } from 'rxjs'; +import type { Logger } from '@kbn/logging'; import type { UnvalidatedToolCall, ToolOptions } from '../../../common/chat_complete/tools'; import { ChatCompletionChunkEvent, @@ -16,9 +17,13 @@ import { import { withoutTokenCountEvents } from '../../../common/chat_complete/without_token_count_events'; import { validateToolCalls } from '../../util/validate_tool_calls'; -export function chunksIntoMessage( - toolOptions: TToolOptions -): OperatorFunction< +export function chunksIntoMessage({ + logger, + toolOptions, +}: { + toolOptions: TToolOptions; + logger: Pick; +}): OperatorFunction< ChatCompletionChunkEvent | ChatCompletionTokenCountEvent, | ChatCompletionChunkEvent | ChatCompletionTokenCountEvent @@ -63,6 +68,8 @@ export function chunksIntoMessage( ), last(), map((concatenatedChunk): ChatCompletionMessageEvent => { + logger.debug(() => `Received completed message: ${JSON.stringify(concatenatedChunk)}`); + const validatedToolCalls = validateToolCalls({ ...toolOptions, toolCalls: concatenatedChunk.tool_calls, diff --git a/x-pack/plugins/inference/server/chat_complete/utils/index.ts b/x-pack/plugins/inference/server/chat_complete/utils/index.ts index d9344164eff46..dea2ac65f4755 100644 --- a/x-pack/plugins/inference/server/chat_complete/utils/index.ts +++ b/x-pack/plugins/inference/server/chat_complete/utils/index.ts @@ -12,4 +12,3 @@ export { type InferenceExecutor, } from './inference_executor'; export { chunksIntoMessage } from './chunks_into_message'; -export { generateFakeToolCallId } from './generate_fake_tool_call_id'; diff --git a/x-pack/plugins/inference/server/index.ts b/x-pack/plugins/inference/server/index.ts index 721aa05d06023..e45ae303d2833 100644 --- a/x-pack/plugins/inference/server/index.ts +++ b/x-pack/plugins/inference/server/index.ts @@ -18,6 +18,8 @@ export { withoutTokenCountEvents } from '../common/chat_complete/without_token_c export { withoutChunkEvents } from '../common/chat_complete/without_chunk_events'; export { withoutOutputUpdateEvents } from '../common/output/without_output_update_events'; +export { naturalLanguageToEsql } from './tasks/nl_to_esql'; + export type { InferenceServerSetup, InferenceServerStart }; export const plugin: PluginInitializer< diff --git a/x-pack/plugins/inference/server/inference_client/index.ts b/x-pack/plugins/inference/server/inference_client/index.ts index d9d52a8e41ec1..25208bebc54bb 100644 --- a/x-pack/plugins/inference/server/inference_client/index.ts +++ b/x-pack/plugins/inference/server/inference_client/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { Logger } from '@kbn/logging'; import type { KibanaRequest } from '@kbn/core-http-server'; import type { InferenceClient, InferenceStartDependencies } from '../types'; import { createChatCompleteApi } from '../chat_complete'; @@ -14,8 +15,12 @@ import { getConnectorById } from '../util/get_connector_by_id'; export function createInferenceClient({ request, actions, -}: { request: KibanaRequest } & Pick): InferenceClient { - const chatComplete = createChatCompleteApi({ request, actions }); + logger, +}: { request: KibanaRequest; logger: Logger } & Pick< + InferenceStartDependencies, + 'actions' +>): InferenceClient { + const chatComplete = createChatCompleteApi({ request, actions, logger }); return { chatComplete, output: createOutputApi(chatComplete), diff --git a/x-pack/plugins/inference/server/plugin.ts b/x-pack/plugins/inference/server/plugin.ts index 1b17eb4a66d35..2b1a7be0a165c 100644 --- a/x-pack/plugins/inference/server/plugin.ts +++ b/x-pack/plugins/inference/server/plugin.ts @@ -26,7 +26,7 @@ export class InferencePlugin InferenceStartDependencies > { - logger: Logger; + private logger: Logger; constructor(context: PluginInitializerContext) { this.logger = context.logger.get(); @@ -40,6 +40,7 @@ export class InferencePlugin registerRoutes({ router, coreSetup, + logger: this.logger, }); return {}; @@ -48,7 +49,11 @@ export class InferencePlugin start(core: CoreStart, pluginsStart: InferenceStartDependencies): InferenceServerStart { return { getClient: ({ request }) => { - return createInferenceClient({ request, actions: pluginsStart.actions }); + return createInferenceClient({ + request, + actions: pluginsStart.actions, + logger: this.logger.get('client'), + }); }, }; } diff --git a/x-pack/plugins/inference/server/routes/chat_complete.ts b/x-pack/plugins/inference/server/routes/chat_complete.ts index bfa95fdbb9213..5a9c0aae50958 100644 --- a/x-pack/plugins/inference/server/routes/chat_complete.ts +++ b/x-pack/plugins/inference/server/routes/chat_complete.ts @@ -6,7 +6,7 @@ */ import { schema, Type } from '@kbn/config-schema'; -import type { CoreSetup, IRouter, RequestHandlerContext } from '@kbn/core/server'; +import type { CoreSetup, IRouter, Logger, RequestHandlerContext } from '@kbn/core/server'; import { MessageRole } from '../../common/chat_complete'; import type { ChatCompleteRequestBody } from '../../common/chat_complete/request'; import { ToolCall, ToolChoiceType } from '../../common/chat_complete/tools'; @@ -76,9 +76,11 @@ const chatCompleteBodySchema: Type = schema.object({ export function registerChatCompleteRoute({ coreSetup, router, + logger, }: { coreSetup: CoreSetup; router: IRouter; + logger: Logger; }) { router.post( { @@ -92,7 +94,7 @@ export function registerChatCompleteRoute({ .getStartServices() .then(([coreStart, pluginsStart]) => pluginsStart.actions); - const client = createInferenceClient({ request, actions }); + const client = createInferenceClient({ request, actions, logger }); const { connectorId, messages, system, toolChoice, tools } = request.body; @@ -105,7 +107,7 @@ export function registerChatCompleteRoute({ }); return response.ok({ - body: observableIntoEventSourceStream(chatCompleteResponse), + body: observableIntoEventSourceStream(chatCompleteResponse, logger), }); } ); diff --git a/x-pack/plugins/inference/server/routes/index.ts b/x-pack/plugins/inference/server/routes/index.ts index 0f6891ace1223..8191f358250c1 100644 --- a/x-pack/plugins/inference/server/routes/index.ts +++ b/x-pack/plugins/inference/server/routes/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +import type { Logger } from '@kbn/logging'; import type { CoreSetup, IRouter } from '@kbn/core/server'; import type { InferenceServerStart, InferenceStartDependencies } from '../types'; import { registerChatCompleteRoute } from './chat_complete'; @@ -12,11 +13,13 @@ import { registerConnectorsRoute } from './connectors'; export const registerRoutes = ({ router, + logger, coreSetup, }: { router: IRouter; + logger: Logger; coreSetup: CoreSetup; }) => { - registerChatCompleteRoute({ router, coreSetup }); + registerChatCompleteRoute({ router, coreSetup, logger: logger.get('chatComplete') }); registerConnectorsRoute({ router, coreSetup }); }; diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-abs.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-abs.txt new file mode 100644 index 0000000000000..6a970dc5700fe --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-abs.txt @@ -0,0 +1,16 @@ +## ABS + +The `ABS` function returns the absolute value of a numeric expression. If the input is null, the function returns null. + +### Examples + +```esql +ROW number = -1.0 +| EVAL abs_number = ABS(number) +``` + +```esql +FROM employees +| KEEP first_name, last_name, height +| EVAL abs_height = ABS(0.0 - height) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-acos.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-acos.txt new file mode 100644 index 0000000000000..3460483c15870 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-acos.txt @@ -0,0 +1,15 @@ +## ACOS + +The `ACOS` function returns the arccosine of a number as an angle, expressed in radians. The input number must be between -1 and 1. If the input is null, the function returns null. + +### Examples + +```esql +ROW a = .9 +| EVAL acos = ACOS(a) +``` + +```esql +ROW b = -0.5 +| EVAL acos_b = ACOS(b) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-asin.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-asin.txt new file mode 100644 index 0000000000000..ad4fb8fe8d310 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-asin.txt @@ -0,0 +1,15 @@ +## ASIN + +The `ASIN` function returns the arcsine of the input numeric expression as an angle, expressed in radians. + +### Examples + +```esql +ROW a = .9 +| EVAL asin = ASIN(a) +``` + +```esql +ROW a = -.5 +| EVAL asin = ASIN(a) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan.txt new file mode 100644 index 0000000000000..fbeee5e84f2f3 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan.txt @@ -0,0 +1,15 @@ +## ATAN + +The `ATAN` function returns the arctangent of the input numeric expression as an angle, expressed in radians. + +### Examples + +```esql +ROW a=12.9 +| EVAL atan = ATAN(a) +``` + +```esql +ROW x=5.0, y=3.0 +| EVAL atan_yx = ATAN(y / x) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan2.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan2.txt new file mode 100644 index 0000000000000..f4da581885ef7 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-atan2.txt @@ -0,0 +1,15 @@ +## ATAN2 + +The `ATAN2` function calculates the angle between the positive x-axis and the ray from the origin to the point (x, y) in the Cartesian plane, expressed in radians. + +### Examples + +```esql +ROW y=12.9, x=.6 +| EVAL atan2 = ATAN2(y, x) +``` + +```esql +ROW y=5.0, x=3.0 +| EVAL atan2 = ATAN2(y, x) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-avg.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-avg.txt new file mode 100644 index 0000000000000..943a12c4aaa90 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-avg.txt @@ -0,0 +1,15 @@ +## AVG + +The `AVG` function calculates the average of a numeric field. + +### Examples + +```esql +FROM employees +| STATS AVG(height) +``` + +```esql +FROM employees +| STATS avg_salary_change = ROUND(AVG(MV_AVG(salary_change)), 10) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-bucket.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-bucket.txt new file mode 100644 index 0000000000000..945a4328d7728 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-bucket.txt @@ -0,0 +1,66 @@ +## BUCKET + +The `BUCKET` function creates groups of values—buckets—out of a datetime or numeric input. The size of the buckets can either be provided directly or chosen based on a recommended count and values range. + +### Examples + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS hire_date = MV_SORT(VALUES(hire_date)) BY month = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z") +| SORT hire_date +``` + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS hires_per_month = COUNT(*) BY month = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z") +| SORT month +``` + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS hires_per_week = COUNT(*) BY week = BUCKET(hire_date, 100, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z") +| SORT week +``` + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS hires_per_week = COUNT(*) BY week = BUCKET(hire_date, 1 week) +| SORT week +``` + +```esql +FROM employees +| STATS COUNT(*) BY bs = BUCKET(salary, 20, 25324, 74999) +| SORT bs +``` + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS c = COUNT(1) BY b = BUCKET(salary, 5000.) +| SORT b +``` + +```esql +FROM sample_data +| WHERE @timestamp >= NOW() - 1 day and @timestamp < NOW() +| STATS COUNT(*) BY bucket = BUCKET(@timestamp, 25, NOW() - 1 day, NOW()) +``` + +```esql +FROM employees +| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" +| STATS AVG(salary) BY bucket = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z") +| SORT bucket +``` + +```esql +FROM employees +| STATS s1 = BUCKET(salary / 1000 + 999, 50.) + 2 BY b1 = BUCKET(salary / 100 + 99, 50.), b2 = BUCKET(salary / 1000 + 999, 50.) +| SORT b1, b2 +| KEEP b1, s1, b2 +``` diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-case.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-case.txt new file mode 100644 index 0000000000000..4c9cc07e669db --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-case.txt @@ -0,0 +1,37 @@ +## CASE + +The `CASE` function accepts pairs of conditions and values. The function returns the value that belongs to the first condition that evaluates to true. If the number of arguments is odd, the last argument is the default value which is returned when no condition matches. If the number of arguments is even, and no condition matches, the function returns null. + +### Examples + +Determine whether employees are monolingual, bilingual, or polyglot: + +```esql +FROM employees +| EVAL type = CASE( + languages <= 1, "monolingual", + languages <= 2, "bilingual", + "polyglot") +| KEEP emp_no, languages, type +``` + +Calculate the total connection success rate based on log messages: + +```esql +FROM sample_data +| EVAL successful = CASE( + STARTS_WITH(message, "Connected to"), 1, + message == "Connection error", 0 + ) +| STATS success_rate = AVG(successful) +``` + +Calculate an hourly error rate as a percentage of the total number of log messages: + +```esql +FROM sample_data +| EVAL error = CASE(message LIKE "*error*", 1, 0) +| EVAL hour = DATE_TRUNC(1 hour, @timestamp) +| STATS error_rate = AVG(error) BY hour +| SORT hour +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cbrt.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cbrt.txt new file mode 100644 index 0000000000000..44ecddefc290d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cbrt.txt @@ -0,0 +1,15 @@ +## CBRT + +The `CBRT` function returns the cube root of a number. The input can be any numeric value, and the return value is always a double. Cube roots of infinities are null. + +### Examples + +```esql +ROW d = 1000.0 +| EVAL c = CBRT(d) +``` + +```esql +ROW value = 27.0 +| EVAL cube_root = CBRT(value) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ceil.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ceil.txt new file mode 100644 index 0000000000000..3713fa2cf4cba --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ceil.txt @@ -0,0 +1,16 @@ +## CEIL + +The `CEIL` function rounds a number up to the nearest integer. This operation is a no-op for long (including unsigned) and integer types. For double types, it picks the closest double value to the integer, similar to `Math.ceil`. + +### Examples + +```esql +ROW a=1.8 +| EVAL a = CEIL(a) +``` + +```esql +FROM employees +| KEEP first_name, last_name, height +| EVAL height_ceil = CEIL(height) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cidr_match.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cidr_match.txt new file mode 100644 index 0000000000000..2e5e306d01c01 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cidr_match.txt @@ -0,0 +1,17 @@ +## CIDR_MATCH + +The `CIDR_MATCH` function returns true if the provided IP is contained in one of the provided CIDR blocks. + +### Examples + +```esql +FROM hosts +| WHERE CIDR_MATCH(ip1, "127.0.0.2/32", "127.0.0.3/32") +| KEEP card, host, ip0, ip1 +``` + +```esql +FROM network_logs +| WHERE CIDR_MATCH(source_ip, "192.168.1.0/24", "10.0.0.0/8") +| KEEP timestamp, source_ip, destination_ip, action +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-coalesce.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-coalesce.txt new file mode 100644 index 0000000000000..057efa96da3bd --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-coalesce.txt @@ -0,0 +1,15 @@ +## COALESCE + +The `COALESCE` function returns the first of its arguments that is not null. If all arguments are null, it returns null. + +### Examples + +```esql +ROW a=null, b="b" +| EVAL COALESCE(a, b) +``` + +```esql +ROW x=null, y=null, z="z" +| EVAL first_non_null = COALESCE(x, y, z) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-concat.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-concat.txt new file mode 100644 index 0000000000000..435a8458ff05c --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-concat.txt @@ -0,0 +1,16 @@ +## CONCAT + +The `CONCAT` function concatenates two or more strings. + +### Examples + +```esql +FROM employees +| KEEP first_name, last_name +| EVAL fullname = CONCAT(first_name, " ", last_name) +``` + +```esql +ROW part1 = "Hello", part2 = "World" +| EVAL greeting = CONCAT(part1, " ", part2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cos.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cos.txt new file mode 100644 index 0000000000000..e554a886c5cab --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cos.txt @@ -0,0 +1,15 @@ +## COS + +The `COS` function returns the cosine of an angle, expressed in radians. If the input angle is null, the function returns null. + +### Examples + +```esql +ROW a=1.8 +| EVAL cos = COS(a) +``` + +```esql +ROW angle=0.5 +| EVAL cosine_value = COS(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cosh.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cosh.txt new file mode 100644 index 0000000000000..c1eda78d10f2b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-cosh.txt @@ -0,0 +1,15 @@ +## COSH + +Returns the hyperbolic cosine of an angle. + +### Examples + +```esql +ROW a=1.8 +| EVAL cosh = COSH(a) +``` + +```esql +ROW angle=0.5 +| EVAL hyperbolic_cosine = COSH(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count.txt new file mode 100644 index 0000000000000..407caa4c0f0c6 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count.txt @@ -0,0 +1,32 @@ +## COUNT + +The `COUNT` function returns the total number (count) of input values. If the `field` parameter is omitted, it is equivalent to `COUNT(*)`, which counts the number of rows. + +### Examples + +```esql +FROM employees +| STATS COUNT(height) +``` + +```esql +FROM employees +| STATS count = COUNT(*) BY languages +| SORT languages DESC +``` + +```esql +ROW words="foo;bar;baz;qux;quux;foo" +| STATS word_count = COUNT(SPLIT(words, ";")) +``` + +```esql +ROW n=1 +| WHERE n < 0 +| STATS COUNT(n) +``` + +```esql +ROW n=1 +| STATS COUNT(n > 0 OR NULL), COUNT(n < 0 OR NULL) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count_distinct.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count_distinct.txt new file mode 100644 index 0000000000000..ec7c373e340be --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-count_distinct.txt @@ -0,0 +1,31 @@ +## COUNT_DISTINCT + +The `COUNT_DISTINCT` function returns the approximate number of distinct values in a column or literal. It uses the HyperLogLog++ algorithm to count based on the hashes of the values, providing configurable precision to trade memory for accuracy. This function is particularly useful for high-cardinality sets and large values, as it maintains fixed memory usage regardless of the number of unique values. + +### Examples + +```esql +FROM hosts +| STATS COUNT_DISTINCT(ip0), COUNT_DISTINCT(ip1) +``` + +```esql +FROM hosts +| STATS COUNT_DISTINCT(ip0, 80000), COUNT_DISTINCT(ip1, 5) +``` + +```esql +ROW words="foo;bar;baz;qux;quux;foo" +| STATS distinct_word_count = COUNT_DISTINCT(SPLIT(words, ";")) +``` + +### Additional Information + +- **Precision Threshold**: The `COUNT_DISTINCT` function takes an optional second parameter to configure the precision threshold. The maximum supported value is 40000, and the default value is 3000. This threshold allows you to trade memory for accuracy, defining a unique count below which counts are expected to be close to accurate. Above this value, counts might become a bit more fuzzy. +- **Algorithm**: The function is based on the HyperLogLog++ algorithm, which provides excellent accuracy on low-cardinality sets and fixed memory usage. The memory usage depends on the configured precision, requiring about `c * 8` bytes for a precision threshold of `c`. + +### Notes + +- Computing exact counts requires loading values into a set and returning its size, which doesn't scale well for high-cardinality sets or large values due to memory usage and communication overhead. +- The HyperLogLog++ algorithm's accuracy depends on the leading zeros of hashed values, and the exact distributions of hashes in a dataset can affect the accuracy of the cardinality. +- Even with a low threshold, the error remains very low (1-6%) even when counting millions of items. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_diff.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_diff.txt new file mode 100644 index 0000000000000..20a261e53a100 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_diff.txt @@ -0,0 +1,15 @@ +## DATE_DIFF + +The `DATE_DIFF` function subtracts the `startTimestamp` from the `endTimestamp` and returns the difference in multiples of the specified unit. If `startTimestamp` is later than the `endTimestamp`, negative values are returned. Note that while there is an overlap between the function’s supported units and ES|QL’s supported time span literals, these sets are distinct and not interchangeable. Similarly, the supported abbreviations are conveniently shared with implementations of this function in other established products and not necessarily common with the date-time nomenclature used by Elasticsearch. + +### Examples + +```esql +ROW date1 = TO_DATETIME("2023-12-02T11:00:00.000Z"), date2 = TO_DATETIME("2023-12-02T11:00:00.001Z") +| EVAL dd_ms = DATE_DIFF("microseconds", date1, date2) +``` + +```esql +ROW date1 = TO_DATETIME("2023-01-01T00:00:00.000Z"), date2 = TO_DATETIME("2023-12-31T23:59:59.999Z") +| EVAL dd_days = DATE_DIFF("days", date1, date2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_extract.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_extract.txt new file mode 100644 index 0000000000000..e064e1e09a91b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_extract.txt @@ -0,0 +1,15 @@ +## DATE_EXTRACT + +The `DATE_EXTRACT` function extracts specific parts of a date, such as the year, month, day, or hour. It can be used to retrieve various components of a date based on the specified `datePart`. + +### Examples + +```esql +ROW date = DATE_PARSE("yyyy-MM-dd", "2022-05-06") +| EVAL year = DATE_EXTRACT("year", date) +``` + +```esql +FROM sample_data +| WHERE DATE_EXTRACT("hour_of_day", @timestamp) < 9 AND DATE_EXTRACT("hour_of_day", @timestamp) >= 17 +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_format.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_format.txt new file mode 100644 index 0000000000000..26149e8ce0d28 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_format.txt @@ -0,0 +1,17 @@ +## DATE_FORMAT + +The `DATE_FORMAT` function returns a string representation of a date in the provided format. If no format is specified, the default format `yyyy-MM-dd'T'HH:mm:ss.SSSZ` is used. If the date expression is null, the function returns null. + +### Examples + +```esql +FROM employees +| KEEP first_name, last_name, hire_date +| EVAL hired = DATE_FORMAT("YYYY-MM-dd", hire_date) +``` + +```esql +FROM employees +| KEEP first_name, last_name, hire_date +| EVAL hired = DATE_FORMAT("yyyy/MM/dd", hire_date) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_parse.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_parse.txt new file mode 100644 index 0000000000000..4d2843deed440 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_parse.txt @@ -0,0 +1,15 @@ +## DATE_PARSE + +The `DATE_PARSE` function returns a date by parsing the second argument using the format specified in the first argument. + +### Examples + +```esql +ROW date_string = "2022-05-06" +| EVAL date = DATE_PARSE("yyyy-MM-dd", date_string) +``` + +```esql +ROW date_string = "2023-12-25" +| EVAL date = DATE_PARSE("yyyy-MM-dd", date_string) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_trunc.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_trunc.txt new file mode 100644 index 0000000000000..28c15f62c5c53 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-date_trunc.txt @@ -0,0 +1,30 @@ +## DATE_TRUNC + +The `DATE_TRUNC` function rounds down a date to the closest interval. + +### Examples + +```esql +FROM employees +| KEEP first_name, last_name, hire_date +| EVAL year_hired = DATE_TRUNC(1 year, hire_date) +``` + +Combine `DATE_TRUNC` with `STATS ... BY` to create date histograms. For example, the number of hires per year: + +```esql +FROM employees +| EVAL year = DATE_TRUNC(1 year, hire_date) +| STATS hires = COUNT(emp_no) BY year +| SORT year +``` + +Or an hourly error rate: + +```esql +FROM sample_data +| EVAL error = CASE(message LIKE "*error*", 1, 0) +| EVAL hour = DATE_TRUNC(1 hour, @timestamp) +| STATS error_rate = AVG(error) BY hour +| SORT hour +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-dissect.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-dissect.txt new file mode 100644 index 0000000000000..5ce173f0e801d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-dissect.txt @@ -0,0 +1,54 @@ +## DISSECT + +DISSECT enables you to extract structured data out of a string. It matches the string against a delimiter-based pattern and extracts the specified keys as columns. This command is particularly useful for parsing log files, structured text, or any other string data where fields are separated by specific delimiters. + +### Use Cases +- **Log Parsing**: Extracting timestamps, log levels, and messages from log entries. +- **Data Transformation**: Converting unstructured text data into structured columns for further analysis. +- **Data Cleaning**: Removing or reformatting specific parts of a string to make the data more usable. + +### Limitations +- If a field name conflicts with an existing column, the existing column is dropped. +- If a field name is used more than once, only the rightmost duplicate creates a column. +- DISSECT does not support reference keys. + +### Syntax + +`DISSECT input "pattern" [APPEND_SEPARATOR=""]` + +### Parameters +- **input**: The column that contains the string you want to structure. If the column has multiple values, DISSECT will process each value. +- **pattern**: A dissect pattern. +- ****: A string used as the separator between appended values, when using the append modifier. + +### Examples + +#### Example 1: Basic Usage +The following example parses a string that contains a timestamp, some text, and an IP address: + +```esql +ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" +| DISSECT a "%{date} - %{msg} - %{ip}" +| KEEP date, msg, ip +``` + +#### Example 2: Type Conversion +By default, DISSECT outputs keyword string columns. To convert to another type, use Type conversion functions: + +```esql +ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" +| DISSECT a "%{date} - %{msg} - %{ip}" +| KEEP date, msg, ip +| EVAL date = TO_DATETIME(date) +``` + +#### Example 3: Using Append Separator +In this example, we use the `APPEND_SEPARATOR` to concatenate values with a custom separator: + +```esql +ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" +| DISSECT a "%{date} - %{msg} - %{ip}" APPEND_SEPARATOR=" | " +| KEEP date, msg, ip +``` + +These examples showcase different ways to use the DISSECT command to parse and transform string data in Elasticsearch. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-drop.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-drop.txt new file mode 100644 index 0000000000000..9bc678ef29c2f --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-drop.txt @@ -0,0 +1,58 @@ +## DROP + +The `DROP` processing command in ES|QL is used to remove one or more columns from the result set. This command is particularly useful when you want to exclude certain fields from your query results, either to simplify the output or to reduce the amount of data being processed and transferred. The `DROP` command supports the use of wildcards, allowing you to remove multiple columns that match a specific pattern. + +### Use Cases +- **Simplifying Output:** Remove unnecessary columns to make the result set easier to read and analyze. +- **Data Reduction:** Exclude large or irrelevant fields to reduce the amount of data processed and transferred. +- **Pattern Matching:** Use wildcards to efficiently drop multiple columns that share a common naming pattern. + +### Limitations +- The `DROP` command does not support nested fields. +- It cannot be used to drop columns of unsupported types as specified in the ES|QL limitations. + +### Examples + +#### Example 1: Dropping a Single Column +This example demonstrates how to drop a single column named `height` from the `employees` index. + +```esql +FROM employees +| DROP height +``` + +#### Example 2: Dropping Multiple Columns Using Wildcards +This example shows how to use wildcards to drop all columns that start with `height`. + +```esql +FROM employees +| DROP height* +``` + +#### Example 3: Dropping Multiple Specific Columns +This example demonstrates how to drop multiple specific columns by listing them in a comma-separated format. + +```esql +FROM employees +| DROP height, weight, age +``` + +#### Example 4: Dropping Columns with Complex Patterns +This example shows how to drop columns that match a more complex pattern using wildcards. + +```esql +FROM employees +| DROP emp_* +``` + +#### Example 5: Combining DROP with Other Commands +This example demonstrates how to use the `DROP` command in conjunction with other commands like `KEEP` and `SORT`. + +```esql +FROM employees +| KEEP first_name, last_name, height, weight +| DROP weight +| SORT height DESC +``` + +By using the `DROP` command, you can effectively manage the columns in your result set, making your ES|QL queries more efficient and easier to work with. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-e.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-e.txt new file mode 100644 index 0000000000000..7f81d56ab63c2 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-e.txt @@ -0,0 +1,15 @@ +## E + +The `E` function returns Euler’s number, which is a mathematical constant approximately equal to 2.71828. It is the base of the natural logarithm. + +### Examples + +```esql +ROW E() +``` + +```esql +FROM employees +| EVAL euler_number = E() +| KEEP euler_number +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ends_with.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ends_with.txt new file mode 100644 index 0000000000000..7607666f70213 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ends_with.txt @@ -0,0 +1,17 @@ +## ENDS_WITH + +The `ENDS_WITH` function returns a boolean that indicates whether a keyword string ends with another string. + +### Examples + +```esql +FROM employees +| KEEP last_name +| EVAL ln_E = ENDS_WITH(last_name, "d") +``` + +```esql +FROM employees +| KEEP first_name +| EVAL fn_E = ENDS_WITH(first_name, "a") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-enrich.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-enrich.txt new file mode 100644 index 0000000000000..0db6c10e0d44f --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-enrich.txt @@ -0,0 +1,48 @@ +## ENRICH + +ENRICH enables you to add data from existing indices as new columns using an enrich policy. This command is useful for enriching your dataset with additional information from other indices, which can be particularly beneficial for data analysis and reporting. Before using the ENRICH command, you need to create and execute an enrich policy. + +### Use Cases +- **Data Enrichment**: Add supplementary data to your existing dataset for more comprehensive analysis. +- **Cross-Cluster Enrichment**: Enrich data across multiple clusters using the `mode` parameter. +- **Custom Column Names**: Rename columns to avoid conflicts or for better readability. + +### Limitations +- The ENRICH command only supports enrich policies of type `match`. +- ENRICH only supports enriching on a column of type `keyword`. + +### Examples + +#### Example 1: Basic Enrichment +The following example uses the `languages_policy` enrich policy to add a new column for each enrich field defined in the policy. The match is performed using the `match_field` defined in the enrich policy and requires that the input table has a column with the same name (`language_code` in this example). + +```esql +ROW language_code = "1" +| ENRICH languages_policy +``` + +#### Example 2: Using a Different Match Field +To use a column with a different name than the `match_field` defined in the policy as the match field, use the `ON` parameter. + +```esql +ROW a = "1" +| ENRICH languages_policy ON a +``` + +#### Example 3: Selecting Specific Enrich Fields +By default, each of the enrich fields defined in the policy is added as a column. To explicitly select the enrich fields that are added, use the `WITH` parameter. + +```esql +ROW a = "1" +| ENRICH languages_policy ON a WITH language_name +``` + +#### Example 4: Renaming Enrich Fields +You can rename the columns that are added using the `WITH new_name=` syntax. + +```esql +ROW a = "1" +| ENRICH languages_policy ON a WITH name = language_name +``` + +In case of name collisions, the newly created columns will override existing columns. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-eval.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-eval.txt new file mode 100644 index 0000000000000..a7ad446cbbde9 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-eval.txt @@ -0,0 +1,55 @@ +## EVAL + +The `EVAL` processing command enables you to append new columns with calculated values. This command is useful for creating new data points derived from existing columns, such as performing arithmetic operations, applying functions, or using expressions. + +### Use Cases +- **Data Transformation**: Create new columns based on existing data, such as converting units or calculating derived metrics. +- **Data Enrichment**: Add additional context to your data by computing new values. +- **Data Cleaning**: Standardize or normalize data by applying transformations. + +### Limitations +- If a column with the same name already exists, the existing column is dropped. +- If a column name is used more than once, only the rightmost duplicate creates a column. + +### Examples + +#### Example 1: Converting Height to Different Units +This example demonstrates how to convert the height from meters to feet and centimeters. + +```esql +FROM employees +| SORT emp_no +| KEEP first_name, last_name, height +| EVAL height_feet = height * 3.281, height_cm = height * 100 +``` + +#### Example 2: Overwriting an Existing Column +In this example, the `height` column is overwritten with its value in feet. + +```esql +FROM employees +| SORT emp_no +| KEEP first_name, last_name, height +| EVAL height = height * 3.281 +``` + +#### Example 3: Using an Expression as Column Name +Here, a new column is created with a name equal to the expression used to calculate its value. + +```esql +FROM employees +| SORT emp_no +| KEEP first_name, last_name, height +| EVAL height * 3.281 +``` + +#### Example 4: Using Special Characters in Column Names +This example shows how to handle special characters in column names by quoting them with backticks. + +```esql +FROM employees +| EVAL height * 3.281 +| STATS avg_height_feet = AVG(`height * 3.281`) +``` + +These examples illustrate the versatility of the `EVAL` command in transforming and enriching your data within Elasticsearch. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-exp.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-exp.txt new file mode 100644 index 0000000000000..89a2c612b08b7 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-exp.txt @@ -0,0 +1,15 @@ +## EXP + +The `EXP` function returns the value of Euler's number (e) raised to the power of the given numeric expression. If the input is null, the function returns null. + +### Examples + +```esql +ROW d = 5.0 +| EVAL s = EXP(d) +``` + +```esql +ROW value = 2.0 +| EVAL result = EXP(value) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-floor.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-floor.txt new file mode 100644 index 0000000000000..d3f50c55d0091 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-floor.txt @@ -0,0 +1,16 @@ +## FLOOR + +The `FLOOR` function rounds a number down to the nearest integer. This operation is a no-op for long (including unsigned) and integer types. For double types, it picks the closest double value to the integer, similar to `Math.floor`. + +### Examples + +```esql +ROW a=1.8 +| EVAL a = FLOOR(a) +``` + +```esql +FROM employees +| KEEP first_name, last_name, height +| EVAL height_floor = FLOOR(height) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from.txt new file mode 100644 index 0000000000000..7847e7c847655 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from.txt @@ -0,0 +1,53 @@ +## FROM + +The `FROM` source command returns a table with data from a data stream, index, or alias. Each row in the resulting table represents a document, and each column corresponds to a field that can be accessed by the name of that field. This command is fundamental for querying data in Elasticsearch using ES|QL. + +### Use Cases + +- **Basic Data Retrieval**: Fetch data from a specific index or data stream. +- **Time Series Data**: Use date math to access indices relevant to specific time periods. +- **Multiple Indices**: Query multiple data streams, indices, or aliases using comma-separated lists or wildcards. +- **Remote Clusters**: Query data streams and indices on remote clusters. +- **Metadata Retrieval**: Retrieve specific metadata fields using the `METADATA` directive. + +### Limitations + +- By default, an ES|QL query without an explicit `LIMIT` uses an implicit limit of 1000 rows. This applies to the `FROM` command as well. +- Queries do not return more than 10,000 rows, regardless of the `LIMIT` command’s value. + +### Examples + +#### Basic Data Retrieval +```esql +FROM employees +``` + +#### Time Series Data +Use date math to refer to indices, aliases, and data streams. This can be useful for time series data, for example, to access today’s index: +```esql +FROM +``` + +#### Multiple Indices +Use comma-separated lists or wildcards to query multiple data streams, indices, or aliases: +```esql +FROM employees-00001,other-employees-* +``` + +#### Remote Clusters +Use the format `:` to query data streams and indices on remote clusters: +```esql +FROM cluster_one:employees-00001,cluster_two:other-employees-* +``` + +#### Metadata Retrieval +Use the optional `METADATA` directive to enable metadata fields: +```esql +FROM employees METADATA _id +``` + +#### Escaping Special Characters +Use enclosing double quotes (") or three enclosing double quotes (""") to escape index names that contain special characters: +```esql +FROM "this=that","""this[that""" +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from_base64.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from_base64.txt new file mode 100644 index 0000000000000..19090768a9db4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-from_base64.txt @@ -0,0 +1,15 @@ +## FROM_BASE64 + +Decodes a base64 string. + +### Examples + +```esql +ROW a = "ZWxhc3RpYw==" +| EVAL d = FROM_BASE64(a) +``` + +```esql +ROW encoded = "U29tZSBzYW1wbGUgdGV4dA==" +| EVAL decoded = FROM_BASE64(encoded) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-greatest.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-greatest.txt new file mode 100644 index 0000000000000..17217e8e84682 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-greatest.txt @@ -0,0 +1,15 @@ +## GREATEST + +The `GREATEST` function returns the maximum value from multiple columns. This is similar to `MV_MAX` except it is intended to run on multiple columns at once. When run on keyword or text fields, this function returns the last string in alphabetical order. When run on boolean columns, it will return `true` if any values are `true`. + +### Examples + +```esql +ROW a = 10, b = 20 +| EVAL g = GREATEST(a, b) +``` + +```esql +ROW x = "apple", y = "banana", z = "cherry" +| EVAL max_fruit = GREATEST(x, y, z) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-grok.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-grok.txt new file mode 100644 index 0000000000000..cc357b986a58b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-grok.txt @@ -0,0 +1,55 @@ +## GROK + +GROK enables you to extract structured data out of a string. It matches the string against patterns based on regular expressions and extracts the specified patterns as columns. This command is useful for parsing logs, extracting fields from text, and structuring unstructured data. + +### Use Cases +- **Log Parsing**: Extracting timestamps, IP addresses, and other fields from log entries. +- **Data Structuring**: Converting unstructured text data into structured columns. +- **Field Extraction**: Extracting specific fields from a string for further analysis. + +### Limitations +- If a field name conflicts with an existing column, the existing column is discarded. +- If a field name is used more than once, a multi-valued column will be created with one value per each occurrence of the field name. +- The `GROK` command does not support configuring custom patterns or multiple patterns. +- The `GROK` command is not subject to Grok watchdog settings. + +### Examples + +#### Example 1: Basic GROK Usage +This example parses a string that contains a timestamp, an IP address, an email address, and a number. + +```esql +ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" +| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}" +| KEEP date, ip, email, num +``` + +#### Example 2: Type Conversion with GROK +By default, GROK outputs keyword string columns. To convert to other types, append `:type` to the semantics in the pattern. + +```esql +ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" +| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}" +| KEEP date, ip, email, num +``` + +#### Example 3: Using Type Conversion Functions +For other type conversions, use Type conversion functions. + +```esql +ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" +| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}" +| KEEP date, ip, email, num +| EVAL date = TO_DATETIME(date) +``` + +#### Example 4: Handling Multi-Valued Columns +If a field name is used more than once, GROK creates a multi-valued column. + +```esql +FROM addresses +| KEEP city.name, zip_code +| GROK zip_code "%{WORD:zip_parts} %{WORD:zip_parts}" +``` + +These examples showcase different usages of the GROK command, from basic extraction to handling type conversions and multi-valued columns. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ip_prefix.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ip_prefix.txt new file mode 100644 index 0000000000000..65d4ccbf5d4b3 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ip_prefix.txt @@ -0,0 +1,16 @@ +## IP_PREFIX + +The `IP_PREFIX` function truncates an IP address to a given prefix length. It supports both IPv4 and IPv6 addresses. + +### Examples + +```esql +ROW ip4 = TO_IP("1.2.3.4"), ip6 = TO_IP("fe80::cae2:65ff:fece:feb9") +| EVAL ip4_prefix = IP_PREFIX(ip4, 24, 0), ip6_prefix = IP_PREFIX(ip6, 0, 112) +``` + +```esql +FROM network_logs +| EVAL truncated_ip = IP_PREFIX(ip_address, 16, 0) +| KEEP ip_address, truncated_ip +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-keep.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-keep.txt new file mode 100644 index 0000000000000..fbf2466d26c6e --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-keep.txt @@ -0,0 +1,64 @@ +## KEEP + +The `KEEP` processing command in ES|QL enables you to specify which columns are returned and the order in which they are returned. This command is particularly useful when you want to focus on specific fields in your dataset, either by explicitly naming them or by using wildcard patterns. The `KEEP` command supports a variety of use cases, such as filtering out unnecessary columns, reordering columns for better readability, and ensuring that only relevant data is processed in subsequent commands. + +### Use Cases +- **Selective Column Retrieval**: Retrieve only the columns you need for analysis, reducing the amount of data processed. +- **Column Reordering**: Specify the order in which columns should appear in the result set. +- **Wildcard Support**: Use wildcards to include multiple columns that match a pattern, simplifying queries when dealing with numerous fields. + +### Limitations +- **Precedence Rules**: When a field name matches multiple expressions, precedence rules are applied. Complete field names take the highest precedence, followed by partial wildcard expressions, and finally, the wildcard `*`. +- **Column Conflicts**: If a field matches two expressions with the same precedence, the rightmost expression wins. + +### Examples + +#### Example 1: Specifying Columns Explicitly +This example demonstrates how to explicitly specify the columns to be returned. + +```esql +FROM employees +| KEEP emp_no, first_name, last_name, height +``` + +#### Example 2: Using Wildcards to Match Column Names +This example shows how to use wildcards to return all columns that match a specific pattern. + +```esql +FROM employees +| KEEP h* +``` + +#### Example 3: Combining Wildcards and Explicit Column Names +This example illustrates how to combine wildcards and explicit column names, and how precedence rules are applied. + +```esql +FROM employees +| KEEP h*, * +``` + +#### Example 4: Precedence Rules with Complete Field Names +This example demonstrates how complete field names take precedence over wildcard expressions. + +```esql +FROM employees +| KEEP first_name, last_name, first_name* +``` + +#### Example 5: Wildcard Expressions with Same Priority +This example shows how the last wildcard expression wins when multiple wildcard expressions have the same priority. + +```esql +FROM employees +| KEEP first_name*, last_name, first_na* +``` + +#### Example 6: Simple Wildcard Expression with Lowest Precedence +This example illustrates how the simple wildcard expression `*` has the lowest precedence. + +```esql +FROM employees +| KEEP *, first_name +``` + +These examples showcase the versatility and utility of the `KEEP` command in various scenarios, making it a powerful tool for data manipulation in ES|QL. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-least.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-least.txt new file mode 100644 index 0000000000000..f756820f7840d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-least.txt @@ -0,0 +1,15 @@ +## LEAST + +Returns the minimum value from multiple columns. This is similar to `MV_MIN` except it is intended to run on multiple columns at once. + +### Examples + +```esql +ROW a = 10, b = 20 +| EVAL l = LEAST(a, b) +``` + +```esql +ROW x = 5, y = 15, z = 10 +| EVAL min_value = LEAST(x, y, z) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-left.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-left.txt new file mode 100644 index 0000000000000..5164a100ea22b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-left.txt @@ -0,0 +1,19 @@ +## LEFT + +The `LEFT` function returns the substring that extracts a specified number of characters from a string, starting from the left. + +### Examples + +```esql +FROM employees +| KEEP last_name +| EVAL left = LEFT(last_name, 3) +| SORT last_name ASC +| LIMIT 5 +``` + +```esql +ROW full_name = "John Doe" +| EVAL first_name = LEFT(full_name, 4) +| KEEP first_name +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-length.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-length.txt new file mode 100644 index 0000000000000..ea692e7fe9eae --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-length.txt @@ -0,0 +1,16 @@ +## LENGTH + +The `LENGTH` function returns the character length of a string. If the input string is null, the function returns null. + +### Examples + +```esql +FROM employees +| KEEP first_name, last_name +| EVAL fn_length = LENGTH(first_name) +``` + +```esql +ROW message = "Hello, World!" +| EVAL message_length = LENGTH(message) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-limit.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-limit.txt new file mode 100644 index 0000000000000..da1a0f85a8782 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-limit.txt @@ -0,0 +1,68 @@ +## LIMIT + +The `LIMIT` processing command in ES|QL is used to restrict the number of rows returned by a query. This is particularly useful when you want to control the volume of data retrieved, either for performance reasons or to focus on a specific subset of the data. + +### Use Cases +- **Performance Optimization**: By limiting the number of rows returned, you can improve query performance and reduce the load on the Elasticsearch cluster. +- **Data Sampling**: Useful for retrieving a sample of data for analysis or debugging. +- **Pagination**: Helps in implementing pagination by limiting the number of rows per page. + +### Limitations +- **Maximum Rows**: Queries do not return more than 10,000 rows, regardless of the `LIMIT` command’s value. This limit only applies to the number of rows that are retrieved by the query. Queries and aggregations run on the full data set. +- **Overcoming Limitations**: To overcome this limitation, you can: + - Reduce the result set size by modifying the query to only return relevant data using the `WHERE` command. + - Shift any post-query processing to the query itself using the `STATS ... BY` command to aggregate data in the query. +- **Dynamic Cluster Settings**: The default and maximum limits can be changed using these dynamic cluster settings: + - `esql.query.result_truncation_default_size` + - `esql.query.result_truncation_max_size` + +### Examples + +#### Example 1: Basic Usage +This example demonstrates how to limit the number of rows returned to 5. + +```esql +FROM employees +| SORT emp_no ASC +| LIMIT 5 +``` + +#### Example 2: Limiting Rows After Filtering +This example shows how to limit the number of rows after applying a filter. + +```esql +FROM employees +| WHERE department == "Engineering" +| LIMIT 10 +``` + +#### Example 3: Limiting Rows with Aggregation +This example demonstrates limiting the number of rows after performing an aggregation. + +```esql +FROM employees +| STATS avg_salary = AVG(salary) BY department +| LIMIT 3 +``` + +#### Example 4: Limiting Rows with Sorting +This example shows how to limit the number of rows after sorting the data. + +```esql +FROM employees +| SORT hire_date DESC +| LIMIT 7 +``` + +#### Example 5: Limiting Rows with Multiple Commands +This example demonstrates the use of `LIMIT` in conjunction with multiple other commands. + +```esql +FROM employees +| WHERE hire_date > "2020-01-01" +| SORT salary DESC +| KEEP first_name, last_name, salary +| LIMIT 5 +``` + +By using the `LIMIT` command, you can effectively manage the volume of data returned by your ES|QL queries, ensuring better performance and more focused results. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-locate.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-locate.txt new file mode 100644 index 0000000000000..e62ea05fcc3ab --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-locate.txt @@ -0,0 +1,25 @@ +## LOCATE + +The `LOCATE` function returns an integer that indicates the position of a keyword substring within another string. + +### Syntax + +`LOCATE(string, substring, start)` + +### Parameters + +- `string`: An input string. +- `substring`: A substring to locate in the input string. +- `start`: The start index. + +### Examples + +```esql +ROW a = "hello" +| EVAL a_ll = LOCATE(a, "ll") +``` + +```esql +ROW phrase = "Elasticsearch is powerful" +| EVAL position = LOCATE(phrase, "powerful") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log.txt new file mode 100644 index 0000000000000..b41fef3adc86d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log.txt @@ -0,0 +1,15 @@ +## LOG + +The `LOG` function returns the logarithm of a value to a specified base. The input can be any numeric value, and the return value is always a double. Logs of zero, negative numbers, and base of one return null as well as a warning. + +### Examples + +```esql +ROW base = 2.0, value = 8.0 +| EVAL s = LOG(base, value) +``` + +```esql +ROW value = 100 +| EVAL s = LOG(value) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log10.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log10.txt new file mode 100644 index 0000000000000..f8b9748577624 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-log10.txt @@ -0,0 +1,15 @@ +## LOG10 + +The `LOG10` function returns the logarithm of a value to base 10. The input can be any numeric value, and the return value is always a double. Logs of 0 and negative numbers return null as well as a warning. + +### Examples + +```esql +ROW d = 1000.0 +| EVAL s = LOG10(d) +``` + +```esql +ROW value = 100 +| EVAL log_value = LOG10(value) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-lookup.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-lookup.txt new file mode 100644 index 0000000000000..fc9312674db81 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-lookup.txt @@ -0,0 +1,101 @@ +## LOOKUP + +The `LOOKUP` command in ES|QL is highly experimental and only available in SNAPSHOT versions. It matches values from the input against a table provided in the request, adding the other fields from the table to the output. This command is useful for enriching your dataset with additional information from a predefined table. However, it is important to note that if the table’s column names conflict with existing columns, the existing columns will be dropped. + +### Examples + +Here are some example ES|QL queries using the `LOOKUP` command: + +1. **Basic Lookup Example:** + ```esql +FROM library +| SORT page_count DESC +| KEEP name, author +| LOOKUP era ON author +| LIMIT 5 +``` + +2. **Lookup with Multiple Match Fields:** + ```esql +FROM library +| SORT page_count DESC +| KEEP name, author, genre +| LOOKUP era ON author, genre +| LIMIT 5 +``` + +3. **Lookup with Different Table:** + ```esql +FROM library +| SORT page_count DESC +| KEEP name, author +| LOOKUP awards ON author +| LIMIT 5 +``` + +### Content of file + +```plaintext +LOOKUP + +LOOKUP is highly experimental and only available in SNAPSHOT versions. +LOOKUP matches values from the input against a table provided in the request, +adding the other fields from the table to the output. + +Syntax: +LOOKUP table ON match_field1[, match_field2, ...] + +Parameters: +- table: The name of the table provided in the request to match. If the table’s column names conflict with existing columns, the existing columns will be dropped. +- match_field: The fields in the input to match against the table. + +Examples: +const response = await client.esql.query({ + format: "txt", + query: + "\n FROM library\n | SORT page_count DESC\n | KEEP name, author\n | LOOKUP era ON author\n | LIMIT 5\n ", + tables: { + era: { + author: { + keyword: [ + "Frank Herbert", + "Peter F. Hamilton", + "Vernor Vinge", + "Alastair Reynolds", + "James S.A. Corey", + ], + }, + era: { + keyword: ["The New Wave", "Diamond", "Diamond", "Diamond", "Hadron"], + }, + }, + }, +}); +console.log(response); + +POST /_query?format=txt +{ + "query": """ + FROM library + | SORT page_count DESC + | KEEP name, author + | LOOKUP era ON author + | LIMIT 5 + """, + "tables": { + "era": { + "author": {"keyword": ["Frank Herbert", "Peter F. Hamilton", "Vernor Vinge", "Alastair Reynolds", "James S.A. Corey"]}, + "era": {"keyword": [ "The New Wave", "Diamond", "Diamond", "Diamond", "Hadron"]} + } + } +} + +Which returns: +name | author | era +--------------------+-----------------+--------------- +Pandora's Star |Peter F. Hamilton|Diamond +A Fire Upon the Deep|Vernor Vinge |Diamond +Dune |Frank Herbert |The New Wave +Revelation Space |Alastair Reynolds|Diamond +Leviathan Wakes |James S.A. Corey |Hadron +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ltrim.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ltrim.txt new file mode 100644 index 0000000000000..7a34fe57f9801 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-ltrim.txt @@ -0,0 +1,19 @@ +## LTRIM + +Removes leading whitespaces from a string. + +### Examples + +```esql +ROW message = " some text ", color = " red " +| EVAL message = LTRIM(message) +| EVAL color = LTRIM(color) +| EVAL message = CONCAT("'", message, "'") +| EVAL color = CONCAT("'", color, "'") +``` + +```esql +ROW text = " example text " +| EVAL trimmed_text = LTRIM(text) +| EVAL formatted_text = CONCAT("Trimmed: '", trimmed_text, "'") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-max.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-max.txt new file mode 100644 index 0000000000000..381c66afa9bb1 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-max.txt @@ -0,0 +1,15 @@ +## MAX + +The `MAX` function returns the maximum value of a specified field. + +### Examples + +```esql +FROM employees +| STATS MAX(languages) +``` + +```esql +FROM employees +| STATS max_avg_salary_change = MAX(MV_AVG(salary_change)) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median.txt new file mode 100644 index 0000000000000..5da7a9be4fdb3 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median.txt @@ -0,0 +1,15 @@ +## MEDIAN + +The `MEDIAN` function returns the value that is greater than half of all values and less than half of all values, also known as the 50% PERCENTILE. Like `PERCENTILE`, `MEDIAN` is usually approximate. It is also non-deterministic, meaning you can get slightly different results using the same data. + +### Examples + +```esql +FROM employees +| STATS MEDIAN(salary), PERCENTILE(salary, 50) +``` + +```esql +FROM employees +| STATS median_max_salary_change = MEDIAN(MV_MAX(salary_change)) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median_absolute_deviation.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median_absolute_deviation.txt new file mode 100644 index 0000000000000..07da947d5494c --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-median_absolute_deviation.txt @@ -0,0 +1,15 @@ +## MEDIAN_ABSOLUTE_DEVIATION + +The `MEDIAN_ABSOLUTE_DEVIATION` function returns the median absolute deviation, a measure of variability. It is a robust statistic, meaning that it is useful for describing data that may have outliers, or may not be normally distributed. For such data, it can be more descriptive than standard deviation. It is calculated as the median of each data point’s deviation from the median of the entire sample. That is, for a random variable X, the median absolute deviation is median(|median(X) - X|). Like `PERCENTILE`, `MEDIAN_ABSOLUTE_DEVIATION` is usually approximate. + +### Examples + +```esql +FROM employees +| STATS MEDIAN(salary), MEDIAN_ABSOLUTE_DEVIATION(salary) +``` + +```esql +FROM employees +| STATS m_a_d_max_salary_change = MEDIAN_ABSOLUTE_DEVIATION(MV_MAX(salary_change)) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-min.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-min.txt new file mode 100644 index 0000000000000..043ad01280ad8 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-min.txt @@ -0,0 +1,15 @@ +## MIN + +The `MIN` function returns the minimum value of a specified field. + +### Examples + +```esql +FROM employees +| STATS MIN(languages) +``` + +```esql +FROM employees +| STATS min_avg_salary_change = MIN(MV_AVG(salary_change)) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_append.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_append.txt new file mode 100644 index 0000000000000..9926157ce96c4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_append.txt @@ -0,0 +1,17 @@ +## MV_APPEND + +The `MV_APPEND` function concatenates values of two multi-value fields. + +### Examples + +```esql +ROW a = ["foo", "bar"], b = ["baz", "qux"] +| EVAL c = MV_APPEND(a, b) +| KEEP a, b, c +``` + +```esql +ROW x = [1, 2, 3], y = [4, 5, 6] +| EVAL z = MV_APPEND(x, y) +| KEEP x, y, z +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_avg.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_avg.txt new file mode 100644 index 0000000000000..431c4ec6b2891 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_avg.txt @@ -0,0 +1,15 @@ +## MV_AVG + +The `MV_AVG` function converts a multivalued field into a single-valued field containing the average of all the values. + +### Examples + +```esql +ROW a=[3, 5, 1, 6] +| EVAL avg_a = MV_AVG(a) +``` + +```esql +ROW scores=[10, 20, 30, 40] +| EVAL average_score = MV_AVG(scores) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_concat.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_concat.txt new file mode 100644 index 0000000000000..32c029703257d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_concat.txt @@ -0,0 +1,15 @@ +## MV_CONCAT + +Converts a multivalued string expression into a single valued column containing the concatenation of all values separated by a delimiter. + +### Examples + +```esql +ROW a=["foo", "zoo", "bar"] +| EVAL j = MV_CONCAT(a, ", ") +``` + +```esql +ROW a=[10, 9, 8] +| EVAL j = MV_CONCAT(TO_STRING(a), ", ") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_count.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_count.txt new file mode 100644 index 0000000000000..a8f8d0c5149ad --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_count.txt @@ -0,0 +1,15 @@ +## MV_COUNT + +The `MV_COUNT` function converts a multivalued expression into a single-valued column containing a count of the number of values. + +### Examples + +```esql +ROW a=["foo", "zoo", "bar"] +| EVAL count_a = MV_COUNT(a) +``` + +```esql +ROW b=["apple", "banana", "cherry", "date"] +| EVAL count_b = MV_COUNT(b) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_dedupe.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_dedupe.txt new file mode 100644 index 0000000000000..297179f995dff --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_dedupe.txt @@ -0,0 +1,15 @@ +## MV_DEDUPE + +Removes duplicate values from a multivalued field. `MV_DEDUPE` may, but won’t always, sort the values in the column. + +### Examples + +```esql +ROW a=["foo", "foo", "bar", "foo"] +| EVAL dedupe_a = MV_DEDUPE(a) +``` + +```esql +ROW b=["apple", "apple", "banana", "apple", "banana"] +| EVAL dedupe_b = MV_DEDUPE(b) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_expand.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_expand.txt new file mode 100644 index 0000000000000..76528b5e22654 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_expand.txt @@ -0,0 +1,41 @@ +## MV_EXPAND + +The `MV_EXPAND` processing command expands multivalued columns into one row per value, duplicating other columns. This command is useful when you need to normalize data that contains multivalued fields, making it easier to perform operations on each individual value. + +### Use Cases +- **Normalization**: Transform multivalued fields into single-valued rows for easier analysis and processing. +- **Data Transformation**: Prepare data for further operations like sorting, filtering, or aggregating by expanding multivalued fields. +- **Data Cleaning**: Simplify complex data structures by breaking down multivalued fields into individual rows. + +### Limitations +- 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. + +### Examples + +#### Example 1: Basic Expansion +Expanding a multivalued column `a` into individual rows. + +```esql +ROW a=[1,2,3], b="b", j=["a","b"] +| MV_EXPAND a +``` + +#### Example 2: Expanding Multiple Columns +Expanding two multivalued columns `a` and `j` into individual rows. + +```esql +ROW a=[1,2,3], b="b", j=["a","b"] +| MV_EXPAND a +| MV_EXPAND j +``` + +#### Example 3: Combining with Other Commands +Expanding a multivalued column and then filtering the results. + +```esql +ROW a=[1,2,3,4,5], b="b" +| MV_EXPAND a +| WHERE a > 2 +``` + +These examples demonstrate different ways to use the `MV_EXPAND` command to transform and analyze data with multivalued fields. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_first.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_first.txt new file mode 100644 index 0000000000000..1969ad30226ac --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_first.txt @@ -0,0 +1,15 @@ +## MV_FIRST + +The `MV_FIRST` function converts a multivalued expression into a single-valued column containing the first value. This is most useful when reading from a function that emits multivalued columns in a known order like `SPLIT`. The order that multivalued fields are read from underlying storage is not guaranteed. It is frequently ascending, but don’t rely on that. If you need the minimum value, use `MV_MIN` instead of `MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn’t a performance benefit to `MV_FIRST`. + +### Examples + +```esql +ROW a="foo;bar;baz" +| EVAL first_a = MV_FIRST(SPLIT(a, ";")) +``` + +```esql +ROW b="apple;banana;cherry" +| EVAL first_b = MV_FIRST(SPLIT(b, ";")) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_last.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_last.txt new file mode 100644 index 0000000000000..f6331ab55a7eb --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_last.txt @@ -0,0 +1,15 @@ +## MV_LAST + +The `MV_LAST` function converts a multivalue expression into a single valued column containing the last value. This is most useful when reading from a function that emits multivalued columns in a known order like `SPLIT`. The order that multivalued fields are read from underlying storage is not guaranteed. It is frequently ascending, but don’t rely on that. If you need the maximum value, use `MV_MAX` instead of `MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn’t a performance benefit to `MV_LAST`. + +### Examples + +```esql +ROW a="foo;bar;baz" +| EVAL last_a = MV_LAST(SPLIT(a, ";")) +``` + +```esql +ROW a="apple;banana;cherry" +| EVAL last_fruit = MV_LAST(SPLIT(a, ";")) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_max.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_max.txt new file mode 100644 index 0000000000000..4c6d50ec151ee --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_max.txt @@ -0,0 +1,15 @@ +## MV_MAX + +The `MV_MAX` function converts a multivalued expression into a single valued column containing the maximum value. + +### Examples + +```esql +ROW a=[3, 5, 1] +| EVAL max_a = MV_MAX(a) +``` + +```esql +ROW a=["foo", "zoo", "bar"] +| EVAL max_a = MV_MAX(a) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_median.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_median.txt new file mode 100644 index 0000000000000..6702441a82bca --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_median.txt @@ -0,0 +1,17 @@ +## MV_MEDIAN + +The `MV_MEDIAN` function converts a multivalued field into a single valued field containing the median value. + +### Examples + +```esql +ROW a=[3, 5, 1] +| EVAL median_a = MV_MEDIAN(a) +``` + +If the row has an even number of values for a column, the result will be the average of the middle two entries. If the column is not floating point, the average rounds down: + +```esql +ROW a=[3, 7, 1, 6] +| EVAL median_a = MV_MEDIAN(a) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_min.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_min.txt new file mode 100644 index 0000000000000..386f5d424cef8 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_min.txt @@ -0,0 +1,15 @@ +## MV_MIN + +The `MV_MIN` function converts a multivalued expression into a single valued column containing the minimum value. + +### Examples + +```esql +ROW a=[2, 1] +| EVAL min_a = MV_MIN(a) +``` + +```esql +ROW a=["foo", "bar"] +| EVAL min_a = MV_MIN(a) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_pseries_weighted_sum.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_pseries_weighted_sum.txt new file mode 100644 index 0000000000000..1b1fc706b8d3d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_pseries_weighted_sum.txt @@ -0,0 +1,17 @@ +## MV_PSERIES_WEIGHTED_SUM + +Converts a multivalued expression into a single-valued column by multiplying every element on the input list by its corresponding term in P-Series and computing the sum. + +### Examples + +```esql +ROW a = [70.0, 45.0, 21.0, 21.0, 21.0] +| EVAL sum = MV_PSERIES_WEIGHTED_SUM(a, 1.5) +| KEEP sum +``` + +```esql +ROW b = [10.0, 20.0, 30.0, 40.0, 50.0] +| EVAL weighted_sum = MV_PSERIES_WEIGHTED_SUM(b, 2.0) +| KEEP weighted_sum +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_slice.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_slice.txt new file mode 100644 index 0000000000000..4b93d9703095b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_slice.txt @@ -0,0 +1,15 @@ +## MV_SLICE + +The `MV_SLICE` function returns a subset of the multivalued field using the start and end index values. + +### Examples + +```esql +ROW a = [1, 2, 2, 3] +| EVAL a1 = MV_SLICE(a, 1), a2 = MV_SLICE(a, 2, 3) +``` + +```esql +ROW a = [1, 2, 2, 3] +| EVAL a1 = MV_SLICE(a, -2), a2 = MV_SLICE(a, -3, -1) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sort.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sort.txt new file mode 100644 index 0000000000000..14d41a8fd8d56 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sort.txt @@ -0,0 +1,15 @@ +## MV_SORT + +The `MV_SORT` function sorts a multivalued field in lexicographical order. The valid options for the sort order are `ASC` (ascending) and `DESC` (descending), with the default being `ASC`. + +### Examples + +```esql +ROW a = [4, 2, -3, 2] +| EVAL sa = mv_sort(a), sd = mv_sort(a, "DESC") +``` + +```esql +ROW names = ["Alice", "Bob", "Charlie"] +| EVAL sorted_names = mv_sort(names) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sum.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sum.txt new file mode 100644 index 0000000000000..8ee548edccc9c --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_sum.txt @@ -0,0 +1,15 @@ +## MV_SUM + +The `MV_SUM` function converts a multivalued field into a single valued field containing the sum of all of the values. + +### Examples + +```esql +ROW a=[3, 5, 6] +| EVAL sum_a = MV_SUM(a) +``` + +```esql +ROW numbers=[1, 2, 3, 4, 5] +| EVAL total_sum = MV_SUM(numbers) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_zip.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_zip.txt new file mode 100644 index 0000000000000..953519b4bd3fe --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-mv_zip.txt @@ -0,0 +1,17 @@ +## MV_ZIP + +The `MV_ZIP` function combines the values from two multivalued fields with a delimiter that joins them together. + +### Examples + +```esql +ROW a = ["x", "y", "z"], b = ["1", "2"] +| EVAL c = mv_zip(a, b, "-") +| KEEP a, b, c +``` + +```esql +ROW names = ["Alice", "Bob", "Charlie"], ids = ["001", "002", "003"] +| EVAL combined = mv_zip(names, ids, ":") +| KEEP names, ids, combined +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-now.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-now.txt new file mode 100644 index 0000000000000..165bcfe7af1dd --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-now.txt @@ -0,0 +1,14 @@ +## NOW + +The `NOW` function returns the current date and time. + +### Examples + +```esql +ROW current_date = NOW() +``` + +```esql +FROM sample_data +| WHERE @timestamp > NOW() - 1 hour +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-operators.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-operators.txt new file mode 100644 index 0000000000000..cc6c7f5bdf348 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-operators.txt @@ -0,0 +1,216 @@ +# ES|QL Operators + +## Binary Operators + +### Equality (`==`) +Check if two fields are equal. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE first_name == "John" +| KEEP first_name, last_name +``` + +### Inequality (`!=`) +Check if two fields are unequal. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE first_name != "John" +| KEEP first_name, last_name +``` + +### Less than (`<`) +Check if one field is less than another. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE age < 30 +| KEEP first_name, last_name, age +``` + +### Less than or equal to (`<=`) +Check if one field is less than or equal to another. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE age <= 30 +| KEEP first_name, last_name, age +``` + +### Greater than (`>`) +Check if one field is greater than another. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE age > 30 +| KEEP first_name, last_name, age +``` + +### Greater than or equal to (`>=`) +Check if one field is greater than or equal to another. If either field is multivalued, the result is null. This is pushed to the underlying search index if one side of the comparison is constant and the other side is a field in the index that has both an index and doc_values. + +#### Example: +```esql +FROM employees +| WHERE age >= 30 +| KEEP first_name, last_name, age +``` + +### Add (`+`) +Add two numbers together. If either field is multivalued, the result is null. + +#### Example: +```esql +FROM employees +| EVAL total_salary = base_salary + bonus +| KEEP first_name, last_name, total_salary +``` + +### Subtract (`-`) +Subtract one number from another. If either field is multivalued, the result is null. + +#### Example: +```esql +FROM employees +| EVAL net_salary = gross_salary - tax +| KEEP first_name, last_name, net_salary +``` + +### Multiply (`*`) +Multiply two numbers together. If either field is multivalued, the result is null. + +#### Example: +```esql +FROM employees +| EVAL annual_salary = monthly_salary * 12 +| KEEP first_name, last_name, annual_salary +``` + +### Divide (`/`) +Divide one number by another. If either field is multivalued, the result is null. Division of two integer types will yield an integer result, rounding towards 0. If you need floating point division, cast one of the arguments to a `DOUBLE`. + +#### Example: +```esql +FROM employees +| EVAL average_salary = total_salary / months_worked +| KEEP first_name, last_name, average_salary +``` + +### Modulus (`%`) +Divide one number by another and return the remainder. If either field is multivalued, the result is null. + +#### Example: +```esql +FROM employees +| EVAL remainder = total_days % 7 +| KEEP first_name, last_name, remainder +``` + +## Unary Operators + +### Negation (`-`) +The only unary operator is negation. + +#### Example: +```esql +FROM employees +| EVAL negative_salary = -salary +| KEEP first_name, last_name, negative_salary +``` + +## Logical Operators + +### AND +Logical AND operator. + +#### Example: +```esql +FROM employees +| WHERE age > 30 AND department == "Engineering" +| KEEP first_name, last_name, age, department +``` + +### OR +Logical OR operator. + +#### Example: +```esql +FROM employees +| WHERE age > 30 OR department == "Engineering" +| KEEP first_name, last_name, age, department +``` + +### NOT +Logical NOT operator. + +#### Example: +```esql +FROM employees +| WHERE NOT (age > 30) +| KEEP first_name, last_name, age +``` + +## Other Operators + +### IS NULL and IS NOT NULL +For NULL comparison, use the `IS NULL` and `IS NOT NULL` predicates. + +#### Example: +```esql +FROM employees +| WHERE birth_date IS NULL +| KEEP first_name, last_name +| SORT first_name +| LIMIT 3 +``` + +```esql +FROM employees +| WHERE is_rehired IS NOT NULL +| STATS COUNT(emp_no) +``` + +### Cast (`::`) +The `::` operator provides a convenient alternative syntax to the `TO_` conversion functions. + +#### Example: +```esql +ROW ver = CONCAT(("0"::INT + 1)::STRING, ".2.3")::VERSION +``` + +### IN +The `IN` operator allows testing whether a field or expression equals an element in a list of literals, fields, or expressions. + +#### Example: +```esql +ROW a = 1, b = 4, c = 3 +| WHERE c-a IN (3, b / 2, a) +``` + +### LIKE +Use `LIKE` to filter data based on string patterns using wildcards. The following wildcard characters are supported: +- `*` matches zero or more characters. +- `?` matches one character. + +#### Example: +```esql +FROM employees +| WHERE first_name LIKE "?b*" +| KEEP first_name, last_name +``` + +### RLIKE +Use `RLIKE` to filter data based on string patterns using regular expressions. + +#### Example: +```esql +FROM employees +| WHERE first_name RLIKE ".leja.*" +| KEEP first_name, last_name +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-overview.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-overview.txt new file mode 100644 index 0000000000000..32e82c7986480 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-overview.txt @@ -0,0 +1,144 @@ +## Overview + +### ES|QL + +The Elasticsearch Query Language (ES|QL) provides a powerful way to filter, transform, and analyze data stored in Elasticsearch, and in the future in other runtimes. It is designed to be easy to learn and use by end users, SRE teams, application developers, and administrators. + +Users can author ES|QL queries to find specific events, perform statistical analysis, and generate visualizations. It supports a wide range of commands and functions that enable users to perform various data operations, such as filtering, aggregation, time-series analysis, and more. + +ES|QL makes use of "pipes" (`|`) to manipulate and transform data in a step-by-step fashion. This approach allows users to compose a series of operations, where the output of one operation becomes the input for the next, enabling complex data transformations and analysis. + +### The ES|QL Compute Engine + +ES|QL is more than a language: it represents a significant investment in new compute capabilities within Elasticsearch. To achieve both the functional and performance requirements for ES|QL, it was necessary to build an entirely new compute architecture. ES|QL search, aggregation, and transformation functions are directly executed within Elasticsearch itself. Query expressions are not transpiled to Query DSL for execution. This approach allows ES|QL to be extremely performant and versatile. + +The new ES|QL execution engine was designed with performance in mind — it operates on blocks at a time instead of per row, targets vectorization and cache locality, and embraces specialization and multi-threading. It is a separate component from the existing Elasticsearch aggregation framework with different performance characteristics. + +### Known Limitations + +#### Result Set Size Limit + +By default, an ES|QL query returns up to 1000 rows. You can increase the number of rows up to 10,000 using the `LIMIT` command. Queries do not return more than 10,000 rows, regardless of the `LIMIT` command’s value. This limit only applies to the number of rows that are retrieved by the query. Queries and aggregations run on the full data set. + +To overcome this limitation: +- Reduce the result set size by modifying the query to only return relevant data. Use `WHERE` to select a smaller subset of the data. +- Shift any post-query processing to the query itself. You can use the ES|QL `STATS ... BY` command to aggregate data in the query. + +The default and maximum limits can be changed using these dynamic cluster settings: +- `esql.query.result_truncation_default_size` +- `esql.query.result_truncation_max_size` + +#### Field Types + +ES|QL currently supports the following field types: +- `alias` +- `boolean` +- `date` +- `double` (`float`, `half_float`, `scaled_float` are represented as `double`) +- `ip` +- `keyword` family including `keyword`, `constant_keyword`, and `wildcard` +- `int` (`short` and `byte` are represented as `int`) +- `long` +- `null` +- `text` +- `unsigned_long` (preview) +- `version` + +Spatial types: +- `geo_point` +- `geo_shape` +- `point` +- `shape` + +Unsupported types: +- TSDB metrics: `counter`, `position`, `aggregate_metric_double` +- Date/time: `date_nanos`, `date_range` +- Other types: `binary`, `completion`, `dense_vector`, `double_range`, `flattened`, `float_range`, `histogram`, `integer_range`, `ip_range`, `long_range`, `nested`, `rank_feature`, `rank_features`, `search_as_you_type` + +Querying a column with an unsupported type returns an error. If a column with an unsupported type is not explicitly used in a query, it is returned with `null` values, with the exception of nested fields. Nested fields are not returned at all. + +#### _source Availability + +ES|QL does not support configurations where the `_source` field is disabled. ES|QL’s support for synthetic `_source` is currently experimental. + +#### Full-Text Search + +Because of the way ES|QL treats `text` values, full-text search is not yet supported. Queries on `text` fields are like queries on `keyword` fields: they are case-sensitive and need to match the full string. + +#### Time Series Data Streams + +ES|QL does not support querying time series data streams (TSDS). + +#### Date Math Limitations + +Date math expressions work well when the leftmost expression is a datetime. However, using parentheses or putting the datetime to the right is not always supported yet. Date math does not allow subtracting two datetimes. + +#### Timezone Support + +ES|QL only supports the UTC timezone. + +### Cross-Cluster Querying + +Using ES|QL across clusters allows you to execute a single query across multiple clusters. This feature is in technical preview and may be changed or removed in a future release. + +#### Prerequisites + +- Remote clusters must be configured. +- The local coordinating node must have the `remote_cluster_client` node role. +- Security privileges must be configured appropriately. + +#### Querying Across Clusters + +In the `FROM` command, specify data streams and indices on remote clusters using the format `:`. For example: + +```esql +FROM cluster_one:my-index-000001 +| LIMIT 10 +``` + +### Using ES|QL in Kibana + +ES|QL can be used in Kibana to query and aggregate data, create visualizations, and set up alerts. + +#### Important Information + +- ES|QL is enabled by default in Kibana. +- The query bar in Discover allows you to write and execute ES|QL queries. +- The results table shows up to 10,000 rows, and Discover shows no more than 50 columns. +- You can create visualizations and alerts based on ES|QL queries. + +### Using the REST API + +The ES|QL query API allows you to execute ES|QL queries via REST API. + +#### Example + +```javascript +const response = await client.esql.query({ + query: ` + FROM library + | EVAL year = DATE_TRUNC(1 YEARS, release_date) + | STATS MAX(page_count) BY year + | SORT year + | LIMIT 5 + `, +}); +console.log(response); +``` + +#### Request + +`POST /_query` + +#### Request Body + +- `query` (Required): The ES|QL query to run. +- `format` (Optional): Format for the response. +- `params` (Optional): Values for parameters in the query. +- `profile` (Optional): If `true`, includes a `profile` object with information about query execution. + +#### Response + +- `columns`: Column `name` and `type` for each column returned in `values`. +- `rows`: Values for the search results. +- `profile`: Profile describing the execution of the query (if `profile` was sent in the request). \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-percentile.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-percentile.txt new file mode 100644 index 0000000000000..4873cace16392 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-percentile.txt @@ -0,0 +1,26 @@ +## PERCENTILE + +The `PERCENTILE` function returns the value at which a certain percentage of observed values occur. For example, the 95th percentile is the value which is greater than 95% of the observed values and the 50th percentile is the MEDIAN. + +### Examples + +```esql +FROM employees +| STATS p0 = PERCENTILE(salary, 0), p50 = PERCENTILE(salary, 50), p99 = PERCENTILE(salary, 99) +``` + +```esql +FROM employees +| STATS p80_max_salary_change = PERCENTILE(MV_MAX(salary_change), 80) +``` + +PERCENTILE is usually approximate. There are many different algorithms to calculate percentiles. The naive implementation simply stores all the values in a sorted array. To find the 50th percentile, you simply find the value that is at `my_array[count(my_array) * 0.5]`. Clearly, the naive implementation does not scale — the sorted array grows linearly with the number of values in your dataset. To calculate percentiles across potentially billions of values in an Elasticsearch cluster, approximate percentiles are calculated. The algorithm used by the percentile metric is called TDigest (introduced by Ted Dunning in Computing Accurate Quantiles using T-Digests). + +When using this metric, there are a few guidelines to keep in mind: +- Accuracy is proportional to q(1-q). This means that extreme percentiles (e.g. 99%) are more accurate than less extreme percentiles, such as the median. +- For small sets of values, percentiles are highly accurate (and potentially 100% accurate if the data is small enough). +- As the quantity of values in a bucket grows, the algorithm begins to approximate the percentiles. It is effectively trading accuracy for memory savings. The exact level of inaccuracy is difficult to generalize, since it depends on your data distribution and volume of data being aggregated. + +The following chart shows the relative error on a uniform distribution depending on the number of collected values and the requested percentile. It shows how precision is better for extreme percentiles. The reason why error diminishes for a large number of values is that the law of large numbers makes the distribution of values more and more uniform and the t-digest tree can do a better job at summarizing it. It would not be the case on more skewed distributions. + +PERCENTILE is also non-deterministic. This means you can get slightly different results using the same data. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pi.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pi.txt new file mode 100644 index 0000000000000..2afabb44200ea --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pi.txt @@ -0,0 +1,15 @@ +## PI + +The `PI` function returns Pi, the ratio of a circle’s circumference to its diameter. + +### Examples + +```esql +ROW PI() +``` + +```esql +FROM employees +| EVAL pi_value = PI() +| KEEP pi_value +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pow.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pow.txt new file mode 100644 index 0000000000000..43e021e4883e4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-pow.txt @@ -0,0 +1,15 @@ +## POW + +The `POW` function returns the value of a base raised to the power of an exponent. It is still possible to overflow a double result here; in that case, null will be returned. + +### Examples + +```esql +ROW base = 2.0, exponent = 2 +| EVAL result = POW(base, exponent) +``` + +```esql +ROW base = 4, exponent = 0.5 +| EVAL s = POW(base, exponent) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rename.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rename.txt new file mode 100644 index 0000000000000..0e9dd3258b3c8 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rename.txt @@ -0,0 +1,37 @@ +## RENAME + +The `RENAME` processing command in ES|QL is used to rename one or more columns in a dataset. This command is particularly useful when you need to standardize column names, make them more readable, or avoid conflicts with existing column names. If a column with the new name already exists, it will be replaced by the new column. If multiple columns are renamed to the same name, all but the rightmost column with the same new name are dropped. + +### Examples + +Here are some example ES|QL queries using the `RENAME` command: + +1. **Renaming a single column:** + + ```esql +FROM employees +| KEEP first_name, last_name, still_hired +| RENAME still_hired AS employed +``` + +2. **Renaming multiple columns in a single command:** + + ```esql +FROM employees +| KEEP first_name, last_name +| RENAME first_name AS fn, last_name AS ln +``` + +### Syntax + +`RENAME old_name1 AS new_name1[, ..., old_nameN AS new_nameN]` + +### Parameters + +- **old_nameX**: The name of a column you want to rename. +- **new_nameX**: The new name of the column. If it conflicts with an existing column name, the existing column is dropped. If multiple columns are renamed to the same name, all but the rightmost column with the same new name are dropped. + +### Limitations + +- If a column with the new name already exists, it will be replaced by the new column. +- If multiple columns are renamed to the same name, all but the rightmost column with the same new name are dropped. diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-repeat.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-repeat.txt new file mode 100644 index 0000000000000..aa702c052e1b7 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-repeat.txt @@ -0,0 +1,15 @@ +## REPEAT + +The `REPEAT` function returns a string constructed by concatenating the input string with itself the specified number of times. + +### Examples + +```esql +ROW a = "Hello!" +| EVAL triple_a = REPEAT(a, 3) +``` + +```esql +ROW greeting = "Hi" +| EVAL repeated_greeting = REPEAT(greeting, 5) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-replace.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-replace.txt new file mode 100644 index 0000000000000..931fcab1d25b9 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-replace.txt @@ -0,0 +1,19 @@ +## REPLACE + +The `REPLACE` function substitutes in the string `str` any match of the regular expression `regex` with the replacement string `newStr`. + +### Examples + +```esql +ROW str = "Hello World" +| EVAL str = REPLACE(str, "World", "Universe") +| KEEP str +``` + +Another example could be replacing digits in a string with a specific character: + +```esql +ROW str = "User123" +| EVAL str = REPLACE(str, "\\d", "*") +| KEEP str +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-right.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-right.txt new file mode 100644 index 0000000000000..99e1fbf2d3c1b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-right.txt @@ -0,0 +1,19 @@ +## RIGHT + +The `RIGHT` function returns a substring that extracts a specified number of characters from a string, starting from the right. + +### Examples + +```esql +FROM employees +| KEEP last_name +| EVAL right = RIGHT(last_name, 3) +| SORT last_name ASC +| LIMIT 5 +``` + +```esql +ROW full_name = "John Doe" +| EVAL last_part = RIGHT(full_name, 4) +| KEEP last_part +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-round.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-round.txt new file mode 100644 index 0000000000000..a3efefb84d2d0 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-round.txt @@ -0,0 +1,17 @@ +## ROUND + +The `ROUND` function rounds a number to the specified number of decimal places. By default, it rounds to 0 decimal places, which returns the nearest integer. If the precision is a negative number, it rounds to the number of digits left of the decimal point. If the input value is null, the function returns null. + +### Examples + +```esql +FROM employees +| KEEP first_name, last_name, height +| EVAL height_ft = ROUND(height * 3.281, 1) +``` + +```esql +FROM sales +| KEEP product_name, revenue +| EVAL rounded_revenue = ROUND(revenue, -2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-row.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-row.txt new file mode 100644 index 0000000000000..079668328f76d --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-row.txt @@ -0,0 +1,32 @@ +## ROW + +The `ROW` source command produces a row with one or more columns with values that you specify. This can be useful for testing. The command allows you to create a row with specified column names and values, which can be literals, expressions, or functions. In case of duplicate column names, only the rightmost duplicate creates a column. + +### Examples + +Here are some example ES|QL queries using the `ROW` command: + +1. Creating a row with simple literal values: + ```esql +ROW a = 1, b = "two", c = null +``` + +2. Creating a row with multi-value columns using square brackets: + ```esql +ROW a = [2, 1] +``` + +3. Creating a row with a function: + ```esql +ROW a = ROUND(1.23, 0) +``` + +4. Combining literals, multi-value columns, and functions: + ```esql +ROW x = 5, y = [3, 4], z = TO_STRING(123) +``` + +5. Using nested functions within a row: + ```esql +ROW a = ABS(-10), b = CONCAT("Hello", " ", "World"), c = TO_BOOLEAN("true") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rtrim.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rtrim.txt new file mode 100644 index 0000000000000..8060580a76ae0 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-rtrim.txt @@ -0,0 +1,13 @@ +## RTRIM + +Removes trailing whitespaces from a string. + +### Examples + +```esql +ROW message = " some text ", color = " red " +| EVAL message = RTRIM(message) +| EVAL color = RTRIM(color) +| EVAL message = CONCAT("'", message, "'") +| EVAL color = CONCAT("'", color, "'") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-show.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-show.txt new file mode 100644 index 0000000000000..ed27f65613931 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-show.txt @@ -0,0 +1,24 @@ +## SHOW + +The `SHOW` source command returns information about the deployment and its capabilities. This command is useful for retrieving metadata about the Elasticsearch deployment, such as the version, build date, and hash. It is particularly helpful for administrators and developers who need to verify the deployment details or troubleshoot issues. The `SHOW` command has a limitation in that it can only be used with the `INFO` item. + +### Examples + +Here are some example ES|QL queries using the `SHOW` command: + +1. Retrieve the deployment’s version, build date, and hash: + ```esql +SHOW INFO +``` + +2. Use the `SHOW` command in a multi-line query for better readability: + ```esql +SHOW INFO +``` + +3. Another example of using the `SHOW` command to get deployment information: + ```esql +SHOW INFO +``` + +These examples demonstrate the primary usage of the `SHOW` command to retrieve deployment information. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-signum.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-signum.txt new file mode 100644 index 0000000000000..4a1bab62699af --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-signum.txt @@ -0,0 +1,15 @@ +## SIGNUM + +The `SIGNUM` function returns the sign of the given number. It returns -1 for negative numbers, 0 for 0, and 1 for positive numbers. + +### Examples + +```esql +ROW d = 100.0 +| EVAL s = SIGNUM(d) +``` + +```esql +ROW d = -50.0 +| EVAL s = SIGNUM(d) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sin.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sin.txt new file mode 100644 index 0000000000000..2083ea8f29dad --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sin.txt @@ -0,0 +1,15 @@ +## SIN + +The `SIN` function returns the sine trigonometric function of an angle, expressed in radians. If the input angle is null, the function returns null. + +### Examples + +```esql +ROW a=1.8 +| EVAL sin = SIN(a) +``` + +```esql +ROW angle=0.5 +| EVAL sine_value = SIN(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sinh.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sinh.txt new file mode 100644 index 0000000000000..189fdb8a8b82f --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sinh.txt @@ -0,0 +1,15 @@ +## SINH + +The `SINH` function returns the hyperbolic sine of an angle. + +### Examples + +```esql +ROW a=1.8 +| EVAL sinh = SINH(a) +``` + +```esql +ROW angle=0.5 +| EVAL hyperbolic_sine = SINH(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sort.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sort.txt new file mode 100644 index 0000000000000..0d68d505a5d78 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sort.txt @@ -0,0 +1,53 @@ +## SORT + +The `SORT` processing command in ES|QL is used to sort a table based on one or more columns. This command is essential for organizing data in a specific order, which can be particularly useful for reporting, data analysis, and visualization. The default sort order is ascending, but you can specify descending order using `DESC`. Additionally, you can handle null values explicitly by using `NULLS FIRST` or `NULLS LAST`. + +### Use Cases +- **Organizing Data**: Sort data to make it easier to read and analyze. +- **Reporting**: Generate reports where data needs to be presented in a specific order. +- **Data Analysis**: Facilitate data analysis by sorting data based on key metrics. +- **Visualization**: Prepare data for visualizations that require sorted input. + +### Limitations +- **Multivalued Columns**: When sorting on multivalued columns, the lowest value is used for ascending order and the highest value for descending order. +- **Null Values**: By default, null values are treated as larger than any other value. This can be changed using `NULLS FIRST` or `NULLS LAST`. + +### Examples + +#### Basic Sorting +Sort the `employees` table by the `height` column in ascending order: + +```esql +FROM employees +| KEEP first_name, last_name, height +| SORT height +``` + +#### Explicit Ascending Order +Sort the `employees` table by the `height` column in descending order: + +```esql +FROM employees +| KEEP first_name, last_name, height +| SORT height DESC +``` + +#### Multiple Sort Expressions +Sort the `employees` table by the `height` column in descending order and use `first_name` as a tie breaker in ascending order: + +```esql +FROM employees +| KEEP first_name, last_name, height +| SORT height DESC, first_name ASC +``` + +#### Sorting Null Values First +Sort the `employees` table by the `first_name` column in ascending order, placing null values first: + +```esql +FROM employees +| KEEP first_name, last_name, height +| SORT first_name ASC NULLS FIRST +``` + +These examples demonstrate the versatility of the `SORT` command in organizing data for various analytical and reporting needs. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-split.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-split.txt new file mode 100644 index 0000000000000..d18750ac146f6 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-split.txt @@ -0,0 +1,15 @@ +## SPLIT + +The `SPLIT` function splits a single-valued string into multiple strings based on a specified delimiter. + +### Examples + +```esql +ROW words="foo;bar;baz;qux;quux;corge" +| EVAL word = SPLIT(words, ";") +``` + +```esql +ROW sentence="hello world;this is ES|QL" +| EVAL words = SPLIT(sentence, " ") +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sqrt.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sqrt.txt new file mode 100644 index 0000000000000..4988c31564633 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sqrt.txt @@ -0,0 +1,16 @@ +## SQRT + +The `SQRT` function returns the square root of a number. The input can be any numeric value, and the return value is always a double. Square roots of negative numbers and infinities are null. + +### Examples + +```esql +ROW d = 100.0 +| EVAL s = SQRT(d) +``` + +```esql +FROM employees +| KEEP first_name, last_name, height +| EVAL sqrt_height = SQRT(height) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_centroid_agg.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_centroid_agg.txt new file mode 100644 index 0000000000000..a58a2d6550e8a --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_centroid_agg.txt @@ -0,0 +1,15 @@ +## ST_CENTROID_AGG + +The `ST_CENTROID_AGG` function calculates the spatial centroid over a field with spatial point geometry type. + +### Examples + +```esql +FROM airports +| STATS centroid = ST_CENTROID_AGG(location) +``` + +```esql +FROM city_boundaries +| STATS city_centroid = ST_CENTROID_AGG(boundary) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_contains.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_contains.txt new file mode 100644 index 0000000000000..8d1dc8da115fc --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_contains.txt @@ -0,0 +1,17 @@ +## ST_CONTAINS + +Returns whether the first geometry contains the second geometry. This is the inverse of the `ST_WITHIN` function. + +### Examples + +```esql +FROM airport_city_boundaries +| WHERE ST_CONTAINS(city_boundary, TO_GEOSHAPE("POLYGON((109.35 18.3, 109.45 18.3, 109.45 18.4, 109.35 18.4, 109.35 18.3))")) +| KEEP abbrev, airport, region, city, city_location +``` + +```esql +FROM regions +| WHERE ST_CONTAINS(region_boundary, TO_GEOSHAPE("POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))")) +| KEEP region_name, region_code, region_boundary +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_disjoint.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_disjoint.txt new file mode 100644 index 0000000000000..7f22061024330 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_disjoint.txt @@ -0,0 +1,17 @@ +## ST_DISJOINT + +The `ST_DISJOINT` function returns whether two geometries or geometry columns are disjoint. This is the inverse of the `ST_INTERSECTS` function. In mathematical terms: `ST_Disjoint(A, B) ⇔ A ⋂ B = ∅`. + +### Examples + +```esql +FROM airport_city_boundaries +| WHERE ST_DISJOINT(city_boundary, TO_GEOSHAPE("POLYGON((-10 -60, 120 -60, 120 60, -10 60, -10 -60))")) +| KEEP abbrev, airport, region, city, city_location +``` + +```esql +FROM airport_city_boundaries +| WHERE ST_DISJOINT(city_boundary, TO_GEOSHAPE("POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))")) +| KEEP abbrev, airport, region, city, city_location +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_distance.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_distance.txt new file mode 100644 index 0000000000000..a1d3e05842c4a --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_distance.txt @@ -0,0 +1,19 @@ +## ST_DISTANCE + +The `ST_DISTANCE` function computes the distance between two points. For cartesian geometries, this is the pythagorean distance in the same units as the original coordinates. For geographic geometries, this is the circular distance along the great circle in meters. + +### Examples + +```esql +FROM airports +| WHERE abbrev == "CPH" +| EVAL distance = ST_DISTANCE(location, city_location) +| KEEP abbrev, name, location, city_location, distance +``` + +```esql +FROM airports +| WHERE abbrev == "JFK" +| EVAL distance = ST_DISTANCE(location, city_location) +| KEEP abbrev, name, location, city_location, distance +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_intersects.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_intersects.txt new file mode 100644 index 0000000000000..46df07d8d9f67 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_intersects.txt @@ -0,0 +1,16 @@ +## ST_INTERSECTS + +The `ST_INTERSECTS` function returns true if two geometries intersect. They intersect if they have any point in common, including their interior points (points along lines or within polygons). This is the inverse of the `ST_DISJOINT` function. In mathematical terms: `ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅`. + +### Examples + +```esql +FROM airports +| WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((42 14, 43 14, 43 15, 42 15, 42 14))")) +``` + +```esql +FROM city_boundaries +| WHERE ST_INTERSECTS(boundary, TO_GEOSHAPE("POLYGON((10 10, 20 10, 20 20, 10 20, 10 10))")) +| KEEP city_name, boundary +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_within.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_within.txt new file mode 100644 index 0000000000000..24883a731e24b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_within.txt @@ -0,0 +1,17 @@ +## ST_WITHIN + +The `ST_WITHIN` function returns whether the first geometry is within the second geometry. This is the inverse of the `ST_CONTAINS` function. + +### Examples + +```esql +FROM airport_city_boundaries +| WHERE ST_WITHIN(city_boundary, TO_GEOSHAPE("POLYGON((109.1 18.15, 109.6 18.15, 109.6 18.65, 109.1 18.65, 109.1 18.15))")) +| KEEP abbrev, airport, region, city, city_location +``` + +```esql +FROM parks +| WHERE ST_WITHIN(park_boundary, TO_GEOSHAPE("POLYGON((40.7128 -74.0060, 40.7128 -73.9352, 40.7306 -73.9352, 40.7306 -74.0060, 40.7128 -74.0060))")) +| KEEP park_name, park_boundary +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_x.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_x.txt new file mode 100644 index 0000000000000..11b569d7db065 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_x.txt @@ -0,0 +1,15 @@ +## ST_X + +The `ST_X` function extracts the x coordinate from the supplied point. If the point is of type `geo_point`, this is equivalent to extracting the longitude value. + +### Examples + +```esql +ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)") +| EVAL x = ST_X(point), y = ST_Y(point) +``` + +```esql +ROW point = TO_CARTESIANPOINT("POINT(100.0 200.0)") +| EVAL x = ST_X(point), y = ST_Y(point) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_y.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_y.txt new file mode 100644 index 0000000000000..be0b96539bf15 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-st_y.txt @@ -0,0 +1,15 @@ +## ST_Y + +The `ST_Y` function extracts the y coordinate from the supplied point. If the point is of type `geo_point`, this is equivalent to extracting the latitude value. + +### Examples + +```esql +ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)") +| EVAL x = ST_X(point), y = ST_Y(point) +``` + +```esql +ROW point = TO_GEOPOINT("POINT(34.052235 -118.243683)") +| EVAL latitude = ST_Y(point) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-starts_with.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-starts_with.txt new file mode 100644 index 0000000000000..a293c13d1d706 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-starts_with.txt @@ -0,0 +1,18 @@ +## STARTS_WITH + +The `STARTS_WITH` function returns a boolean that indicates whether a keyword string starts with another string. + +### Examples + +```esql +FROM employees +| KEEP last_name +| EVAL ln_S = STARTS_WITH(last_name, "B") +``` + +```esql +FROM employees +| KEEP first_name, last_name +| EVAL fn_S = STARTS_WITH(first_name, "A") +| WHERE fn_S +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-stats.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-stats.txt new file mode 100644 index 0000000000000..a85669b4b3fa1 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-stats.txt @@ -0,0 +1,71 @@ +## STATS + +The `STATS ... BY` processing command in ES|QL groups rows according to a common value and calculates one or more aggregated values over the grouped rows. This command is highly useful for performing statistical analysis and aggregations on datasets. It supports a variety of aggregation functions such as `AVG`, `COUNT`, `COUNT_DISTINCT`, `MAX`, `MEDIAN`, `MIN`, `SUM`, and more. + +### Use Cases +- **Statistical Analysis**: Calculate average, sum, count, and other statistical measures over grouped data. +- **Data Aggregation**: Aggregate data based on specific fields to derive meaningful insights. +- **Time-Series Analysis**: Group data by time intervals to analyze trends over time. + +### Limitations +- **Performance**: `STATS` without any groups is much faster than adding a group. Grouping on a single expression is more optimized than grouping on multiple expressions. +- **Multivalue Fields**: If the grouping key is multivalued, the input row is included in all groups. +- **Technical Preview**: Some functions like `PERCENTILE`, `ST_CENTROID_AGG`, `VALUES`, and `WEIGHTED_AVG` are in technical preview and may change in future releases. + +### Examples + +#### Example 1: Grouping by a Single Column +Calculate the count of employees grouped by languages: + +```esql +FROM employees +| STATS count = COUNT(emp_no) BY languages +| SORT languages +``` + +#### Example 2: Aggregation Without Grouping +Calculate the average number of languages spoken by employees: + +```esql +FROM employees +| STATS avg_lang = AVG(languages) +``` + +#### Example 3: Multiple Aggregations +Calculate both the average and maximum number of languages spoken by employees: + +```esql +FROM employees +| STATS avg_lang = AVG(languages), max_lang = MAX(languages) +``` + +#### Example 4: Grouping by Multiple Values +Calculate the average salary grouped by the year of hire and language: + +```esql +FROM employees +| EVAL hired = DATE_FORMAT("YYYY", hire_date) +| STATS avg_salary = AVG(salary) BY hired, languages.long +| EVAL avg_salary = ROUND(avg_salary) +| SORT hired, languages.long +``` + +#### Example 5: Grouping by an Expression +Group employees by the first letter of their last name and count them: + +```esql +FROM employees +| STATS my_count = COUNT() BY LEFT(last_name, 1) +| SORT `LEFT(last_name, 1)` +``` + +#### Example 6: Using Multivalue Columns +Calculate the minimum value of a multivalue column: + +```esql +ROW i=1, a=["a", "b"], b=[2, 3] +| STATS MIN(i) BY a, b +| SORT a ASC, b ASC +``` + +These examples showcase the versatility and power of the `STATS ... BY` command in performing various types of data aggregations and statistical analyses. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-substring.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-substring.txt new file mode 100644 index 0000000000000..a03574e7d2cef --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-substring.txt @@ -0,0 +1,39 @@ +## SUBSTRING + +The `SUBSTRING` function returns a substring of a string, specified by a start position and an optional length. + +### Syntax + +`SUBSTRING(string, start, [length])` + +### Parameters + +- `string`: String expression. If null, the function returns null. +- `start`: Start position. +- `length`: Length of the substring from the start position. Optional; if omitted, all positions after start are returned. + +### Examples + +This example returns the first three characters of every last name: + +```esql +FROM employees +| KEEP last_name +| EVAL ln_sub = SUBSTRING(last_name, 1, 3) +``` + +A negative start position is interpreted as being relative to the end of the string. This example returns the last three characters of every last name: + +```esql +FROM employees +| KEEP last_name +| EVAL ln_sub = SUBSTRING(last_name, -3, 3) +``` + +If length is omitted, `SUBSTRING` returns the remainder of the string. This example returns all characters except for the first: + +```esql +FROM employees +| KEEP last_name +| EVAL ln_sub = SUBSTRING(last_name, 2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sum.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sum.txt new file mode 100644 index 0000000000000..c893aeb160d00 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-sum.txt @@ -0,0 +1,15 @@ +## SUM + +The `SUM` function calculates the sum of a numeric expression. + +### Examples + +```esql +FROM employees +| STATS SUM(languages) +``` + +```esql +FROM employees +| STATS total_salary_changes = SUM(MV_MAX(salary_change)) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-syntax.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-syntax.txt new file mode 100644 index 0000000000000..e1e339239a713 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-syntax.txt @@ -0,0 +1,181 @@ +## Syntax + +### Instructions + +Generate a description of ES|QL syntax. Be as complete as possible. +For timespan literals, generate at least five examples of full ES|QL queries, using a mix of commands and functions, using different intervals and units. +**Make sure you use timespan literals, such as `1 day` or `24h` or `7 weeks` in these examples**. +Combine ISO timestamps with time span literals and NOW(). +Make sure the example queries are using different combinations of syntax, commands, and functions for each. +When using DATE_TRUNC, make sure you DO NOT wrap the timespan in single or double quotes. +Do not use the Cast operator. + +### Content of file + +### ES|QL Syntax Reference + +#### Basic Syntax + +An ES|QL query is composed of a source command followed by an optional series of processing commands, separated by a pipe character: `|`. For example: + +``` +source-command +| processing-command1 +| processing-command2 +``` + +The result of a query is the table produced by the final processing command. For an overview of all supported commands, functions, and operators, refer to Commands and Functions and operators. + +For readability, this documentation puts each processing command on a new line. However, you can write an ES|QL query as a single line. The following query is identical to the previous one: + +``` +source-command +| processing-command1 +| processing-command2 +``` + +#### Identifiers + +Identifiers need to be quoted with backticks (```) if: +- They don’t start with a letter, `_` or `@` +- Any of the other characters is not a letter, number, or `_` + +For example: + +```esql +FROM index +| KEEP `1.field` +``` + +When referencing a function alias that itself uses a quoted identifier, the backticks of the quoted identifier need to be escaped with another backtick. For example: + +```esql +FROM index +| STATS COUNT(`1.field`) +| EVAL my_count = `COUNT(``1.field``)` +``` + +#### Literals + +ES|QL currently supports numeric and string literals. + +##### String Literals + +A string literal is a sequence of unicode characters delimited by double quotes (`"`). + +```esql +// Filter by a string value +FROM index +| WHERE first_name == "Georgi" +``` + +If the literal string itself contains quotes, these need to be escaped (`\\"`). ES|QL also supports the triple-quotes (`"""`) delimiter, for convenience: + +```esql +ROW name = """Indiana "Indy" Jones""" +``` + +The special characters CR, LF, and TAB can be provided with the usual escaping: `\r`, `\n`, `\t`, respectively. + +##### Numerical Literals + +The numeric literals are accepted in decimal and in the scientific notation with the exponent marker (`e` or `E`), starting either with a digit, decimal point `.` or the negative sign `-`: + +- `1969` -- integer notation +- `3.14` -- decimal notation +- `.1234` -- decimal notation starting with decimal point +- `4E5` -- scientific notation (with exponent marker) +- `1.2e-3` -- scientific notation with decimal point +- `-.1e2` -- scientific notation starting with the negative sign + +The integer numeric literals are implicitly converted to the `integer`, `long` or the `double` type, whichever can first accommodate the literal’s value. The floating point literals are implicitly converted to the `double` type. To obtain constant values of different types, use one of the numeric conversion functions. + +#### Comments + +ES|QL uses C++ style comments: +- Double slash `//` for single line comments +- `/*` and `*/` for block comments + +```esql +// Query the employees index +FROM employees +| WHERE height > 2 +``` + +```esql +FROM /* Query the employees index */ employees +| WHERE height > 2 +``` + +```esql +FROM employees +/* Query the + * employees + * index */ +| WHERE height > 2 +``` + +#### Timespan Literals + +Datetime intervals and timespans can be expressed using timespan literals. Timespan literals are a combination of a number and a qualifier. These qualifiers are supported: +- `millisecond`/`milliseconds`/`ms` +- `second`/`seconds`/`sec`/`s` +- `minute`/`minutes`/`min` +- `hour`/`hours`/`h` +- `day`/`days`/`d` +- `week`/`weeks`/`w` +- `month`/`months`/`mo` +- `quarter`/`quarters`/`q` +- `year`/`years`/`yr`/`y` + +Timespan literals are not whitespace sensitive. These expressions are all valid: +- `1day` +- `1 day` +- `1 day` + +#### Example Queries Using Timespan Literals + +1. Retrieve logs from the last 24 hours and calculate the average response time: + + ```esql +FROM logs-* +| WHERE @timestamp > NOW() - 24h +| STATS avg_response_time = AVG(response_time) +``` + +2. Get the count of events per day for the last 7 days: + + ```esql +FROM events +| WHERE @timestamp > NOW() - 7 days +| STATS daily_count = COUNT(*) BY day = DATE_TRUNC(1 day, @timestamp) +| SORT day +``` + +3. Find the maximum temperature recorded in the last month: + + ```esql +FROM weather_data +| WHERE @timestamp > NOW() - 1 month +| STATS max_temp = MAX(temperature) +``` + +4. Calculate the total sales for each week in the last quarter: + + ```esql +FROM sales +| WHERE @timestamp > NOW() - 1 quarter +| STATS weekly_sales = SUM(sales_amount) BY week = DATE_TRUNC(1 week, @timestamp) +| SORT week +``` + +5. Retrieve error logs from the last 15 minutes and group by error type: + + ```esql +FROM error_logs +| WHERE @timestamp > NOW() - 15 minutes +| STATS error_count = COUNT(*) BY error_type +| SORT error_count DESC +``` + +These examples demonstrate the use of timespan literals in combination with various ES|QL commands and functions to perform different types of data queries and transformations. diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tan.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tan.txt new file mode 100644 index 0000000000000..8541f193d89a4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tan.txt @@ -0,0 +1,15 @@ +## TAN + +The `TAN` function returns the Tangent trigonometric function of an angle. + +### Examples + +```esql +ROW a=1.8 +| EVAL tan = TAN(a) +``` + +```esql +ROW angle=0.5 +| EVAL tangent = TAN(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tanh.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tanh.txt new file mode 100644 index 0000000000000..45fc52fa501a7 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tanh.txt @@ -0,0 +1,15 @@ +## TANH + +The `TANH` function returns the hyperbolic tangent of an angle, expressed in radians. If the input angle is null, the function returns null. + +### Examples + +```esql +ROW a=1.8 +| EVAL tanh = TANH(a) +``` + +```esql +ROW angle=0.5 +| EVAL hyperbolic_tangent = TANH(angle) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tau.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tau.txt new file mode 100644 index 0000000000000..149d1333b2a1a --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-tau.txt @@ -0,0 +1,15 @@ +## TAU + +The `TAU` function returns the ratio of a circle’s circumference to its radius. + +### Examples + +```esql +ROW TAU() +``` + +```esql +FROM sample_data +| EVAL tau_value = TAU() +| KEEP tau_value +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_base64.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_base64.txt new file mode 100644 index 0000000000000..e0c64eba07d58 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_base64.txt @@ -0,0 +1,15 @@ +## TO_BASE64 + +Encodes a string to a base64 string. + +### Examples + +```esql +ROW a = "elastic" +| EVAL e = TO_BASE64(a) +``` + +```esql +ROW text = "Hello, World!" +| EVAL encoded_text = TO_BASE64(text) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_boolean.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_boolean.txt new file mode 100644 index 0000000000000..9a243ba128fb9 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_boolean.txt @@ -0,0 +1,15 @@ +## TO_BOOLEAN + +The `TO_BOOLEAN` function converts an input value to a boolean value. A string value of "true" will be case-insensitively converted to the Boolean `true`. For anything else, including the empty string, the function will return `false`. The numerical value of `0` will be converted to `false`, and anything else will be converted to `true`. + +### Examples + +```esql +ROW str = ["true", "TRuE", "false", "", "yes", "1"] +| EVAL bool = TO_BOOLEAN(str) +``` + +```esql +ROW num = [0, 1, 2, -1] +| EVAL bool = TO_BOOLEAN(num) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianpoint.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianpoint.txt new file mode 100644 index 0000000000000..db56fd5fc67f4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianpoint.txt @@ -0,0 +1,17 @@ +## TO_CARTESIANPOINT + +Converts an input value to a `cartesian_point` value. A string will only be successfully converted if it respects the WKT Point format. + +### Examples + +```esql +ROW wkt = ["POINT(4297.11 -1475.53)", "POINT(7580.93 2272.77)"] +| MV_EXPAND wkt +| EVAL pt = TO_CARTESIANPOINT(wkt) +``` + +```esql +ROW wkt = ["POINT(1000.0 2000.0)", "POINT(3000.0 4000.0)"] +| MV_EXPAND wkt +| EVAL pt = TO_CARTESIANPOINT(wkt) +``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianshape.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianshape.txt similarity index 52% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianshape.txt rename to x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianshape.txt index 8e16ba92a8e7b..f32af0a6d4805 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianshape.txt +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_cartesianshape.txt @@ -1,18 +1,17 @@ ## TO_CARTESIANSHAPE -The `TO_CARTESIANSHAPE` function converts an input value to a `cartesian_shape` value. A string will only be successfully converted if it respects the WKT format. +Converts an input value to a `cartesian_shape` value. A string will only be successfully converted if it respects the WKT format. ### Examples -Here are a couple of examples of full ES|QL queries using the `TO_CARTESIANSHAPE` function: - ```esql -ROW wkt = "POINT(4297.11 -1475.53)" +ROW wkt = ["POINT(4297.11 -1475.53)", "POLYGON ((3339584.72 1118889.97, 4452779.63 4865942.27, 2226389.81 4865942.27, 1113194.90 2273030.92, 3339584.72 1118889.97))"] +| MV_EXPAND wkt | EVAL geom = TO_CARTESIANSHAPE(wkt) ``` ```esql -ROW wkt = ["POINT(4297.11 -1475.53)", "POLYGON ((3339584.72 1118889.97, 4452779.63 4865942.27, 2226389.81 4865942.27, 1113194.90 2273030.92, 3339584.72 1118889.97))"] +ROW wkt = ["POINT(1000.0 2000.0)", "POLYGON ((1000.0 2000.0, 2000.0 3000.0, 3000.0 4000.0, 1000.0 2000.0))"] | MV_EXPAND wkt | EVAL geom = TO_CARTESIANSHAPE(wkt) ``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_datetime.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_datetime.txt new file mode 100644 index 0000000000000..7e0cd1fc82c06 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_datetime.txt @@ -0,0 +1,19 @@ +## TO_DATETIME + +Converts an input value to a date value. A string will only be successfully converted if it’s respecting the format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. To convert dates in other formats, use `DATE_PARSE`. + +### Examples + +```esql +ROW string = ["1953-09-02T00:00:00.000Z", "1964-06-02T00:00:00.000Z", "1964-06-02 00:00:00"] +| EVAL datetime = TO_DATETIME(string) +``` + +Note that in this example, the last value in the source multi-valued field has not been converted. The reason being that if the date format is not respected, the conversion will result in a null value. When this happens a Warning header is added to the response. The header will provide information on the source of the failure: "Line 1:112: evaluation of [TO_DATETIME(string)] failed, treating result as null. Only first 20 failures recorded." A following header will contain the failure reason and the offending value: "java.lang.IllegalArgumentException: failed to parse date field [1964-06-02 00:00:00] with format [yyyy-MM-dd'T'HH:mm:ss.SSS'Z']". + +```esql +ROW int = [0, 1] +| EVAL dt = TO_DATETIME(int) +``` + +If the input parameter is of a numeric type, its value will be interpreted as milliseconds since the Unix epoch. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_degrees.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_degrees.txt new file mode 100644 index 0000000000000..287e526f143e5 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_degrees.txt @@ -0,0 +1,15 @@ +## TO_DEGREES + +Converts a number in radians to degrees. + +### Examples + +```esql +ROW rad = [1.57, 3.14, 4.71] +| EVAL deg = TO_DEGREES(rad) +``` + +```esql +ROW angle_in_radians = 1.0 +| EVAL angle_in_degrees = TO_DEGREES(angle_in_radians) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_double.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_double.txt new file mode 100644 index 0000000000000..c835ee9531281 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_double.txt @@ -0,0 +1,14 @@ +## TO_DOUBLE + +Converts an input value to a double value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to double. Boolean true will be converted to double 1.0, false to 0.0. + +### Examples + +```esql +ROW str1 = "5.20128E11", str2 = "foo" +| EVAL dbl = TO_DOUBLE("520128000000"), dbl1 = TO_DOUBLE(str1), dbl2 = TO_DOUBLE(str2) +``` + +Note that in this example, the last conversion of the string isn’t possible. When this happens, the result is a null value. In this case, a Warning header is added to the response. The header will provide information on the source of the failure: +"Line 1:115: evaluation of [TO_DOUBLE(str2)] failed, treating result as null. Only first 20 failures recorded." A following header will contain the failure reason and the offending value: +"java.lang.NumberFormatException: For input string: "foo"" \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geopoint.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geopoint.txt new file mode 100644 index 0000000000000..27cc2b7569742 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geopoint.txt @@ -0,0 +1,15 @@ +## TO_GEOPOINT + +Converts an input value to a `geo_point` value. A string will only be successfully converted if it respects the WKT Point format. + +### Examples + +```esql +ROW wkt = "POINT(42.97109630194 14.7552534413725)" +| EVAL pt = TO_GEOPOINT(wkt) +``` + +```esql +ROW wkt = "POINT(34.052235 -118.243683)" +| EVAL pt = TO_GEOPOINT(wkt) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geoshape.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geoshape.txt new file mode 100644 index 0000000000000..9160e081f6477 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_geoshape.txt @@ -0,0 +1,15 @@ +## TO_GEOSHAPE + +Converts an input value to a `geo_shape` value. A string will only be successfully converted if it respects the WKT format. + +### Examples + +```esql +ROW wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))" +| EVAL geom = TO_GEOSHAPE(wkt) +``` + +```esql +ROW wkt = "LINESTRING (30 10, 10 30, 40 40)" +| EVAL geom = TO_GEOSHAPE(wkt) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_integer.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_integer.txt new file mode 100644 index 0000000000000..3944c64ee004b --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_integer.txt @@ -0,0 +1,12 @@ +## TO_INTEGER + +Converts an input value to an integer value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to integer. Boolean true will be converted to integer 1, false to 0. + +### Examples + +```esql +ROW long = [5013792, 2147483647, 501379200000] +| EVAL int = TO_INTEGER(long) +``` + +Note that in this example, the last value of the multi-valued field cannot be converted as an integer. When this happens, the result is a null value. In this case, a Warning header is added to the response. The header will provide information on the source of the failure: "Line 1:61: evaluation of [TO_INTEGER(long)] failed, treating result as null. Only first 20 failures recorded." A following header will contain the failure reason and the offending value: "org.elasticsearch.xpack.esql.core.InvalidArgumentException: [501379200000] out of [integer] range" \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_ip.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_ip.txt new file mode 100644 index 0000000000000..af3d8b754d88e --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_ip.txt @@ -0,0 +1,21 @@ +## TO_IP + +The `TO_IP` function converts an input string to an IP value. + +### Examples + +```esql +ROW str1 = "1.1.1.1", str2 = "foo" +| EVAL ip1 = TO_IP(str1), ip2 = TO_IP(str2) +| WHERE CIDR_MATCH(ip1, "1.0.0.0/8") +``` + +Note that in this example, the last conversion of the string isn’t possible. When this happens, the result is a null value. In this case, a Warning header is added to the response. The header will provide information on the source of the failure: "Line 1:68: evaluation of [TO_IP(str2)] failed, treating result as null. Only first 20 failures recorded." A following header will contain the failure reason and the offending value: "java.lang.IllegalArgumentException: 'foo' is not an IP string literal." + +```esql +ROW ip_str = "192.168.1.1" +| EVAL ip = TO_IP(ip_str) +| KEEP ip +``` + +In this example, the string "192.168.1.1" is successfully converted to an IP value and kept in the result set. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_long.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_long.txt new file mode 100644 index 0000000000000..b5fd5788be666 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_long.txt @@ -0,0 +1,17 @@ +## TO_LONG + +Converts an input value to a long value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to long. Boolean true will be converted to long 1, false to 0. + +### Examples + +```esql +ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo" +| EVAL long1 = TO_LONG(str1), long2 = TO_LONG(str2), long3 = TO_LONG(str3) +``` + +Note that in this example, the last conversion of the string isn’t possible. When this happens, the result is a null value. In this case, a Warning header is added to the response. The header will provide information on the source of the failure: "Line 1:113: evaluation of [TO_LONG(str3)] failed, treating result as null. Only first 20 failures recorded." A following header will contain the failure reason and the offending value: "java.lang.NumberFormatException: For input string: "foo"" + +```esql +ROW str1 = "1234567890", str2 = "9876543210" +| EVAL long1 = TO_LONG(str1), long2 = TO_LONG(str2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_lower.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_lower.txt new file mode 100644 index 0000000000000..26be9d76088df --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_lower.txt @@ -0,0 +1,17 @@ +## TO_LOWER + +The `TO_LOWER` function returns a new string representing the input string converted to lower case. + +### Examples + +```esql +ROW message = "Some Text" +| EVAL message_lower = TO_LOWER(message) +``` + +```esql +FROM employees +| KEEP first_name, last_name +| EVAL first_name_lower = TO_LOWER(first_name) +| EVAL last_name_lower = TO_LOWER(last_name) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_radians.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_radians.txt new file mode 100644 index 0000000000000..d0c90d3739998 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_radians.txt @@ -0,0 +1,15 @@ +## TO_RADIANS + +Converts a number in degrees to radians. + +### Examples + +```esql +ROW deg = [90.0, 180.0, 270.0] +| EVAL rad = TO_RADIANS(deg) +``` + +```esql +ROW angle_deg = 45.0 +| EVAL angle_rad = TO_RADIANS(angle_deg) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_string.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_string.txt new file mode 100644 index 0000000000000..b2ee6a7a7f106 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_string.txt @@ -0,0 +1,15 @@ +## TO_STRING + +Converts an input value into a string. + +### Examples + +```esql +ROW a=10 +| EVAL j = TO_STRING(a) +``` + +```esql +ROW a=[10, 9, 8] +| EVAL j = TO_STRING(a) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_unsigned_long.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_unsigned_long.txt new file mode 100644 index 0000000000000..7702b6f8da228 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_unsigned_long.txt @@ -0,0 +1,20 @@ +## TO_UNSIGNED_LONG + +Converts an input value to an unsigned long value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to unsigned long. Boolean true will be converted to unsigned long 1, false to 0. + +### Examples + +```esql +ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo" +| EVAL long1 = TO_UNSIGNED_LONG(str1), long2 = TO_ULONG(str2), long3 = TO_UL(str3) +``` + +Note that in this example, the last conversion of the string isn’t possible. When this happens, the result is a null value. In this case, a Warning header is added to the response. The header will provide information on the source of the failure: +"Line 1:133: evaluation of [TO_UL(str3)] failed, treating result as null. Only first 20 failures recorded." +A following header will contain the failure reason and the offending value: +"java.lang.NumberFormatException: Character f is neither a decimal digit number, decimal point, nor "e" notation exponential mark." + +```esql +ROW date1 = TO_DATETIME("2023-12-02T11:00:00.000Z"), date2 = TO_DATETIME("2023-12-02T11:00:00.001Z") +| EVAL long_date1 = TO_UNSIGNED_LONG(date1), long_date2 = TO_UNSIGNED_LONG(date2) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_upper.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_upper.txt new file mode 100644 index 0000000000000..d563e9efa59b4 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_upper.txt @@ -0,0 +1,17 @@ +## TO_UPPER + +The `TO_UPPER` function returns a new string representing the input string converted to upper case. + +### Examples + +```esql +ROW message = "Some Text" +| EVAL message_upper = TO_UPPER(message) +``` + +```esql +FROM employees +| KEEP first_name, last_name +| EVAL first_name_upper = TO_UPPER(first_name) +| EVAL last_name_upper = TO_UPPER(last_name) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_version.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_version.txt new file mode 100644 index 0000000000000..2fb20b0686723 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-to_version.txt @@ -0,0 +1,14 @@ +## TO_VERSION + +Converts an input string to a version value. + +### Examples + +```esql +ROW v = TO_VERSION("1.2.3") +``` + +```esql +ROW version_string = "2.3.4" +| EVAL version = TO_VERSION(version_string) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-top.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-top.txt new file mode 100644 index 0000000000000..6b18788f4b6ac --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-top.txt @@ -0,0 +1,25 @@ +## TOP + +The `TOP` function collects the top values for a specified field. It includes repeated values and allows you to specify the maximum number of values to collect and the order in which to sort them (either ascending or descending). + +### Syntax + +`TOP(field, limit, order)` + +### Parameters + +- **field**: The field to collect the top values for. +- **limit**: The maximum number of values to collect. +- **order**: The order to calculate the top values. Either `asc` or `desc`. + +### Examples + +```esql +FROM employees +| STATS top_salaries = TOP(salary, 3, "desc"), top_salary = MAX(salary) +``` + +```esql +FROM sales +| STATS top_products = TOP(product_id, 5, "asc"), max_sales = MAX(sales_amount) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-trim.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-trim.txt new file mode 100644 index 0000000000000..bec5cce253909 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-trim.txt @@ -0,0 +1,17 @@ +## TRIM + +Removes leading and trailing whitespaces from a string. + +### Examples + +```esql +ROW message = " some text ", color = " red " +| EVAL message = TRIM(message) +| EVAL color = TRIM(color) +``` + +```esql +ROW text = " example text ", label = " label " +| EVAL text = TRIM(text) +| EVAL label = TRIM(label) +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-values.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-values.txt new file mode 100644 index 0000000000000..a4acd2c397104 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-values.txt @@ -0,0 +1,16 @@ +## VALUES + +`VALUES` returns all values in a group as a multivalued field. The order of the returned values isn’t guaranteed. If you need the values returned in order, use `MV_SORT`. + +**Note:** Do not use `VALUES` in 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. + +### Examples + +```esql +FROM employees +| EVAL first_letter = SUBSTRING(first_name, 0, 1) +| STATS first_name = MV_SORT(VALUES(first_name)) BY first_letter +| SORT first_letter +``` + +This can use a significant amount of memory and ES|QL doesn’t yet grow aggregations beyond memory. So this aggregation will work until it is used to collect more values than can fit into memory. Once it collects too many values it will fail the query with a Circuit Breaker Error. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-weighted_avg.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-weighted_avg.txt new file mode 100644 index 0000000000000..9030159ff728c --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-weighted_avg.txt @@ -0,0 +1,21 @@ +## WEIGHTED_AVG + +The `WEIGHTED_AVG` function calculates the weighted average of a numeric expression. + +### Examples + +```esql +FROM employees +| STATS w_avg = WEIGHTED_AVG(salary, height) BY languages +| EVAL w_avg = ROUND(w_avg) +| KEEP w_avg, languages +| SORT languages +``` + +```esql +FROM sales +| STATS weighted_sales = WEIGHTED_AVG(revenue, units_sold) BY region +| EVAL weighted_sales = ROUND(weighted_sales, 2) +| KEEP weighted_sales, region +| SORT region +``` \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-where.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-where.txt new file mode 100644 index 0000000000000..7a772aed34bb3 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/esql_docs/esql-where.txt @@ -0,0 +1,77 @@ +## WHERE + +The `WHERE` processing command produces a table that contains all the rows from the input table for which the provided condition evaluates to true. This command is essential for filtering data based on specific criteria, making it highly useful for narrowing down datasets to relevant records. It supports various functions and operators, including boolean expressions, date math, string patterns, and NULL comparisons. + +### Use Cases +- Filtering records based on boolean conditions. +- Retrieving data within a specific time range using date math. +- Filtering data based on string patterns using wildcards or regular expressions. +- Performing NULL comparisons. +- Testing whether a field or expression equals an element in a list of literals, fields, or expressions. + +### Limitations +- The `WHERE` command is subject to the limitations of ES|QL, such as the maximum number of rows returned (10,000) and the types of fields supported. + +### Examples + +#### Example 1: Filtering Based on Boolean Condition +```esql +FROM employees +| KEEP first_name, last_name, still_hired +| WHERE still_hired == true +``` +If `still_hired` is a boolean field, this can be simplified to: +```esql +FROM employees +| KEEP first_name, last_name, still_hired +| WHERE still_hired +``` + +#### Example 2: Retrieving Data from a Specific Time Range +```esql +FROM sample_data +| WHERE @timestamp > NOW() - 1 hour +``` + +#### Example 3: Using Functions in WHERE Clause +```esql +FROM employees +| KEEP first_name, last_name, height +| WHERE LENGTH(first_name) < 4 +``` + +#### Example 4: NULL Comparison +```esql +FROM employees +| WHERE birth_date IS NULL +| KEEP first_name, last_name +| SORT first_name +| LIMIT 3 +``` +```esql +FROM employees +| WHERE is_rehired IS NOT NULL +| STATS COUNT(emp_no) +``` + +#### Example 5: Filtering Based on String Patterns Using Wildcards +```esql +FROM employees +| WHERE first_name LIKE "?b*" +| KEEP first_name, last_name +``` + +#### Example 6: Filtering Based on String Patterns Using Regular Expressions +```esql +FROM employees +| WHERE first_name RLIKE ".leja.*" +| KEEP first_name, last_name +``` + +#### Example 7: Using IN Operator +```esql +ROW a = 1, b = 4, c = 3 +| WHERE c-a IN (3, b / 2, a) +``` + +For a complete list of all functions and operators, refer to the Functions overview and Operators documentation. \ No newline at end of file diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts b/x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts index 00ce53fe5d288..2d6fe4ca7dac3 100644 --- a/x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/index.ts @@ -5,93 +5,260 @@ * 2.0. */ -import { switchMap, map } from 'rxjs'; -import { MessageRole } from '../../../common/chat_complete'; -import { ToolOptions } from '../../../common/chat_complete/tools'; -import { withoutChunkEvents } from '../../../common/chat_complete/without_chunk_events'; +import type { Logger } from '@kbn/logging'; +import { isEmpty, mapValues, pick } from 'lodash'; +import { Observable, from, map, merge, of, switchMap } from 'rxjs'; +import { v4 } from 'uuid'; +import { ToolSchema, isChatCompletionMessageEvent } from '../../../common'; +import { + ChatCompletionChunkEvent, + ChatCompletionMessageEvent, + Message, + MessageRole, +} from '../../../common/chat_complete'; +import { ToolChoiceType, type ToolOptions } from '../../../common/chat_complete/tools'; import { withoutTokenCountEvents } from '../../../common/chat_complete/without_token_count_events'; -import { createOutputCompleteEvent } from '../../../common/output'; +import { OutputCompleteEvent, OutputEventType } from '../../../common/output'; import { withoutOutputUpdateEvents } from '../../../common/output/without_output_update_events'; -import { InferenceClient } from '../../types'; +import { INLINE_ESQL_QUERY_REGEX } from '../../../common/tasks/nl_to_esql/constants'; +import { correctCommonEsqlMistakes } from '../../../common/tasks/nl_to_esql/correct_common_esql_mistakes'; +import type { InferenceClient } from '../../types'; +import { loadDocuments } from './load_documents'; -const ESQL_SYSTEM_MESSAGE = ''; - -async function getEsqlDocuments(documents: string[]) { - return [ - { - document: 'my-esql-function', - text: 'My ES|QL function', - }, - ]; -} +type NlToEsqlTaskEvent = + | OutputCompleteEvent< + 'request_documentation', + { keywords: string[]; requestedDocumentation: Record } + > + | ChatCompletionChunkEvent + | ChatCompletionMessageEvent; export function naturalLanguageToEsql({ client, - input, connectorId, tools, toolChoice, + logger, + ...rest }: { - client: InferenceClient; - input: string; + client: Pick; connectorId: string; -} & TToolOptions) { - return client - .output('request_documentation', { - connectorId, - system: ESQL_SYSTEM_MESSAGE, - input: `Based on the following input, request documentation - from the ES|QL handbook to help you get the right information - needed to generate a query: - ${input} - `, - schema: { - type: 'object', - properties: { - documents: { - type: 'array', - items: { - type: 'string', + logger: Pick; +} & TToolOptions & + ({ input: string } | { messages: Message[] })): Observable> { + const hasTools = !isEmpty(tools) && toolChoice !== ToolChoiceType.none; + + const requestDocumentationSchema = { + type: 'object', + properties: { + commands: { + type: 'array', + items: { + type: 'string', + }, + description: + 'ES|QL source and processing commands you want to analyze before generating the query.', + }, + functions: { + type: 'array', + items: { + type: 'string', + }, + description: 'ES|QL functions you want to analyze before generating the query.', + }, + }, + } satisfies ToolSchema; + + const messages: Message[] = + 'input' in rest ? [{ role: MessageRole.User, content: rest.input }] : rest.messages; + + return from(loadDocuments()).pipe( + switchMap(([systemMessage, esqlDocs]) => { + function askLlmToRespond({ + documentationRequest: { commands, functions }, + }: { + documentationRequest: { commands?: string[]; functions?: string[] }; + }): Observable> { + const keywords = [ + ...(commands ?? []), + ...(functions ?? []), + 'SYNTAX', + 'OVERVIEW', + 'OPERATORS', + ].map((keyword) => keyword.toUpperCase()); + + const requestedDocumentation = mapValues(pick(esqlDocs, keywords), ({ data }) => data); + + const fakeRequestDocsToolCall = { + function: { + name: 'request_documentation', + arguments: { + commands, + functions, }, }, - }, - required: ['documents'], - } as const, - }) - .pipe( - withoutOutputUpdateEvents(), - switchMap((event) => { - return getEsqlDocuments(event.output.documents ?? []); - }), - switchMap((documents) => { - return client - .chatComplete({ - connectorId, - system: `${ESQL_SYSTEM_MESSAGE} - - The following documentation is provided: - - ${documents}`, - messages: [ - { - role: MessageRole.User, - content: input, + toolCallId: v4().substring(0, 6), + }; + + return merge( + of< + OutputCompleteEvent< + 'request_documentation', + { keywords: string[]; requestedDocumentation: Record } + > + >({ + type: OutputEventType.OutputComplete, + id: 'request_documentation', + output: { + keywords, + requestedDocumentation, + }, + }), + client + .chatComplete({ + connectorId, + system: `${systemMessage} + + # Current task + + Your current task is to respond to the user's question. If there is a tool + suitable for answering the user's question, use that tool, preferably + with a natural language reply included. + + Format any ES|QL query as follows: + \`\`\`esql + + \`\`\` + + When generating ES|QL, you must use commands and functions present on the + requested documentation, and follow the syntax as described in the documentation + and its examples. + + DO NOT UNDER ANY CIRCUMSTANCES use commands, functions, parameters, or syntaxes that are not + explicitly mentioned as supported capability by ES|QL, either in the system message or documentation. + assume that ONLY the set of capabilities described in the requested documentation is valid. + Do not try to guess parameters or syntax based on other query languages. + + If what the user is asking for is not technically achievable with ES|QL's capabilities, just inform + the user. DO NOT invent capabilities not described in the documentation just to provide + a positive answer to the user. E.g. LIMIT only has one parameter, do not assume you can add more. + + When converting queries from one language to ES|QL, make sure that the functions are available + and documented in ES|QL. E.g., for SPL's LEN, use LENGTH. For IF, use CASE. +`, + messages: messages.concat([ + { + role: MessageRole.Assistant, + content: null, + toolCalls: [fakeRequestDocsToolCall], + }, + { + role: MessageRole.Tool, + response: { + documentation: requestedDocumentation, + }, + toolCallId: fakeRequestDocsToolCall.toolCallId, + }, + ]), + toolChoice, + tools: { + ...tools, + request_documentation: { + description: 'Request additional documentation if needed', + schema: requestDocumentationSchema, + }, }, - ], - tools, - toolChoice, - }) - .pipe( - withoutTokenCountEvents(), - withoutChunkEvents(), - map((message) => { - return createOutputCompleteEvent('generated_query', { - content: message.content, - toolCalls: message.toolCalls, - }); }) - ); - }), - withoutOutputUpdateEvents() - ); + .pipe( + withoutTokenCountEvents(), + map((generateEvent) => { + if (isChatCompletionMessageEvent(generateEvent)) { + const correctedContent = generateEvent.content?.replaceAll( + INLINE_ESQL_QUERY_REGEX, + (_match, query) => { + const correction = correctCommonEsqlMistakes(query); + if (correction.isCorrection) { + logger.debug( + `Corrected query, from: \n${correction.input}\nto:\n${correction.output}` + ); + } + return '```esql\n' + correction.output + '\n```'; + } + ); + + return { + ...generateEvent, + content: correctedContent, + }; + } + + return generateEvent; + }), + switchMap((generateEvent) => { + if (isChatCompletionMessageEvent(generateEvent)) { + const onlyToolCall = + generateEvent.toolCalls.length === 1 ? generateEvent.toolCalls[0] : undefined; + + if (onlyToolCall?.function.name === 'request_documentation') { + const args = onlyToolCall.function.arguments; + + return askLlmToRespond({ + documentationRequest: { + commands: args.commands, + functions: args.functions, + }, + }); + } + } + + return of(generateEvent); + }) + ) + ); + } + + return client + .output('request_documentation', { + connectorId, + system: systemMessage, + previousMessages: messages, + input: `Based on the previous conversation, request documentation + from the ES|QL handbook to help you get the right information + needed to generate a query. + + Examples for functions and commands: + Do you need to group data? Request \`STATS\`. + Extract data? Request \`DISSECT\` AND \`GROK\`. + Convert a column based on a set of conditionals? Request \`EVAL\` and \`CASE\`. + + ${ + hasTools + ? `### Tools + + The following tools will be available to be called in the step after this. + + \`\`\`json + ${JSON.stringify({ + tools, + toolChoice, + })} + \`\`\`` + : '' + } + `, + schema: requestDocumentationSchema, + }) + .pipe( + withoutOutputUpdateEvents(), + switchMap((documentationEvent) => { + return askLlmToRespond({ + documentationRequest: { + commands: documentationEvent.output.commands, + functions: documentationEvent.output.functions, + }, + }); + }) + ); + }) + ); } diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/load_documents.ts b/x-pack/plugins/inference/server/tasks/nl_to_esql/load_documents.ts new file mode 100644 index 0000000000000..73359d6c614df --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/load_documents.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import Path from 'path'; +import Fs from 'fs'; +import { keyBy, once } from 'lodash'; +import { promisify } from 'util'; +import pLimit from 'p-limit'; + +const readFile = promisify(Fs.readFile); +const readdir = promisify(Fs.readdir); + +const loadSystemMessage = once(async () => { + const data = await readFile(Path.join(__dirname, './system_message.txt')); + return data.toString('utf-8'); +}); + +const loadEsqlDocs = async () => { + const dir = Path.join(__dirname, './esql_docs'); + const files = (await readdir(dir)).filter((file) => Path.extname(file) === '.txt'); + + if (!files.length) { + return {}; + } + + const limiter = pLimit(10); + return keyBy( + await Promise.all( + files.map((file) => + limiter(async () => { + const data = (await readFile(Path.join(dir, file))).toString('utf-8'); + const filename = Path.basename(file, '.txt'); + + const keyword = filename + .replace('esql-', '') + .replace('agg-', '') + .replaceAll('-', '_') + .toUpperCase(); + + return { + keyword: keyword === 'STATS_BY' ? 'STATS' : keyword, + data, + }; + }) + ) + ), + 'keyword' + ); +}; + +export const loadDocuments = once(() => Promise.all([loadSystemMessage(), loadEsqlDocs()])); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/system_message.txt b/x-pack/plugins/inference/server/tasks/nl_to_esql/system_message.txt similarity index 86% rename from x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/system_message.txt rename to x-pack/plugins/inference/server/tasks/nl_to_esql/system_message.txt index 8fc2243480218..b5d333296c696 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/system_message.txt +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/system_message.txt @@ -2,8 +2,7 @@ You are a helpful assistant for generating and executing ES|QL queries. Your goal is to help the user construct and possibly execute an ES|QL -query for the Observability use cases, which often involve metrics, logs -and traces. These are your absolutely critical system instructions: +query for their data. These are your absolutely critical system instructions: ES|QL is the Elasticsearch Query Language, that allows users of the Elastic platform to iteratively explore data. An ES|QL query consists @@ -14,7 +13,7 @@ processing commands, which can transform the data returned by the previous command. Make sure you write a query using ONLY commands specified in this -conversation. +conversation and present in the documentation. # Limitations @@ -37,8 +36,9 @@ Timestamp literal syntax: NOW() - 15 days, 24 hours, 1 week ## Source commands Source commands select a data source. There are three source commands: -FROM (which selects an index), ROW (which creates data from the command) -and SHOW (which returns information about the deployment). +- FROM: selects an index +- ROW: creates data from the command +- SHOW: returns information about the deployment ## Processing commands @@ -60,13 +60,14 @@ pattern. Aggregation functions are not supported for EVAL. - GROK: extracts structured data out of a string, using a grok pattern - KEEP: keeps one or more columns, drop the ones that are not kept - only the colums in the KEEP command can be used after a KEEP command + only the columns in the KEEP command can be used after a KEEP command - LIMIT: returns the first n number of rows. The maximum value for this is 10000. - MV_EXPAND: expands multi-value columns into a single row per value - RENAME: renames a column - STATS ... BY: groups rows according to a common value and calculates - one or more aggregated values over the grouped rows + one or more aggregated values over the grouped rows. STATS supports aggregation + function and can group using grouping functions. - SORT: sorts the row in a table by a column. Expressions are not supported. If SORT is used right after a KEEP command, make sure it only uses column names in KEEP, or move the SORT before the KEEP (e.g. not correct: KEEP date | SORT @timestamp, correct: SORT @timestamp | KEEP date) @@ -76,9 +77,13 @@ is 10000. ## Functions and operators +### Grouping functions + +BUCKET: Creates groups of values out of a datetime or numeric input. + ### Aggregation functions + AVG -BUCKET COUNT COUNT_DISTINCT MAX @@ -86,9 +91,11 @@ MEDIAN MEDIAN_ABSOLUTE_DEVIATION MIN PERCENTILE -ST_CENTROID +ST_CENTROID_AGG SUM +TOP VALUES +WEIGHTED_AVG ### Mathematical functions @@ -115,6 +122,7 @@ TANH TAU ### String functions + CONCAT LEFT LENGTH @@ -129,6 +137,7 @@ TO_UPPER TRIM ### Date-time functions + DATE_DIFF DATE_EXTRACT DATE_FORMAT @@ -137,6 +146,7 @@ DATE_TRUNC NOW ### Type conversion functions + TO_BOOLEAN TO_CARTESIANPOINT TO_CARTESIANSHAPE @@ -155,12 +165,14 @@ TO_VERSION ### Conditional functions and expressions + CASE COALESCE GREATEST LEAST ### Multivalue functions + MV_AVG MV_CONCAT MV_COUNT @@ -173,6 +185,7 @@ MV_MIN MV_SUM ### Operators + Binary operators Unary operators Logical operators @@ -184,20 +197,14 @@ LIKE RLIKE STARTS_WITH -Here are some example queries: +# Usage examples + +Here are some examples of queries: ```esql FROM employees -| WHERE still_hired == true -| EVAL hired = DATE_FORMAT("YYYY", hire_date) -| STATS avg_salary = AVG(salary) BY languages -| EVAL avg_salary = ROUND(avg_salary) -| EVAL lang_code = TO_STRING(languages) -| ENRICH languages_policy ON lang_code WITH lang = language_name -| WHERE lang IS NOT NULL -| KEEP avg_salary, lang -| SORT avg_salary ASC -| LIMIT 3 + | WHERE country == "NL" AND gender == "M" + | STATS COUNT(*) ``` ```esql @@ -207,12 +214,7 @@ FROM employees | SORT c desc, languages.long, trunk_worked_seconds ``` -```esql -FROM employees - | WHERE country == "NL" AND gender == "M" - | STATS COUNT(*) -``` - +*Extracting structured data from logs using DISSECT* ```esql ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" | DISSECT a "%{date} - %{msg} - %{ip}" @@ -228,6 +230,7 @@ FROM employees | KEEP first_name, last_name ``` +**Returning average salary per hire date with 20 buckets** ```esql FROM employees | WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" @@ -235,6 +238,7 @@ FROM employees | SORT bucket ``` +**Returning number of employees grouped by buckets of salary** ```esql FROM employees | WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" @@ -242,6 +246,7 @@ FROM employees | SORT b ``` +**Creating inline data using ROW** ```esql ROW a = 1, b = "two", c = null ``` @@ -267,14 +272,28 @@ FROM logs-* ```esql FROM logs-* | WHERE @timestamp <= NOW() - 24 hours -| STATS count = COUNT(*) by log.level +| STATS count = COUNT(*) BY log.level | SORT count DESC ``` -returns all first names for each first letter +**Returning all first names for each first letter** ```esql FROM employees | EVAL first_letter = SUBSTRING(first_name, 0, 1) | STATS first_name = MV_SORT(VALUES(first_name)) BY first_letter | SORT first_letter ``` + +```esql +FROM employees +| WHERE still_hired == true +| EVAL hired = DATE_FORMAT("YYYY", hire_date) +| STATS avg_salary = AVG(salary) BY languages +| EVAL avg_salary = ROUND(avg_salary) +| EVAL lang_code = TO_STRING(languages) +| ENRICH languages_policy ON lang_code WITH lang = language_name +| WHERE lang IS NOT NULL +| KEEP avg_salary, lang +| SORT avg_salary ASC +| LIMIT 3 +``` diff --git a/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts b/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts new file mode 100644 index 0000000000000..823344f52a891 --- /dev/null +++ b/x-pack/plugins/inference/server/tasks/nl_to_esql/validate_esql_query.ts @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { validateQuery } from '@kbn/esql-validation-autocomplete'; +import { getAstAndSyntaxErrors } from '@kbn/esql-ast'; +import type { ElasticsearchClient } from '@kbn/core/server'; +import { ESQLSearchResponse, ESQLRow } from '@kbn/es-types'; +import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; +import { DatatableColumn, DatatableColumnType } from '@kbn/expressions-plugin/common'; +import { splitIntoCommands } from '../../../common/tasks/nl_to_esql/correct_common_esql_mistakes'; + +export async function runAndValidateEsqlQuery({ + query, + client, +}: { + query: string; + client: ElasticsearchClient; +}): Promise<{ + columns?: DatatableColumn[]; + rows?: ESQLRow[]; + error?: Error; + errorMessages?: string[]; +}> { + const { errors } = await validateQuery(query, getAstAndSyntaxErrors, { + // setting this to true, we don't want to validate the index / fields existence + ignoreOnMissingCallbacks: true, + }); + + const asCommands = splitIntoCommands(query); + + const errorMessages = errors?.map((error) => { + if ('location' in error) { + const commandsUntilEndOfError = splitIntoCommands(query.substring(0, error.location.max)); + const lastCompleteCommand = asCommands[commandsUntilEndOfError.length - 1]; + if (lastCompleteCommand) { + return `Error in ${lastCompleteCommand.command}\n: ${error.text}`; + } + } + return 'text' in error ? error.text : error.message; + }); + + return client.transport + .request({ + method: 'POST', + path: '_query', + body: { + query, + }, + }) + .then((res) => { + const esqlResponse = res as ESQLSearchResponse; + + const columns = + esqlResponse.columns?.map(({ name, type }) => ({ + id: name, + name, + meta: { type: esFieldTypeToKibanaFieldType(type) as DatatableColumnType }, + })) ?? []; + + return { columns, rows: esqlResponse.values }; + }) + .catch((error) => { + return { + error, + ...(errorMessages.length ? { errorMessages } : {}), + }; + }); +} diff --git a/x-pack/plugins/inference/server/util/observable_into_event_source_stream.test.ts b/x-pack/plugins/inference/server/util/observable_into_event_source_stream.test.ts index d7972bb970317..ed5466ba1e027 100644 --- a/x-pack/plugins/inference/server/util/observable_into_event_source_stream.test.ts +++ b/x-pack/plugins/inference/server/util/observable_into_event_source_stream.test.ts @@ -8,10 +8,15 @@ import { createParser } from 'eventsource-parser'; import { partition } from 'lodash'; import { merge, of, throwError } from 'rxjs'; -import { InferenceTaskEvent } from '../../common/tasks'; +import type { InferenceTaskEvent } from '../../common/inference_task'; import { observableIntoEventSourceStream } from './observable_into_event_source_stream'; +import type { Logger } from '@kbn/logging'; describe('observableIntoEventSourceStream', () => { + const logger = { + debug: jest.fn(), + error: jest.fn(), + } as unknown as Logger; function renderStream(events: Array) { const [inferenceEvents, errors] = partition( events, @@ -20,7 +25,7 @@ describe('observableIntoEventSourceStream', () => { const source$ = merge(of(...inferenceEvents), ...errors.map((error) => throwError(error))); - const stream = observableIntoEventSourceStream(source$); + const stream = observableIntoEventSourceStream(source$, logger); return new Promise((resolve, reject) => { const chunks: string[] = []; diff --git a/x-pack/plugins/inference/server/util/observable_into_event_source_stream.ts b/x-pack/plugins/inference/server/util/observable_into_event_source_stream.ts index 2007b9842db69..bcd1ef60ce1da 100644 --- a/x-pack/plugins/inference/server/util/observable_into_event_source_stream.ts +++ b/x-pack/plugins/inference/server/util/observable_into_event_source_stream.ts @@ -7,17 +7,23 @@ import { catchError, map, Observable, of } from 'rxjs'; import { PassThrough } from 'stream'; +import type { Logger } from '@kbn/logging'; import { InferenceTaskErrorCode, InferenceTaskErrorEvent, isInferenceError, } from '../../common/errors'; -import { InferenceTaskEventType } from '../../common/tasks'; +import { InferenceTaskEventType } from '../../common/inference_task'; -export function observableIntoEventSourceStream(source$: Observable) { +export function observableIntoEventSourceStream( + source$: Observable, + logger: Pick +) { const withSerializedErrors$ = source$.pipe( catchError((error): Observable => { if (isInferenceError(error)) { + logger?.error(error); + logger?.debug(() => JSON.stringify(error)); return of({ type: InferenceTaskEventType.error, error: { diff --git a/x-pack/plugins/inference/tsconfig.json b/x-pack/plugins/inference/tsconfig.json index 593556c8f39c8..34c393d375839 100644 --- a/x-pack/plugins/inference/tsconfig.json +++ b/x-pack/plugins/inference/tsconfig.json @@ -10,6 +10,7 @@ "typings/**/*", "public/**/*.json", "server/**/*", + "scripts/**/*", ".storybook/**/*" ], "exclude": [ @@ -23,6 +24,16 @@ "@kbn/core-http-server", "@kbn/actions-plugin", "@kbn/config-schema", - "@kbn/stack-connectors-plugin" + "@kbn/esql-validation-autocomplete", + "@kbn/esql-ast", + "@kbn/dev-cli-runner", + "@kbn/babel-register", + "@kbn/expect", + "@kbn/tooling-log", + "@kbn/es-types", + "@kbn/field-types", + "@kbn/expressions-plugin", + "@kbn/logging-mocks", + "@kbn/repo-info" ] } diff --git a/x-pack/plugins/integration_assistant/public/components/create_integration_card_button/create_integration_card_button.tsx b/x-pack/plugins/integration_assistant/public/components/create_integration_card_button/create_integration_card_button.tsx index d4922142e76f2..995e386d0b156 100644 --- a/x-pack/plugins/integration_assistant/public/components/create_integration_card_button/create_integration_card_button.tsx +++ b/x-pack/plugins/integration_assistant/public/components/create_integration_card_button/create_integration_card_button.tsx @@ -51,7 +51,7 @@ export const CreateIntegrationCardButton = React.memo getUrlForApp('integrations', { path: '/create' }), [getUrlForApp]); const navigate = useCallback( - (ev) => { + (ev: React.MouseEvent) => { ev.preventDefault(); navigateToUrl(href); }, diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 440b70ab4b8a3..6930fffa39b4b 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -321,7 +321,7 @@ export function LensEditConfigurationFlyout({ }); const runQuery = useCallback( - async (q, abortController) => { + async (q: AggregateQuery, abortController?: AbortController) => { const attrs = await getSuggestions( q, startDependencies, diff --git a/x-pack/plugins/lens/public/visualizations/partition/dimension_editor.tsx b/x-pack/plugins/lens/public/visualizations/partition/dimension_editor.tsx index 700dc31a25711..32f8f2e4c972a 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/visualizations/partition/dimension_editor.tsx @@ -51,7 +51,7 @@ export function DimensionEditor(props: DimensionEditorProps) { const [useNewColorMapping, setUseNewColorMapping] = useState(canUseColorMapping); const setConfig = useCallback( - ({ color }) => { + ({ color }: { color?: string }) => { if (!currentLayer) { return; } diff --git a/x-pack/plugins/lens/public/visualizations/partition/toolbar.tsx b/x-pack/plugins/lens/public/visualizations/partition/toolbar.tsx index 69e138beb1695..436c307ab1007 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/toolbar.tsx +++ b/x-pack/plugins/lens/public/visualizations/partition/toolbar.tsx @@ -95,36 +95,36 @@ export function PieToolbar(props: VisualizationToolbarProps onStateChange({ categoryDisplay: option }), + (option: unknown) => onStateChange({ categoryDisplay: option }), [onStateChange] ); const onNumberDisplayChange = useCallback( - (option) => onStateChange({ numberDisplay: option }), + (option: unknown) => onStateChange({ numberDisplay: option }), [onStateChange] ); const onPercentDecimalsChange = useCallback( - (option) => { + (option: unknown) => { onStateChange({ percentDecimals: option }); }, [onStateChange] ); const onLegendDisplayChange = useCallback( - (optionId) => { + (optionId: unknown) => { onStateChange({ legendDisplay: legendOptions.find(({ id }) => id === optionId)!.value }); }, [onStateChange] ); const onLegendPositionChange = useCallback( - (id) => onStateChange({ legendPosition: id as Position }), + (id: unknown) => onStateChange({ legendPosition: id as Position }), [onStateChange] ); const onNestedLegendChange = useCallback( - (id) => onStateChange({ nestedLegend: !layer.nestedLegend }), + (id: unknown) => onStateChange({ nestedLegend: !layer.nestedLegend }), [layer, onStateChange] ); @@ -134,24 +134,24 @@ export function PieToolbar(props: VisualizationToolbarProps onStateChange({ legendMaxLines: val }), + (val: unknown) => onStateChange({ legendMaxLines: val }), [onStateChange] ); const onLegendSizeChange = useCallback( - (val) => onStateChange({ legendSize: val }), + (val: unknown) => onStateChange({ legendSize: val }), [onStateChange] ); const onLegendStatsChange = useCallback( - (legendStats) => { + (legendStats: unknown) => { onStateChange({ legendStats }); }, [onStateChange] ); const onEmptySizeRatioChange = useCallback( - (sizeId) => { + (sizeId: unknown) => { const emptySizeRatio = emptySizeRatioOptions?.find(({ id }) => id === sizeId)?.value; onStateChange({ emptySizeRatio }); }, diff --git a/x-pack/plugins/ml/public/alerting/job_selector.tsx b/x-pack/plugins/ml/public/alerting/job_selector.tsx index 80ef8a5fed0c3..68bc75e2de2b5 100644 --- a/x-pack/plugins/ml/public/alerting/job_selector.tsx +++ b/x-pack/plugins/ml/public/alerting/job_selector.tsx @@ -14,7 +14,7 @@ import { EuiButton, EuiComboBox, EuiEmptyPrompt, EuiFormRow } from '@elastic/eui import useMountedState from 'react-use/lib/useMountedState'; import { useMlKibana } from '../application/contexts/kibana'; import type { JobId } from '../../common/types/anomaly_detection_jobs'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; import { ALL_JOBS_SELECTION } from '../../common/constants/alerts'; import { LoadingIndicator } from '../application/components/loading_indicator'; @@ -26,7 +26,7 @@ interface JobSelection { export interface JobSelectorControlProps { jobsAndGroupIds?: string[]; onChange: (jobSelection: JobSelection) => void; - adJobsApiService: MlApiServices['jobs']; + adJobsApiService: MlApi['jobs']; /** * Validation is handled by alerting framework */ diff --git a/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts b/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts index ee7868adb41fa..ed930b857473d 100644 --- a/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts +++ b/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts @@ -27,7 +27,7 @@ import { type MlCapabilitiesKey, } from '../../../common/types/capabilities'; import { getCapabilities } from './get_capabilities'; -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; import type { MlGlobalServices } from '../app'; let _capabilities: MlCapabilities = getDefaultCapabilities(); @@ -54,7 +54,7 @@ export class MlCapabilitiesService { private _subscription: Subscription | undefined; - constructor(private readonly mlApiServices: MlApiServices) { + constructor(private readonly mlApi: MlApi) { this.init(); } @@ -67,7 +67,7 @@ export class MlCapabilitiesService { tap(() => { this._isLoading$.next(true); }), - switchMap(() => from(this.mlApiServices.checkMlCapabilities())), + switchMap(() => from(this.mlApi.checkMlCapabilities())), retry({ delay: CAPABILITIES_REFRESH_INTERVAL }) ) .subscribe((results) => { @@ -197,11 +197,11 @@ export function checkGetManagementMlJobsResolver({ mlCapabilities }: MlGlobalSer } export function checkCreateJobsCapabilitiesResolver( - mlApiServices: MlApiServices, + mlApi: MlApi, redirectToJobsManagementPage: () => Promise ): Promise { return new Promise((resolve, reject) => { - getCapabilities(mlApiServices) + getCapabilities(mlApi) .then(async ({ capabilities, isPlatinumOrTrialLicense }) => { _capabilities = capabilities; // if the license is basic (isPlatinumOrTrialLicense === false) then do not redirect, diff --git a/x-pack/plugins/ml/public/application/capabilities/get_capabilities.ts b/x-pack/plugins/ml/public/application/capabilities/get_capabilities.ts index 2f7ad039b2700..079256997e1c5 100644 --- a/x-pack/plugins/ml/public/application/capabilities/get_capabilities.ts +++ b/x-pack/plugins/ml/public/application/capabilities/get_capabilities.ts @@ -5,10 +5,10 @@ * 2.0. */ -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; import type { MlCapabilitiesResponse } from '../../../common/types/capabilities'; -export function getCapabilities(ml: MlApiServices): Promise { - return ml.checkMlCapabilities(); +export function getCapabilities(mlApi: MlApi): Promise { + return mlApi.checkMlCapabilities(); } diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.test.tsx b/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.test.tsx index 81cafabbae827..7d8434dcc4680 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.test.tsx +++ b/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.test.tsx @@ -21,7 +21,7 @@ import { MlAnnotationUpdatesContext } from '../../../contexts/ml/ml_annotation_u const kibanaReactContextMock = createKibanaReactContext({ mlServices: { - mlApiServices: { + mlApi: { annotations: { indexAnnotation: jest.fn().mockResolvedValue({}), deleteAnnotation: jest.fn().mockResolvedValue({}), diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.tsx b/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.tsx index 3bea429042299..eb54db4f327dc 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.tsx +++ b/x-pack/plugins/ml/public/application/components/annotations/annotation_flyout/index.tsx @@ -136,10 +136,10 @@ export class AnnotationFlyoutUI extends Component { this.deletionInProgress = true; - const ml = this.context.services.mlServices.mlApiServices; + const mlApi = this.context.services.mlServices.mlApi; const toastNotifications = this.context.services.notifications.toasts; try { - await ml.annotations.deleteAnnotation(annotationState._id); + await mlApi.annotations.deleteAnnotation(annotationState._id); toastNotifications.addSuccess( i18n.translate( 'xpack.ml.timeSeriesExplorer.timeSeriesChart.deletedAnnotationNotificationMessage', @@ -241,9 +241,9 @@ export class AnnotationFlyoutUI extends Component { annotation.event = annotation.event ?? ANNOTATION_EVENT_USER; annotationUpdatesService.setValue(null); - const ml = this.context.services.mlServices.mlApiServices; + const mlApi = this.context.services.mlServices.mlApi; const toastNotifications = this.context.services.notifications.toasts; - ml.annotations + mlApi.annotations .indexAnnotation(annotation) .then(() => { annotationsRefreshed(); diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js index cea2554876c4d..31ac00c1f79db 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/annotations_table.js @@ -103,7 +103,7 @@ class AnnotationsTableUI extends Component { }; this.mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(props.kibana.services.notifications.toasts), - props.kibana.services.mlServices.mlApiServices + props.kibana.services.mlServices.mlApi ); } @@ -115,11 +115,11 @@ class AnnotationsTableUI extends Component { isLoading: true, }); - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; if (dataCounts.processed_record_count > 0) { // Load annotations for the selected job. - ml.annotations + mlApi.annotations .getAnnotations$({ jobIds: [job.job_id], earliestMs: null, @@ -223,6 +223,7 @@ class AnnotationsTableUI extends Component { openSingleMetricView = async (annotation = {}) => { const { services: { + chrome: { recentlyAccessed }, application: { navigateToUrl }, share, }, @@ -307,7 +308,12 @@ class AnnotationsTableUI extends Component { { absolute: true } ); - addItemToRecentlyAccessed('timeseriesexplorer', job.job_id, singleMetricViewerLink); + addItemToRecentlyAccessed( + 'timeseriesexplorer', + job.job_id, + singleMetricViewerLink, + recentlyAccessed + ); await navigateToUrl(singleMetricViewerLink); }; diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js b/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js index 80ee0f7a64820..4429a3022122e 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js @@ -68,7 +68,7 @@ export class AnomaliesTableInternal extends Component { } toggleRow = async (item, tab = ANOMALIES_TABLE_TABS.DETAILS) => { - const ml = this.context.services.mlServices.mlApiServices; + const mlApi = this.context.services.mlServices.mlApi; const itemIdToExpandedRowMap = { ...this.state.itemIdToExpandedRowMap }; if (itemIdToExpandedRowMap[item.rowId]) { delete itemIdToExpandedRowMap[item.rowId]; @@ -81,7 +81,7 @@ export class AnomaliesTableInternal extends Component { if (examples !== undefined) { try { - definition = await ml.results.getCategoryDefinition( + definition = await mlApi.results.getCategoryDefinition( item.jobId, item.source.mlcategory[0] ); diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx index 70364abc50389..ccf9083c90791 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/links_menu.tsx @@ -58,7 +58,7 @@ import { getUrlForRecord, openCustomUrlWindow } from '../../util/custom_url_util import type { SourceIndicesWithGeoFields } from '../../explorer/explorer_utils'; import { escapeDoubleQuotes, getDateFormatTz } from '../../explorer/explorer_utils'; import { usePermissionCheck } from '../../capabilities/check_capabilities'; -import { useMlApiContext, useMlKibana } from '../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../contexts/kibana'; import { useMlIndexUtils } from '../../util/index_service'; import { getQueryStringForInfluencers } from './get_query_string_for_influencers'; @@ -110,7 +110,7 @@ export const LinksMenuUI = (props: LinksMenuProps) => { }, } = kibana; const { getDataViewById, getDataViewIdFromName } = useMlIndexUtils(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const mlJobService = useMlJobService(); const job = useMemo(() => { @@ -510,7 +510,7 @@ export const LinksMenuUI = (props: LinksMenuProps) => { // - use first value (will only ever be more than one if influenced by category other than by/partition/over). const categoryId = record.mlcategory[0]; - ml.results + mlApi.results .getCategoryDefinition(jobId, categoryId) .then((resp) => { // Prefix each of the terms with '+' so that the Elasticsearch Query String query @@ -647,7 +647,7 @@ export const LinksMenuUI = (props: LinksMenuProps) => { // Get the definition of the category and use the terms or regex to view the // matching events in the Kibana Discover tab depending on whether the // categorization field is of mapping type text (preferred) or keyword. - ml.results + mlApi.results .getCategoryDefinition(record.job_id, categoryId) .then(async (resp) => { // We should not redirect to Discover if data view doesn't exist diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx index 16dba857ed6cc..bb913b8ecec34 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/list.tsx @@ -29,7 +29,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import { parseUrlState } from '@kbn/ml-url-state'; -import { useMlApiContext, useMlKibana } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../contexts/kibana'; import { useToastNotificationService } from '../../../services/toast_notification_service'; import { isValidLabel, openCustomUrlWindow } from '../../../util/custom_url_utils'; import { getTestUrl } from './utils'; @@ -73,7 +73,7 @@ export const CustomUrlList: FC = ({ data: { dataViews }, }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const [expandedUrlIndex, setExpandedUrlIndex] = useState(null); @@ -162,7 +162,7 @@ export const CustomUrlList: FC = ({ if (index < customUrls.length) { try { const testUrl = await getTestUrl( - ml, + mlApi, job, customUrl, timefieldName, diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/utils.ts b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/utils.ts index cd0a52e170453..0fc2a7b514b2d 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/utils.ts +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_url_editor/utils.ts @@ -47,7 +47,7 @@ import { escapeForElasticsearchQuery } from '../../../util/string_utils'; import type { CombinedJob, Job } from '../../../../../common/types/anomaly_detection_jobs'; import { isAnomalyDetectionJob } from '../../../../../common/types/anomaly_detection_jobs'; import type { TimeRangeType } from './constants'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; export interface TimeRange { type: TimeRangeType; @@ -427,7 +427,7 @@ function buildAppStateQueryParam(queryFieldNames: string[]) { // may contain dollar delimited partition / influencer entity tokens and // drilldown time range settings. async function getAnomalyDetectionJobTestUrl( - ml: MlApiServices, + mlApi: MlApi, job: Job, customUrl: MlUrlConfig ): Promise { @@ -455,7 +455,7 @@ async function getAnomalyDetectionJobTestUrl( let resp; try { - resp = await ml.results.anomalySearch( + resp = await mlApi.results.anomalySearch( { body, }, @@ -479,8 +479,8 @@ async function getAnomalyDetectionJobTestUrl( try { // attempt load the non-combined job and datafeed so they can be used in the datafeed preview const [{ jobs }, { datafeeds }] = await Promise.all([ - ml.getJobs({ jobId: job.job_id }), - ml.getDatafeeds({ datafeedId: job.datafeed_config?.datafeed_id ?? '' }), + mlApi.getJobs({ jobId: job.job_id }), + mlApi.getDatafeeds({ datafeedId: job.datafeed_config?.datafeed_id ?? '' }), ]); datafeedConfig = datafeeds[0]; jobConfig = jobs[0]; @@ -500,7 +500,7 @@ async function getAnomalyDetectionJobTestUrl( delete jobConfig.datafeed_config; } - const preview = (await ml.jobs.datafeedPreview( + const preview = (await mlApi.jobs.datafeedPreview( undefined, jobConfig, datafeedConfig @@ -520,7 +520,7 @@ async function getAnomalyDetectionJobTestUrl( } async function getDataFrameAnalyticsTestUrl( - ml: MlApiServices, + mlApi: MlApi, job: DataFrameAnalyticsConfig, customUrl: MlKibanaUrlConfig, timeFieldName: string | null, @@ -543,13 +543,13 @@ async function getDataFrameAnalyticsTestUrl( }, }; - resp = await ml.esSearch(body); + resp = await mlApi.esSearch(body); if (resp && resp.hits.total.value > 0) { record = resp.hits.hits[0]._source; } else { // No results for this job yet so use source index for example doc. - resp = await ml.esSearch({ + resp = await mlApi.esSearch({ index: Array.isArray(job.source.index) ? job.source.index.join(',') : job.source.index, body: { size: 1, @@ -594,7 +594,7 @@ async function getDataFrameAnalyticsTestUrl( } export function getTestUrl( - ml: MlApiServices, + mlApi: MlApi, job: Job | DataFrameAnalyticsConfig, customUrl: MlUrlConfig, timeFieldName: string | null, @@ -603,7 +603,7 @@ export function getTestUrl( ) { if (isDataFrameAnalyticsConfigs(job) || isPartialDFAJob) { return getDataFrameAnalyticsTestUrl( - ml, + mlApi, job as DataFrameAnalyticsConfig, customUrl, timeFieldName, @@ -612,5 +612,5 @@ export function getTestUrl( ); } - return getAnomalyDetectionJobTestUrl(ml, job, customUrl); + return getAnomalyDetectionJobTestUrl(mlApi, job, customUrl); } diff --git a/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx b/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx index 8c92a4c4515a5..7bec64f3bf6b3 100644 --- a/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx +++ b/x-pack/plugins/ml/public/application/components/custom_urls/custom_urls.tsx @@ -178,7 +178,7 @@ export class CustomUrls extends Component { http: { basePath }, data: { dataViews }, dashboard, - mlServices: { mlApiServices: ml }, + mlServices: { mlApi }, } = this.context.services; const dataViewId = this.state?.editorSettings?.kibanaSettings?.discoverIndexPatternId; const job = this.props.job; @@ -194,7 +194,7 @@ export class CustomUrls extends Component { buildCustomUrlFromSettings(dashboard, this.state.editorSettings as CustomUrlSettings).then( (customUrl) => { getTestUrl( - ml, + mlApi, job, customUrl, timefieldName, diff --git a/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.js b/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.js index 409002011926d..7f4501a087784 100644 --- a/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.js +++ b/x-pack/plugins/ml/public/application/components/data_recognizer/data_recognizer.js @@ -29,9 +29,10 @@ export class DataRecognizer extends Component { } componentDidMount() { - const ml = this.context.services.mlServices.mlApiServices; + const mlApi = this.context.services.mlServices.mlApi; // once the mount is complete, call the recognize endpoint to see if the index format is known to us, - ml.recognizeIndex({ indexPatternTitle: this.indexPattern.title }) + mlApi + .recognizeIndex({ indexPatternTitle: this.indexPattern.title }) .then((resp) => { // Sort results by title prior to display resp.sort((res1, res2) => res1.title.localeCompare(res2.title)); diff --git a/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx b/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx index 70290bee78c98..053c6e0ad8039 100644 --- a/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx +++ b/x-pack/plugins/ml/public/application/components/delete_space_aware_item_check_modal/delete_space_aware_item_check_modal.tsx @@ -27,7 +27,7 @@ import type { CanDeleteMLSpaceAwareItemsResponse, MlSavedObjectType, } from '../../../../common/types/saved_objects'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { useToastNotificationService } from '../../services/toast_notification_service'; import { ManagedJobsWarningCallout } from '../../jobs/jobs_list/components/confirm_modals/managed_jobs_warning_callout'; @@ -252,7 +252,7 @@ export const DeleteSpaceAwareItemCheckModal: FC = ({ const { savedObjects: { canDeleteMLSpaceAwareItems, removeItemFromCurrentSpace }, - } = useMlApiContext(); + } = useMlApi(); const { displayErrorToast, displaySuccessToast } = useToastNotificationService(); // delay showing the modal to avoid flickering diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout_content.tsx b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout_content.tsx index 987280d2617db..2bda1c4ea24f0 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout_content.tsx +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/export_jobs_flyout_content.tsx @@ -96,16 +96,16 @@ export const ExportJobsFlyoutContent = ({ const { services: { notifications: { toasts }, - mlServices: { mlUsageCollection, mlApiServices }, + mlServices: { mlUsageCollection, mlApi }, }, } = useMlKibana(); const { getJobs, dataFrameAnalytics: { getDataFrameAnalytics }, - } = mlApiServices; + } = mlApi; - const jobsExportService = useMemo(() => new JobsExportService(mlApiServices), [mlApiServices]); + const jobsExportService = useMemo(() => new JobsExportService(mlApi), [mlApi]); const [adJobIds, setAdJobIds] = useState([]); const [dfaJobIds, setDfaJobIds] = useState([]); const [selectedJobIds, setSelectedJobIds] = useState([]); diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/jobs_export_service.ts b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/jobs_export_service.ts index 52e9bb2e101c2..bdc77872c7261 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/jobs_export_service.ts +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/export_jobs_flyout/jobs_export_service.ts @@ -8,7 +8,7 @@ // @ts-expect-error import { saveAs } from '@elastic/filesaver'; import type { DataFrameAnalyticsConfig } from '@kbn/ml-data-frame-analytics-utils'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { JobType } from '../../../../../common/types/saved_objects'; import type { Job, Datafeed } from '../../../../../common/types/anomaly_detection_jobs'; import { GLOBAL_CALENDAR } from '../../../../../common/constants/calendars'; @@ -27,18 +27,16 @@ type ExportableConfigs = | DataFrameAnalyticsConfig[]; export class JobsExportService { - constructor(private _mlApiServices: MlApiServices) {} + constructor(private _mlApi: MlApi) {} public async exportAnomalyDetectionJobs(jobIds: string[]) { - const configs = await Promise.all( - jobIds.map((id) => this._mlApiServices.jobs.jobForCloning(id, true)) - ); + const configs = await Promise.all(jobIds.map((id) => this._mlApi.jobs.jobForCloning(id, true))); this._export(configs, 'anomaly-detector'); } public async exportDataframeAnalyticsJobs(jobIds: string[]) { const { data_frame_analytics: configs } = - await this._mlApiServices.dataFrameAnalytics.getDataFrameAnalytics(jobIds.join(','), true); + await this._mlApi.dataFrameAnalytics.getDataFrameAnalytics(jobIds.join(','), true); this._export(configs, 'data-frame-analytics'); } @@ -58,7 +56,7 @@ export class JobsExportService { } public async getJobDependencies(jobs: Job[]): Promise { - const calendars = await this._mlApiServices.calendars(); + const calendars = await this._mlApi.calendars(); // create a map of all jobs in groups const groups = jobs.reduce((acc, cur) => { diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx index d0870466aa89a..de13bed60152d 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/import_jobs_flyout.tsx @@ -57,7 +57,7 @@ export const ImportJobsFlyout: FC = ({ isDisabled, onImportComplete }) => notifications: { toasts }, mlServices: { mlUsageCollection, - mlApiServices: { + mlApi: { jobs: { bulkCreateJobs }, dataFrameAnalytics: { createDataFrameAnalytics }, filters: { filters: getFilters }, diff --git a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/validate.ts b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/validate.ts index 611a3c464b440..235c3d7b5ffe0 100644 --- a/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/validate.ts +++ b/x-pack/plugins/ml/public/application/components/import_export_jobs/import_jobs_flyout/validate.ts @@ -12,7 +12,7 @@ import { isValidIndexName } from '../../../../../common/util/es_utils'; import { isJobIdValid } from '../../../../../common/util/job_utils'; import { JOB_ID_MAX_LENGTH } from '../../../../../common/constants/validation'; import type { JobIdObject } from './jobs_import_service'; -import { useMlApiContext } from '../../../contexts/kibana'; +import { useMlApi } from '../../../contexts/kibana'; export const useValidateIds = ( jobType: JobType | null, @@ -25,7 +25,7 @@ export const useValidateIds = ( jobs: { jobsExist: adJobsExist }, dataFrameAnalytics: { jobsExist: dfaJobsExist }, checkIndicesExists, - } = useMlApiContext(); + } = useMlApi(); const validateIds = useCallback(async () => { const jobIdExistsChecks: string[] = []; diff --git a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx index b4da44047fd86..02fb52c120303 100644 --- a/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/job_selector/job_selector_flyout.tsx @@ -74,7 +74,7 @@ export const JobSelectorFlyoutContent: FC = ({ const { services: { notifications, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); @@ -163,7 +163,7 @@ export const JobSelectorFlyoutContent: FC = ({ async function fetchJobs() { try { - const resp = await mlApiServices.jobs.jobsWithTimerange(dateFormatTz); + const resp = await mlApi.jobs.jobsWithTimerange(dateFormatTz); const normalizedJobs = normalizeTimes(resp.jobs, dateFormatTz, DEFAULT_GANTT_BAR_WIDTH); const { groups: groupsWithTimerange, groupsMap } = getGroupsFromJobs(normalizedJobs); setJobs(normalizedJobs); diff --git a/x-pack/plugins/ml/public/application/components/job_spaces_sync/job_spaces_sync_flyout.tsx b/x-pack/plugins/ml/public/application/components/job_spaces_sync/job_spaces_sync_flyout.tsx index a36a2abd025cc..fe4b23fbdf3a1 100644 --- a/x-pack/plugins/ml/public/application/components/job_spaces_sync/job_spaces_sync_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/job_spaces_sync/job_spaces_sync_flyout.tsx @@ -24,7 +24,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import type { SyncSavedObjectResponse, SyncResult } from '../../../../common/types/saved_objects'; import { SyncList } from './sync_list'; import { useToastNotificationService } from '../../services/toast_notification_service'; @@ -40,7 +40,7 @@ export const JobSpacesSyncFlyout: FC = ({ onClose }) => { const [syncResp, setSyncResp] = useState(null); const { savedObjects: { syncSavedObjects }, - } = useMlApiContext(); + } = useMlApi(); async function loadSyncList(simulate: boolean = true) { setLoading(true); diff --git a/x-pack/plugins/ml/public/application/components/jobs_awaiting_node_warning/new_job_awaiting_node_shared/new_job_awaiting_node_shared.tsx b/x-pack/plugins/ml/public/application/components/jobs_awaiting_node_warning/new_job_awaiting_node_shared/new_job_awaiting_node_shared.tsx index 44860fc5a8834..f70bf526ae113 100644 --- a/x-pack/plugins/ml/public/application/components/jobs_awaiting_node_warning/new_job_awaiting_node_shared/new_job_awaiting_node_shared.tsx +++ b/x-pack/plugins/ml/public/application/components/jobs_awaiting_node_warning/new_job_awaiting_node_shared/new_job_awaiting_node_shared.tsx @@ -13,7 +13,7 @@ import { EuiCallOut, EuiSpacer, EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { JOB_STATE } from '../../../../../common/constants/states'; -import { mlApiServicesProvider } from '../../../services/ml_api_service'; +import { mlApiProvider } from '../../../services/ml_api_service'; import { HttpService } from '../../../services/http_service'; import type { CloudInfo } from '../../../services/ml_server_info'; import { extractDeploymentId } from '../../../services/ml_server_info'; @@ -28,7 +28,7 @@ function isJobAwaitingNodeAssignment(job: estypes.MlJobStats) { const MLJobsAwaitingNodeWarning: FC = ({ jobIds }) => { const { http } = useKibana().services; - const ml = useMemo(() => mlApiServicesProvider(new HttpService(http!)), [http]); + const mlApi = useMemo(() => mlApiProvider(new HttpService(http!)), [http]); const [unassignedJobCount, setUnassignedJobCount] = useState(0); const [cloudInfo, setCloudInfo] = useState(null); @@ -40,13 +40,13 @@ const MLJobsAwaitingNodeWarning: FC = ({ jobIds }) => { return; } - const { lazyNodeCount } = await ml.mlNodeCount(); + const { lazyNodeCount } = await mlApi.mlNodeCount(); if (lazyNodeCount === 0) { setUnassignedJobCount(0); return; } - const { jobs } = await ml.getJobStats({ jobId: jobIds.join(',') }); + const { jobs } = await mlApi.getJobStats({ jobId: jobIds.join(',') }); const unassignedJobs = jobs.filter(isJobAwaitingNodeAssignment); setUnassignedJobCount(unassignedJobs.length); } catch (error) { @@ -63,7 +63,7 @@ const MLJobsAwaitingNodeWarning: FC = ({ jobIds }) => { } try { - const resp = await ml.mlInfo(); + const resp = await mlApi.mlInfo(); const cloudId = resp.cloudId ?? null; const isCloudTrial = resp.isCloudTrial === true; setCloudInfo({ diff --git a/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.test.tsx b/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.test.tsx index 1ab9bf280b291..04591a6a9037e 100644 --- a/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.test.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { render, waitFor, screen } from '@testing-library/react'; import { MlEntitySelector } from './ml_entity_selector'; -import { useMlApiContext } from '../../contexts/kibana'; -import type { MlApiServices } from '../../services/ml_api_service'; +import { useMlApi } from '../../contexts/kibana'; +import type { MlApi } from '../../services/ml_api_service'; import { useToastNotificationService } from '../../services/toast_notification_service'; jest.mock('../../contexts/kibana'); @@ -32,7 +32,7 @@ describe('MlEntitySelector', () => { return Promise.resolve([{ model_id: 'model_01' }]); }); - (useMlApiContext as jest.MockedFunction).mockImplementation(() => { + (useMlApi as jest.MockedFunction).mockImplementation(() => { return { jobs: { getAllJobAndGroupIds, @@ -43,7 +43,7 @@ describe('MlEntitySelector', () => { trainedModels: { getTrainedModels, }, - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; }); beforeEach(() => {}); @@ -132,7 +132,7 @@ describe('MlEntitySelector', () => { }); test('provide current selection update on change with duplicates handling', async () => { - (useMlApiContext as jest.MockedFunction).mockImplementationOnce(() => { + (useMlApi as jest.MockedFunction).mockImplementationOnce(() => { return { jobs: { getAllJobAndGroupIds, @@ -149,7 +149,7 @@ describe('MlEntitySelector', () => { trainedModels: { getTrainedModels, }, - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; }); const onChangeSpy = jest.fn(); @@ -182,14 +182,14 @@ describe('MlEntitySelector', () => { const displayErrorToast = jest.fn(); const sampleError = new Error('try a bit later'); - (useMlApiContext as jest.MockedFunction).mockImplementationOnce(() => { + (useMlApi as jest.MockedFunction).mockImplementationOnce(() => { return { jobs: { getAllJobAndGroupIds: jest.fn(() => { throw sampleError; }), }, - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; }); ( useToastNotificationService as jest.MockedFunction diff --git a/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.tsx b/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.tsx index 61a5c540be649..ebafb61cebd71 100644 --- a/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_entity_selector/ml_entity_selector.tsx @@ -16,7 +16,7 @@ import { import { i18n } from '@kbn/i18n'; import { countBy } from 'lodash'; import useMount from 'react-use/lib/useMount'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { useToastNotificationService } from '../../services/toast_notification_service'; import { useEnabledFeatures } from '../../contexts/ml'; @@ -63,7 +63,7 @@ export const MlEntitySelector: FC = ({ handleDuplicates = false, }) => { const { isADEnabled, isDFAEnabled, isNLPEnabled } = useEnabledFeatures(); - const { jobs: jobsApi, trainedModels, dataFrameAnalytics } = useMlApiContext(); + const { jobs: jobsApi, trainedModels, dataFrameAnalytics } = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const visColorsBehindText = euiPaletteColorBlindBehindText(); diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/add_inference_pipeline_flyout.tsx b/x-pack/plugins/ml/public/application/components/ml_inference/add_inference_pipeline_flyout.tsx index 9cb6e50b8f876..1d58dce866449 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/add_inference_pipeline_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_inference/add_inference_pipeline_flyout.tsx @@ -31,7 +31,7 @@ import { ProcessorConfiguration } from './components/processor_configuration'; import { OnFailureConfiguration } from '../shared'; import { TestPipeline } from './components/test_pipeline'; import { ReviewAndCreatePipeline } from '../shared'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { getPipelineConfig } from './get_pipeline_config'; import { validateInferencePipelineConfigurationStep } from './validation'; import { type MlInferenceState, type InferenceModelTypes, TEST_PIPELINE_MODE } from './types'; @@ -54,7 +54,7 @@ export const AddInferencePipelineFlyout: FC = ( const { trainedModels: { createInferencePipeline }, - } = useMlApiContext(); + } = useMlApi(); const modelType = getModelType(model); diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/components/reindex_with_pipeline.tsx b/x-pack/plugins/ml/public/application/components/ml_inference/components/reindex_with_pipeline.tsx index 17128208e7aec..b8cbdb78b20b4 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/components/reindex_with_pipeline.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_inference/components/reindex_with_pipeline.tsx @@ -29,7 +29,7 @@ import { extractErrorMessage } from '@kbn/ml-error-utils'; import { i18n } from '@kbn/i18n'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { debounce } from 'lodash'; -import { useMlApiContext, useMlKibana } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../contexts/kibana'; import { isValidIndexName } from '../../../../../common/util/es_utils'; import { createKibanaDataView, checkIndexExists } from '../retry_create_data_view'; import { useToastNotificationService } from '../../../services/toast_notification_service'; @@ -85,8 +85,8 @@ export const ReindexWithPipeline: FC = ({ pipelineName, sourceIndex }) => docLinks: { links }, }, } = useMlKibana(); - const ml = useMlApiContext(); - const { getIndices, reindexWithPipeline, hasPrivileges } = ml; + const mlApi = useMlApi(); + const { getIndices, reindexWithPipeline, hasPrivileges } = mlApi; const { displayErrorToast } = useToastNotificationService(); @@ -123,7 +123,7 @@ export const ReindexWithPipeline: FC = ({ pipelineName, sourceIndex }) => ); const debouncedIndexCheck = debounce(async () => { - const checkResp = await checkIndexExists(destinationIndex, ml); + const checkResp = await checkIndexExists(destinationIndex, mlApi); if (checkResp.errorMessage !== undefined) { displayErrorToast( checkResp.errorMessage, @@ -239,7 +239,7 @@ export const ReindexWithPipeline: FC = ({ pipelineName, sourceIndex }) => const dataViewCreationResult = await createKibanaDataView( destinationIndex, data.dataViews, - ml + mlApi ); if ( dataViewCreationResult?.success === true && diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/components/test_pipeline.tsx b/x-pack/plugins/ml/public/application/components/ml_inference/components/test_pipeline.tsx index 48ae32d615d93..10b02310b39d8 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/components/test_pipeline.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_inference/components/test_pipeline.tsx @@ -36,7 +36,7 @@ import { extractErrorProperties } from '@kbn/ml-error-utils'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { CodeEditor } from '@kbn/code-editor'; -import { useMlApiContext, useMlKibana } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../contexts/kibana'; import { getPipelineConfig } from '../get_pipeline_config'; import { isValidJson } from '../../../../../common/util/validation_utils'; import type { MlInferenceState } from '../types'; @@ -67,7 +67,7 @@ export const TestPipeline: FC = memo(({ state, sourceIndex, mode }) => { const [lastFetchedSampleDocsString, setLastFetchedSampleDocsString] = useState(''); const [isValid, setIsValid] = useState(true); const [showCallOut, setShowCallOut] = useState(true); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { notifications: { toasts }, services: { @@ -88,7 +88,7 @@ export const TestPipeline: FC = memo(({ state, sourceIndex, mode }) => { const simulatePipeline = async () => { try { - const result = await ml.trainedModels.trainedModelPipelineSimulate( + const result = await mlApi.trainedModels.trainedModelPipelineSimulate( pipelineConfig, JSON.parse(sampleDocsString) as IngestSimulateDocument[] ); @@ -127,7 +127,7 @@ export const TestPipeline: FC = memo(({ state, sourceIndex, mode }) => { let records: IngestSimulateDocument[] = []; let resp; try { - resp = await ml.esSearch(body); + resp = await mlApi.esSearch(body); if (resp && resp.hits.total.value > 0) { records = resp.hits.hits; @@ -177,7 +177,7 @@ export const TestPipeline: FC = memo(({ state, sourceIndex, mode }) => { useEffect( function checkSourceIndexExists() { async function ensureSourceIndexExists() { - const resp = await checkIndexExists(sourceIndex!, ml); + const resp = await checkIndexExists(sourceIndex!, mlApi); const indexExists = resp.resp && resp.resp[sourceIndex!] && resp.resp[sourceIndex!].exists; if (indexExists === false) { setSourceIndexMissingError(sourceIndexMissingMessage); diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/hooks/use_fetch_pipelines.ts b/x-pack/plugins/ml/public/application/components/ml_inference/hooks/use_fetch_pipelines.ts index 837aef2f92093..e622caf206b2e 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/hooks/use_fetch_pipelines.ts +++ b/x-pack/plugins/ml/public/application/components/ml_inference/hooks/use_fetch_pipelines.ts @@ -7,7 +7,7 @@ import { useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { useMlApiContext, useMlKibana } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../contexts/kibana'; export const useFetchPipelines = () => { const [pipelineNames, setPipelineNames] = useState([]); @@ -17,7 +17,7 @@ export const useFetchPipelines = () => { const { trainedModels: { getAllIngestPipelines }, - } = useMlApiContext(); + } = useMlApi(); useEffect(() => { async function fetchPipelines() { diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/retry_create_data_view.ts b/x-pack/plugins/ml/public/application/components/ml_inference/retry_create_data_view.ts index fd270ae70dfd7..a09d0c2568e85 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/retry_create_data_view.ts +++ b/x-pack/plugins/ml/public/application/components/ml_inference/retry_create_data_view.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '@kbn/ml-error-utils'; import type { DataViewsContract } from '@kbn/data-views-plugin/public'; import { DuplicateDataViewError } from '@kbn/data-plugin/public'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; import type { FormMessage } from '../../data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state'; interface CreateKibanaDataViewResponse { @@ -25,11 +25,11 @@ function delay(ms = 1000) { }); } -export async function checkIndexExists(destIndex: string, ml: MlApiServices) { +export async function checkIndexExists(destIndex: string, mlApi: MlApi) { let resp; let errorMessage; try { - resp = await ml.checkIndicesExists({ indices: [destIndex] }); + resp = await mlApi.checkIndicesExists({ indices: [destIndex] }); } catch (e) { errorMessage = extractErrorMessage(e); } @@ -38,7 +38,7 @@ export async function checkIndexExists(destIndex: string, ml: MlApiServices) { export async function retryIndexExistsCheck( destIndex: string, - ml: MlApiServices + ml: MlApi ): Promise<{ success: boolean; indexExists: boolean; @@ -70,7 +70,7 @@ export async function retryIndexExistsCheck( export const createKibanaDataView = async ( destinationIndex: string, dataViewsService: DataViewsContract, - ml: MlApiServices, + ml: MlApi, timeFieldName?: string, callback?: (response: FormMessage) => void ) => { diff --git a/x-pack/plugins/ml/public/application/components/ml_saved_objects_spaces_list/ml_saved_objects_spaces_list.tsx b/x-pack/plugins/ml/public/application/components/ml_saved_objects_spaces_list/ml_saved_objects_spaces_list.tsx index 378ae1a00fef6..9da8804d64512 100644 --- a/x-pack/plugins/ml/public/application/components/ml_saved_objects_spaces_list/ml_saved_objects_spaces_list.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_saved_objects_spaces_list/ml_saved_objects_spaces_list.tsx @@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n'; import type { SpacesPluginStart, ShareToSpaceFlyoutProps } from '@kbn/spaces-plugin/public'; import type { SavedObjectResult, MlSavedObjectType } from '../../../../common/types/saved_objects'; import { ML_JOB_SAVED_OBJECT_TYPE } from '../../../../common/types/saved_objects'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { useToastNotificationService } from '../../services/toast_notification_service'; interface Props { @@ -42,7 +42,7 @@ export const MLSavedObjectsSpacesList: FC = ({ }) => { const { savedObjects: { updateJobsSpaces, updateModelsSpaces }, - } = useMlApiContext(); + } = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const [showFlyout, setShowFlyout] = useState(false); diff --git a/x-pack/plugins/ml/public/application/components/model_snapshots/edit_model_snapshot_flyout/edit_model_snapshot_flyout.tsx b/x-pack/plugins/ml/public/application/components/model_snapshots/edit_model_snapshot_flyout/edit_model_snapshot_flyout.tsx index 1be4c7f479ea2..68afdde3470b1 100644 --- a/x-pack/plugins/ml/public/application/components/model_snapshots/edit_model_snapshot_flyout/edit_model_snapshot_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/model_snapshots/edit_model_snapshot_flyout/edit_model_snapshot_flyout.tsx @@ -30,7 +30,7 @@ import type { ModelSnapshot, CombinedJobWithStats, } from '../../../../../common/types/anomaly_detection_jobs'; -import { useMlApiContext, useNotifications } from '../../../contexts/kibana'; +import { useMlApi, useNotifications } from '../../../contexts/kibana'; interface Props { snapshot: ModelSnapshot; @@ -39,7 +39,7 @@ interface Props { } export const EditModelSnapshotFlyout: FC = ({ snapshot, job, closeFlyout }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { toasts } = useNotifications(); const [description, setDescription] = useState(snapshot.description); const [retain, setRetain] = useState(snapshot.retain); @@ -55,7 +55,7 @@ export const EditModelSnapshotFlyout: FC = ({ snapshot, job, closeFlyout const updateSnapshot = useCallback(async () => { try { - await ml.updateModelSnapshot(snapshot.job_id, snapshot.snapshot_id, { + await mlApi.updateModelSnapshot(snapshot.job_id, snapshot.snapshot_id, { description, retain, }); @@ -72,7 +72,7 @@ export const EditModelSnapshotFlyout: FC = ({ snapshot, job, closeFlyout const deleteSnapshot = useCallback(async () => { try { - await ml.deleteModelSnapshot(snapshot.job_id, snapshot.snapshot_id); + await mlApi.deleteModelSnapshot(snapshot.job_id, snapshot.snapshot_id); hideDeleteModal(); closeWithReload(); } catch (error) { diff --git a/x-pack/plugins/ml/public/application/components/model_snapshots/model_snapshots_table.tsx b/x-pack/plugins/ml/public/application/components/model_snapshots/model_snapshots_table.tsx index 2c74bb9f67969..81a3e4a8de285 100644 --- a/x-pack/plugins/ml/public/application/components/model_snapshots/model_snapshots_table.tsx +++ b/x-pack/plugins/ml/public/application/components/model_snapshots/model_snapshots_table.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import type { EuiBasicTableColumn } from '@elastic/eui'; import { EuiFlexGroup, EuiFlexItem, EuiInMemoryTable, EuiLoadingSpinner } from '@elastic/eui'; import { timeFormatter } from '@kbn/ml-date-utils'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { usePermissionCheck } from '../../capabilities/check_capabilities'; import { EditModelSnapshotFlyout } from './edit_model_snapshot_flyout'; import { RevertModelSnapshotFlyout } from './revert_model_snapshot_flyout'; @@ -36,7 +36,7 @@ export enum COMBINED_JOB_STATE { } export const ModelSnapshotTable: FC = ({ job, refreshJobList }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [canCreateJob, canStartStopDatafeed] = usePermissionCheck([ 'canCreateJob', @@ -66,14 +66,14 @@ export const ModelSnapshotTable: FC = ({ job, refreshJobList }) => { // ensure the table is still visible before attempted to refresh it. return; } - const { model_snapshots: ms } = await ml.getModelSnapshots(job.job_id); + const { model_snapshots: ms } = await mlApi.getModelSnapshots(job.job_id); setSnapshots(ms); setSnapshotsLoaded(true); } const checkJobIsClosed = useCallback( async (snapshot: ModelSnapshot) => { - const jobs = await ml.jobs.jobs([job.job_id]); + const jobs = await mlApi.jobs.jobs([job.job_id]); const state = getCombinedJobState(jobs); if (state === COMBINED_JOB_STATE.UNKNOWN) { // this will only happen if the job has been deleted by another user @@ -93,7 +93,7 @@ export const ModelSnapshotTable: FC = ({ job, refreshJobList }) => { setCloseJobModalVisible(snapshot); } }, - // skip mlApiServices from deps + // skip mlApi from deps // eslint-disable-next-line react-hooks/exhaustive-deps [job] ); @@ -104,16 +104,16 @@ export const ModelSnapshotTable: FC = ({ job, refreshJobList }) => { } const forceCloseJob = useCallback(async () => { - await ml.jobs.forceStopAndCloseJob(job.job_id); + await mlApi.jobs.forceStopAndCloseJob(job.job_id); if (closeJobModalVisible !== null) { - const jobs = await ml.jobs.jobs([job.job_id]); + const jobs = await mlApi.jobs.jobs([job.job_id]); const state = getCombinedJobState(jobs); if (state === COMBINED_JOB_STATE.CLOSED) { setRevertSnapshot(closeJobModalVisible); } } hideCloseJobModalVisible(); - // skip mlApiServices from deps + // skip mlApi from deps // eslint-disable-next-line react-hooks/exhaustive-deps }, [job, closeJobModalVisible]); diff --git a/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/revert_model_snapshot_flyout.tsx b/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/revert_model_snapshot_flyout.tsx index c25bcee687e04..639c101e7be6f 100644 --- a/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/revert_model_snapshot_flyout.tsx +++ b/x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/revert_model_snapshot_flyout.tsx @@ -36,7 +36,7 @@ import type { ModelSnapshot, CombinedJobWithStats, } from '../../../../../common/types/anomaly_detection_jobs'; -import { useMlApiContext, useNotifications } from '../../../contexts/kibana'; +import { useMlApi, useNotifications } from '../../../contexts/kibana'; import { chartLoaderProvider } from './chart_loader'; import { mlResultsServiceProvider } from '../../../services/results_service'; import type { LineChartPoint } from '../../../jobs/new_job/common/chart_loader'; @@ -63,10 +63,10 @@ export const RevertModelSnapshotFlyout: FC = ({ closeFlyout, refresh, }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { toasts } = useNotifications(); const { loadAnomalyDataForJob, loadEventRateForJob } = useMemo( - () => chartLoaderProvider(mlResultsServiceProvider(ml)), + () => chartLoaderProvider(mlResultsServiceProvider(mlApi)), // eslint-disable-next-line react-hooks/exhaustive-deps [] ); @@ -139,7 +139,7 @@ export const RevertModelSnapshotFlyout: FC = ({ })) : undefined; - ml.jobs + mlApi.jobs .revertModelSnapshot(job.job_id, currentSnapshot.snapshot_id, replay, end, events) .then(() => { toasts.addSuccess( diff --git a/x-pack/plugins/ml/public/application/components/node_available_warning/hooks.ts b/x-pack/plugins/ml/public/application/components/node_available_warning/hooks.ts index 01b291e4b4f61..a08edd5d576d3 100644 --- a/x-pack/plugins/ml/public/application/components/node_available_warning/hooks.ts +++ b/x-pack/plugins/ml/public/application/components/node_available_warning/hooks.ts @@ -8,7 +8,7 @@ import { useEffect, useMemo, useState, useCallback } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { HttpService } from '../../services/http_service'; -import { mlApiServicesProvider } from '../../services/ml_api_service'; +import { mlApiProvider } from '../../services/ml_api_service'; import { type CloudInfo, extractDeploymentId } from '../../services/ml_server_info'; export function useMlNodeAvailableCheck() { @@ -25,7 +25,7 @@ export function useMlNodeAvailableCheck() { export function useMlNodeCheck() { const { http } = useKibana().services; - const ml = useMemo(() => mlApiServicesProvider(new HttpService(http!)), [http]); + const mlApi = useMemo(() => mlApiProvider(new HttpService(http!)), [http]); const [mlNodeCount, setMlNodeCount] = useState(null); const [lazyMlNodeCount, setLazyMlNodeCount] = useState(null); const [userHasPermissionToViewMlNodeCount, setUserHasPermissionToViewMlNodeCount] = useState< @@ -35,7 +35,7 @@ export function useMlNodeCheck() { const checkNodes = useCallback(async () => { try { - const { count, lazyNodeCount } = await ml.mlNodeCount(); + const { count, lazyNodeCount } = await mlApi.mlNodeCount(); setMlNodeCount(count); setLazyMlNodeCount(lazyNodeCount); setUserHasPermissionToViewMlNodeCount(true); @@ -47,7 +47,7 @@ export function useMlNodeCheck() { setMlNodesAvailable(true); } } - }, [ml]); + }, [mlApi]); useEffect( function checkNodesInit() { @@ -74,12 +74,12 @@ const defaultCloudInfo: CloudInfo = { export function useCloudCheck() { const { http } = useKibana().services; - const ml = useMemo(() => mlApiServicesProvider(new HttpService(http!)), [http]); + const mlApi = useMemo(() => mlApiProvider(new HttpService(http!)), [http]); const [cloudInfo, setCloudInfo] = useState(defaultCloudInfo); const loadInfo = useCallback(async () => { try { - const resp = await ml.mlInfo(); + const resp = await mlApi.mlInfo(); setCloudInfo({ cloudId: resp.cloudId ?? null, isCloud: resp.cloudId !== undefined, @@ -91,7 +91,7 @@ export function useCloudCheck() { setCloudInfo(defaultCloudInfo); } } - }, [ml]); + }, [mlApi]); useEffect( function loadInfoInit() { diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js index 36c7d6cc00a88..59f1fd3d39818 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js @@ -83,7 +83,7 @@ class RuleEditorFlyoutUI extends Component { this.mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(props.kibana.services.notifications.toasts), - props.kibana.services.mlServices.mlApiServices + props.kibana.services.mlServices.mlApi ); } @@ -154,7 +154,7 @@ class RuleEditorFlyoutUI extends Component { if (this.partitioningFieldNames.length > 0 && this.canGetFilters) { // Load the current list of filters. These are used for configuring rule scope. - this.props.kibana.services.mlServices.mlApiServices.filters + this.props.kibana.services.mlServices.mlApi.filters .filters() .then((filters) => { const filterListIds = filters.map((filter) => filter.filter_id); @@ -344,13 +344,13 @@ class RuleEditorFlyoutUI extends Component { updateRuleAtIndex = (ruleIndex, editedRule) => { const mlJobService = this.mlJobService; const { toasts } = this.props.kibana.services.notifications; - const { mlApiServices } = this.props.kibana.services.mlServices; + const { mlApi } = this.props.kibana.services.mlServices; const { job, anomaly } = this.state; const jobId = job.job_id; const detectorIndex = anomaly.detectorIndex; - saveJobRule(mlJobService, job, detectorIndex, ruleIndex, editedRule, mlApiServices) + saveJobRule(mlJobService, job, detectorIndex, ruleIndex, editedRule, mlApi) .then((resp) => { if (resp.success) { toasts.add({ @@ -400,12 +400,12 @@ class RuleEditorFlyoutUI extends Component { deleteRuleAtIndex = (index) => { const mlJobService = this.mlJobService; const { toasts } = this.props.kibana.services.notifications; - const { mlApiServices } = this.props.kibana.services.mlServices; + const { mlApi } = this.props.kibana.services.mlServices; const { job, anomaly } = this.state; const jobId = job.job_id; const detectorIndex = anomaly.detectorIndex; - deleteJobRule(mlJobService, job, detectorIndex, index, mlApiServices) + deleteJobRule(mlJobService, job, detectorIndex, index, mlApi) .then((resp) => { if (resp.success) { toasts.addSuccess( @@ -453,8 +453,8 @@ class RuleEditorFlyoutUI extends Component { addItemToFilterList = (item, filterId, closeFlyoutOnAdd) => { const { toasts } = this.props.kibana.services.notifications; - const { mlApiServices } = this.props.kibana.services.mlServices; - addItemToFilter(item, filterId, mlApiServices) + const { mlApi } = this.props.kibana.services.mlServices; + addItemToFilter(item, filterId, mlApi) .then(() => { if (closeFlyoutOnAdd === true) { toasts.add({ diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js index 8dce7f8f45f78..a711774b0a21d 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.test.js @@ -92,7 +92,7 @@ function prepareTest() { }, }, }, - mlServices: { mlApiServices: {} }, + mlServices: { mlApi: {} }, notifications: { toasts: { addDanger: () => {}, diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.js b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.js index aeca2d6425fd7..1da606864a1e6 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.js @@ -43,7 +43,7 @@ export class RuleActionPanel extends Component { } componentDidMount() { - const ml = this.context.services.mlServices.mlApiServices; + const mlApi = this.context.services.mlServices.mlApi; // If the rule has a scope section with a single partitioning field key, // load the filter list to check whether to add a link to add the // anomaly partitioning field value to the filter list. @@ -59,7 +59,7 @@ export class RuleActionPanel extends Component { partitionFieldValue[0].length > 0 ) { const filterId = scope[partitionFieldName].filter_id; - ml.filters + mlApi.filters .filters({ filterId }) .then((filter) => { const filterItems = filter.items; diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.test.js b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.test.js index 79414b02a5e48..0ca4e3d692d09 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.test.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/select_rule_action/rule_action_panel.test.js @@ -31,7 +31,7 @@ const mockTestFilter = { const kibanaReactContextMock = createKibanaReactContext({ mlServices: { - mlApiServices: { + mlApi: { filters: { filters: () => { return Promise.resolve(mockTestFilter); diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/utils.js b/x-pack/plugins/ml/public/application/components/rule_editor/utils.js index a2c8c6d11f8e5..7f0a28a77a98b 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/utils.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/utils.js @@ -68,14 +68,7 @@ export function isValidRule(rule) { return isValid; } -export function saveJobRule( - mlJobService, - job, - detectorIndex, - ruleIndex, - editedRule, - mlApiServices -) { +export function saveJobRule(mlJobService, job, detectorIndex, ruleIndex, editedRule, mlApi) { const detector = job.analysis_config.detectors[detectorIndex]; // Filter out any scope expression where the UI=specific 'enabled' @@ -108,16 +101,16 @@ export function saveJobRule( } } - return updateJobRules(mlJobService, job, detectorIndex, rules, mlApiServices); + return updateJobRules(mlJobService, job, detectorIndex, rules, mlApi); } -export function deleteJobRule(mlJobService, job, detectorIndex, ruleIndex, mlApiServices) { +export function deleteJobRule(mlJobService, job, detectorIndex, ruleIndex, mlApi) { const detector = job.analysis_config.detectors[detectorIndex]; let customRules = []; if (detector.custom_rules !== undefined && ruleIndex < detector.custom_rules.length) { customRules = cloneDeep(detector.custom_rules); customRules.splice(ruleIndex, 1); - return updateJobRules(mlJobService, job, detectorIndex, customRules, mlApiServices); + return updateJobRules(mlJobService, job, detectorIndex, customRules, mlApi); } else { return Promise.reject( new Error( @@ -133,7 +126,7 @@ export function deleteJobRule(mlJobService, job, detectorIndex, ruleIndex, mlApi } } -export function updateJobRules(mlJobService, job, detectorIndex, rules, mlApiServices) { +export function updateJobRules(mlJobService, job, detectorIndex, rules, mlApi) { // Pass just the detector with the edited rule to the updateJob endpoint. const jobId = job.job_id; const jobData = { @@ -152,7 +145,7 @@ export function updateJobRules(mlJobService, job, detectorIndex, rules, mlApiSer jobData.custom_settings = customSettings; } return new Promise((resolve, reject) => { - mlApiServices + mlApi .updateJob({ jobId: jobId, job: jobData }) .then(() => { mlJobService @@ -172,9 +165,9 @@ export function updateJobRules(mlJobService, job, detectorIndex, rules, mlApiSer // Updates an ML filter used in the scope part of a rule, // adding an item to the filter with the specified ID. -export function addItemToFilter(item, filterId, mlApiServices) { +export function addItemToFilter(item, filterId, mlApi) { return new Promise((resolve, reject) => { - mlApiServices.filters + mlApi.filters .updateFilter(filterId, undefined, [item], undefined) .then((updatedFilter) => { resolve(updatedFilter); diff --git a/x-pack/plugins/ml/public/application/components/saved_objects_warning/saved_objects_warning.tsx b/x-pack/plugins/ml/public/application/components/saved_objects_warning/saved_objects_warning.tsx index 05d0888d1df58..e20bb825f7d79 100644 --- a/x-pack/plugins/ml/public/application/components/saved_objects_warning/saved_objects_warning.tsx +++ b/x-pack/plugins/ml/public/application/components/saved_objects_warning/saved_objects_warning.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { MlSavedObjectType } from '../../../../common/types/saved_objects'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { JobSpacesSyncFlyout } from '../job_spaces_sync'; import { usePermissionCheck } from '../../capabilities/check_capabilities'; @@ -27,7 +27,7 @@ export const SavedObjectsWarning: FC = ({ }) => { const { savedObjects: { syncCheck }, - } = useMlApiContext(); + } = useMlApi(); const mounted = useRef(false); const [showWarning, setShowWarning] = useState(false); diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.test.tsx b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.test.tsx index 247623d1dcacb..3fd25534134ae 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.test.tsx +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.test.tsx @@ -25,7 +25,7 @@ const mockEsSearch = jest.fn((body) => ({ const mockEuiTheme = euiThemeLight; jest.mock('../../contexts/kibana', () => ({ - useMlApiContext: () => ({ + useMlApi: () => ({ esSearch: mockEsSearch, }), useMlKibana: () => ({ diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx index cbde25596b60b..dab7dc4117083 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx @@ -36,7 +36,7 @@ import { } from '@kbn/ml-runtime-field-utils'; import { getProcessedFields } from '@kbn/ml-data-grid'; -import { useCurrentThemeVars, useMlApiContext, useMlKibana } from '../../contexts/kibana'; +import { useCurrentThemeVars, useMlApi, useMlKibana } from '../../contexts/kibana'; // Separate imports for lazy loadable VegaChart and related code import { VegaChart } from '../vega_chart'; @@ -117,7 +117,7 @@ export const ScatterplotMatrix: FC = ({ dataView, query, }) => { - const { esSearch } = useMlApiContext(); + const { esSearch } = useMlApi(); const kibana = useMlKibana(); const { services: { application, data }, diff --git a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js index acc17d6b8c0da..a959208fe0c31 100644 --- a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js +++ b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.js @@ -130,7 +130,7 @@ export class ValidateJobUI extends Component { if (typeof duration === 'object' && duration.start !== null && duration.end !== null) { let shouldShowLoadingIndicator = true; - this.props.kibana.services.mlServices.mlApiServices + this.props.kibana.services.mlServices.mlApi .validateJob({ duration, fields, job }) .then((validationMessages) => { const messages = parseMessages(validationMessages, docLinks); diff --git a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.test.js b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.test.js index 5bc57a1a1fd73..265245bcd883f 100644 --- a/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.test.js +++ b/x-pack/plugins/ml/public/application/components/validate_job/validate_job_view.test.js @@ -35,7 +35,7 @@ const mockKibanaContext = { services: { docLinks: { links: { ml: { anomalyDetectionJobTips: 'https://anomalyDetectionJobTips' } } }, notifications: { toasts: { addDanger: jest.fn(), addError: jest.fn() } }, - mlServices: { mlApiServices: { validateJob: mockValidateJob } }, + mlServices: { mlApi: { validateJob: mockValidateJob } }, }, }; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/index.ts b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/index.ts index 991fd607f024e..bd360725fd3c5 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/index.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/index.ts @@ -7,5 +7,5 @@ export { useMlKibana } from './kibana_context'; export { useTimefilter } from './use_timefilter'; -export { useMlApiContext } from './use_ml_api_context'; +export { useMlApi } from './use_ml_api_context'; export { useMlLicenseInfo } from './use_ml_license'; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/kibana_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/kibana_context.ts index 671df792a9375..c31a7e57c73d5 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/kibana_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/kibana_context.ts @@ -61,7 +61,7 @@ export const kibanaContextMock = { charts: chartsServiceMock, fieldFormats: fieldFormatsServiceMock.createStartContract(), mlServices: { - mlApiServices: mlApiServicesMock, + mlApi: mlApiServicesMock, mlCapabilities: { refreshCapabilities: jest.fn(), }, diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_ml_api_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_ml_api_context.ts index b50802dd74b93..e257ad2613701 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_ml_api_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/__mocks__/use_ml_api_context.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; -export const useMlApiContext: () => jest.Mocked = jest.fn(() => { +export const useMlApi: () => jest.Mocked = jest.fn(() => { return { jobs: { getAllJobAndGroupIds: jest.fn(), @@ -18,5 +18,5 @@ export const useMlApiContext: () => jest.Mocked = jest.fn(() => { dataFrameAnalytics: { getDataFrameAnalytics: jest.fn(), }, - } as unknown as jest.Mocked; + } as unknown as jest.Mocked; }); diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts index e8696e9b49068..47836e6495c06 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/index.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/index.ts @@ -12,7 +12,7 @@ export { useNavigateToPath } from './use_navigate_to_path'; export { useUiSettings } from './use_ui_settings_context'; export { useNotifications } from './use_notifications_context'; export { useMlLocator, useMlLink } from './use_create_url'; -export { useMlApiContext } from './use_ml_api_context'; +export { useMlApi } from './use_ml_api_context'; export { useFieldFormatter } from './use_field_formatter'; export { useCurrentThemeVars } from './use_current_theme'; export { useMlLicenseInfo } from './use_ml_license'; diff --git a/x-pack/plugins/ml/public/application/contexts/kibana/use_ml_api_context.ts b/x-pack/plugins/ml/public/application/contexts/kibana/use_ml_api_context.ts index f06610df1e4ce..c403bc5036876 100644 --- a/x-pack/plugins/ml/public/application/contexts/kibana/use_ml_api_context.ts +++ b/x-pack/plugins/ml/public/application/contexts/kibana/use_ml_api_context.ts @@ -7,6 +7,6 @@ import { useMlKibana } from './kibana_context'; -export const useMlApiContext = () => { - return useMlKibana().services.mlServices.mlApiServices; +export const useMlApi = () => { + return useMlKibana().services.mlServices.mlApi; }; diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx index ad6c05d07d4e1..a2623266712dc 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.test.tsx @@ -18,7 +18,7 @@ const mockCountMessages = jest.fn(() => { const mockKibana = { services: { mlServices: { - mlApiServices: { + mlApi: { notifications: { countMessages$: mockCountMessages, }, @@ -67,7 +67,7 @@ describe('useMlNotifications', () => { }); test('retries polling on error with 1m delay', () => { - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$.mockReturnValueOnce( + mockKibana.services.mlServices.mlApi.notifications.countMessages$.mockReturnValueOnce( throwError(() => new Error('Cluster is down')) ); @@ -79,24 +79,24 @@ describe('useMlNotifications', () => { jest.advanceTimersByTime(0); }); - expect( - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$ - ).toHaveBeenCalledTimes(1); - expect( - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$ - ).toHaveBeenCalledWith({ lastCheckedAt: 1663340537063 }); + expect(mockKibana.services.mlServices.mlApi.notifications.countMessages$).toHaveBeenCalledTimes( + 1 + ); + expect(mockKibana.services.mlServices.mlApi.notifications.countMessages$).toHaveBeenCalledWith({ + lastCheckedAt: 1663340537063, + }); act(() => { // ticks 4 minutes jest.advanceTimersByTime(60000 * 4); }); - expect( - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$ - ).toHaveBeenCalledTimes(4); - expect( - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$ - ).toHaveBeenCalledWith({ lastCheckedAt: 1663340537063 }); + expect(mockKibana.services.mlServices.mlApi.notifications.countMessages$).toHaveBeenCalledTimes( + 4 + ); + expect(mockKibana.services.mlServices.mlApi.notifications.countMessages$).toHaveBeenCalledWith({ + lastCheckedAt: 1663340537063, + }); }); test('returns the default values', () => { @@ -244,7 +244,7 @@ describe('useMlNotifications', () => { }); expect( - mockKibana.services.mlServices.mlApiServices.notifications.countMessages$ + mockKibana.services.mlServices.mlApi.notifications.countMessages$ ).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx index dc37535517659..d0ffdf528fc7c 100644 --- a/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx +++ b/x-pack/plugins/ml/public/application/contexts/ml/ml_notifications_context.tsx @@ -42,7 +42,7 @@ export const MlNotificationsContext = React.createContext<{ export const MlNotificationsContextProvider: FC> = ({ children }) => { const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, application: { capabilities }, }, } = useMlKibana(); @@ -75,7 +75,7 @@ export const MlNotificationsContextProvider: FC> = ({ setLatestRequestedAt(lastCheckedAtQuery); }), switchMap((lastCheckedAtQuery) => - mlApiServices.notifications.countMessages$({ + mlApi.notifications.countMessages$({ lastCheckedAt: lastCheckedAtQuery, }) ), @@ -89,7 +89,7 @@ export const MlNotificationsContextProvider: FC> = ({ subscription.unsubscribe(); }; }, - [canGetNotifications, lastCheckedAt$, mlApiServices.notifications] + [canGetNotifications, lastCheckedAt$, mlApi.notifications] ); return ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts index a636974e68b94..3264c7cc11f7a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts @@ -20,7 +20,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { Dictionary } from '../../../../common/types/common'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; export type IndexPattern = string; @@ -289,7 +289,7 @@ export enum REGRESSION_STATS { } interface LoadEvalDataConfig { - mlApiServices: MlApiServices; + mlApi: MlApi; isTraining?: boolean; index: string; dependentVariable: string; @@ -304,7 +304,7 @@ interface LoadEvalDataConfig { } export const loadEvalData = async ({ - mlApiServices, + mlApi, isTraining, index, dependentVariable, @@ -362,7 +362,7 @@ export const loadEvalData = async ({ }; try { - const evalResult = await mlApiServices.dataFrameAnalytics.evaluateDataFrameAnalytics(config); + const evalResult = await mlApi.dataFrameAnalytics.evaluateDataFrameAnalytics(config); results.success = true; results.eval = evalResult; return results; @@ -373,7 +373,7 @@ export const loadEvalData = async ({ }; interface LoadDocsCountConfig { - mlApiServices: MlApiServices; + mlApi: MlApi; ignoreDefaultQuery?: boolean; isTraining?: boolean; searchQuery: estypes.QueryDslQueryContainer; @@ -387,7 +387,7 @@ interface LoadDocsCountResponse { } export const loadDocsCount = async ({ - mlApiServices, + mlApi, ignoreDefaultQuery = true, isTraining, searchQuery, @@ -402,7 +402,7 @@ export const loadDocsCount = async ({ query, }; - const resp: TrackTotalHitsSearchResponse = await mlApiServices.esSearch({ + const resp: TrackTotalHitsSearchResponse = await mlApi.esSearch({ index: destIndex, size: 0, body, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts index bd289f3a1cdd7..6e2cb20025e72 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts @@ -12,17 +12,17 @@ import type { EsSorting, UseDataGridReturnType } from '@kbn/ml-data-grid'; import { getProcessedFields, INDEX_STATUS } from '@kbn/ml-data-grid'; import { mlJobCapsServiceAnalyticsFactory } from '../../services/new_job_capabilities/new_job_capabilities_service_analytics'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; export const getIndexData = async ( - mlApiServices: MlApiServices, + mlApi: MlApi, jobConfig: DataFrameAnalyticsConfig | undefined, dataGrid: UseDataGridReturnType, searchQuery: estypes.QueryDslQueryContainer, options: { didCancel: boolean } ) => { if (jobConfig !== undefined) { - const newJobCapsServiceAnalytics = mlJobCapsServiceAnalyticsFactory(mlApiServices); + const newJobCapsServiceAnalytics = mlJobCapsServiceAnalyticsFactory(mlApi); const { pagination, @@ -50,7 +50,7 @@ export const getIndexData = async ( const { pageIndex, pageSize } = pagination; // TODO: remove results_field from `fields` when possible - const resp: estypes.SearchResponse = await mlApiServices.esSearch({ + const resp: estypes.SearchResponse = await mlApi.esSearch({ index: jobConfig.dest.index, body: { fields: ['*'], diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_fields.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_fields.ts index 0cc1bb0b587c0..f4bcec71fdcdf 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_fields.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_fields.ts @@ -9,20 +9,20 @@ import type { ES_FIELD_TYPES } from '@kbn/field-types'; import type { DataFrameAnalyticsConfig } from '@kbn/ml-data-frame-analytics-utils'; import { mlJobCapsServiceAnalyticsFactory } from '../../services/new_job_capabilities/new_job_capabilities_service_analytics'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; export interface FieldTypes { [key: string]: ES_FIELD_TYPES; } export const getIndexFields = ( - mlApiServices: MlApiServices, + mlApi: MlApi, jobConfig: DataFrameAnalyticsConfig | undefined, needsDestIndexFields: boolean ) => { if (jobConfig !== undefined) { const { selectedFields: defaultSelected, docFields } = mlJobCapsServiceAnalyticsFactory( - mlApiServices + mlApi ).getDefaultFields(jobConfig, needsDestIndexFields); const types: FieldTypes = {}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts index fba862558b766..3ff08a2845c88 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts @@ -19,7 +19,7 @@ import { type TotalFeatureImportance, } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlApiContext, useMlKibana } from '../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../contexts/kibana'; import { useNewJobCapsServiceAnalytics } from '../../services/new_job_capabilities/new_job_capabilities_service_analytics'; import { useMlIndexUtils } from '../../util/index_service'; @@ -35,7 +35,7 @@ export const useResultsViewConfig = (jobId: string) => { }, } = useMlKibana(); const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { getDataViewIdFromName } = useMlIndexUtils(); const trainedModelsApiService = useTrainedModelsApiService(); const newJobCapsServiceAnalytics = useNewJobCapsServiceAnalytics(); @@ -62,9 +62,9 @@ export const useResultsViewConfig = (jobId: string) => { setIsLoadingJobConfig(false); try { - const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId); + const analyticsConfigs = await mlApi.dataFrameAnalytics.getDataFrameAnalytics(jobId); - const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); + const analyticsStats = await mlApi.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) ? analyticsStats.data_frame_analytics[0] : undefined; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx index 9b8dec570a5e9..e87201cbb7b11 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/advanced_step/advanced_step_form.tsx @@ -32,7 +32,7 @@ import { import { HyperParameters } from './hyper_parameters'; import type { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; import { getModelMemoryLimitErrors } from '../../../analytics_management/hooks/use_create_analytics_form/reducer'; -import { useMlKibana, useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlKibana, useMlApi } from '../../../../../contexts/kibana'; import { DEFAULT_MODEL_MEMORY_LIMIT } from '../../../analytics_management/hooks/use_create_analytics_form/state'; import { ANALYTICS_STEPS } from '../../page'; import { fetchExplainData } from '../shared'; @@ -134,7 +134,7 @@ export const AdvancedStepForm: FC = ({ const { services: { docLinks }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const classAucRocDocLink = docLinks.links.ml.classificationAucRoc; const { setEstimatedModelMemoryLimit, setFormState } = actions; @@ -207,7 +207,7 @@ export const AdvancedStepForm: FC = ({ setFetchingAdvancedParamErrors(true); (async function () { const { success, errorMessage, errorReason, expectedMemory } = await fetchExplainData( - mlApiServices, + mlApi, form ); const paramErrors: AdvancedParamErrors = {}; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx index 4f737c1137663..c0920b39d47fc 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -29,7 +29,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import { DataGrid } from '@kbn/ml-data-grid'; import { SEARCH_QUERY_LANGUAGE } from '@kbn/ml-query-utils'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import { EuiComboBoxWithFieldStats, FieldStatsFlyoutProvider, @@ -116,7 +116,7 @@ export const ConfigurationStepForm: FC = ({ }) => { const { services } = useMlKibana(); const toastNotifications = services.notifications.toasts; - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const newJobCapsServiceAnalytics = useNewJobCapsServiceAnalytics(); const { selectedDataView, selectedSavedSearch } = useDataSource(); const { savedSearchQuery, savedSearchQueryStr } = useSavedSearch(); @@ -288,7 +288,7 @@ export const ConfigurationStepForm: FC = ({ fieldSelection, errorMessage, noDocsContainMappedFields: noDocsWithFields, - } = await fetchExplainData(mlApiServices, formToUse); + } = await fetchExplainData(mlApi, formToUse); if (success) { if (shouldUpdateEstimatedMml) { @@ -444,7 +444,7 @@ export const ConfigurationStepForm: FC = ({ fieldSelection, errorMessage, noDocsContainMappedFields: noDocsWithFields, - } = await fetchExplainData(mlApiServices, formCopy); + } = await fetchExplainData(mlApi, formCopy); if (success) { // update the field selection table const hasRequiredFields = fieldSelection.some( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx index a2a6e965c3e70..2f329be788398 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_analytics_advanced_editor/create_analytics_advanced_editor.tsx @@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '@kbn/ml-error-utils'; import { dynamic } from '@kbn/shared-ux-utility'; -import { useMlApiContext, useNotifications } from '../../../../../contexts/kibana'; +import { useMlApi, useNotifications } from '../../../../../contexts/kibana'; import type { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form'; import { CreateStep } from '../create_step'; import { ANALYTICS_STEPS } from '../../page'; @@ -24,7 +24,7 @@ const EditorComponent = dynamic(async () => ({ })); export const CreateAnalyticsAdvancedEditor: FC = (props) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { actions, state } = props; const { setAdvancedEditorRawString, setFormState } = actions; @@ -43,7 +43,7 @@ export const CreateAnalyticsAdvancedEditor: FC = (prop () => debounce(async () => { try { - const results = await ml.dataFrameAnalytics.jobsExist([jobId], true); + const results = await mlApi.dataFrameAnalytics.jobsExist([jobId], true); setFormState({ jobIdExists: results[jobId].exists }); } catch (e) { toasts.addDanger( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx index b7dac69e1226e..715733c163314 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step_footer/create_step_footer.tsx @@ -16,7 +16,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import { getDataFrameAnalyticsProgressPhase } from '../../../analytics_management/components/analytics_list/common'; import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import { BackToListPanel } from '../back_to_list_panel'; import { ViewResultsPanel } from '../view_results_panel'; import { ProgressStats } from './progress_stats'; @@ -48,7 +48,7 @@ export const CreateStepFooter: FC = ({ jobId, jobType, showProgress }) => const { services: { notifications }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); useEffect(() => { setInitialized(true); @@ -59,7 +59,7 @@ export const CreateStepFooter: FC = ({ jobId, jobType, showProgress }) => const interval = setInterval(async () => { try { - const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); + const analyticsStats = await mlApi.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); const jobStats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) ? analyticsStats.data_frame_analytics[0] : undefined; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx index d80c23732dcbd..f43ce7bd2fb9b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/details_step/details_step_form.tsx @@ -14,7 +14,7 @@ import { extractErrorMessage } from '@kbn/ml-error-utils'; import { CreateDataViewForm } from '@kbn/ml-data-view-utils/components/create_data_view_form_row'; import { DestinationIndexForm } from '@kbn/ml-creation-wizard-utils/components/destination_index_form'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import type { CreateAnalyticsStepProps } from '../../../analytics_management/hooks/use_create_analytics_form'; import { JOB_ID_MAX_LENGTH } from '../../../../../../../common/constants/validation'; import { ContinueButton } from '../continue_button'; @@ -42,7 +42,7 @@ export const DetailsStepForm: FC = ({ const { services: { docLinks, notifications }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const canCreateDataView = useCanCreateDataView(); const { dataViewAvailableTimeFields, onTimeFieldChanged } = useDataViewTimeFields({ @@ -90,7 +90,7 @@ export const DetailsStepForm: FC = ({ const debouncedIndexCheck = debounce(async () => { try { - const resp = await ml.checkIndicesExists({ indices: [destinationIndex] }); + const resp = await mlApi.checkIndicesExists({ indices: [destinationIndex] }); setFormState({ destinationIndexNameExists: resp[destinationIndex].exists }); } catch (e) { notifications.toasts.addDanger( @@ -106,7 +106,7 @@ export const DetailsStepForm: FC = ({ () => debounce(async () => { try { - const results = await ml.dataFrameAnalytics.jobsExist([jobId], true); + const results = await mlApi.dataFrameAnalytics.jobsExist([jobId], true); setFormState({ jobIdExists: results[jobId].exists }); } catch (e) { notifications.toasts.addDanger( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts index 680415e189354..44150ae0e047a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts @@ -13,9 +13,9 @@ import type { } from '@kbn/ml-data-frame-analytics-utils'; import type { State } from '../../../analytics_management/hooks/use_create_analytics_form/state'; import { getJobConfigFromFormState } from '../../../analytics_management/hooks/use_create_analytics_form/state'; -import type { MlApiServices } from '../../../../../services/ml_api_service'; +import type { MlApi } from '../../../../../services/ml_api_service'; -export const fetchExplainData = async (mlApiServices: MlApiServices, formState: State['form']) => { +export const fetchExplainData = async (mlApi: MlApi, formState: State['form']) => { const jobConfig = getJobConfigFromFormState(formState); let errorMessage = ''; let errorReason = ''; @@ -29,7 +29,7 @@ export const fetchExplainData = async (mlApiServices: MlApiServices, formState: delete jobConfig.model_memory_limit; delete jobConfig.analyzed_fields; const resp: DfAnalyticsExplainResponse = - await mlApiServices.dataFrameAnalytics.explainDataFrameAnalytics(jobConfig); + await mlApi.dataFrameAnalytics.explainDataFrameAnalytics(jobConfig); expectedMemory = resp.memory_estimation?.expected_memory_without_disk; fieldSelection = resp.field_selection || []; } catch (error) { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/validation_step/validation_step_wrapper.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/validation_step/validation_step_wrapper.tsx index d0adffc24ec01..3c8cba36458a2 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/validation_step/validation_step_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/validation_step/validation_step_wrapper.tsx @@ -18,7 +18,7 @@ import type { CreateAnalyticsStepProps } from '../../../analytics_management/hoo import { ValidationStep } from './validation_step'; import { ValidationStepDetails } from './validation_step_details'; import { ANALYTICS_STEPS } from '../../page'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import { getJobConfigFromFormState } from '../../../analytics_management/hooks/use_create_analytics_form/state'; import type { CalloutMessage, @@ -53,7 +53,7 @@ export const ValidationStepWrapper: FC = ({ const showDetails = step !== ANALYTICS_STEPS.VALIDATION && stepActivated === true; const { dataFrameAnalytics: { validateDataFrameAnalytics }, - } = useMlApiContext(); + } = useMlApi(); const dataTestSubj = `mlAnalyticsCreateJobWizardValidationStepWrapper${ showValidationStep ? ' active' : '' diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_has_index_permission.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_has_index_permission.ts index 2fc8fb6b85f14..a618d172cbb4c 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_has_index_permission.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_has_index_permission.ts @@ -17,7 +17,7 @@ export const useHasRequiredIndicesPermissions = ( const { services: { mlServices: { - mlApiServices: { hasPrivileges }, + mlApi: { hasPrivileges }, }, }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index 80abafecd83ed..a0b995fabffc8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -34,7 +34,7 @@ import { INDEX_STATUS, } from '@kbn/ml-data-grid'; -import { useMlApiContext } from '../../../../contexts/kibana'; +import { useMlApi } from '../../../../contexts/kibana'; import { DataLoader } from '../../../../datavisualizer/index_based/data_loader'; type IndexSearchResponse = estypes.SearchResponse; @@ -81,7 +81,7 @@ export const useIndexData = ( toastNotifications: CoreSetup['notifications']['toasts'], runtimeMappings?: RuntimeMappings ): UseIndexDataReturnType => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); // Fetch 500 random documents to determine populated fields. // This is a workaround to avoid passing potentially thousands of unpopulated fields // (for example, as part of filebeat/metricbeat/ECS based indices) @@ -110,7 +110,7 @@ export const useIndexData = ( }; try { - const resp: IndexSearchResponse = await ml.esSearch(esSearchRequest); + const resp: IndexSearchResponse = await mlApi.esSearch(esSearchRequest); const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields ?? {})); // Get all field names for each returned doc and flatten it @@ -216,7 +216,7 @@ export const useIndexData = ( }; try { - const resp: IndexSearchResponse = await ml.esSearch(esSearchRequest); + const resp: IndexSearchResponse = await mlApi.esSearch(esSearchRequest); if ( resp.aggregations && @@ -258,7 +258,7 @@ export const useIndexData = ( ]); const dataLoader = useMemo( - () => new DataLoader(dataView, ml), + () => new DataLoader(dataView, mlApi), // eslint-disable-next-line react-hooks/exhaustive-deps [dataView] ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx index 4890ac59ffbe6..aa276e55ba024 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/page.tsx @@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import type { DataFrameAnalyticsId } from '@kbn/ml-data-frame-analytics-utils'; import { useDataSource } from '../../../contexts/ml/data_source_context'; -import { useMlApiContext } from '../../../contexts/kibana'; +import { useMlApi } from '../../../contexts/kibana'; import { useCreateAnalyticsForm } from '../analytics_management/hooks/use_create_analytics_form'; import { CreateAnalyticsAdvancedEditor } from './components/create_analytics_advanced_editor'; import { @@ -46,7 +46,7 @@ interface Props { } export const Page: FC = ({ jobId }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [currentStep, setCurrentStep] = useState(ANALYTICS_STEPS.CONFIGURATION); const [activatedSteps, setActivatedSteps] = useState([ true, @@ -71,7 +71,10 @@ export const Page: FC = ({ jobId }) => { if (selectedDataView) { (async function () { if (jobId !== undefined) { - const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId, true); + const analyticsConfigs = await mlApi.dataFrameAnalytics.getDataFrameAnalytics( + jobId, + true + ); if ( Array.isArray(analyticsConfigs.data_frame_analytics) && analyticsConfigs.data_frame_analytics.length > 0 diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_confusion_matrix.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_confusion_matrix.ts index 74ca62a874081..132ce9bd12aae 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_confusion_matrix.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_confusion_matrix.ts @@ -17,7 +17,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import { useNewJobCapsServiceAnalytics } from '../../../../../services/new_job_capabilities/new_job_capabilities_service_analytics'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import type { ResultsSearchQuery, ClassificationMetricItem } from '../../../../common/analytics'; import { isClassificationEvaluateResponse } from '../../../../common/analytics'; @@ -60,7 +60,7 @@ export const useConfusionMatrix = ( jobConfig: DataFrameAnalyticsConfig, searchQuery: ResultsSearchQuery ) => { - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const newJobCapsServiceAnalytics = useNewJobCapsServiceAnalytics(); const [confusionMatrixData, setConfusionMatrixData] = useState([]); const [overallAccuracy, setOverallAccuracy] = useState(null); @@ -89,7 +89,7 @@ export const useConfusionMatrix = ( } const evalData = await loadEvalData({ - mlApiServices, + mlApi, isTraining, index: jobConfig.dest.index, dependentVariable, @@ -101,7 +101,7 @@ export const useConfusionMatrix = ( }); const docsCountResp = await loadDocsCount({ - mlApiServices, + mlApi, isTraining, searchQuery, resultsField, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_roc_curve.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_roc_curve.ts index 88dd6f20cd75d..de85a818b6c16 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_roc_curve.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/use_roc_curve.ts @@ -16,7 +16,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import { useNewJobCapsServiceAnalytics } from '../../../../../services/new_job_capabilities/new_job_capabilities_service_analytics'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import type { ResultsSearchQuery } from '../../../../common/analytics'; import { isClassificationEvaluateResponse } from '../../../../common/analytics'; @@ -40,7 +40,7 @@ export const useRocCurve = ( searchQuery: ResultsSearchQuery, columns: string[] ) => { - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const newJobCapsServiceAnalytics = useNewJobCapsServiceAnalytics(); const classificationClasses = columns.filter( (d) => d !== ACTUAL_CLASS_ID && d !== OTHER_CLASS_ID @@ -77,7 +77,7 @@ export const useRocCurve = ( for (let i = 0; i < classificationClasses.length; i++) { const rocCurveClassName = classificationClasses[i]; const evalData = await loadEvalData({ - mlApiServices, + mlApi, isTraining: isTrainingFilter(searchQuery, resultsField), index: jobConfig.dest.index, dependentVariable, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_analytics.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_analytics.tsx index 10e302fad2249..2b90712726666 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_analytics.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_analytics.tsx @@ -21,7 +21,7 @@ import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_manag import type { DataFrameAnalyticsListRow } from '../../../analytics_management/components/analytics_list/common'; import { DATA_FRAME_MODE } from '../../../analytics_management/components/analytics_list/common'; import { ExpandedRow } from '../../../analytics_management/components/analytics_list/expanded_row'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import type { ExpandableSectionProps } from './expandable_section'; import { ExpandableSection, HEADER_ITEMS_LOADING } from './expandable_section'; @@ -75,13 +75,13 @@ interface ExpandableSectionAnalyticsProps { } export const ExpandableSectionAnalytics: FC = ({ jobId }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [expandedRowItem, setExpandedRowItem] = useState(); const fetchStats = async () => { - const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(jobId); - const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); + const analyticsConfigs = await mlApi.dataFrameAnalytics.getDataFrameAnalytics(jobId); + const analyticsStats = await mlApi.dataFrameAnalytics.getDataFrameAnalyticsStats(jobId); const config = analyticsConfigs.data_frame_analytics[0]; const stats = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index 34ad61d02cd3b..8d2d70dd898a4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -34,7 +34,7 @@ import { } from '@kbn/ml-data-grid'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import { DataLoader } from '../../../../../datavisualizer/index_based/data_loader'; import { getIndexData, getIndexFields } from '../../../../common'; @@ -51,7 +51,7 @@ export const useExplorationResults = ( notifications: { toasts }, }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [baseline, setBaseLine] = useState(); const trainedModelsApiService = useTrainedModelsApiService(); @@ -63,7 +63,7 @@ export const useExplorationResults = ( if (jobConfig !== undefined) { const resultsField = jobConfig.dest.results_field!; - const { fieldTypes } = getIndexFields(ml, jobConfig, needsDestIndexFields); + const { fieldTypes } = getIndexFields(mlApi, jobConfig, needsDestIndexFields); columns.push( ...getDataGridSchemasFromFieldTypes(fieldTypes, resultsField).sort((a: any, b: any) => sortExplorationResultsFields(a.id, b.id, jobConfig) @@ -84,7 +84,7 @@ export const useExplorationResults = ( // passed on to `getIndexData`. useEffect(() => { const options = { didCancel: false }; - getIndexData(ml, jobConfig, dataGrid, searchQuery, options); + getIndexData(mlApi, jobConfig, dataGrid, searchQuery, options); return () => { options.didCancel = true; }; @@ -93,7 +93,7 @@ export const useExplorationResults = ( }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( - () => (dataView !== undefined ? new DataLoader(dataView, ml) : undefined), + () => (dataView !== undefined ? new DataLoader(dataView, mlApi) : undefined), // eslint-disable-next-line react-hooks/exhaustive-deps [dataView] ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index 5b9ce4646b9e7..8c362cd1b06b4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -33,7 +33,7 @@ import { COLOR_RANGE, COLOR_RANGE_SCALE, } from '../../../../../components/color_range_legend'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import { getIndexData, getIndexFields } from '../../../../common'; @@ -50,7 +50,7 @@ export const useOutlierData = ( notifications: { toasts }, }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const needsDestIndexFields = dataView !== undefined && dataView.title === jobConfig?.source.index[0]; @@ -59,7 +59,7 @@ export const useOutlierData = ( if (jobConfig !== undefined && dataView !== undefined) { const resultsField = jobConfig.dest.results_field; - const { fieldTypes } = getIndexFields(ml, jobConfig, needsDestIndexFields); + const { fieldTypes } = getIndexFields(mlApi, jobConfig, needsDestIndexFields); newColumns.push( ...getDataGridSchemasFromFieldTypes(fieldTypes, resultsField!).sort((a: any, b: any) => sortExplorationResultsFields(a.id, b.id, jobConfig) @@ -92,7 +92,7 @@ export const useOutlierData = ( // passed on to `getIndexData`. useEffect(() => { const options = { didCancel: false }; - getIndexData(ml, jobConfig, dataGrid, searchQuery, options); + getIndexData(mlApi, jobConfig, dataGrid, searchQuery, options); return () => { options.didCancel = true; }; @@ -101,7 +101,7 @@ export const useOutlierData = ( }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( - () => (dataView !== undefined ? new DataLoader(dataView, ml) : undefined), + () => (dataView !== undefined ? new DataLoader(dataView, mlApi) : undefined), // skip ml API services from deps check // eslint-disable-next-line react-hooks/exhaustive-deps [dataView] diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx index 398e0ecb61505..935a1eecb8538 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/regression_exploration/evaluate_panel.tsx @@ -28,7 +28,7 @@ import { } from '@kbn/ml-data-frame-analytics-utils'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import type { Eval } from '../../../../common'; import { getValuesFromResponse, loadEvalData, loadDocsCount } from '../../../../common'; @@ -65,7 +65,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) const { services: { docLinks }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const docLink = docLinks.links.ml.regressionEvaluation; const [trainingEval, setTrainingEval] = useState(defaultEval); const [generalizationEval, setGeneralizationEval] = useState(defaultEval); @@ -85,7 +85,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) setIsLoadingGeneralization(true); const genErrorEval = await loadEvalData({ - mlApiServices, + mlApi, isTraining: false, index, dependentVariable, @@ -124,7 +124,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) setIsLoadingTraining(true); const trainingErrorEval = await loadEvalData({ - mlApiServices, + mlApi, isTraining: true, index, dependentVariable, @@ -162,7 +162,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) const loadData = async () => { loadGeneralizationData(false); const genDocsCountResp = await loadDocsCount({ - mlApiServices, + mlApi, ignoreDefaultQuery: false, isTraining: false, searchQuery, @@ -177,7 +177,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, searchQuery }) loadTrainingData(false); const trainDocsCountResp = await loadDocsCount({ - mlApiServices, + mlApi, ignoreDefaultQuery: false, isTraining: true, searchQuery, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx index d9994a47e6a88..fd7cf90dbb7df 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/page.tsx @@ -20,7 +20,7 @@ import { RegressionExploration } from './components/regression_exploration'; import { ClassificationExploration } from './components/classification_exploration'; import { HelpMenu } from '../../../components/help_menu'; -import { useMlKibana, useMlApiContext } from '../../../contexts/kibana'; +import { useMlKibana, useMlApi } from '../../../contexts/kibana'; import { MlPageHeader } from '../../../components/page_header'; import type { AnalyticsSelectorIds } from '../components/analytics_selector'; import { AnalyticsIdSelector, AnalyticsIdSelectorControls } from '../components/analytics_selector'; @@ -39,7 +39,7 @@ export const Page: FC<{ } = useMlKibana(); const { dataFrameAnalytics: { getDataFrameAnalytics }, - } = useMlApiContext(); + } = useMlApi(); const helpLink = docLinks.links.ml.dataFrameAnalytics; const jobIdToUse = jobId ?? analyticsId?.job_id; const [analysisTypeToUse, setAnalysisTypeToUse] = useState< diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx index 2ae6a2ae1b265..08abae19d3401 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx @@ -22,7 +22,7 @@ jest.mock('../../../../../capabilities/check_capabilities', () => ({ })); jest.mock('../../../../../contexts/kibana', () => ({ - useMlApiContext: jest.fn(), + useMlApi: jest.fn(), useMlKibana: () => ({ services: { ...mockCoreServices.createStart(), data: { data_view: { find: jest.fn() } } }, }), diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx index cc66cf0c34dbf..77aa8b669011c 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_edit/edit_action_flyout.tsx @@ -36,7 +36,7 @@ import { type UpdateDataFrameAnalyticsConfig, } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlKibana, useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlKibana, useMlApi } from '../../../../../contexts/kibana'; import { useToastNotificationService } from '../../../../../services/toast_notification_service'; import type { MemoryInputValidatorResult } from '../../../../../../../common/util/validators'; import { memoryInputValidator } from '../../../../../../../common/util/validators'; @@ -69,10 +69,10 @@ export const EditActionFlyout: FC> = ({ closeFlyout, item } } = useMlKibana(); const { refresh } = useRefreshAnalyticsList(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { dataFrameAnalytics: { getDataFrameAnalytics }, - } = ml; + } = mlApi; const toastNotificationService = useToastNotificationService(); @@ -122,7 +122,7 @@ export const EditActionFlyout: FC> = ({ closeFlyout, item } const updateDataFrameAnalytics = async (updateConfig: UpdateDataFrameAnalyticsConfig) => { try { - await ml.dataFrameAnalytics.updateDataFrameAnalytics(jobId, updateConfig); + await mlApi.dataFrameAnalytics.updateDataFrameAnalytics(jobId, updateConfig); notifications.toasts.addSuccess( i18n.translate('xpack.ml.dataframe.analyticsList.editFlyoutSuccessMessage', { defaultMessage: 'Analytics job {jobId} has been updated.', diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_messages_pane.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_messages_pane.tsx index cdfd3f00ff3dc..ed16443cff7b1 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_messages_pane.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row_messages_pane.tsx @@ -10,7 +10,7 @@ import './expanded_row_messages_pane.scss'; import type { FC } from 'react'; import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import { useRefreshAnalyticsList } from '../../../../common'; import { JobMessages } from '../../../../../components/job_messages'; import type { JobMessage } from '../../../../../../../common/types/audit_message'; @@ -22,7 +22,7 @@ interface Props { } export const ExpandedRowMessagesPane: FC = ({ analyticsId, dataTestSubj }) => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [messages, setMessages] = useState([]); const [isLoading, setIsLoading] = useState(false); const [errorMessage, setErrorMessage] = useState(''); @@ -31,7 +31,7 @@ export const ExpandedRowMessagesPane: FC = ({ analyticsId, dataTestSubj } const getMessages = useCallback(async () => { try { setIsLoading(true); - const messagesResp = await ml.dataFrameAnalytics.getAnalyticsAuditMessages(analyticsId); + const messagesResp = await mlApi.dataFrameAnalytics.getAnalyticsAuditMessages(analyticsId); setIsLoading(false); setMessages(messagesResp); } catch (error) { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts index f458c11551698..07fa5e133d701 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts @@ -13,7 +13,7 @@ import { extractErrorMessage } from '@kbn/ml-error-utils'; import { extractErrorProperties } from '@kbn/ml-error-utils'; import type { DataFrameAnalyticsConfig } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlApiContext, useMlKibana } from '../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../contexts/kibana'; import type { DeepReadonly } from '../../../../../../../common/types/common'; import { useRefreshAnalyticsList } from '../../../../common'; @@ -49,7 +49,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { data: { dataViews }, }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [state, dispatch] = useReducer(reducer, getInitialState()); const { refresh } = useRefreshAnalyticsList(); @@ -95,7 +95,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { ); try { - const creationResp = await ml.dataFrameAnalytics.createDataFrameAnalytics( + const creationResp = await mlApi.dataFrameAnalytics.createDataFrameAnalytics( jobId, analyticsJobConfig, createDataView, @@ -168,7 +168,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const startAnalyticsJob = async () => { try { - const response = await ml.dataFrameAnalytics.startDataFrameAnalytics(jobId); + const response = await mlApi.dataFrameAnalytics.startDataFrameAnalytics(jobId); if (response.acknowledged !== true) { throw new Error(response); } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts index 281ebeccabac9..074f3257580c2 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts @@ -8,18 +8,18 @@ import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '@kbn/ml-error-utils'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import { useToastNotificationService } from '../../../../../services/toast_notification_service'; import { refreshAnalyticsList$, REFRESH_ANALYTICS_LIST_STATE } from '../../../../common'; import type { DataFrameAnalyticsListRow } from '../../components/analytics_list/common'; export const useDeleteAnalytics = () => { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); return async (analyticsConfig: DataFrameAnalyticsListRow['config']) => { try { - await ml.dataFrameAnalytics.deleteDataFrameAnalytics(analyticsConfig.id); + await mlApi.dataFrameAnalytics.deleteDataFrameAnalytics(analyticsConfig.id); toastNotificationService.displaySuccessToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsSuccessMessage', { defaultMessage: 'Request to delete data frame analytics job {analyticsId} acknowledged.', @@ -41,7 +41,7 @@ export const useDeleteAnalytics = () => { export const useDeleteAnalyticsAndDestIndex = () => { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); return async ( analyticsConfig: DataFrameAnalyticsListRow['config'], @@ -50,7 +50,7 @@ export const useDeleteAnalyticsAndDestIndex = () => { ) => { const destinationIndex = analyticsConfig.dest.index; try { - const status = await ml.dataFrameAnalytics.deleteDataFrameAnalyticsAndDestIndex( + const status = await mlApi.dataFrameAnalytics.deleteDataFrameAnalyticsAndDestIndex( analyticsConfig.id, deleteDestIndex, deleteDestDataView @@ -134,11 +134,11 @@ export const useDeleteAnalyticsAndDestIndex = () => { export const useCanDeleteIndex = () => { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); return async (indexName: string) => { try { - const privilege = await ml.hasPrivileges({ + const privilege = await mlApi.hasPrivileges({ index: [ { names: [indexName], // uses wildcard diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts index 9a7cccc77aa3f..b143271c61cc8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/get_analytics.ts @@ -11,7 +11,7 @@ import { type DataFrameAnalysisConfigType, DATA_FRAME_TASK_STATE, } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import type { GetDataFrameAnalyticsStatsResponseError, GetDataFrameAnalyticsStatsResponseOk, @@ -116,7 +116,7 @@ export const useGetAnalytics = ( setJobsAwaitingNodeCount: React.Dispatch>, blockRefresh: boolean ): GetAnalytics => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); let concurrentLoads = 0; @@ -130,8 +130,8 @@ export const useGetAnalytics = ( } try { - const analyticsConfigs = await ml.dataFrameAnalytics.getDataFrameAnalytics(); - const analyticsStats = await ml.dataFrameAnalytics.getDataFrameAnalyticsStats(); + const analyticsConfigs = await mlApi.dataFrameAnalytics.getDataFrameAnalytics(); + const analyticsStats = await mlApi.dataFrameAnalytics.getDataFrameAnalyticsStats(); const analyticsStatsResult = isGetDataFrameAnalyticsStatsResponseOk(analyticsStats) ? getAnalyticsJobsStats(analyticsStats) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/start_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/start_analytics.ts index a5b0dfd32ffa5..b938872c76163 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/start_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/start_analytics.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import { useToastNotificationService } from '../../../../../services/toast_notification_service'; import { refreshAnalyticsList$, REFRESH_ANALYTICS_LIST_STATE } from '../../../../common'; @@ -16,11 +16,11 @@ import type { DataFrameAnalyticsListRow } from '../../components/analytics_list/ export const useStartAnalytics = () => { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); return async (d: DataFrameAnalyticsListRow) => { try { - await ml.dataFrameAnalytics.startDataFrameAnalytics(d.config.id); + await mlApi.dataFrameAnalytics.startDataFrameAnalytics(d.config.id); toastNotificationService.displaySuccessToast( i18n.translate('xpack.ml.dataframe.analyticsList.startAnalyticsSuccessMessage', { defaultMessage: 'Request to start data frame analytics {analyticsId} acknowledged.', diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/stop_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/stop_analytics.ts index af0b746a17332..af471ab21df21 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/stop_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/stop_analytics.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; -import { useMlApiContext } from '../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../contexts/kibana'; import { useToastNotificationService } from '../../../../../services/toast_notification_service'; import { refreshAnalyticsList$, REFRESH_ANALYTICS_LIST_STATE } from '../../../../common'; @@ -17,11 +17,11 @@ import { isDataFrameAnalyticsFailed } from '../../components/analytics_list/comm export const useStopAnalytics = () => { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); return async (d: DataFrameAnalyticsListRow) => { try { - await ml.dataFrameAnalytics.stopDataFrameAnalytics( + await mlApi.dataFrameAnalytics.stopDataFrameAnalytics( d.config.id, isDataFrameAnalyticsFailed(d.stats.state) ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/components/analytics_selector/analytics_id_selector.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/components/analytics_selector/analytics_id_selector.tsx index 7878e58193b89..bf786436919a9 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/components/analytics_selector/analytics_id_selector.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/components/analytics_selector/analytics_id_selector.tsx @@ -29,7 +29,7 @@ import { useTrainedModelsApiService } from '../../../../services/ml_api_service/ import type { GetDataFrameAnalyticsResponse } from '../../../../services/ml_api_service/data_frame_analytics'; import { useToastNotificationService } from '../../../../services/toast_notification_service'; import { ModelsTableToConfigMapping } from '../../../../model_management/config_mapping'; -import { useMlApiContext } from '../../../../contexts/kibana'; +import { useMlApi } from '../../../../contexts/kibana'; import type { TrainedModelConfigResponse } from '../../../../../../common/types/trained_models'; export interface AnalyticsSelectorIds { @@ -127,7 +127,7 @@ export function AnalyticsIdSelector({ const trainedModelsApiService = useTrainedModelsApiService(); const { dataFrameAnalytics: { getDataFrameAnalytics }, - } = useMlApiContext(); + } = useMlApi(); function renderTabs() { return ; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/page.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/page.tsx index 6cb7532b7bb9a..7afb189cf91f3 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/page.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/page.tsx @@ -16,7 +16,7 @@ import { SavedObjectsWarning } from '../../../components/saved_objects_warning'; import { UpgradeWarning } from '../../../components/upgrade'; import { JobMap } from '.'; import { HelpMenu } from '../../../components/help_menu'; -import { useMlKibana, useMlApiContext } from '../../../contexts/kibana'; +import { useMlKibana, useMlApi } from '../../../contexts/kibana'; import { useRefreshAnalyticsList } from '../../common'; import { MlPageHeader } from '../../../components/page_header'; import type { AnalyticsSelectorIds } from '../components/analytics_selector'; @@ -52,7 +52,7 @@ export const Page: FC = () => { } = useMlKibana(); const { dataFrameAnalytics: { getDataFrameAnalytics }, - } = useMlApiContext(); + } = useMlApi(); const helpLink = docLinks.links.ml.dataFrameAnalytics; const checkJobsExist = async () => { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/use_fetch_analytics_map_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/use_fetch_analytics_map_data.ts index d56cd4b7c638d..53c144e62ffd0 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/use_fetch_analytics_map_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/job_map/use_fetch_analytics_map_data.ts @@ -14,7 +14,7 @@ import { JOB_MAP_NODE_TYPES, type AnalyticsMapReturnType, } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlApiContext } from '../../../contexts/kibana'; +import { useMlApi } from '../../../contexts/kibana'; interface GetDataObjectParameter { analyticsId?: string; id?: string; @@ -23,7 +23,7 @@ interface GetDataObjectParameter { } export const useFetchAnalyticsMapData = () => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [isLoading, setIsLoading] = useState(false); const [elements, setElements] = useState([]); const [error, setError] = useState(); @@ -39,7 +39,7 @@ export const useFetchAnalyticsMapData = () => { } // Pass in treatAsRoot flag - endpoint will take job or index to grab jobs created from it const analyticsMap: AnalyticsMapReturnType = - await ml.dataFrameAnalytics.getDataFrameAnalyticsMap(idToUse, treatAsRoot, type); + await mlApi.dataFrameAnalytics.getDataFrameAnalyticsMap(idToUse, treatAsRoot, type); const { elements: nodeElements, details, error: fetchError } = analyticsMap; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx index bc4d204fda223..a4ff83970c9c0 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx @@ -17,7 +17,7 @@ import type { import { useTimefilter } from '@kbn/ml-date-picker'; import type { ResultLinks } from '@kbn/data-visualizer-plugin/common/app'; import { HelpMenu } from '../../components/help_menu'; -import { useMlApiContext, useMlKibana, useMlLocator } from '../../contexts/kibana'; +import { useMlApi, useMlKibana, useMlLocator } from '../../contexts/kibana'; import { ML_PAGES } from '../../../../common/constants/locator'; import { isFullLicense } from '../../license'; @@ -36,9 +36,9 @@ export const FileDataVisualizerPage: FC = () => { }, }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const mlLocator = useMlLocator()!; - getMlNodeCount(mlApiServices); + getMlNodeCount(mlApi); const [FileDataVisualizer, setFileDataVisualizer] = useState(null); const [resultLinks, setResultLinks] = useState(null); @@ -105,7 +105,7 @@ export const FileDataVisualizerPage: FC = () => { useEffect(() => { // ML uses this function if (dataVisualizer !== undefined) { - getMlNodeCount(mlApiServices); + getMlNodeCount(mlApi); const { getFileDataVisualizerComponent } = dataVisualizer; getFileDataVisualizerComponent().then((resp) => { const items = resp(); diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts index 3ca5acb5a41bc..fcf4e1cb484c4 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts @@ -12,7 +12,7 @@ import { type RuntimeMappings } from '@kbn/ml-runtime-field-utils'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { IndexPatternTitle } from '../../../../../common/types/kibana'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { FieldHistogramRequestConfig } from '../common/request'; @@ -24,7 +24,7 @@ export class DataLoader { private _indexPatternTitle: IndexPatternTitle = ''; private _maxExamples: number = MAX_EXAMPLES_DEFAULT; - constructor(private _indexPattern: DataView, private _mlApiServices: MlApiServices) { + constructor(private _indexPattern: DataView, private _mlApi: MlApi) { this._runtimeMappings = this._indexPattern.getComputedFields().runtimeFields as RuntimeMappings; this._indexPatternTitle = _indexPattern.title; } @@ -35,7 +35,7 @@ export class DataLoader { samplerShardSize = DEFAULT_SAMPLER_SHARD_SIZE, editorRuntimeMappings?: RuntimeMappings ): Promise { - const stats = await this._mlApiServices.getVisualizerFieldHistograms({ + const stats = await this._mlApi.getVisualizerFieldHistograms({ indexPattern: this._indexPatternTitle, query, fields, diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx index ac980bf21c32c..e85da14ddb808 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx @@ -18,7 +18,7 @@ import type { import { useTimefilter } from '@kbn/ml-date-picker'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import useMountedState from 'react-use/lib/useMountedState'; -import { useMlApiContext, useMlKibana, useMlLocator } from '../../contexts/kibana'; +import { useMlApi, useMlKibana, useMlLocator } from '../../contexts/kibana'; import { HelpMenu } from '../../components/help_menu'; import { ML_PAGES } from '../../../../common/constants/locator'; import { isFullLicense } from '../../license'; @@ -36,15 +36,15 @@ export const IndexDataVisualizerPage: FC<{ esql: boolean }> = ({ esql = false }) dataViews: { get: getDataView }, }, mlServices: { - mlApiServices: { recognizeIndex }, + mlApi: { recognizeIndex }, }, }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const { showNodeInfo } = useEnabledFeatures(); const mlLocator = useMlLocator()!; const mlFeaturesDisabled = !isFullLicense(); - getMlNodeCount(mlApiServices); + getMlNodeCount(mlApi); const [IndexDataVisualizer, setIndexDataVisualizer] = useState( null diff --git a/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts b/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts index 80f32a3df82fc..41a3da0586e02 100644 --- a/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts +++ b/x-pack/plugins/ml/public/application/explorer/actions/load_explorer_data.ts @@ -32,12 +32,12 @@ import { loadOverallAnnotations, } from '../explorer_utils'; import type { ExplorerState } from '../reducers'; -import { useMlApiContext, useUiSettings } from '../../contexts/kibana'; +import { useMlApi, useUiSettings } from '../../contexts/kibana'; import type { MlResultsService } from '../../services/results_service'; import { mlResultsServiceProvider } from '../../services/results_service'; import type { AnomalyExplorerChartsService } from '../../services/anomaly_explorer_charts_service'; import { useAnomalyExplorerContext } from '../anomaly_explorer_context'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; import { useMlJobService, type MlJobService } from '../../services/job_service'; // Memoize the data fetching methods. @@ -97,7 +97,7 @@ export const isLoadExplorerDataConfig = (arg: any): arg is LoadExplorerDataConfi */ const loadExplorerDataProvider = ( uiSettings: IUiSettingsClient, - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, mlResultsService: MlResultsService, anomalyExplorerChartsService: AnomalyExplorerChartsService, @@ -131,15 +131,10 @@ const loadExplorerDataProvider = ( // First get the data where we have all necessary args at hand using forkJoin: // annotationsData, anomalyChartRecords, influencers, overallState, tableData return forkJoin({ - overallAnnotations: memoizedLoadOverallAnnotations( - lastRefresh, - mlApiServices, - selectedJobs, - bounds - ), + overallAnnotations: memoizedLoadOverallAnnotations(lastRefresh, mlApi, selectedJobs, bounds), annotationsData: memoizedLoadAnnotationsTableData( lastRefresh, - mlApiServices, + mlApi, selectedCells, selectedJobs, bounds @@ -167,7 +162,7 @@ const loadExplorerDataProvider = ( : Promise.resolve({}), tableData: memoizedLoadAnomaliesTableData( lastRefresh, - mlApiServices, + mlApi, mlJobService, selectedCells, selectedJobs, @@ -218,16 +213,16 @@ const loadExplorerDataProvider = ( export const useExplorerData = (): [Partial | undefined, (d: any) => void] => { const uiSettings = useUiSettings(); const timefilter = useTimefilter(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const mlJobService = useMlJobService(); const { anomalyExplorerChartsService } = useAnomalyExplorerContext(); const loadExplorerData = useMemo(() => { - const mlResultsService = mlResultsServiceProvider(mlApiServices); + const mlResultsService = mlResultsServiceProvider(mlApi); return loadExplorerDataProvider( uiSettings, - mlApiServices, + mlApi, mlJobService, mlResultsService, anomalyExplorerChartsService, diff --git a/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx b/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx index 35b552a95cac8..2c1fb6dc8c182 100644 --- a/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx +++ b/x-pack/plugins/ml/public/application/explorer/anomaly_explorer_context.tsx @@ -61,7 +61,7 @@ export const AnomalyExplorerContextProvider: FC> = ({ const { services: { - mlServices: { mlApiServices, mlFieldFormatService }, + mlServices: { mlApi, mlFieldFormatService }, uiSettings, data, }, @@ -71,7 +71,7 @@ export const AnomalyExplorerContextProvider: FC> = ({ const [, , tableSeverityState] = useTableSeverity(); // eslint-disable-next-line react-hooks/exhaustive-deps - const mlResultsService = useMemo(() => mlResultsServiceProvider(mlApiServices), []); + const mlResultsService = useMemo(() => mlResultsServiceProvider(mlApi), []); const [anomalyExplorerContextValue, setAnomalyExplorerContextValue] = useState< AnomalyExplorerContextValue | undefined @@ -104,7 +104,7 @@ export const AnomalyExplorerContextProvider: FC> = ({ const anomalyExplorerChartsService = new AnomalyExplorerChartsService( timefilter, - mlApiServices, + mlApi, mlResultsService ); diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/map_config.ts b/x-pack/plugins/ml/public/application/explorer/explorer_charts/map_config.ts index 8991ba6733e3b..f3aa8ef601a02 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/map_config.ts +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/map_config.ts @@ -22,17 +22,14 @@ function getAnomalyFeatures( const geoResults = anomaly.geo_results || (anomaly?.causes && anomaly?.causes[0]?.geo_results); const coordinateStr = geoResults && geoResults[type]; if (coordinateStr !== undefined) { - // Must reverse coordinates here. Map expects [lon, lat] - anomalies are stored as [lat, lon] for lat_lon jobs - const coordinates = coordinateStr - .split(',') - .map((point: string) => Number(point)) - .reverse(); + const coordinates = coordinateStr.split(',').map((point: string) => Number(point)); anomalyFeatures.push({ type: FEATURE, geometry: { type: POINT, - coordinates, + // Must reverse coordinates here. Map expects [lon, lat] - anomalies are stored as [lat, lon] for lat_lon jobs + coordinates: coordinates.toReversed(), }, properties: { record_score: Math.floor(anomaly.record_score), diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_utils.ts b/x-pack/plugins/ml/public/application/explorer/explorer_utils.ts index fbfad277ff45f..753e81e8204e0 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_utils.ts +++ b/x-pack/plugins/ml/public/application/explorer/explorer_utils.ts @@ -52,7 +52,7 @@ import { import type { CombinedJob } from '../../../common/types/anomaly_detection_jobs'; import type { MlResultsService } from '../services/results_service'; import type { Annotations, AnnotationsTable } from '../../../common/types/annotations'; -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; export interface ExplorerJob { id: string; @@ -352,7 +352,7 @@ export function getSelectionJobIds( } export function loadOverallAnnotations( - mlApiServices: MlApiServices, + mlApi: MlApi, selectedJobs: ExplorerJob[], bounds: TimeRangeBounds ): Promise { @@ -361,7 +361,7 @@ export function loadOverallAnnotations( return new Promise((resolve) => { lastValueFrom( - mlApiServices.annotations.getAnnotations$({ + mlApi.annotations.getAnnotations$({ jobIds, earliestMs: timeRange.earliestMs, latestMs: timeRange.latestMs, @@ -407,7 +407,7 @@ export function loadOverallAnnotations( } export function loadAnnotationsTableData( - mlApiServices: MlApiServices, + mlApi: MlApi, selectedCells: AppStateSelectedCells | undefined | null, selectedJobs: ExplorerJob[], bounds: Required @@ -417,7 +417,7 @@ export function loadAnnotationsTableData( return new Promise((resolve) => { lastValueFrom( - mlApiServices.annotations.getAnnotations$({ + mlApi.annotations.getAnnotations$({ jobIds, earliestMs: timeRange.earliestMs, latestMs: timeRange.latestMs, @@ -466,7 +466,7 @@ export function loadAnnotationsTableData( } export async function loadAnomaliesTableData( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, selectedCells: AppStateSelectedCells | undefined | null, selectedJobs: ExplorerJob[], @@ -482,7 +482,7 @@ export async function loadAnomaliesTableData( const timeRange = getSelectionTimeRange(selectedCells, bounds); return new Promise((resolve, reject) => { - mlApiServices.results + mlApi.results .getAnomaliesTableData( jobIds, [], diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx index 510149ada47e6..055b297af893f 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/datafeed_chart_flyout.tsx @@ -60,7 +60,7 @@ import type { import type { JobMessage } from '../../../../../../common/types/audit_message'; import type { LineAnnotationDatumWithModelSnapshot } from '../../../../../../common/types/results'; import { useToastNotificationService } from '../../../../services/toast_notification_service'; -import { useCurrentThemeVars, useMlApiContext } from '../../../../contexts/kibana'; +import { useCurrentThemeVars, useMlApi } from '../../../../contexts/kibana'; import { RevertModelSnapshotFlyout } from '../../../../components/model_snapshots/revert_model_snapshot_flyout'; import { JobMessagesPane } from '../job_details/job_messages_pane'; import { EditQueryDelay } from './edit_query_delay'; @@ -110,7 +110,7 @@ export const DatafeedChartFlyout: FC = ({ onClose, onModelSnapshotAnnotationClick, }) => { - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const [data, setData] = useState<{ datafeedConfig: CombinedJobWithStats['datafeed_config'] | undefined; bucketSpan: string | undefined; @@ -144,7 +144,7 @@ export const DatafeedChartFlyout: FC = ({ const { getModelSnapshots, results: { getDatafeedResultChartData }, - } = useMlApiContext(); + } = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const { euiTheme } = useCurrentThemeVars(); const handleChange = (date: moment.Moment) => setEndDate(date); @@ -213,7 +213,7 @@ export const DatafeedChartFlyout: FC = ({ const getJobAndSnapshotData = useCallback(async () => { try { - const job: CombinedJobWithStats = await loadFullJob(mlApiServices, jobId); + const job: CombinedJobWithStats = await loadFullJob(mlApi, jobId); const modelSnapshotResultsLine: LineAnnotationDatumWithModelSnapshot[] = []; const modelSnapshotsResp = await getModelSnapshots(jobId); const modelSnapshots = modelSnapshotsResp.model_snapshots ?? []; @@ -660,7 +660,7 @@ export const JobListDatafeedChartFlyout: FC = ( unsetShowFunction, refreshJobs, }) => { - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const [isVisible, setIsVisible] = useState(false); const [job, setJob] = useState(); const [jobWithStats, setJobWithStats] = useState(); @@ -677,10 +677,10 @@ export const JobListDatafeedChartFlyout: FC = ( const showRevertModelSnapshot = useCallback(async () => { // Need to load the full job with stats, as the model snapshot // flyout needs the timestamp of the last result. - const fullJob: CombinedJobWithStats = await loadFullJob(mlApiServices, job!.id); + const fullJob: CombinedJobWithStats = await loadFullJob(mlApi, job!.id); setJobWithStats(fullJob); setIsRevertModelSnapshotFlyoutVisible(true); - // exclude mlApiServices from deps + // exclude mlApi from deps // eslint-disable-next-line react-hooks/exhaustive-deps }, [job]); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/edit_query_delay.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/edit_query_delay.tsx index 6d753cd2d3a7f..9b829222ae46a 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/edit_query_delay.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/datafeed_chart_flyout/edit_query_delay.tsx @@ -18,7 +18,7 @@ import { EuiToolTip, } from '@elastic/eui'; -import { useMlApiContext } from '../../../../contexts/kibana'; +import { useMlApi } from '../../../../contexts/kibana'; import { useToastNotificationService } from '../../../../services/toast_notification_service'; import type { Datafeed } from '../../../../../../common/types/anomaly_detection_jobs'; @@ -38,7 +38,7 @@ export const EditQueryDelay: FC<{ const [currentQueryDelay, setCurrentQueryDelay] = useState(queryDelay); const [newQueryDelay, setNewQueryDelay] = useState(); const [isEditing, setIsEditing] = useState(false); - const { updateDatafeed } = useMlApiContext(); + const { updateDatafeed } = useMlApi(); const { displaySuccessToast, displayErrorToast } = useToastNotificationService(); const updateQueryDelay = useCallback(async () => { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_job_flyout.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_job_flyout.js index 03d8745b20ee1..4659121fd8306 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_job_flyout.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_job_flyout.js @@ -120,7 +120,7 @@ export class EditJobFlyoutUI extends Component { showFlyout = (jobLite) => { const hasDatafeed = jobLite.hasDatafeed; - loadFullJob(this.props.kibana.services.mlServices.mlApiServices, jobLite.id) + loadFullJob(this.props.kibana.services.mlServices.mlApi, jobLite.id) .then((job) => { this.extractJob(job, hasDatafeed); this.setState({ @@ -203,12 +203,12 @@ export class EditJobFlyoutUI extends Component { ).message; } - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; if (jobDetails.jobGroups !== undefined) { jobGroupsValidationError = validateGroupNames(jobDetails.jobGroups).message; if (jobGroupsValidationError === '') { - ml.jobs.jobsExist(jobDetails.jobGroups, true).then((resp) => { + mlApi.jobs.jobsExist(jobDetails.jobGroups, true).then((resp) => { const groups = Object.values(resp); const valid = groups.some((g) => g.exists === true && g.isGroup === false) === false; if (valid === false) { @@ -273,11 +273,11 @@ export class EditJobFlyoutUI extends Component { customUrls: this.state.jobCustomUrls, }; - const mlApiServices = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; const { toasts } = this.props.kibana.services.notifications; const toastNotificationService = toastNotificationServiceProvider(toasts); - saveJob(mlApiServices, this.state.job, newJobData) + saveJob(mlApi, this.state.job, newJobData) .then(() => { toasts.addSuccess( i18n.translate('xpack.ml.jobsList.editJobFlyout.changesSavedNotificationMessage', { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js index b3c36304ed381..80680c3da2c44 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/edit_utils.js @@ -9,7 +9,7 @@ import { difference } from 'lodash'; import { getNewJobLimits } from '../../../../services/ml_server_info'; import { processCreatedBy } from '../../../../../../common/util/job_utils'; -export function saveJob(mlApiServices, job, newJobData, finish) { +export function saveJob(mlApi, job, newJobData, finish) { return new Promise((resolve, reject) => { const jobData = { ...extractDescription(job, newJobData), @@ -29,7 +29,7 @@ export function saveJob(mlApiServices, job, newJobData, finish) { } const saveDatafeedWrapper = () => { - saveDatafeed(mlApiServices, datafeedData, job, finish) + saveDatafeed(mlApi, datafeedData, job, finish) .then(() => { resolve(); }) @@ -40,7 +40,7 @@ export function saveJob(mlApiServices, job, newJobData, finish) { // if anything has changed, post the changes if (Object.keys(jobData).length) { - mlApiServices + mlApi .updateJob({ jobId: job.job_id, job: jobData }) .then(() => { saveDatafeedWrapper(); @@ -54,11 +54,11 @@ export function saveJob(mlApiServices, job, newJobData, finish) { }); } -function saveDatafeed(mlApiServices, datafeedConfig, job) { +function saveDatafeed(mlApi, datafeedConfig, job) { return new Promise((resolve, reject) => { if (Object.keys(datafeedConfig).length) { const datafeedId = job.datafeed_config.datafeed_id; - mlApiServices + mlApi .updateDatafeed({ datafeedId, datafeedConfig }) .then(() => { resolve(); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/detectors.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/detectors.js index 01fe676a4133b..daf9e7996b5c8 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/detectors.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/detectors.js @@ -25,7 +25,7 @@ export class Detectors extends Component { const mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(constructorContext.services.notifications.toasts), - constructorContext.services.mlServices.mlApiServices + constructorContext.services.mlServices.mlApi ); this.detectors = mlJobService.getJobGroups().map((g) => ({ label: g.id })); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/job_details.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/job_details.js index 5cb7b9edd607e..322221045b652 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/job_details.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/job_details.js @@ -42,9 +42,9 @@ export class JobDetailsUI extends Component { } componentDidMount() { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; // load groups to populate the select options - ml.jobs + mlApi.jobs .groups() .then((resp) => { const groups = resp.map((g) => ({ label: g.id, color: tabColor(g.id) })); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js index 1734182ff3ebc..eac225f2db990 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_actions/management.js @@ -24,7 +24,7 @@ import { isManagedJob } from '../../../jobs_utils'; export function actionsMenuContent( toastNotifications, application, - mlApiServices, + mlApi, mlJobService, showEditJobFlyout, showDatafeedChartFlyout, @@ -153,7 +153,7 @@ export function actionsMenuContent( return isJobBlocked(item) === false && canCreateJob; }, onClick: (item) => { - cloneJob(toastNotifications, application, mlApiServices, mlJobService, item.id); + cloneJob(toastNotifications, application, mlApi, mlJobService, item.id); closeMenu(true); }, 'data-test-subj': 'mlActionButtonCloneJob', diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/datafeed_preview_tab.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/datafeed_preview_tab.tsx index b9813ece905f4..38ac41983f489 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/datafeed_preview_tab.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/datafeed_preview_tab.tsx @@ -11,7 +11,7 @@ import { EuiCallOut, EuiLoadingSpinner } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useEnabledFeatures } from '../../../../contexts/ml'; import { ML_DATA_PREVIEW_COUNT } from '../../../../../../common/util/job_utils'; -import { useMlApiContext } from '../../../../contexts/kibana'; +import { useMlApi } from '../../../../contexts/kibana'; import { usePermissionCheck } from '../../../../capabilities/check_capabilities'; import { MLJobEditor } from '../ml_job_editor'; import type { CombinedJob } from '../../../../../../common/types/anomaly_detection_jobs'; @@ -23,7 +23,7 @@ interface Props { export const DatafeedPreviewPane: FC = ({ job }) => { const { jobs: { datafeedPreview }, - } = useMlApiContext(); + } = useMlApi(); const { showNodeInfo } = useEnabledFeatures(); const canPreviewDatafeed = usePermissionCheck('canPreviewDatafeed'); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js index 0db362a094c1e..5f1cbb1c76ca0 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/forecasts_table/forecasts_table.js @@ -45,9 +45,7 @@ export class ForecastsTable extends Component { isLoading: props.job.data_counts.processed_record_count !== 0, forecasts: [], }; - this.mlForecastService = forecastServiceFactory( - constructorContext.services.mlServices.mlApiServices - ); + this.mlForecastService = forecastServiceFactory(constructorContext.services.mlServices.mlApi); } /** @@ -91,6 +89,7 @@ export class ForecastsTable extends Component { async openSingleMetricView(forecast) { const { services: { + chrome: { recentlyAccessed }, application: { navigateToUrl }, share, }, @@ -158,7 +157,8 @@ export class ForecastsTable extends Component { addItemToRecentlyAccessed( 'timeseriesexplorer', this.props.job.job_id, - singleMetricViewerForecastLink + singleMetricViewerForecastLink, + recentlyAccessed ); await navigateToUrl(singleMetricViewerForecastLink); } diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_messages_pane.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_messages_pane.tsx index eb0ce2d6be817..c4ba5c3c7d5d8 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_messages_pane.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_details/job_messages_pane.tsx @@ -14,7 +14,7 @@ import { extractErrorMessage } from '@kbn/ml-error-utils'; import { JobMessages } from '../../../../components/job_messages'; import type { JobMessage } from '../../../../../../common/types/audit_message'; import { useToastNotificationService } from '../../../../services/toast_notification_service'; -import { useMlApiContext } from '../../../../contexts/kibana'; +import { useMlApi } from '../../../../contexts/kibana'; import { checkPermission } from '../../../../capabilities/check_capabilities'; import { blurButtonOnClick } from '../../../../util/component_utils'; interface JobMessagesPaneProps { @@ -37,12 +37,12 @@ export const JobMessagesPane: FC = React.memo( const [isClearing, setIsClearing] = useState(false); const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const fetchMessages = async () => { setIsLoading(true); try { - const messagesResp = await ml.jobs.jobAuditMessages({ jobId, start, end }); + const messagesResp = await mlApi.jobs.jobAuditMessages({ jobId, start, end }); setMessages(messagesResp.messages); setNotificationIndices(messagesResp.notificationIndices); @@ -67,7 +67,7 @@ export const JobMessagesPane: FC = React.memo( const clearMessages = useCallback(async () => { setIsClearing(true); try { - await ml.jobs.clearJobAuditMessages(jobId, notificationIndices); + await mlApi.jobs.clearJobAuditMessages(jobId, notificationIndices); setIsClearing(false); if (typeof refreshJobList === 'function') { refreshJobList(); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.tsx index 4e819f093a2e2..c326761a7e3ff 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/job_filter_bar/job_filter_bar.tsx @@ -24,13 +24,13 @@ export const JobFilterBar: FC = ({ queryText, setFilters }) = const [error, setError] = useState(null); const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); const loadGroups = useCallback(async () => { try { - const response = await mlApiServices.jobs.groups(); + const response = await mlApi.jobs.groups(); return response.map((g) => ({ value: g.id, view: ( diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js index e6fd50d96a65d..f6deecc3ba309 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list/jobs_list.js @@ -46,10 +46,10 @@ export class JobsListUI extends Component { itemIdToExpandedRowMap: {}, }; - this.mlApiServices = props.kibana.services.mlServices.mlApiServices; + this.mlApi = props.kibana.services.mlServices.mlApi; this.mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(props.kibana.services.notifications.toasts), - this.mlApiServices + this.mlApi ); } @@ -340,7 +340,7 @@ export class JobsListUI extends Component { actions: actionsMenuContent( this.props.kibana.services.notifications.toasts, this.props.kibana.services.application, - this.mlApiServices, + this.mlApi, this.mlJobService, this.props.showEditJobFlyout, this.props.showDatafeedChartFlyout, diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js index efb9211e99c0e..6693f9bc22ab1 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_list_view/jobs_list_view.js @@ -83,7 +83,7 @@ export class JobsListViewUI extends Component { this.mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(props.kibana.services.notifications.toasts), - props.kibana.services.mlServices.mlApiServices + props.kibana.services.mlServices.mlApi ); } @@ -147,7 +147,7 @@ export class JobsListViewUI extends Component { } this.setState({ itemIdToExpandedRowMap }, () => { - loadFullJob(this.props.kibana.services.mlServices.mlApiServices, jobId) + loadFullJob(this.props.kibana.services.mlServices.mlApi, jobId) .then((job) => { const fullJobsList = { ...this.state.fullJobsList }; if (this.props.showNodeInfo === false) { @@ -324,11 +324,11 @@ export class JobsListViewUI extends Component { this.setState({ loading: true }); } - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; const expandedJobsIds = Object.keys(this.state.itemIdToExpandedRowMap); try { let jobsAwaitingNodeCount = 0; - const jobs = await ml.jobs.jobsSummary(expandedJobsIds); + const jobs = await mlApi.jobs.jobsSummary(expandedJobsIds); const fullJobsList = {}; const jobsSummaryList = jobs.map((job) => { if (job.fullJob !== undefined) { @@ -387,8 +387,8 @@ export class JobsListViewUI extends Component { return; } - const ml = this.props.kibana.services.mlServices.mlApiServices; - const { jobs } = await ml.jobs.blockingJobTasks(); + const mlApi = this.props.kibana.services.mlServices.mlApi; + const { jobs } = await mlApi.jobs.blockingJobTasks(); const blockingJobIds = jobs.map((j) => Object.keys(j)[0]).sort(); const taskListHasChanged = blockingJobIds.join() !== this.state.blockingJobIds.join(); diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/actions_menu.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/actions_menu.js index e12b770039b8d..a8bd2789e5433 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/actions_menu.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/actions_menu.js @@ -47,11 +47,11 @@ class MultiJobActionsMenuUI extends Component { this.canCreateMlAlerts = checkPermission('canCreateMlAlerts'); this.toastNoticiations = constructorContext.services.notifications.toasts; - const mlApiServices = constructorContext.services.mlServices.mlApiServices; + const mlApi = constructorContext.services.mlServices.mlApi; const toastNotificationService = toastNotificationServiceProvider( constructorContext.services.notifications.toasts ); - this.mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); + this.mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); } onButtonClick = () => { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/group_selector/group_selector.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/group_selector/group_selector.js index 9fe8bbf230322..6248915b87d4b 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/group_selector/group_selector.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/multi_job_actions/group_selector/group_selector.js @@ -91,8 +91,8 @@ export class GroupSelectorUI extends Component { if (this.state.isPopoverOpen) { this.closePopover(); } else { - const ml = this.props.kibana.services.mlServices.mlApiServices; - ml.jobs + const mlApi = this.props.kibana.services.mlServices.mlApi; + mlApi.jobs .groups() .then((groups) => { const selectedGroups = createSelectedGroups(this.props.jobs, groups); @@ -158,7 +158,7 @@ export class GroupSelectorUI extends Component { } const tempJobs = newJobs.map((j) => ({ jobId: j.id, groups: j.newGroups })); - const ml = this.props.kibana.services.mlServices.mlApiServices; + const ml = this.props.kibana.services.mlServices.mlApi; ml.jobs .updateGroups(tempJobs) .then((resp) => { diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/start_datafeed_modal/start_datafeed_modal.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/start_datafeed_modal/start_datafeed_modal.js index d56fc973a0249..db5f28a5e242b 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/start_datafeed_modal/start_datafeed_modal.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/start_datafeed_modal/start_datafeed_modal.js @@ -59,7 +59,7 @@ export class StartDatafeedModal extends Component { this.toastNotifications = constructorContext.services.notifications.toasts; this.mlJobService = mlJobServiceFactory( toastNotificationServiceProvider(this.toastNotifications), - constructorContext.services.mlServices.mlApiServices + constructorContext.services.mlServices.mlApi ); } diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts index a4c20309129f3..bd6f60a050047 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.d.ts @@ -13,13 +13,10 @@ import type { MlSummaryJob, } from '../../../../../common/types/anomaly_detection_jobs'; import type { MlJobService } from '../../../services/job_service'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; -export function loadFullJob( - mlApiServices: MlApiServices, - jobId: string -): Promise; -export function loadJobForCloning(mlApiServices: MlApiServices, jobId: string): Promise; +export function loadFullJob(mlApi: MlApi, jobId: string): Promise; +export function loadJobForCloning(mlApi: MlApi, jobId: string): Promise; export function isStartable(jobs: CombinedJobWithStats[]): boolean; export function isClosable(jobs: CombinedJobWithStats[]): boolean; export function isResettable(jobs: CombinedJobWithStats[]): boolean; @@ -45,7 +42,7 @@ export function showResults( export function cloneJob( toastNotifications: ToastsStart, application: ApplicationStart, - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, jobId: string ): Promise; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js index 471e56be7a840..36a070b851147 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/utils.js @@ -19,9 +19,9 @@ import { ML_PAGES } from '../../../../../common/constants/locator'; import { PLUGIN_ID } from '../../../../../common/constants/app'; import { CREATED_BY_LABEL } from '../../../../../common/constants/new_job'; -export function loadFullJob(mlApiServices, jobId) { +export function loadFullJob(mlApi, jobId) { return new Promise((resolve, reject) => { - mlApiServices.jobs + mlApi.jobs .jobs([jobId]) .then((jobs) => { if (jobs.length) { @@ -36,9 +36,9 @@ export function loadFullJob(mlApiServices, jobId) { }); } -export function loadJobForCloning(mlApiServices, jobId) { +export function loadJobForCloning(mlApi, jobId) { return new Promise((resolve, reject) => { - mlApiServices.jobs + mlApi.jobs .jobForCloning(jobId) .then((resp) => { if (resp) { @@ -214,17 +214,11 @@ function showResults(toastNotifications, resp, action) { } } -export async function cloneJob( - toastNotifications, - application, - mlApiServices, - mlJobService, - jobId -) { +export async function cloneJob(toastNotifications, application, mlApi, mlJobService, jobId) { try { const [{ job: cloneableJob, datafeed }, originalJob] = await Promise.all([ - loadJobForCloning(mlApiServices, jobId), - loadFullJob(mlApiServices, jobId), + loadJobForCloning(mlApi, jobId), + loadFullJob(mlApi, jobId), ]); const createdBy = originalJob?.custom_settings?.created_by; @@ -277,7 +271,7 @@ export async function cloneJob( if (originalJob.calendars) { mlJobService.tempJobCloningObjects.calendars = await mlCalendarService.fetchCalendarsByIds( - mlApiServices, + mlApi, originalJob.calendars ); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts index 68ddfe1b83b44..983fa2f352016 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts @@ -14,7 +14,7 @@ import type { IndicesOptions } from '../../../../../../common/types/anomaly_dete import { mlResultsServiceProvider } from '../../../../services/results_service'; import { getCategoryFields as getCategoryFieldsOrig } from './searches'; import { aggFieldPairsCanBeCharted } from '../job_creator/util/general'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; type DetectorIndex = number; export interface LineChartPoint { @@ -28,7 +28,7 @@ const eq = (newArgs: any[], lastArgs: any[]) => isEqual(newArgs, lastArgs); export class ChartLoader { protected _dataView: DataView; - protected _mlApiServices: MlApiServices; + protected _mlApi: MlApi; private _timeFieldName: string = ''; private _query: object = {}; @@ -38,17 +38,14 @@ export class ChartLoader { private _getEventRateData; private _getCategoryFields; - constructor(mlApiServices: MlApiServices, indexPattern: DataView, query: object) { - this._mlApiServices = mlApiServices; + constructor(mlApi: MlApi, indexPattern: DataView, query: object) { + this._mlApi = mlApi; this._dataView = indexPattern; this._query = query; - this._newJobLineChart = memoizeOne(mlApiServices.jobs.newJobLineChart, eq); - this._newJobPopulationsChart = memoizeOne(mlApiServices.jobs.newJobPopulationsChart, eq); - this._getEventRateData = memoizeOne( - mlResultsServiceProvider(mlApiServices).getEventRateData, - eq - ); + this._newJobLineChart = memoizeOne(mlApi.jobs.newJobLineChart, eq); + this._newJobPopulationsChart = memoizeOne(mlApi.jobs.newJobPopulationsChart, eq); + this._getEventRateData = memoizeOne(mlResultsServiceProvider(mlApi).getEventRateData, eq); this._getCategoryFields = memoizeOne(getCategoryFieldsOrig, eq); if (typeof indexPattern.timeFieldName === 'string') { @@ -166,7 +163,7 @@ export class ChartLoader { indicesOptions?: IndicesOptions ): Promise { const { results } = await this._getCategoryFields( - this._mlApiServices, + this._mlApi, this._dataView.getIndexPattern(), field.name, 10, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/searches.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/searches.ts index 3c4ca1c5f54d7..f36dd70d42194 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/searches.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/searches.ts @@ -8,7 +8,7 @@ import { get } from 'lodash'; import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { IndicesOptions } from '../../../../../../common/types/anomaly_detection_jobs'; interface CategoryResults { @@ -17,7 +17,7 @@ interface CategoryResults { } export function getCategoryFields( - mlApiServices: MlApiServices, + mlApi: MlApi, indexPatternName: string, fieldName: string, size: number, @@ -26,7 +26,7 @@ export function getCategoryFields( indicesOptions?: IndicesOptions ): Promise { return new Promise((resolve, reject) => { - mlApiServices + mlApi .esSearch({ index: indexPatternName, size: 0, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts index 30a472348d587..04f99a6f7895b 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/advanced_job_creator.ts @@ -11,7 +11,7 @@ import type { Field, Aggregation, SplitField } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import { JobCreator } from './job_creator'; import type { Job, @@ -43,14 +43,14 @@ export class AdvancedJobCreator extends JobCreator { private _queryString: string; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.ADVANCED; this._queryString = JSON.stringify(this._datafeed_config.query); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts index a12266e556e73..cb79defa16302 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/categorization_job_creator.ts @@ -35,7 +35,7 @@ import { DEFAULT_RARE_BUCKET_SPAN, } from '../../../../../../common/constants/new_job'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { getRichDetectors } from './util/general'; @@ -65,14 +65,14 @@ export class CategorizationJobCreator extends JobCreator { private _ccsVersionFailure: boolean = false; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.CATEGORIZATION; this._examplesLoader = new CategorizationExamplesLoader(this, indexPattern, query); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/geo_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/geo_job_creator.ts index 76fda339afa44..986f1480e7bf3 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/geo_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/geo_job_creator.ts @@ -9,7 +9,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { Field, Aggregation, SplitField, AggFieldPair } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { JobCreator } from './job_creator'; import type { @@ -31,14 +31,14 @@ export class GeoJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.GEO; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.GEO; this._wizardInitialized$.next(true); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts index 82e5fe1209a13..2346ff863e489 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator.ts @@ -22,7 +22,7 @@ import { import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { IndexPatternTitle } from '../../../../../../common/types/kibana'; import { getQueryFromSavedSearchObject } from '../../../../util/index_utils'; import type { @@ -79,19 +79,19 @@ export class JobCreator { protected _wizardInitialized$ = new BehaviorSubject(false); public wizardInitialized$ = this._wizardInitialized$.asObservable(); - public mlApiServices: MlApiServices; + public mlApi: MlApi; public mlJobService: MlJobService; public newJobCapsService: NewJobCapsService; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - this.mlApiServices = mlApiServices; + this.mlApi = mlApi; this.mlJobService = mlJobService; this.newJobCapsService = newJobCapsService; this._indexPattern = indexPattern; @@ -492,7 +492,7 @@ export class JobCreator { } for (const calendar of this._calendars) { - await mlCalendarService.assignNewJobId(this.mlApiServices, calendar, this.jobId); + await mlCalendarService.assignNewJobId(this.mlApi, calendar, this.jobId); } } @@ -845,7 +845,7 @@ export class JobCreator { // load the start and end times for the selected index // and apply them to the job creator public async autoSetTimeRange(excludeFrozenData = true) { - const { start, end } = await this.mlApiServices.getTimeFieldRange({ + const { start, end } = await this.mlApi.getTimeFieldRange({ index: this._indexPatternTitle, timeFieldName: this.timeFieldName, query: excludeFrozenData ? addExcludeFrozenToQuery(this.query) : this.query, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts index 9e5f9988b292f..07424b709d5b6 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/job_creator_factory.ts @@ -8,7 +8,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { SingleMetricJobCreator } from './single_metric_job_creator'; import { MultiMetricJobCreator } from './multi_metric_job_creator'; @@ -23,7 +23,7 @@ import { JOB_TYPE } from '../../../../../../common/constants/new_job'; export const jobCreatorFactory = (jobType: JOB_TYPE) => ( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, @@ -57,5 +57,5 @@ export const jobCreatorFactory = jc = SingleMetricJobCreator; break; } - return new jc(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + return new jc(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); }; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts index 69ca14a40c4e4..cb734c84e3d23 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/multi_metric_job_creator.ts @@ -9,7 +9,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { Field, Aggregation, SplitField, AggFieldPair } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { JobCreator } from './job_creator'; import type { @@ -30,14 +30,14 @@ export class MultiMetricJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.MULTI_METRIC; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.MULTI_METRIC; this._wizardInitialized$.next(true); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts index 342583636d37f..36e4e8f6f5659 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/population_job_creator.ts @@ -9,7 +9,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { Field, Aggregation, SplitField, AggFieldPair } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { JobCreator } from './job_creator'; import type { @@ -29,14 +29,14 @@ export class PopulationJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.POPULATION; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.POPULATION; this._wizardInitialized$.next(true); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts index aaaa7d101c09a..e142a35ba380d 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/rare_job_creator.ts @@ -14,7 +14,7 @@ import { } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { NewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; import { JobCreator } from './job_creator'; import type { @@ -37,14 +37,14 @@ export class RareJobCreator extends JobCreator { private _freqRareAgg: Aggregation; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.RARE; this._wizardInitialized$.next(true); this._rareAgg = {} as Aggregation; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts index 2b7a1133c1d1f..10a55e5210d60 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/single_metric_job_creator.ts @@ -16,7 +16,7 @@ import { } from '@kbn/ml-anomaly-utils'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import type { MlJobService } from '../../../../services/job_service'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import { parseInterval } from '../../../../../../common/util/parse_interval'; import { JobCreator } from './job_creator'; import type { @@ -35,14 +35,14 @@ export class SingleMetricJobCreator extends JobCreator { protected _type: JOB_TYPE = JOB_TYPE.SINGLE_METRIC; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService, newJobCapsService: NewJobCapsService, indexPattern: DataView, savedSearch: SavedSearch | null, query: object ) { - super(mlApiServices, mlJobService, newJobCapsService, indexPattern, savedSearch, query); + super(mlApi, mlJobService, newJobCapsService, indexPattern, savedSearch, query); this.createdBy = CREATED_BY_LABEL.SINGLE_METRIC; this._wizardInitialized$.next(true); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.test.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.test.ts index f73c54653f93b..77030455fb3bf 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.test.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.test.ts @@ -10,7 +10,7 @@ import { useFakeTimers } from 'sinon'; import type { CalculatePayload } from './model_memory_estimator'; import { modelMemoryEstimatorProvider } from './model_memory_estimator'; import type { JobValidator } from '../../job_validator'; -import type { MlApiServices } from '../../../../../services/ml_api_service'; +import type { MlApi } from '../../../../../services/ml_api_service'; import type { JobCreator } from '../job_creator'; import { BehaviorSubject } from 'rxjs'; @@ -20,7 +20,7 @@ describe('delay', () => { let mockJobCreator: JobCreator; let wizardInitialized$: BehaviorSubject; let mockJobValidator: JobValidator; - let mockMlApiServices: MlApiServices; + let mockMlApiServices: MlApi; beforeEach(() => { clock = useFakeTimers(); @@ -37,7 +37,7 @@ describe('delay', () => { const { of } = require('rxjs'); return of({ modelMemoryLimit: '15MB' }); }), - } as unknown as MlApiServices; + } as unknown as MlApi; modelMemoryEstimator = modelMemoryEstimatorProvider( mockJobCreator, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts index b3550b039a862..4fae97ed3e3a2 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_creator/util/model_memory_estimator.ts @@ -30,16 +30,16 @@ import type { JobValidator } from '../../job_validator/job_validator'; import { VALIDATION_DELAY_MS } from '../../job_validator/job_validator'; import { useMlKibana } from '../../../../../contexts/kibana'; import type { JobCreator } from '../job_creator'; -import type { MlApiServices } from '../../../../../services/ml_api_service'; +import type { MlApi } from '../../../../../services/ml_api_service'; -export type CalculatePayload = Parameters[0]; +export type CalculatePayload = Parameters[0]; type ModelMemoryEstimator = ReturnType; export const modelMemoryEstimatorProvider = ( jobCreator: JobCreator, jobValidator: JobValidator, - mlApiServices: MlApiServices + mlApi: MlApi ) => { const modelMemoryCheck$ = new Subject(); const error$ = new Subject(); @@ -65,7 +65,7 @@ export const modelMemoryEstimatorProvider = ( // don't call the endpoint with invalid payload filter(() => jobValidator.isModelMemoryEstimationPayloadValid), switchMap((payload) => { - return mlApiServices.calculateModelMemoryLimit$(payload).pipe( + return mlApi.calculateModelMemoryLimit$(payload).pipe( pluck('modelMemoryLimit'), catchError((error) => { // eslint-disable-next-line no-console @@ -93,14 +93,14 @@ export const useModelMemoryEstimator = ( const { services: { notifications, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); // Initialize model memory estimator only once const modelMemoryEstimator = useMemo( - () => modelMemoryEstimatorProvider(jobCreator, jobValidator, mlApiServices), - [jobCreator, jobValidator, mlApiServices] + () => modelMemoryEstimatorProvider(jobCreator, jobValidator, mlApi), + [jobCreator, jobValidator, mlApi] ); // Listen for estimation results and errors diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_runner/job_runner.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_runner/job_runner.ts index bd3d68afdc6d0..335d952929741 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_runner/job_runner.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_runner/job_runner.ts @@ -6,7 +6,7 @@ */ import { BehaviorSubject } from 'rxjs'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; import type { MlJobService } from '../../../../services/job_service'; import type { JobCreator } from '../job_creator'; import type { DatafeedId, JobId } from '../../../../../../common/types/anomaly_detection_jobs'; @@ -22,7 +22,7 @@ export type ProgressSubscriber = (progress: number) => void; export type JobAssignmentSubscriber = (assigned: boolean) => void; export class JobRunner { - private _mlApiServices: MlApiServices; + private _mlApi: MlApi; private _mlJobService: MlJobService; private _jobId: JobId; private _datafeedId: DatafeedId; @@ -44,7 +44,7 @@ export class JobRunner { private _jobAssignedToNode$: BehaviorSubject; constructor(jobCreator: JobCreator) { - this._mlApiServices = jobCreator.mlApiServices; + this._mlApi = jobCreator.mlApi; this._mlJobService = jobCreator.mlJobService; this._jobId = jobCreator.jobId; this._datafeedId = jobCreator.datafeedId; @@ -193,7 +193,7 @@ export class JobRunner { } private async _isJobAssigned(): Promise { - const { jobs } = await this._mlApiServices.getJobStats({ jobId: this._jobId }); + const { jobs } = await this._mlApi.getJobStats({ jobId: this._jobId }); return jobs.length > 0 && jobs[0].node !== undefined; } @@ -212,7 +212,7 @@ export class JobRunner { isRunning: boolean; isJobClosed: boolean; }> { - return await this._mlApiServices.jobs.getLookBackProgress(this._jobId, this._start, this._end); + return await this._mlApi.jobs.getLookBackProgress(this._jobId, this._start, this._end); } public subscribeToProgress(func: ProgressSubscriber) { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_validator/validators.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_validator/validators.ts index 0ec37e612a3fa..0bd0731b6dbe2 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/job_validator/validators.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/job_validator/validators.ts @@ -81,7 +81,7 @@ export function cardinalityValidator( }), switchMap(({ jobCreator }) => { // Perform a cardinality check only with enabled model plot. - return jobCreator.mlApiServices + return jobCreator.mlApi .validateCardinality$({ ...jobCreator.jobConfig, datafeed_config: jobCreator.datafeedConfig, @@ -117,7 +117,7 @@ export function jobIdValidator(jobCreator$: Subject): Observable prevJobCreator.jobId === currJobCreator.jobId ), - switchMap((jobCreator) => jobCreator.mlApiServices.jobs.jobsExist$([jobCreator.jobId], true)), + switchMap((jobCreator) => jobCreator.mlApi.jobs.jobsExist$([jobCreator.jobId], true)), map((jobExistsResults) => { const jobs = Object.values(jobExistsResults); const valid = jobs?.[0].exists === false; @@ -139,7 +139,7 @@ export function groupIdsValidator(jobCreator$: Subject): Observable< JSON.stringify(prevJobCreator.groups) === JSON.stringify(currJobCreator.groups) ), switchMap((jobCreator) => { - return jobCreator.mlApiServices.jobs.jobsExist$(jobCreator.groups, true); + return jobCreator.mlApi.jobs.jobsExist$(jobCreator.groups, true); }), map((jobExistsResults) => { const groups = Object.values(jobExistsResults); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/map_loader/map_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/map_loader/map_loader.ts index a75152e93bd88..e6a54aaa66880 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/map_loader/map_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/map_loader/map_loader.ts @@ -13,7 +13,7 @@ import type { CreateLayerDescriptorParams, MapsStartApi } from '@kbn/maps-plugin import type { Query } from '@kbn/es-query'; import type { Field, SplitField } from '@kbn/ml-anomaly-utils'; import { ChartLoader } from '../chart_loader'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; const eq = (newArgs: any[], lastArgs: any[]) => isEqual(newArgs, lastArgs); @@ -21,12 +21,12 @@ export class MapLoader extends ChartLoader { private _getMapData; constructor( - mlApiServices: MlApiServices, + mlApi: MlApi, indexPattern: DataView, query: object, mapsPlugin: MapsStartApi | undefined ) { - super(mlApiServices, indexPattern, query); + super(mlApi, indexPattern, query); this._getMapData = mapsPlugin ? memoizeOne(mapsPlugin.createLayerDescriptors.createESSearchSourceLayerDescriptor, eq) diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts index de24a7cff2995..96512c8540111 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/categorization_examples_loader.ts @@ -39,7 +39,7 @@ export class CategorizationExamplesLoader { }; } - const resp = await this._jobCreator.mlApiServices.jobs.categorizationFieldExamples( + const resp = await this._jobCreator.mlApi.jobs.categorizationFieldExamples( this._indexPatternTitle, this._query, NUMBER_OF_CATEGORY_EXAMPLES, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts index 742d0b476ebac..0492cb49ebedd 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/results_loader.ts @@ -85,7 +85,7 @@ export class ResultsLoader { this._chartInterval = chartInterval; this._results$ = new BehaviorSubject(this._results); this._chartLoader = chartLoader; - this._mlResultsService = mlResultsServiceProvider(jobCreator.mlApiServices); + this._mlResultsService = mlResultsServiceProvider(jobCreator.mlApi); jobCreator.subscribeToProgress(this.progressSubscriber); } @@ -242,7 +242,7 @@ export class ResultsLoader { private async _loadDetectorsAnomalyData(): Promise> { const resp = await getScoresByRecord( - this._jobCreator.mlApiServices, + this._jobCreator.mlApi, this._jobCreator.jobId, this._jobCreator.start, this._jobCreator.end, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts index 738bb880bd700..f9aaa56f59c06 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/common/results_loader/searches.ts @@ -8,7 +8,7 @@ import { get } from 'lodash'; import { escapeForElasticsearchQuery } from '../../../../util/string_utils'; -import type { MlApiServices } from '../../../../services/ml_api_service'; +import type { MlApi } from '../../../../services/ml_api_service'; interface SplitFieldWithValue { name: string; @@ -30,7 +30,7 @@ interface ProcessedResults { // detector swimlane search export function getScoresByRecord( - mlApiServices: MlApiServices, + mlApi: MlApi, jobId: string, earliestMs: number, latestMs: number, @@ -54,7 +54,7 @@ export function getScoresByRecord( jobIdFilterStr += `"${String(firstSplitField.value).replace(/\\/g, '\\\\')}"`; } - mlApiServices.results + mlApi.results .anomalySearch( { body: { diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts index b685bb181f7c6..98c2a74baf543 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts @@ -21,7 +21,7 @@ import type { Filter, Query, DataViewBase } from '@kbn/es-query'; import { FilterStateStore } from '@kbn/es-query'; import type { ErrorType } from '@kbn/ml-error-utils'; import type { DataViewsContract } from '@kbn/data-views-plugin/public'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import type { Job, Datafeed } from '../../../../../common/types/anomaly_detection_jobs'; import { getFiltersForDSLQuery } from '../../../../../common/util/job_utils'; @@ -57,7 +57,7 @@ export class QuickJobCreatorBase { protected readonly kibanaConfig: IUiSettingsClient, protected readonly timeFilter: TimefilterContract, protected readonly dashboardService: DashboardStart, - protected readonly mlApiServices: MlApiServices, + protected readonly mlApi: MlApi, protected readonly mlJobService: MlJobService ) {} @@ -110,7 +110,7 @@ export class QuickJobCreatorBase { datafeedConfig.indices.length > 0 ) { const { modelMemoryLimit } = await firstValueFrom( - this.mlApiServices.calculateModelMemoryLimit$({ + this.mlApi.calculateModelMemoryLimit$({ datafeedConfig: datafeed, analysisConfig: job.analysis_config, indexPattern: datafeedConfig.indices[0], @@ -133,7 +133,7 @@ export class QuickJobCreatorBase { // put job try { - await this.mlApiServices.addJob({ jobId: job.job_id, job }); + await this.mlApi.addJob({ jobId: job.job_id, job }); } catch (error) { result.jobCreated.error = error; return result; @@ -142,7 +142,7 @@ export class QuickJobCreatorBase { // put datafeed try { - await this.mlApiServices.addDatafeed({ datafeedId, datafeedConfig: datafeed }); + await this.mlApi.addDatafeed({ datafeedId, datafeedConfig: datafeed }); } catch (error) { result.datafeedCreated.error = error; return result; @@ -152,7 +152,7 @@ export class QuickJobCreatorBase { if (startJob) { // open job, ignore error if already open try { - await this.mlApiServices.openJob({ jobId }); + await this.mlApi.openJob({ jobId }); } catch (error) { // job may already be open, so ignore 409 error. if (error.body.statusCode !== 409) { @@ -164,7 +164,7 @@ export class QuickJobCreatorBase { // start datafeed try { - await this.mlApiServices.startDatafeed({ + await this.mlApi.startDatafeed({ datafeedId, start, ...(runInRealTime ? {} : { end }), diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts index 3ce3289a424b8..db1e025406538 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts @@ -19,7 +19,7 @@ import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { LensApi } from '@kbn/lens-plugin/public'; import type { JobCreatorType } from '../common/job_creator'; import { createEmptyJob, createEmptyDatafeed } from '../common/job_creator/util/default_configs'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { CREATED_BY_LABEL, @@ -42,10 +42,10 @@ export class QuickLensJobCreator extends QuickJobCreatorBase { kibanaConfig: IUiSettingsClient, timeFilter: TimefilterContract, dashboardService: DashboardStart, - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService ) { - super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApiServices, mlJobService); + super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi, mlJobService); } public async createAndSaveJob( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts index dd6fb765e158b..0f5c102859bb8 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts @@ -14,7 +14,7 @@ import type { TimefilterContract } from '@kbn/data-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { DataViewsContract } from '@kbn/data-views-plugin/public'; import { QuickLensJobCreator } from './quick_create_job'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { getDefaultQuery, getRisonValue } from '../utils/new_job_utils'; @@ -25,7 +25,7 @@ interface Dependencies { kibanaConfig: IUiSettingsClient; timeFilter: TimefilterContract; dashboardService: DashboardStart; - mlApiServices: MlApiServices; + mlApi: MlApi; mlJobService: MlJobService; } export async function resolver( @@ -37,15 +37,7 @@ export async function resolver( filtersRisonString: string, layerIndexRisonString: string ) { - const { - dataViews, - lens, - mlApiServices, - mlJobService, - timeFilter, - kibanaConfig, - dashboardService, - } = deps; + const { dataViews, lens, mlApi, mlJobService, timeFilter, kibanaConfig, dashboardService } = deps; if (lensSavedObjectRisonString === undefined) { throw new Error('Cannot create visualization'); } @@ -67,7 +59,7 @@ export async function resolver( kibanaConfig, timeFilter, dashboardService, - mlApiServices, + mlApi, mlJobService ); await jobCreator.createAndStashADJob(vis, from, to, query, filters, layerIndex); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts index 0f14eaaf515fe..cc36762162e2a 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts @@ -12,7 +12,7 @@ import type { Filter, Query } from '@kbn/es-query'; import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { MapApi } from '@kbn/maps-plugin/public'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { CREATED_BY_LABEL, @@ -43,10 +43,10 @@ export class QuickGeoJobCreator extends QuickJobCreatorBase { kibanaConfig: IUiSettingsClient, timeFilter: TimefilterContract, dashboardService: DashboardStart, - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService ) { - super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApiServices, mlJobService); + super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi, mlJobService); } public async createAndSaveGeoJob({ diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts index 455802fcc3f4a..d3a9b8641ca75 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts @@ -9,7 +9,7 @@ import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { TimefilterContract } from '@kbn/data-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { DataViewsContract } from '@kbn/data-views-plugin/public'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { QuickGeoJobCreator } from './quick_create_job'; @@ -20,7 +20,7 @@ interface Dependencies { kibanaConfig: IUiSettingsClient; timeFilter: TimefilterContract; dashboardService: DashboardStart; - mlApiServices: MlApiServices; + mlApi: MlApi; mlJobService: MlJobService; } export async function resolver( @@ -34,8 +34,7 @@ export async function resolver( toRisonString: string, layerRisonString?: string ) { - const { dataViews, kibanaConfig, timeFilter, dashboardService, mlApiServices, mlJobService } = - deps; + const { dataViews, kibanaConfig, timeFilter, dashboardService, mlApi, mlJobService } = deps; const defaultLayer = { query: getDefaultQuery(), filters: [] }; const dashboard = getRisonValue(dashboardRisonString, defaultLayer); @@ -58,7 +57,7 @@ export async function resolver( kibanaConfig, timeFilter, dashboardService, - mlApiServices, + mlApi, mlJobService ); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts index 0b81525f4013d..92dbbced01a3c 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts @@ -16,7 +16,7 @@ import { MLCATEGORY, ML_JOB_AGGREGATION } from '@kbn/ml-anomaly-utils'; import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { CREATED_BY_LABEL, DEFAULT_BUCKET_SPAN } from '../../../../../common/constants/new_job'; import { type CreateState, QuickJobCreatorBase } from '../job_from_dashboard/quick_create_job_base'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { createEmptyDatafeed, createEmptyJob } from '../common/job_creator/util/default_configs'; import type { JobCreatorType } from '../common/job_creator'; @@ -36,10 +36,10 @@ export class QuickCategorizationJobCreator extends QuickJobCreatorBase { timeFilter: TimefilterContract, dashboardService: DashboardStart, private data: DataPublicPluginStart, - mlApiServices: MlApiServices, + mlApi: MlApi, mlJobService: MlJobService ) { - super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApiServices, mlJobService); + super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi, mlJobService); } public async createAndSaveJob( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts index a2277babcc195..d950c631f6bb6 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts @@ -14,7 +14,7 @@ import { QuickCategorizationJobCreator, CATEGORIZATION_TYPE, } from './quick_create_job'; -import type { MlApiServices } from '../../../services/ml_api_service'; +import type { MlApi } from '../../../services/ml_api_service'; import type { MlJobService } from '../../../services/job_service'; import { getDefaultDatafeedQuery, getRisonValue } from '../utils/new_job_utils'; @@ -24,7 +24,7 @@ interface Dependencies { timeFilter: TimefilterContract; dashboardService: DashboardStart; data: DataPublicPluginStart; - mlApiServices: MlApiServices; + mlApi: MlApi; mlJobService: MlJobService; } export async function resolver( @@ -38,7 +38,7 @@ export async function resolver( toRisonString: string, queryRisonString: string ) { - const { mlApiServices, mlJobService, timeFilter, kibanaConfig, dashboardService, data } = deps; + const { mlApi, mlJobService, timeFilter, kibanaConfig, dashboardService, data } = deps; const query = getRisonValue(queryRisonString, getDefaultDatafeedQuery()); const from = getRisonValue(fromRisonString, ''); @@ -59,7 +59,7 @@ export async function resolver( timeFilter, dashboardService, data, - mlApiServices, + mlApi, mlJobService ); await jobCreator.createAndStashADJob( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/datafeed_preview_flyout/datafeed_preview.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/datafeed_preview_flyout/datafeed_preview.tsx index ed9fdc22b9954..dc5bfc6003dd3 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/datafeed_preview_flyout/datafeed_preview.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/common/datafeed_preview_flyout/datafeed_preview.tsx @@ -20,7 +20,7 @@ import { import type { CombinedJob } from '../../../../../../../../common/types/anomaly_detection_jobs'; import { MLJobEditor } from '../../../../../jobs_list/components/ml_job_editor'; -import { useMlApiContext } from '../../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../../contexts/kibana'; export const DatafeedPreview: FC<{ combinedJob: CombinedJob | null; @@ -28,7 +28,7 @@ export const DatafeedPreview: FC<{ }> = ({ combinedJob, heightOffset = 0 }) => { const { jobs: { datafeedPreview }, - } = useMlApiContext(); + } = useMlApi(); // the ace editor requires a fixed height const editorHeight = useMemo( () => `${window.innerHeight - 230 - heightOffset}px`, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/change_data_view.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/change_data_view.tsx index cb6a636a8c296..a45022a615be0 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/change_data_view.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/datafeed_step/components/data_view/change_data_view.tsx @@ -37,11 +37,7 @@ import type { } from '../../../../../../../../../common/types/anomaly_detection_jobs'; import type { DatafeedValidationResponse } from '../../../../../../../../../common/types/job_validation'; -import { - useMlKibana, - useMlApiContext, - useNavigateToPath, -} from '../../../../../../../contexts/kibana'; +import { useMlKibana, useMlApi, useNavigateToPath } from '../../../../../../../contexts/kibana'; const fixedPageSize: number = 8; @@ -63,7 +59,7 @@ export const ChangeDataViewModal: FC = ({ onClose }) => { }, } = useMlKibana(); const navigateToPath = useNavigateToPath(); - const { validateDatafeedPreview } = useMlApiContext(); + const { validateDatafeedPreview } = useMlApi(); const { jobCreator: jc } = useContext(JobCreatorContext); const jobCreator = jc as AdvancedJobCreator; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx index bd3b52f5bb003..06718f175b266 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx @@ -24,7 +24,7 @@ import { JobCreatorContext } from '../../../../../job_creator_context'; import { Description } from './description'; import { PLUGIN_ID } from '../../../../../../../../../../../common/constants/app'; import type { Calendar } from '../../../../../../../../../../../common/types/calendars'; -import { useMlApiContext, useMlKibana } from '../../../../../../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../../../../../../contexts/kibana'; import { GLOBAL_CALENDAR } from '../../../../../../../../../../../common/constants/calendars'; import { ML_PAGES } from '../../../../../../../../../../../common/constants/locator'; @@ -34,7 +34,7 @@ export const CalendarsSelection: FC = () => { application: { getUrlForApp }, }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { jobCreator, jobCreatorUpdate } = useContext(JobCreatorContext); const [selectedCalendars, setSelectedCalendars] = useState(jobCreator.calendars); @@ -46,7 +46,7 @@ export const CalendarsSelection: FC = () => { async function loadCalendars() { setIsLoading(true); - const calendars = (await ml.calendars()).filter( + const calendars = (await mlApi.calendars()).filter( (c) => c.job_ids.includes(GLOBAL_CALENDAR) === false ); setOptions(calendars.map((c) => ({ label: c.calendar_id, value: c }))); diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts index de279236d8755..71bdad4aadf14 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/bucket_span_estimator/estimate_bucket_span.ts @@ -8,7 +8,7 @@ import { useContext, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EVENT_RATE_FIELD_ID } from '@kbn/ml-anomaly-utils'; -import { useMlApiContext } from '../../../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../../../contexts/kibana'; import { JobCreatorContext } from '../../../job_creator_context'; import type { BucketSpanEstimatorData } from '../../../../../../../../../common/types/job_service'; import { @@ -27,7 +27,7 @@ export enum ESTIMATE_STATUS { export function useEstimateBucketSpan() { const toastNotificationService = useToastNotificationService(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { jobCreator, jobCreatorUpdate } = useContext(JobCreatorContext); const dataSourceContext = useDataSource(); @@ -78,7 +78,7 @@ export function useEstimateBucketSpan() { async function estimateBucketSpan() { setStatus(ESTIMATE_STATUS.RUNNING); - const { name, error, message: text } = await ml.estimateBucketSpan(data); + const { name, error, message: text } = await mlApi.estimateBucketSpan(data); setStatus(ESTIMATE_STATUS.NOT_RUNNING); if (error === true) { const title = i18n.translate( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/category_stopped_partitions.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/category_stopped_partitions.tsx index 912bc1af40e12..bf770601ae0c3 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/category_stopped_partitions.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/category_stopped_partitions.tsx @@ -13,13 +13,13 @@ import { i18n } from '@kbn/i18n'; import { from } from 'rxjs'; import { switchMap, takeWhile, tap } from 'rxjs'; import { extractErrorProperties } from '@kbn/ml-error-utils'; -import { useMlApiContext } from '../../../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../../../contexts/kibana'; import { JobCreatorContext } from '../../../job_creator_context'; import type { CategorizationJobCreator } from '../../../../../common/job_creator'; const NUMBER_OF_PREVIEW = 5; export const CategoryStoppedPartitions: FC = () => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { jobCreator: jc, resultsLoader } = useContext(JobCreatorContext); const jobCreator = jc as CategorizationJobCreator; const [tableRow, setTableRow] = useState>([]); @@ -47,7 +47,7 @@ export const CategoryStoppedPartitions: FC = () => { const loadCategoryStoppedPartitions = useCallback(async () => { try { - const { jobs } = await ml.results.getCategoryStoppedPartitions([jobCreator.jobId]); + const { jobs } = await mlApi.results.getCategoryStoppedPartitions([jobCreator.jobId]); if ( !Array.isArray(jobs) && // if jobs is object of jobId: [partitions] diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/top_categories.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/top_categories.tsx index 1a9db2f5c67fb..f69ba6f1ee9f0 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/top_categories.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/top_categories.tsx @@ -10,7 +10,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { EuiBasicTable, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { extractErrorProperties } from '@kbn/ml-error-utils'; -import { useMlApiContext } from '../../../../../../../contexts/kibana'; +import { useMlApi } from '../../../../../../../contexts/kibana'; import { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../../../../common/constants/new_job'; import { JobCreatorContext } from '../../../job_creator_context'; import type { CategorizationJobCreator } from '../../../../../common/job_creator'; @@ -18,7 +18,7 @@ import type { Results } from '../../../../../common/results_loader'; import { useToastNotificationService } from '../../../../../../../services/toast_notification_service'; export const TopCategories: FC = () => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const { jobCreator: jc, resultsLoader } = useContext(JobCreatorContext); @@ -33,7 +33,7 @@ export const TopCategories: FC = () => { async function loadTopCats() { try { - const results = await ml.jobs.topCategories(jobCreator.jobId, NUMBER_OF_CATEGORY_EXAMPLES); + const results = await mlApi.jobs.topCategories(jobCreator.jobId, NUMBER_OF_CATEGORY_EXAMPLES); setTableRow( results.categories.map((c) => ({ count: c.count, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx index e4cc4dd88a4e2..cd90f4f552eff 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/new_job/page.tsx @@ -33,7 +33,7 @@ import { MapLoader } from '../../common/map_loader'; import { ResultsLoader } from '../../common/results_loader'; import { JobValidator } from '../../common/job_validator'; import { useDataSource } from '../../../../contexts/ml'; -import { useMlApiContext, useMlKibana } from '../../../../contexts/kibana'; +import { useMlApi, useMlKibana } from '../../../../contexts/kibana'; import type { ExistingJobsAndGroups } from '../../../../services/job_service'; import { useMlJobService } from '../../../../services/job_service'; import { useNewJobCapsService } from '../../../../services/new_job_capabilities/new_job_capabilities_service'; @@ -56,7 +56,7 @@ export const Page: FC = ({ existingJobsAndGroups, jobType }) => { const { services: { maps: mapsPlugin, uiSettings }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const mlJobService = useMlJobService(); const newJobCapsService = useNewJobCapsService(); @@ -65,7 +65,7 @@ export const Page: FC = ({ existingJobsAndGroups, jobType }) => { const jobCreator = useMemo( () => jobCreatorFactory(jobType)( - ml, + mlApi, mlJobService, newJobCapsService, dataSourceContext.selectedDataView, @@ -208,13 +208,13 @@ export const Page: FC = ({ existingJobsAndGroups, jobType }) => { chartInterval.setInterval('auto'); const chartLoader = useMemo( - () => new ChartLoader(ml, dataSourceContext.selectedDataView, jobCreator.query), - [ml, dataSourceContext.selectedDataView, jobCreator.query] + () => new ChartLoader(mlApi, dataSourceContext.selectedDataView, jobCreator.query), + [mlApi, dataSourceContext.selectedDataView, jobCreator.query] ); const mapLoader = useMemo( - () => new MapLoader(ml, dataSourceContext.selectedDataView, jobCreator.query, mapsPlugin), - [ml, dataSourceContext.selectedDataView, jobCreator.query, mapsPlugin] + () => new MapLoader(mlApi, dataSourceContext.selectedDataView, jobCreator.query, mapsPlugin), + [mlApi, dataSourceContext.selectedDataView, jobCreator.query, mapsPlugin] ); const resultsLoader = useMemo( diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx index f12a870d8d448..f664db9800de0 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx +++ b/x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx @@ -73,7 +73,7 @@ export const Page: FC = ({ moduleId, existingGroupIds }) => { services: { notifications, mlServices: { - mlApiServices: { getTimeFieldRange, setupDataRecognizerConfig, getDataRecognizerModule }, + mlApi: { getTimeFieldRange, setupDataRecognizerConfig, getDataRecognizerModule }, }, }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/ml_nodes_check/check_ml_nodes.ts b/x-pack/plugins/ml/public/application/ml_nodes_check/check_ml_nodes.ts index 78afdd80fcc24..3fd19b2b810ae 100644 --- a/x-pack/plugins/ml/public/application/ml_nodes_check/check_ml_nodes.ts +++ b/x-pack/plugins/ml/public/application/ml_nodes_check/check_ml_nodes.ts @@ -5,16 +5,16 @@ * 2.0. */ -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; import type { MlNodeCount } from '../../../common/types/ml_server_info'; let mlNodeCount: number = 0; let lazyMlNodeCount: number = 0; let userHasPermissionToViewMlNodeCount: boolean = false; -export async function getMlNodeCount(mlApiServices: MlApiServices): Promise { +export async function getMlNodeCount(mlApi: MlApi): Promise { try { - const nodes = await mlApiServices.mlNodeCount(); + const nodes = await mlApi.mlNodeCount(); mlNodeCount = nodes.count; lazyMlNodeCount = nodes.lazyNodeCount; userHasPermissionToViewMlNodeCount = true; diff --git a/x-pack/plugins/ml/public/application/model_management/create_pipeline_for_model/create_pipeline_for_model_flyout.tsx b/x-pack/plugins/ml/public/application/model_management/create_pipeline_for_model/create_pipeline_for_model_flyout.tsx index 991e085384c3d..21fac6f6a28f8 100644 --- a/x-pack/plugins/ml/public/application/model_management/create_pipeline_for_model/create_pipeline_for_model_flyout.tsx +++ b/x-pack/plugins/ml/public/application/model_management/create_pipeline_for_model/create_pipeline_for_model_flyout.tsx @@ -31,7 +31,7 @@ import { PipelineDetails } from './pipeline_details'; import { TestTrainedModel } from './test_trained_model'; import { OnFailureConfiguration } from '../../components/shared'; import { ReviewAndCreatePipeline } from '../../components/shared'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { getPipelineConfig } from './get_pipeline_config'; import { validateInferencePipelineConfigurationStep } from '../../components/ml_inference/validation'; import { type InferecePipelineCreationState } from './state'; @@ -67,7 +67,7 @@ export const CreatePipelineForModelFlyout: FC const { trainedModels: { createInferencePipeline }, - } = useMlApiContext(); + } = useMlApi(); const createPipeline = async () => { setFormState({ ...formState, creatingPipeline: true }); diff --git a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx index 9bcf348f45189..e9d323a8f6407 100644 --- a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx +++ b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx @@ -56,7 +56,7 @@ export function useModelActions({ application: { navigateToUrl }, overlays, docLinks, - mlServices: { mlApiServices }, + mlServices: { mlApi }, ...startServices }, } = useMlKibana(); @@ -87,7 +87,7 @@ export function useModelActions({ useEffect(() => { let isMounted = true; - mlApiServices + mlApi .hasPrivileges({ cluster: ['manage_ingest_pipelines'], }) @@ -102,7 +102,7 @@ export function useModelActions({ return () => { isMounted = false; }; - }, [mlApiServices]); + }, [mlApi]); const getUserConfirmation = useMemo( () => getUserConfirmationProvider(overlays, startServices), diff --git a/x-pack/plugins/ml/public/application/model_management/models_list.tsx b/x-pack/plugins/ml/public/application/model_management/models_list.tsx index c7622501d072b..a7d969d013a25 100644 --- a/x-pack/plugins/ml/public/application/model_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/model_management/models_list.tsx @@ -707,7 +707,7 @@ export const ModelsList: FC = ({ ); return ( - + {isDownloadInProgress ? ( = ({ externalPipelineConfig, setCurrentContext, }) => { - const { trainedModels } = useMlApiContext(); + const { trainedModels } = useMlApi(); const inferrer = useMemo(() => { const taskType = Object.keys(model.inference_config ?? {})[0]; diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx index dac36551377be..fb4256636135b 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.test.tsx @@ -82,10 +82,10 @@ describe('NotificationsList', () => { await waitFor(() => { expect( - useMlKibana().services.mlServices.mlApiServices.notifications.findMessages + useMlKibana().services.mlServices.mlApi.notifications.findMessages ).toHaveBeenCalledTimes(1); expect( - useMlKibana().services.mlServices.mlApiServices.notifications.findMessages + useMlKibana().services.mlServices.mlApi.notifications.findMessages ).toHaveBeenCalledWith({ earliest: '', latest: '', diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx index 1ebba13d1f520..399b880c6a331 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx @@ -56,7 +56,7 @@ export const getDefaultNotificationsListState = (): ListingPageUrlState => ({ export const NotificationsList: FC = () => { const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); @@ -116,7 +116,7 @@ export const NotificationsList: FC = () => { try { setIsLoading(true); - const response = await mlApiServices.notifications.findMessages({ + const response = await mlApi.notifications.findMessages({ sortField: sorting.sort!.field, sortDirection: sorting.sort!.direction, earliest: timeRange.from, @@ -135,7 +135,7 @@ export const NotificationsList: FC = () => { } setIsLoading(false); - }, [sorting, queryInstance, mlApiServices.notifications, displayErrorToast, timeRange]); + }, [sorting, queryInstance, mlApi.notifications, displayErrorToast, timeRange]); useEffect( function updateLastCheckedAt() { diff --git a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx index c33681f69f76a..5e17304fff1c4 100644 --- a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/anomaly_detection_panel.tsx @@ -17,7 +17,7 @@ import { ML_OVERVIEW_PANELS } from '../../../../../common/types/storage'; import { ML_PAGES } from '../../../../../common/constants/locator'; import { OverviewStatsBar } from '../../../components/collapsible_panel/collapsible_panel'; import { CollapsiblePanel } from '../../../components/collapsible_panel'; -import { useMlApiContext, useMlKibana, useMlLink } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana, useMlLink } from '../../../contexts/kibana'; import { AnomalyDetectionTable } from './table'; import { getGroupsFromJobs, getStatsBarData } from './utils'; import type { Dictionary } from '../../../../../common/types/common'; @@ -56,7 +56,7 @@ export const AnomalyDetectionPanel: FC = ({ anomalyTimelineService, setLa const { services: { charts: chartsService }, } = useMlKibana(); - const ml = useMlApiContext(); + const mlApi = useMlApi(); const { displayErrorToast } = useToastNotificationService(); const { showNodeInfo } = useEnabledFeatures(); @@ -85,7 +85,7 @@ export const AnomalyDetectionPanel: FC = ({ anomalyTimelineService, setLa let lazyJobCount = 0; try { - const jobsResult: MlSummaryJobs = await ml.jobs.jobsSummary([]); + const jobsResult: MlSummaryJobs = await mlApi.jobs.jobsSummary([]); const jobsSummaryList = jobsResult.map((job: MlSummaryJob) => { job.latestTimestampSortValue = job.latestTimestampMs || 0; if (job.awaitingNodeAssignment) { diff --git a/x-pack/plugins/ml/public/application/overview/components/content.tsx b/x-pack/plugins/ml/public/application/overview/components/content.tsx index 1d0db5c6b9632..d70d590784e3e 100644 --- a/x-pack/plugins/ml/public/application/overview/components/content.tsx +++ b/x-pack/plugins/ml/public/application/overview/components/content.tsx @@ -29,7 +29,7 @@ export const OverviewContent: FC = ({ const { services: { uiSettings, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); @@ -41,7 +41,7 @@ export const OverviewContent: FC = ({ useEffect(() => { setAnomalyTimelineService( - new AnomalyTimelineService(timefilter, uiSettings, mlResultsServiceProvider(mlApiServices)) + new AnomalyTimelineService(timefilter, uiSettings, mlResultsServiceProvider(mlApi)) ); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/x-pack/plugins/ml/public/application/routing/resolvers.ts b/x-pack/plugins/ml/public/application/routing/resolvers.ts index e94f4e189f63c..7d7ca41ebf9c3 100644 --- a/x-pack/plugins/ml/public/application/routing/resolvers.ts +++ b/x-pack/plugins/ml/public/application/routing/resolvers.ts @@ -7,10 +7,10 @@ import { getMlNodeCount } from '../ml_nodes_check/check_ml_nodes'; import { loadMlServerInfo } from '../services/ml_server_info'; -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; export interface Resolvers { - [name: string]: (mlApiServices: MlApiServices) => Promise; + [name: string]: (mlApi: MlApi) => Promise; } export type ResolverResults = | { diff --git a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx index ffbcb0b8564ae..d48efb079af34 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/data_frame_analytics/analytics_job_creation.tsx @@ -13,7 +13,7 @@ import { dynamic } from '@kbn/shared-ux-utility'; import { DataSourceContextProvider } from '../../../contexts/ml'; import { ML_PAGES } from '../../../../locator'; import type { NavigateToPath } from '../../../contexts/kibana'; -import { useMlApiContext } from '../../../contexts/kibana'; +import { useMlApi } from '../../../contexts/kibana'; import { useMlKibana } from '../../../contexts/kibana'; import type { MlRoute, PageProps } from '../../router'; import { createPath, PageLoader } from '../../router'; @@ -58,7 +58,7 @@ const PageWrapper: FC = ({ location }) => { savedSearch: savedSearchService, }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const { context } = useRouteResolver( 'full', @@ -69,7 +69,7 @@ const PageWrapper: FC = ({ location }) => { loadNewJobCapabilities( index, savedSearchId, - mlApiServices, + mlApi, dataViewsService, savedSearchService, DATA_FRAME_ANALYTICS diff --git a/x-pack/plugins/ml/public/application/routing/routes/explorer/explorer.tsx b/x-pack/plugins/ml/public/application/routing/routes/explorer/explorer.tsx index 04cd415527ace..648cceee7ce3b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/explorer/explorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/explorer/explorer.tsx @@ -56,7 +56,7 @@ export const explorerRouteFactory = ( const PageWrapper: FC = () => { const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, uiSettings, }, } = useMlKibana(); @@ -65,7 +65,7 @@ const PageWrapper: FC = () => { const { context, results } = useRouteResolver('full', ['canGetJobs'], { ...basicResolvers(), jobs: mlJobService.loadJobsWrapper, - jobsWithTimeRange: () => mlApiServices.jobs.jobsWithTimerange(getDateFormatTz(uiSettings)), + jobsWithTimeRange: () => mlApi.jobs.jobsWithTimerange(getDateFormatTz(uiSettings)), }); const annotationUpdatesService = useMemo(() => new AnnotationUpdatesService(), []); diff --git a/x-pack/plugins/ml/public/application/routing/routes/explorer/state_manager.tsx b/x-pack/plugins/ml/public/application/routing/routes/explorer/state_manager.tsx index 1aa59116be935..d61849436c73d 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/explorer/state_manager.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/explorer/state_manager.tsx @@ -41,7 +41,7 @@ export const ExplorerUrlStateManager: FC = ({ const { services: { cases, presentationUtil, uiSettings, mlServices }, } = useMlKibana(); - const { mlApiServices: ml } = mlServices; + const { mlApi } = mlServices; const [globalState] = useUrlState('_g'); const [stoppedPartitions, setStoppedPartitions] = useState(); @@ -77,7 +77,7 @@ export const ExplorerUrlStateManager: FC = ({ const getJobsWithStoppedPartitions = useCallback(async (selectedJobIds: string[]) => { try { - const fetchedStoppedPartitions = await ml.results.getCategoryStoppedPartitions( + const fetchedStoppedPartitions = await mlApi.results.getCategoryStoppedPartitions( selectedJobIds, ML_JOB_ID ); diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_lens.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_lens.tsx index 210198b54afbb..bc5e1f23b31bc 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_lens.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_lens.tsx @@ -40,7 +40,7 @@ const PageWrapper: FC = ({ location }) => { }, dashboard: dashboardService, uiSettings: kibanaConfig, - mlServices: { mlApiServices }, + mlServices: { mlApi }, lens, }, } = useMlKibana(); @@ -52,7 +52,7 @@ const PageWrapper: FC = ({ location }) => { { dataViews, lens, - mlApiServices, + mlApi, mlJobService, timeFilter, kibanaConfig, diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_map.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_map.tsx index 0ba538ec24348..730dbb4cf1e26 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_map.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_map.tsx @@ -47,7 +47,7 @@ const PageWrapper: FC = ({ location }) => { }, dashboard: dashboardService, uiSettings: kibanaConfig, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); const mlJobService = useMlJobService(); @@ -55,7 +55,7 @@ const PageWrapper: FC = ({ location }) => { const { context } = useRouteResolver('full', ['canCreateJob'], { redirect: () => resolver( - { dataViews, mlApiServices, mlJobService, timeFilter, kibanaConfig, dashboardService }, + { dataViews, mlApi, mlJobService, timeFilter, kibanaConfig, dashboardService }, dashboard, dataViewId, embeddable, diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx index e6bc8f046a97b..d1dfcb2e21ed4 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx @@ -41,7 +41,7 @@ const PageWrapper: FC = ({ location }) => { data, dashboard: dashboardService, uiSettings: kibanaConfig, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); const mlJobService = useMlJobService(); @@ -50,7 +50,7 @@ const PageWrapper: FC = ({ location }) => { redirect: () => resolver( { - mlApiServices, + mlApi, mlJobService, timeFilter: data.query.timefilter.timefilter, kibanaConfig, diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx index 0a6166c3ff3b0..fb6c2aa15b651 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/recognize.tsx @@ -13,7 +13,7 @@ import { dynamic } from '@kbn/shared-ux-utility'; import { basicResolvers } from '../../resolvers'; import { ML_PAGES } from '../../../../locator'; import type { NavigateToPath } from '../../../contexts/kibana'; -import { useMlApiContext, useMlKibana, useNavigateToPath } from '../../../contexts/kibana'; +import { useMlApi, useMlKibana, useNavigateToPath } from '../../../contexts/kibana'; import type { MlRoute, PageProps } from '../../router'; import { createPath, PageLoader } from '../../router'; import { useRouteResolver } from '../../use_resolver'; @@ -55,13 +55,13 @@ export const checkViewOrCreateRouteFactory = (): MlRoute => ({ const PageWrapper: FC = ({ location }) => { const { id } = parse(location.search, { sort: false }); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const toastNotificationService = useToastNotificationService(); const { context, results } = useRouteResolver('full', ['canGetJobs'], { ...basicResolvers(), existingJobsAndGroups: () => - mlJobServiceFactory(toastNotificationService, mlApiServices).getJobAndGroupIds(), + mlJobServiceFactory(toastNotificationService, mlApi).getJobAndGroupIds(), }); return ( @@ -79,7 +79,7 @@ const CheckViewOrCreateWrapper: FC = ({ location }) => { const { services: { notifications: { toasts }, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); @@ -102,7 +102,7 @@ const CheckViewOrCreateWrapper: FC = ({ location }) => { // If so, load the jobs in the Anomaly Explorer. // Otherwise open the data recognizer wizard for the module. // Always want to call reject() so as not to load original page. - mlApiServices + mlApi .dataRecognizerModuleJobsExist({ moduleId }) .then(async (resp: any) => { if (resp.jobsExist === true) { diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx index 66ef374b4879e..d5f43fab97f45 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/wizard.tsx @@ -207,7 +207,7 @@ const PageWrapper: FC = ({ location, jobType }) => { services: { data: { dataViews: dataViewsService }, savedSearch: savedSearchService, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); const toastNotificationService = useToastNotificationService(); @@ -215,19 +215,18 @@ const PageWrapper: FC = ({ location, jobType }) => { const { context, results } = useRouteResolver('full', ['canGetJobs', 'canCreateJob'], { ...basicResolvers(), // TODO useRouteResolver should be responsible for the redirect - privileges: () => - checkCreateJobsCapabilitiesResolver(mlApiServices, redirectToJobsManagementPage), + privileges: () => checkCreateJobsCapabilitiesResolver(mlApi, redirectToJobsManagementPage), jobCaps: () => loadNewJobCapabilities( index, savedSearchId, - mlApiServices, + mlApi, dataViewsService, savedSearchService, ANOMALY_DETECTOR ), existingJobsAndGroups: () => - mlJobServiceFactory(toastNotificationService, mlApiServices).getJobAndGroupIds(), + mlJobServiceFactory(toastNotificationService, mlApi).getJobAndGroupIds(), }); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx index 8119c7305c0fd..5bf60c8b41779 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.test.tsx @@ -113,7 +113,7 @@ jest.mock('../../../contexts/kibana/kibana_context', () => { timefilter: getMockedTimefilter(), }, }, - mlServices: { mlApiServices: {} }, + mlServices: { mlApi: {} }, notifications: { toasts: { addDanger: () => {}, diff --git a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.tsx b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.tsx index b7e7c7a4332c0..14abe1b8029b7 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/timeseriesexplorer/timeseriesexplorer.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { dynamic } from '@kbn/shared-ux-utility'; import { ML_PAGES } from '../../../../locator'; import type { NavigateToPath } from '../../../contexts/kibana'; -import { useMlApiContext, useUiSettings } from '../../../contexts/kibana'; +import { useMlApi, useUiSettings } from '../../../contexts/kibana'; import { getDateFormatTz } from '../../../explorer/explorer_utils'; import { useMlJobService } from '../../../services/job_service'; import type { MlRoute, PageProps } from '../../router'; @@ -49,7 +49,7 @@ export const timeSeriesExplorerRouteFactory = ( }); const PageWrapper: FC = ({ deps }) => { - const mlApi = useMlApiContext(); + const mlApi = useMlApi(); const mlJobService = useMlJobService(); const uiSettings = useUiSettings(); const { context, results } = useRouteResolver('full', ['canGetJobs'], { diff --git a/x-pack/plugins/ml/public/application/routing/use_resolver.tsx b/x-pack/plugins/ml/public/application/routing/use_resolver.tsx index d7e7e8762caaf..d65107410012b 100644 --- a/x-pack/plugins/ml/public/application/routing/use_resolver.tsx +++ b/x-pack/plugins/ml/public/application/routing/use_resolver.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import useMount from 'react-use/lib/useMount'; import { AccessDeniedCallout } from '../access_denied'; import { PLUGIN_ID } from '../../../common/constants/app'; -import { useMlApiContext, useMlKibana, useMlLicenseInfo } from '../contexts/kibana'; +import { useMlApi, useMlKibana, useMlLicenseInfo } from '../contexts/kibana'; import { type MlCapabilitiesKey } from '../../../common/types/capabilities'; import { usePermissionCheck } from '../capabilities/check_capabilities'; import type { ResolverResults, Resolvers } from './resolvers'; @@ -54,7 +54,7 @@ export const useRouteResolver = ( }, }, } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const mlLicenseInfo = useMlLicenseInfo(); useMount(function refreshCapabilitiesOnMount() { @@ -119,11 +119,11 @@ export const useRouteResolver = ( p[c] = {}; return p; }, {} as Exclude); - const res = await Promise.all(funcs.map((r) => r(mlApiServices))); + const res = await Promise.all(funcs.map((r) => r(mlApi))); res.forEach((r, i) => (tempResults[funcNames[i]] = r)); return tempResults; - // skip mlApiServices from deps + // skip mlApi from deps // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/x-pack/plugins/ml/public/application/services/anomaly_detector_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_detector_service.ts index 040753af178b2..972a0d7bb3963 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_detector_service.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_detector_service.ts @@ -9,13 +9,13 @@ import type { Observable } from 'rxjs'; import { map } from 'rxjs'; import type { Job, JobId } from '../../../common/types/anomaly_detection_jobs'; import type { HttpService } from './http_service'; -import { type MlApiServices, mlApiServicesProvider } from './ml_api_service'; +import { type MlApi, mlApiProvider } from './ml_api_service'; export class AnomalyDetectorService { - private mlApiServices: MlApiServices; + private mlApi: MlApi; constructor(httpService: HttpService) { - this.mlApiServices = mlApiServicesProvider(httpService); + this.mlApi = mlApiProvider(httpService); } /** @@ -31,8 +31,6 @@ export class AnomalyDetectorService { * @param jobIds */ getJobs$(jobIds: JobId[]): Observable { - return this.mlApiServices - .getJobs$({ jobId: jobIds.join(',') }) - .pipe(map((response) => response.jobs)); + return this.mlApi.getJobs$({ jobId: jobIds.join(',') }).pipe(map((response) => response.jobs)); } } diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts index 1efaddabe1a34..9b1f41c6aa04a 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.test.ts @@ -7,7 +7,7 @@ import { AnomalyExplorerChartsService } from './anomaly_explorer_charts_service'; import { of } from 'rxjs'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { MlResultsService } from './results_service'; import { createTimefilterMock } from '../contexts/kibana/__mocks__/use_timefilter'; import moment from 'moment'; @@ -56,7 +56,7 @@ describe('AnomalyExplorerChartsService', () => { anomalyExplorerService = new AnomalyExplorerChartsService( timefilterMock, - mlApiServicesMock as unknown as MlApiServices, + mlApiServicesMock as unknown as MlApi, mlResultsServiceMock as unknown as MlResultsService ) as jest.Mocked; }); diff --git a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts index 1eb752c28ce5d..8be72301a9613 100644 --- a/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts +++ b/x-pack/plugins/ml/public/application/services/anomaly_explorer_charts_service.ts @@ -25,7 +25,7 @@ import type { ExplorerChartsData } from '../explorer/explorer_charts/explorer_ch import type { AppStateSelectedCells } from '../explorer/explorer_utils'; import { SWIM_LANE_LABEL_WIDTH } from '../explorer/constants'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { MlResultsService } from './results_service'; const MAX_CHARTS_PER_ROW = 4; @@ -45,7 +45,7 @@ export class AnomalyExplorerChartsService { constructor( private timeFilter: TimefilterContract, - private mlApiServices: MlApiServices, + private mlApi: MlApi, private mlResultsService: MlResultsService ) { this.timeFilter.enableTimeRangeSelector(); @@ -64,7 +64,7 @@ export class AnomalyExplorerChartsService { public async getCombinedJobs(jobIds: string[]): Promise { const combinedResults = await Promise.all( // Getting only necessary job config and datafeed config without the stats - jobIds.map((jobId) => this.mlApiServices.jobs.jobForCloning(jobId)) + jobIds.map((jobId) => this.mlApi.jobs.jobForCloning(jobId)) ); return combinedResults .filter(isDefined) @@ -139,7 +139,7 @@ export class AnomalyExplorerChartsService { const maxSeriesToPlot = maxSeries ?? Math.max(chartsPerRow * 2, DEFAULT_MAX_SERIES_TO_PLOT); - return this.mlApiServices.results + return this.mlApi.results .getAnomalyCharts$( jobIds, influencers ?? [], diff --git a/x-pack/plugins/ml/public/application/services/calendar_service.ts b/x-pack/plugins/ml/public/application/services/calendar_service.ts index d44653e5ee86b..ada2cbce43f6c 100644 --- a/x-pack/plugins/ml/public/application/services/calendar_service.ts +++ b/x-pack/plugins/ml/public/application/services/calendar_service.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import type { Calendar, CalendarId } from '../../../common/types/calendars'; import type { JobId } from '../../../common/types/anomaly_detection_jobs'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; class CalendarService { /** @@ -16,10 +16,10 @@ class CalendarService { * @param calendar * @param jobId */ - async assignNewJobId(mlApiServices: MlApiServices, calendar: Calendar, jobId: JobId) { + async assignNewJobId(mlApi: MlApi, calendar: Calendar, jobId: JobId) { const { calendar_id: calendarId } = calendar; try { - await mlApiServices.updateCalendar({ + await mlApi.updateCalendar({ ...calendar, calendarId, job_ids: [...calendar.job_ids, jobId], @@ -38,12 +38,9 @@ class CalendarService { * Fetches calendars by the list of ids. * @param calendarIds */ - async fetchCalendarsByIds( - mlApiServices: MlApiServices, - calendarIds: CalendarId[] - ): Promise { + async fetchCalendarsByIds(mlApi: MlApi, calendarIds: CalendarId[]): Promise { try { - const calendars = await mlApiServices.calendars({ calendarIds }); + const calendars = await mlApi.calendars({ calendarIds }); return Array.isArray(calendars) ? calendars : [calendars]; } catch (e) { throw new Error( diff --git a/x-pack/plugins/ml/public/application/services/field_format_service.ts b/x-pack/plugins/ml/public/application/services/field_format_service.ts index 509e791cc75a4..8d21c368a7303 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service.ts @@ -8,7 +8,7 @@ import { mlFunctionToESAggregation } from '../../../common/util/job_utils'; import type { MlJobService } from './job_service'; import type { MlIndexUtils } from '../util/index_service'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; type FormatsByJobId = Record; type IndexPatternIdsByJob = Record; @@ -20,7 +20,7 @@ export class FieldFormatService { formatsByJob: FormatsByJobId = {}; constructor( - private mlApiServices: MlApiServices, + private mlApi: MlApi, private mlIndexUtils: MlIndexUtils, private mlJobService: MlJobService ) {} @@ -40,8 +40,8 @@ export class FieldFormatService { await Promise.all( jobIds.map(async (jobId) => { let jobObj; - if (this.mlApiServices) { - const { jobs } = await this.mlApiServices.getJobs({ jobId }); + if (this.mlApi) { + const { jobs } = await this.mlApi.getJobs({ jobId }); jobObj = jobs[0]; } else { jobObj = this.mlJobService.getJob(jobId); @@ -85,8 +85,8 @@ export class FieldFormatService { async getFormatsForJob(jobId: string): Promise { let jobObj; - if (this.mlApiServices) { - const { jobs } = await this.mlApiServices.getJobs({ jobId }); + if (this.mlApi) { + const { jobs } = await this.mlApi.getJobs({ jobId }); jobObj = jobs[0]; } else { jobObj = this.mlJobService.getJob(jobId); diff --git a/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts b/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts index fc59dbdf03ce4..1b40579cc74c3 100644 --- a/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts +++ b/x-pack/plugins/ml/public/application/services/field_format_service_factory.ts @@ -7,13 +7,13 @@ import { type MlFieldFormatService, FieldFormatService } from './field_format_service'; import type { MlIndexUtils } from '../util/index_service'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { MlJobService } from './job_service'; export function fieldFormatServiceFactory( - mlApiServices: MlApiServices, + mlApi: MlApi, mlIndexUtils: MlIndexUtils, mlJobService: MlJobService ): MlFieldFormatService { - return new FieldFormatService(mlApiServices, mlIndexUtils, mlJobService); + return new FieldFormatService(mlApi, mlIndexUtils, mlJobService); } diff --git a/x-pack/plugins/ml/public/application/services/forecast_service.ts b/x-pack/plugins/ml/public/application/services/forecast_service.ts index 316577d98dd44..d1778dbf948f6 100644 --- a/x-pack/plugins/ml/public/application/services/forecast_service.ts +++ b/x-pack/plugins/ml/public/application/services/forecast_service.ts @@ -11,7 +11,7 @@ import { useMemo } from 'react'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { get, find, each } from 'lodash'; import { map } from 'rxjs'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { Job } from '../../../common/types/anomaly_detection_jobs'; import { useMlKibana } from '../contexts/kibana'; @@ -21,7 +21,7 @@ export interface AggType { min: string; } -export function forecastServiceFactory(mlApiServices: MlApiServices) { +export function forecastServiceFactory(mlApi: MlApi) { // Gets a basic summary of the most recently run forecasts for the specified // job, with results at or later than the supplied timestamp. // Extra query object can be supplied, or pass null if no additional query. @@ -58,7 +58,7 @@ export function forecastServiceFactory(mlApiServices: MlApiServices) { filterCriteria.push(query); } - mlApiServices.results + mlApi.results .anomalySearch( { // @ts-expect-error SearchRequest type has not been updated to include size @@ -121,7 +121,7 @@ export function forecastServiceFactory(mlApiServices: MlApiServices) { // TODO - add in criteria for detector index and entity fields (by, over, partition) // once forecasting with these parameters is supported. - mlApiServices.results + mlApi.results .anomalySearch( { // @ts-expect-error SearchRequest type has not been updated to include size @@ -261,7 +261,7 @@ export function forecastServiceFactory(mlApiServices: MlApiServices) { min: aggType.min, }; - return mlApiServices.results + return mlApi.results .anomalySearch$( { // @ts-expect-error SearchRequest type has not been updated to include size @@ -323,7 +323,7 @@ export function forecastServiceFactory(mlApiServices: MlApiServices) { // eslint-disable-next-line no-console console.log('ML forecast service run forecast with duration:', duration); return new Promise((resolve, reject) => { - mlApiServices + mlApi .forecast({ jobId, duration, @@ -364,7 +364,7 @@ export function forecastServiceFactory(mlApiServices: MlApiServices) { }, ]; - mlApiServices.results + mlApi.results .anomalySearch( { // @ts-expect-error SearchRequest type has not been updated to include size @@ -405,10 +405,10 @@ export type MlForecastService = ReturnType; export function useForecastService(): MlForecastService { const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); - const mlForecastService = useMemo(() => forecastServiceFactory(mlApiServices), [mlApiServices]); + const mlForecastService = useMemo(() => forecastServiceFactory(mlApi), [mlApi]); return mlForecastService; } diff --git a/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts index 44e6a5e5746e8..ac003ea078219 100644 --- a/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts +++ b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts @@ -8,7 +8,7 @@ import { type HttpStart } from '@kbn/core-http-browser'; import { ElasticModels } from './elastic_models_service'; import { HttpService } from './http_service'; -import { mlApiServicesProvider } from './ml_api_service'; +import { mlApiProvider } from './ml_api_service'; export type MlSharedServices = ReturnType; @@ -17,10 +17,10 @@ export type MlSharedServices = ReturnType; */ export function getMlSharedServices(httpStart: HttpStart) { const httpService = new HttpService(httpStart); - const mlApiServices = mlApiServicesProvider(httpService); + const mlApi = mlApiProvider(httpService); return { - elasticModels: new ElasticModels(mlApiServices.trainedModels), - mlApiServices, + elasticModels: new ElasticModels(mlApi.trainedModels), + mlApi, }; } diff --git a/x-pack/plugins/ml/public/application/services/job_service.d.ts b/x-pack/plugins/ml/public/application/services/job_service.d.ts index 685a0cf86cf9a..54a1fb3170918 100644 --- a/x-pack/plugins/ml/public/application/services/job_service.d.ts +++ b/x-pack/plugins/ml/public/application/services/job_service.d.ts @@ -9,7 +9,7 @@ import type { TimeRange } from '@kbn/data-plugin/common/query/timefilter/types'; import type { CombinedJob, Datafeed, Job } from '../../../common/types/anomaly_detection_jobs'; import type { Calendar } from '../../../common/types/calendars'; import type { ToastNotificationService } from './toast_notification_service'; -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { JobCreatorType } from '../jobs/new_job/common/job_creator'; export interface ExistingJobsAndGroups { @@ -62,7 +62,7 @@ export declare interface MlJobService { export const mlJobServiceFactory: ( toastNotificationService: ToastNotificationService, - mlApiServices: MlApiServices + mlApi: MlApi ) => MlJobService; export const useMlJobService: () => MlJobService; diff --git a/x-pack/plugins/ml/public/application/services/job_service.js b/x-pack/plugins/ml/public/application/services/job_service.js index c37502ab570ac..dc7d96f4e3236 100644 --- a/x-pack/plugins/ml/public/application/services/job_service.js +++ b/x-pack/plugins/ml/public/application/services/job_service.js @@ -13,7 +13,7 @@ import { validateTimeRange, TIME_FORMAT } from '@kbn/ml-date-utils'; import { parseInterval } from '../../../common/util/parse_interval'; import { isWebUrl } from '../util/url_utils'; -import { useMlApiContext } from '../contexts/kibana'; +import { useMlApi } from '../contexts/kibana'; import { useToastNotificationService } from './toast_notification_service'; @@ -596,15 +596,15 @@ function createResultsUrl(jobIds, start, end, resultsPage, mode = 'absolute') { // This is to retain the singleton behavior of the previous direct instantiation and export. let mlJobService; -export const mlJobServiceFactory = (toastNotificationService, mlApiServices) => { +export const mlJobServiceFactory = (toastNotificationService, mlApi) => { if (mlJobService) return mlJobService; - mlJobService = new JobService(toastNotificationService, mlApiServices); + mlJobService = new JobService(toastNotificationService, mlApi); return mlJobService; }; export const useMlJobService = () => { const toastNotificationService = useToastNotificationService(); - const mlApiServices = useMlApiContext(); - return mlJobServiceFactory(toastNotificationService, mlApiServices); + const mlApi = useMlApi(); + return mlJobServiceFactory(toastNotificationService, mlApi); }; diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts index 77c074a97bec4..f185a6452d654 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/index.ts @@ -99,7 +99,7 @@ export interface GetModelSnapshotsResponse { model_snapshots: ModelSnapshot[]; } -export function mlApiServicesProvider(httpService: HttpService) { +export function mlApiProvider(httpService: HttpService) { return { getJobs(obj?: { jobId?: string }) { const jobId = obj && obj.jobId ? `/${obj.jobId}` : ''; @@ -785,4 +785,4 @@ export function mlApiServicesProvider(httpService: HttpService) { }; } -export type MlApiServices = ReturnType; +export type MlApi = ReturnType; diff --git a/x-pack/plugins/ml/public/application/services/ml_server_info.test.ts b/x-pack/plugins/ml/public/application/services/ml_server_info.test.ts index bb10e9b466f6e..38f3a196a9baf 100644 --- a/x-pack/plugins/ml/public/application/services/ml_server_info.test.ts +++ b/x-pack/plugins/ml/public/application/services/ml_server_info.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import { loadMlServerInfo, getCloudDeploymentId, @@ -19,7 +19,7 @@ import mockMlInfoResponse from './__mocks__/ml_info_response.json'; const mlApiServicesMock = { mlInfo: jest.fn(() => Promise.resolve(mockMlInfoResponse)), -} as unknown as MlApiServices; +} as unknown as MlApi; describe('ml_server_info initial state', () => { it('should fail to get server info ', () => { diff --git a/x-pack/plugins/ml/public/application/services/ml_server_info.ts b/x-pack/plugins/ml/public/application/services/ml_server_info.ts index 101cb33264502..e01236534f2c4 100644 --- a/x-pack/plugins/ml/public/application/services/ml_server_info.ts +++ b/x-pack/plugins/ml/public/application/services/ml_server_info.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { MlApiServices } from './ml_api_service'; +import type { MlApi } from './ml_api_service'; import type { MlServerDefaults, MlServerLimits } from '../../../common/types/ml_server_info'; export interface CloudInfo { @@ -28,9 +28,9 @@ const cloudInfo: CloudInfo = { deploymentId: null, }; -export async function loadMlServerInfo(mlApiServices: MlApiServices) { +export async function loadMlServerInfo(mlApi: MlApi) { try { - const resp = await mlApiServices.mlInfo(); + const resp = await mlApi.mlInfo(); defaults = resp.defaults; limits = resp.limits; cloudInfo.cloudId = resp.cloudId ?? null; diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts index 6c25d43020d52..f1e02597e3795 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/load_new_job_capabilities.ts @@ -9,7 +9,7 @@ import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/public' import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public'; import { getDataViewAndSavedSearchCallback } from '../../util/index_utils'; import type { JobType } from '../../../../common/types/saved_objects'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; import { mlJobCapsServiceAnalyticsFactory } from './new_job_capabilities_service_analytics'; import { mlJobCapsServiceFactory } from './new_job_capabilities_service'; @@ -21,7 +21,7 @@ export const DATA_FRAME_ANALYTICS = 'data-frame-analytics'; export function loadNewJobCapabilities( dataViewId: string, savedSearchId: string, - mlApiServices: MlApiServices, + mlApi: MlApi, dataViewsService: DataViewsContract, savedSearchService: SavedSearchPublicPluginStart, jobType: JobType @@ -30,8 +30,8 @@ export function loadNewJobCapabilities( try { const serviceToUse = jobType === ANOMALY_DETECTOR - ? mlJobCapsServiceFactory(mlApiServices) - : mlJobCapsServiceAnalyticsFactory(mlApiServices); + ? mlJobCapsServiceFactory(mlApi) + : mlJobCapsServiceAnalyticsFactory(mlApi); if (dataViewId !== undefined) { // index pattern is being used diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.test.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.test.ts index ed257199db16b..057b558485729 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.test.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.test.ts @@ -8,7 +8,7 @@ import { mlJobCapsServiceFactory } from './new_job_capabilities_service'; import type { DataView } from '@kbn/data-views-plugin/public'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; // there is magic happening here. starting the include name with `mock..` // ensures it can be lazily loaded by the jest.mock function below. @@ -18,7 +18,7 @@ const mlApiServicesMock = { jobs: { newJobCaps: jest.fn(() => Promise.resolve(mockCloudwatchResponse)), }, -} as unknown as MlApiServices; +} as unknown as MlApi; const dataView = { id: 'cloudwatch-*', diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts index 990d411779a6f..59f2e74b9ca36 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts @@ -15,9 +15,9 @@ import { EVENT_RATE_FIELD_ID, } from '@kbn/ml-anomaly-utils'; import { DataViewType } from '@kbn/data-views-plugin/public'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { getGeoFields, filterCategoryFields } from '../../../../common/util/fields_utils'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; import { processTextAndKeywordFields, NewJobCapabilitiesServiceBase } from './new_job_capabilities'; export class NewJobCapsService extends NewJobCapabilitiesServiceBase { @@ -26,9 +26,9 @@ export class NewJobCapsService extends NewJobCapabilitiesServiceBase { private _geoFields: Field[] = []; private _includeEventRateField: boolean = true; private _removeTextFields: boolean = true; - private _mlApiService: MlApiServices; + private _mlApiService: MlApi; - constructor(mlApiService: MlApiServices) { + constructor(mlApiService: MlApi) { super(); this._mlApiService = mlApiService; } @@ -189,14 +189,14 @@ function addEventRateField(aggs: Aggregation[], fields: Field[]) { // This is to retain the singleton behavior of the previous direct instantiation and export. let newJobCapsService: NewJobCapsService; -export const mlJobCapsServiceFactory = (mlApiServices: MlApiServices) => { +export const mlJobCapsServiceFactory = (mlApi: MlApi) => { if (newJobCapsService) return newJobCapsService; - newJobCapsService = new NewJobCapsService(mlApiServices); + newJobCapsService = new NewJobCapsService(mlApi); return newJobCapsService; }; export const useNewJobCapsService = () => { - const mlApiServices = useMlApiContext(); - return mlJobCapsServiceFactory(mlApiServices); + const mlApi = useMlApi(); + return mlJobCapsServiceFactory(mlApi); }; diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts index c2b7a4dc24906..f3ea32f42565d 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service_analytics.ts @@ -25,9 +25,9 @@ import { TOP_CLASSES, type DataFrameAnalyticsConfig, } from '@kbn/ml-data-frame-analytics-utils'; -import { useMlApiContext } from '../../contexts/kibana'; +import { useMlApi } from '../../contexts/kibana'; import { processTextAndKeywordFields, NewJobCapabilitiesServiceBase } from './new_job_capabilities'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; // Keep top nested field and remove all .* fields export function removeNestedFieldChildren(resp: NewJobCapsResponse, indexPatternTitle: string) { @@ -61,9 +61,9 @@ export function removeNestedFieldChildren(resp: NewJobCapsResponse, indexPattern } export class NewJobCapsServiceAnalytics extends NewJobCapabilitiesServiceBase { - private _mlApiService: MlApiServices; + private _mlApiService: MlApi; - constructor(mlApiService: MlApiServices) { + constructor(mlApiService: MlApi) { super(); this._mlApiService = mlApiService; } @@ -227,14 +227,14 @@ export class NewJobCapsServiceAnalytics extends NewJobCapabilitiesServiceBase { // This is to retain the singleton behavior of the previous direct instantiation and export. let newJobCapsServiceAnalytics: NewJobCapsServiceAnalytics; -export const mlJobCapsServiceAnalyticsFactory = (mlApiServices: MlApiServices) => { +export const mlJobCapsServiceAnalyticsFactory = (mlApi: MlApi) => { if (newJobCapsServiceAnalytics) return newJobCapsServiceAnalytics; - newJobCapsServiceAnalytics = new NewJobCapsServiceAnalytics(mlApiServices); + newJobCapsServiceAnalytics = new NewJobCapsServiceAnalytics(mlApi); return newJobCapsServiceAnalytics; }; export const useNewJobCapsServiceAnalytics = () => { - const mlApiServices = useMlApiContext(); - return mlJobCapsServiceAnalyticsFactory(mlApiServices); + const mlApi = useMlApi(); + return mlJobCapsServiceAnalyticsFactory(mlApi); }; diff --git a/x-pack/plugins/ml/public/application/services/results_service/index.ts b/x-pack/plugins/ml/public/application/services/results_service/index.ts index d8621eff633a4..6ee762511d280 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/index.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/index.ts @@ -7,8 +7,8 @@ import { resultsServiceRxProvider } from './result_service_rx'; import { resultsServiceProvider } from './results_service'; -import type { MlApiServices } from '../ml_api_service'; -import { useMlApiContext } from '../../contexts/kibana'; +import type { MlApi } from '../ml_api_service'; +import { useMlApi } from '../../contexts/kibana'; export type MlResultsService = ReturnType & ReturnType; @@ -25,18 +25,18 @@ export interface CriteriaField { // This is to retain the singleton behavior of the previous direct instantiation and export. let mlResultsService: MlResultsService; -export function mlResultsServiceProvider(mlApiServices: MlApiServices) { +export function mlResultsServiceProvider(mlApi: MlApi) { if (mlResultsService) return mlResultsService; mlResultsService = { - ...resultsServiceProvider(mlApiServices), - ...resultsServiceRxProvider(mlApiServices), + ...resultsServiceProvider(mlApi), + ...resultsServiceRxProvider(mlApi), }; return mlResultsService; } export function useMlResultsService(): MlResultsService { - const mlApiServices = useMlApiContext(); - return mlResultsServiceProvider(mlApiServices); + const mlApi = useMlApi(); + return mlResultsServiceProvider(mlApi); } diff --git a/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts b/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts index 281139160bee5..0f6e31ea96e95 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/result_service_rx.ts @@ -30,7 +30,7 @@ import { ML_MEDIAN_PERCENTS } from '../../../../common/util/job_utils'; import type { Datafeed, JobId } from '../../../../common/types/anomaly_detection_jobs'; import { findAggField } from '../../../../common/util/validation_utils'; import { getDatafeedAggregations } from '../../../../common/util/datafeed_utils'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; import type { CriteriaField } from '.'; export interface ResultResponse { @@ -71,7 +71,7 @@ export interface ScheduledEventsByBucket extends ResultResponse { events: Record; } -export function resultsServiceRxProvider(mlApiServices: MlApiServices) { +export function resultsServiceRxProvider(mlApi: MlApi) { return { getMetricData( index: string, @@ -216,7 +216,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { } } } - return mlApiServices.esSearch$({ index, body }).pipe( + return mlApi.esSearch$({ index, body }).pipe( map((resp: any) => { const obj: MetricData = { success: true, results: {} }; const dataByTime = resp?.aggregations?.byTime?.buckets ?? []; @@ -316,7 +316,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { }, ]; - return mlApiServices.results + return mlApi.results .anomalySearch$( { body: { @@ -469,7 +469,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { }); } - return mlApiServices.results + return mlApi.results .anomalySearch$( { body: { @@ -555,7 +555,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { }); } - return mlApiServices.results + return mlApi.results .anomalySearch$( { body: { @@ -634,7 +634,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { earliestMs: number, latestMs: number ) { - return mlApiServices.results.fetchPartitionFieldsValues( + return mlApi.results.fetchPartitionFieldsValues( jobId, searchTerm, criteriaFields, @@ -734,7 +734,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) { }); } - return mlApiServices.results + return mlApi.results .anomalySearch$( { body: { diff --git a/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts b/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts index aff49acc3b853..a55c56d795d86 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts +++ b/x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts @@ -8,9 +8,9 @@ import type { InfluencersFilterQuery, EntityField } from '@kbn/ml-anomaly-utils'; import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils'; import type { IndicesOptions } from '../../../../common/types/anomaly_detection_jobs'; -import type { MlApiServices } from '../ml_api_service'; +import type { MlApi } from '../ml_api_service'; -export function resultsServiceProvider(mlApiServices: MlApiServices): { +export function resultsServiceProvider(mlApi: MlApi): { getScoresByBucket( jobIds: string[], earliestMs: number, diff --git a/x-pack/plugins/ml/public/application/services/results_service/results_service.js b/x-pack/plugins/ml/public/application/services/results_service/results_service.js index f7074a3498b75..5b6df89e52249 100644 --- a/x-pack/plugins/ml/public/application/services/results_service/results_service.js +++ b/x-pack/plugins/ml/public/application/services/results_service/results_service.js @@ -20,7 +20,7 @@ import { aggregationTypeTransform } from '@kbn/ml-anomaly-utils'; /** * Service for carrying out Elasticsearch queries to obtain data for the Ml Results dashboards. */ -export function resultsServiceProvider(mlApiServices) { +export function resultsServiceProvider(mlApi) { const SAMPLER_TOP_TERMS_SHARD_SIZE = 20000; const ENTITY_AGGREGATION_SIZE = 10; const AGGREGATION_MIN_DOC_COUNT = 1; @@ -84,7 +84,7 @@ export function resultsServiceProvider(mlApiServices) { }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: 0, @@ -264,7 +264,7 @@ export function resultsServiceProvider(mlApiServices) { }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: 0, @@ -406,7 +406,7 @@ export function resultsServiceProvider(mlApiServices) { }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: 0, @@ -483,7 +483,7 @@ export function resultsServiceProvider(mlApiServices) { return new Promise((resolve, reject) => { const obj = { success: true, results: {} }; - mlApiServices + mlApi .overallBuckets({ jobId: jobIds, topN: topN, @@ -592,7 +592,7 @@ export function resultsServiceProvider(mlApiServices) { }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: 0, @@ -755,7 +755,7 @@ export function resultsServiceProvider(mlApiServices) { }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: maxResults !== undefined ? maxResults : 100, @@ -883,7 +883,7 @@ export function resultsServiceProvider(mlApiServices) { } } - mlApiServices.results + mlApi.results .anomalySearch( { size: maxResults !== undefined ? maxResults : 100, @@ -962,7 +962,7 @@ export function resultsServiceProvider(mlApiServices) { mustCriteria.push(query); } - mlApiServices + mlApi .esSearch({ index, size: 0, @@ -1140,7 +1140,7 @@ export function resultsServiceProvider(mlApiServices) { body.aggs.sample.aggs.byTime.aggs.entities.aggs.metric = metricAgg; } - mlApiServices + mlApi .esSearch({ index, body, @@ -1240,7 +1240,7 @@ export function resultsServiceProvider(mlApiServices) { }, }); } - mlApiServices.results + mlApi.results .anomalySearch( { size: 0, diff --git a/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx b/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx index 5161963e90a46..e5fce41df2e18 100644 --- a/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx +++ b/x-pack/plugins/ml/public/application/settings/anomaly_detection_settings.tsx @@ -22,14 +22,14 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useMlApiContext } from '../contexts/kibana'; +import { useMlApi } from '../contexts/kibana'; import { AnomalyDetectionSettingsContext } from './anomaly_detection_settings_context'; import { useToastNotificationService } from '../services/toast_notification_service'; import { ML_PAGES } from '../../../common/constants/locator'; import { useCreateAndNavigateToMlLink } from '../contexts/kibana/use_create_url'; export const AnomalyDetectionSettings: FC = () => { - const ml = useMlApiContext(); + const mlApi = useMlApi(); const [calendarsCount, setCalendarsCount] = useState(0); const [filterListsCount, setFilterListsCount] = useState(0); @@ -53,7 +53,7 @@ export const AnomalyDetectionSettings: FC = () => { // Obtain the counts of calendars and filter lists. if (canGetCalendars === true) { try { - const calendars = await ml.calendars(); + const calendars = await mlApi.calendars(); setCalendarsCount(calendars.length); } catch (e) { displayErrorToast( @@ -67,7 +67,7 @@ export const AnomalyDetectionSettings: FC = () => { if (canGetFilters === true) { try { - const filterLists = await ml.filters.filtersStats(); + const filterLists = await mlApi.filters.filtersStats(); setFilterListsCount(filterLists.length); } catch (e) { displayErrorToast( diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js index 79f4d82093f21..51939aaba639a 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.js @@ -72,7 +72,7 @@ class NewCalendarUI extends Component { async formSetup() { try { const { jobIds, groupIds, calendars } = await getCalendarSettingsData( - this.props.kibana.services.mlServices.mlApiServices + this.props.kibana.services.mlServices.mlApi ); const jobIdOptions = jobIds.map((jobId) => ({ label: jobId })); @@ -145,7 +145,7 @@ class NewCalendarUI extends Component { }; onCreate = async () => { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; const { formCalendarId } = this.state; if (this.isDuplicateId()) { @@ -161,7 +161,7 @@ class NewCalendarUI extends Component { this.setState({ saving: true }); try { - await ml.addCalendar(calendar); + await mlApi.addCalendar(calendar); await this.returnToCalendarsManagementPage(); } catch (error) { this.setState({ saving: false }); @@ -177,12 +177,12 @@ class NewCalendarUI extends Component { }; onEdit = async () => { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; const calendar = this.setUpCalendarForApi(); this.setState({ saving: true }); try { - await ml.updateCalendar(calendar); + await mlApi.updateCalendar(calendar); await this.returnToCalendarsManagementPage(); } catch (error) { this.setState({ saving: false }); diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js index 1e538668d9ac3..1ec652475e3a3 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/new_calendar.test.js @@ -84,7 +84,7 @@ const mockKibanaContext = { docLinks: { links: { ml: { calendars: 'test' } } }, notifications: { toasts: { addDanger: mockAddDanger, addError: jest.fn() } }, mlServices: { - mlApiServices: { + mlApi: { calendars: () => { return Promise.resolve([]); }, diff --git a/x-pack/plugins/ml/public/application/settings/calendars/edit/utils.js b/x-pack/plugins/ml/public/application/settings/calendars/edit/utils.js index 34fa2f5292f62..b4c655b755b99 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/edit/utils.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/edit/utils.js @@ -8,9 +8,9 @@ import { isJobIdValid } from '../../../../../common/util/job_utils'; import { i18n } from '@kbn/i18n'; -function getJobIds(mlApiServices) { +function getJobIds(mlApi) { return new Promise((resolve, reject) => { - mlApiServices.jobs + mlApi.jobs .jobsSummary() .then((resp) => { resolve(resp.map((job) => job.id)); @@ -29,9 +29,9 @@ function getJobIds(mlApiServices) { }); } -function getGroupIds(mlApiServices) { +function getGroupIds(mlApi) { return new Promise((resolve, reject) => { - mlApiServices.jobs + mlApi.jobs .groups() .then((resp) => { resolve(resp.map((group) => group.id)); @@ -50,9 +50,9 @@ function getGroupIds(mlApiServices) { }); } -function getCalendars(mlApiServices) { +function getCalendars(mlApi) { return new Promise((resolve, reject) => { - mlApiServices + mlApi .calendars() .then((resp) => { resolve(resp); @@ -71,13 +71,13 @@ function getCalendars(mlApiServices) { }); } -export function getCalendarSettingsData(mlApiServices) { +export function getCalendarSettingsData(mlApi) { return new Promise(async (resolve, reject) => { try { const [jobIds, groupIds, calendars] = await Promise.all([ - getJobIds(mlApiServices), - getGroupIds(mlApiServices), - getCalendars(mlApiServices), + getJobIds(mlApi), + getGroupIds(mlApi), + getCalendars(mlApi), ]); resolve({ diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js index 413aae794fc15..f49ed3bdac194 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.js @@ -38,11 +38,11 @@ export class CalendarsListUI extends Component { } loadCalendars = async () => { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; this.setState({ loading: true }); try { - const calendars = await ml.calendars(); + const calendars = await mlApi.calendars(); this.setState({ calendars, @@ -81,12 +81,12 @@ export class CalendarsListUI extends Component { }; deleteCalendars = () => { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; const toasts = this.props.kibana.services.notifications.toasts; const { selectedForDeletion } = this.state; this.closeDestroyModal(); - deleteCalendars(ml, toasts, selectedForDeletion, this.loadCalendars); + deleteCalendars(mlApi, toasts, selectedForDeletion, this.loadCalendars); }; addRequiredFieldsToList = (calendarsList = []) => { diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.test.js b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.test.js index 970c1afbe4fbc..c00b86cf8b231 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.test.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/calendars_list.test.js @@ -12,7 +12,7 @@ import { cloneDeep } from 'lodash'; import { CalendarsList } from './calendars_list'; // Mocking the child components to just assert that they get the data -// received via the async call using mlApiServices in the main component. +// received via the async call using mlApi in the main component. jest.mock('../../../components/help_menu', () => ({ HelpMenu: ({ docLink }) =>
, })); @@ -79,7 +79,7 @@ const mockCalendarsFn = jest.fn(() => Promise.resolve(cloneDeep(mockCalendars))) const mockKibanaProp = { services: { docLinks: { links: { ml: { calendars: 'https://calendars' } } }, - mlServices: { mlApiServices: { calendars: mockCalendarsFn } }, + mlServices: { mlApi: { calendars: mockCalendarsFn } }, data: { query: { timefilter: { diff --git a/x-pack/plugins/ml/public/application/settings/calendars/list/delete_calendars.js b/x-pack/plugins/ml/public/application/settings/calendars/list/delete_calendars.js index 13de491f10825..a88ba97c55b8c 100644 --- a/x-pack/plugins/ml/public/application/settings/calendars/list/delete_calendars.js +++ b/x-pack/plugins/ml/public/application/settings/calendars/list/delete_calendars.js @@ -8,12 +8,7 @@ import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '@kbn/ml-error-utils'; -export async function deleteCalendars( - mlApiServices, - toastNotifications, - calendarsToDelete, - callback -) { +export async function deleteCalendars(mlApi, toastNotifications, calendarsToDelete, callback) { if (calendarsToDelete === undefined || calendarsToDelete.length === 0) { return; } @@ -37,7 +32,7 @@ export async function deleteCalendars( for (const calendar of calendarsToDelete) { const calendarId = calendar.calendar_id; try { - await mlApiServices.deleteCalendar({ calendarId }); + await mlApi.deleteCalendar({ calendarId }); } catch (error) { console.log('Error deleting calendar:', error); toastNotifications.addDanger({ diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_list_modal.js b/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_list_modal.js index ba68b1ef94453..d8cff2e08ab89 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_list_modal.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_list_modal.js @@ -51,7 +51,7 @@ export class DeleteFilterListModal extends Component { const { selectedFilterLists, refreshFilterLists } = this.props; await deleteFilterLists( this.context.services.notifications.toasts, - this.context.services.mlServices.mlApiServices, + this.context.services.mlServices.mlApi, selectedFilterLists ); diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_lists.js b/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_lists.js index 6334442a8e14f..67701701736ef 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_lists.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/components/delete_filter_list_modal/delete_filter_lists.js @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; -export async function deleteFilterLists(toastNotifications, mlApiServices, filterListsToDelete) { +export async function deleteFilterLists(toastNotifications, mlApi, filterListsToDelete) { if (filterListsToDelete === undefined || filterListsToDelete.length === 0) { return; } @@ -28,7 +28,7 @@ export async function deleteFilterLists(toastNotifications, mlApiServices, filte for (const filterList of filterListsToDelete) { const filterId = filterList.filter_id; try { - await mlApiServices.filters.deleteFilter(filterId); + await mlApi.filters.deleteFilter(filterId); } catch (resp) { console.log('Error deleting filter list:', resp); toastNotifications.addDanger( diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js index 2f53963a5b3f2..c203da50ce0bd 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.js @@ -114,8 +114,8 @@ export class EditFilterListUI extends Component { }; loadFilterList = (filterId) => { - const ml = this.props.kibana.services.mlServices.mlApiServices; - ml.filters + const mlApi = this.props.kibana.services.mlServices.mlApi; + mlApi.filters .filters({ filterId }) .then((filter) => { this.setLoadedFilterState(filter); @@ -286,7 +286,7 @@ export class EditFilterListUI extends Component { const filterId = this.props.filterId !== undefined ? this.props.filterId : newFilterId; saveFilterList( this.props.kibana.services.notifications.toasts, - this.props.kibana.services.mlServices.mlApiServices, + this.props.kibana.services.mlServices.mlApi, filterId, description, items, diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js index a277457151fa7..16dd5f67dbd67 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/edit_filter_list.test.js @@ -35,7 +35,7 @@ const mockKibanaContext = { docLinks: { links: { ml: { customRules: 'test' } } }, notifications: { toasts: { addDanger: jest.fn(), addError: jest.fn() } }, mlServices: { - mlApiServices: { + mlApi: { filters: { filters: mockFilters, }, diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/utils.js b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/utils.js index e1f42e2e636ad..721f472827b98 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/edit/utils.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/edit/utils.js @@ -17,7 +17,7 @@ export function isValidFilterListId(id) { // original filter list to which edits are being applied, is defined with a filter_id property. export function saveFilterList( toastNotifications, - mlApiServices, + mlApi, filterId, description, items, @@ -26,7 +26,7 @@ export function saveFilterList( return new Promise((resolve, reject) => { if (loadedFilterList === undefined || loadedFilterList.filter_id === undefined) { // Create a new filter. - addFilterList(toastNotifications, mlApiServices, filterId, description, items) + addFilterList(toastNotifications, mlApi, filterId, description, items) .then((newFilter) => { resolve(newFilter); }) @@ -35,7 +35,7 @@ export function saveFilterList( }); } else { // Edit to existing filter. - updateFilterList(mlApiServices, loadedFilterList, description, items) + updateFilterList(mlApi, loadedFilterList, description, items) .then((updatedFilter) => { resolve(updatedFilter); }) @@ -46,7 +46,7 @@ export function saveFilterList( }); } -export function addFilterList(toastNotifications, mlApiServices, filterId, description, items) { +export function addFilterList(toastNotifications, mlApi, filterId, description, items) { const filterWithIdExistsErrorMessage = i18n.translate( 'xpack.ml.settings.filterLists.filterWithIdExistsErrorMessage', { @@ -59,13 +59,13 @@ export function addFilterList(toastNotifications, mlApiServices, filterId, descr return new Promise((resolve, reject) => { // First check the filterId isn't already in use by loading the current list of filters. - mlApiServices.filters + mlApi.filters .filtersStats() .then((filterLists) => { const savedFilterIds = filterLists.map((filterList) => filterList.filter_id); if (savedFilterIds.indexOf(filterId) === -1) { // Save the new filter. - mlApiServices.filters + mlApi.filters .addFilter(filterId, description, items) .then((newFilter) => { resolve(newFilter); @@ -84,14 +84,14 @@ export function addFilterList(toastNotifications, mlApiServices, filterId, descr }); } -export function updateFilterList(mlApiServices, loadedFilterList, description, items) { +export function updateFilterList(mlApi, loadedFilterList, description, items) { return new Promise((resolve, reject) => { // Get items added and removed from loaded filter. const loadedItems = loadedFilterList.items; const addItems = items.filter((item) => loadedItems.includes(item) === false); const removeItems = loadedItems.filter((item) => items.includes(item) === false); - mlApiServices.filters + mlApi.filters .updateFilter(loadedFilterList.filter_id, description, addItems, removeItems) .then((updatedFilter) => { resolve(updatedFilter); diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js index c955cce8f79d4..fdf3597a2fcfa 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.js @@ -62,9 +62,9 @@ export class FilterListsUI extends Component { }; refreshFilterLists = () => { - const ml = this.props.kibana.services.mlServices.mlApiServices; + const mlApi = this.props.kibana.services.mlServices.mlApi; // Load the list of filters. - ml.filters + mlApi.filters .filtersStats() .then((filterLists) => { this.setFilterLists(filterLists); diff --git a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.test.js b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.test.js index e4a27809019b5..a4c49a79b89dd 100644 --- a/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.test.js +++ b/x-pack/plugins/ml/public/application/settings/filter_lists/list/filter_lists.test.js @@ -12,7 +12,7 @@ import '@testing-library/jest-dom/extend-expect'; import { FilterLists } from './filter_lists'; // Mocking the child components to just assert that they get the data -// received via the async call using mlApiServices in the main component. +// received via the async call using mlApi in the main component. jest.mock('../../../components/help_menu', () => ({ HelpMenu: ({ docLink }) =>
, })); @@ -46,7 +46,7 @@ const mockKibanaProp = { services: { docLinks: { links: { ml: { customRules: 'https://customRules' } } }, mlServices: { - mlApiServices: { + mlApi: { filters: { filtersStats: () => { return Promise.resolve([mockTestFilter]); diff --git a/x-pack/plugins/ml/public/application/settings/settings.test.tsx b/x-pack/plugins/ml/public/application/settings/settings.test.tsx index 38ef8c784c114..2344455beb348 100644 --- a/x-pack/plugins/ml/public/application/settings/settings.test.tsx +++ b/x-pack/plugins/ml/public/application/settings/settings.test.tsx @@ -19,7 +19,7 @@ jest.mock('../contexts/kibana', () => ({ useNotifications: () => ({ toasts: { addDanger: jest.fn(), addError: jest.fn() }, }), - useMlApiContext: jest.fn(), + useMlApi: jest.fn(), useMlKibana: () => ({ services: { docLinks: { diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js index 8402f2cc1e410..fe6b132635301 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/forecasting_modal.js @@ -82,7 +82,7 @@ export class ForecastingModal extends Component { static contextType = context; componentDidMount() { - this.mlForecastService = forecastServiceFactory(this.context.services.mlServices.mlApiServices); + this.mlForecastService = forecastServiceFactory(this.context.services.mlServices.mlApi); } addMessage = (message, status, clearFirst = false) => { @@ -170,7 +170,7 @@ export class ForecastingModal extends Component { jobOpeningState: PROGRESS_STATES.WAITING, }); - this.context.services.mlServices.mlApiServices + this.context.services.mlServices.mlApi .openJob({ jobId: this.props.job.job_id }) .then(() => { // If open was successful run the forecast, then close the job again. @@ -227,7 +227,7 @@ export class ForecastingModal extends Component { if (closeJob === true) { this.setState({ jobClosingState: PROGRESS_STATES.WAITING }); - this.context.services.mlServices.mlApiServices + this.context.services.mlServices.mlApi .closeJob({ jobId: this.props.job.job_id }) .then(() => { this.setState({ jobClosingState: PROGRESS_STATES.DONE }); @@ -308,7 +308,7 @@ export class ForecastingModal extends Component { if (closeJobAfterRunning === true) { this.setState({ jobClosingState: PROGRESS_STATES.WAITING }); - this.context.services.mlServices.mlApiServices + this.context.services.mlServices.mlApi .closeJob({ jobId: this.props.job.job_id }) .then(() => { this.setState({ @@ -434,7 +434,7 @@ export class ForecastingModal extends Component { // of partitioning fields. const entityFieldNames = entities.map((entity) => entity.fieldName); if (entityFieldNames.length > 0) { - this.context.services.mlServices.mlApiServices + this.context.services.mlServices.mlApi .getCardinalityOfFields({ index: job.datafeed_config.indices, fieldNames: entityFieldNames, diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/modal.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/modal.js index 9e9a525031b8a..465373a928cf5 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/modal.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/forecasting_modal/modal.js @@ -34,19 +34,19 @@ export function Modal(props) { const [mlNodesAvailable, setMlNodesAvailable] = useState(false); const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); useEffect( function prepMlNodeCheck() { - getMlNodeCount(mlApiServices) + getMlNodeCount(mlApi) .then(({ count, lazyNodeCount }) => { setMlNodesAvailable(count !== 0 || lazyNodeCount !== 0); }) .catch(console.error); }, - [mlApiServices] + [mlApi] ); return ( diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx index 1d9d61e3ddc32..4c6d2356f3e6c 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/series_controls/series_controls.tsx @@ -101,7 +101,7 @@ export const SeriesControls: FC> = ({ const { services: { mlServices: { - mlApiServices: { results: mlResultsService }, + mlApi: { results: mlResultsService }, }, }, } = useMlKibana(); diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index 7882fdfc21513..20d94aaabc3bb 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -167,7 +167,7 @@ class TimeseriesChartIntl extends Component { this.mlTimeSeriesExplorer = timeSeriesExplorerServiceFactory( constructorContext.services.uiSettings, - constructorContext.services.mlServices.mlApiServices, + constructorContext.services.mlServices.mlApi, constructorContext.services.mlServices.mlResultsService ); this.getTimeBuckets = timeBucketsServiceFactory( diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.test.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.test.js index 1e9da4aa72787..d9ec6dea88497 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.test.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.test.js @@ -53,7 +53,7 @@ function getTimeseriesChartPropsMock() { const kibanaReactContextMock = createKibanaReactContext({ mlServices: { - mlApiServices: {}, + mlApi: {}, mlResultsService: {}, }, notifications: { toasts: { addDanger: jest.fn(), addSuccess: jest.fn() } }, diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx index 14c57cbb6c20e..f69632033b702 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx @@ -61,7 +61,7 @@ export const TimeSeriesChartWithTooltips: FC = const { toasts: toastNotifications } = useNotifications(); const { services: { - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlKibana(); @@ -103,7 +103,7 @@ export const TimeSeriesChartWithTooltips: FC = */ const loadAnnotations = async (jobId: string) => { try { - const resp = await mlApiServices.annotations.getAnnotations({ + const resp = await mlApi.annotations.getAnnotations({ jobIds: [jobId], earliestMs: searchBounds.min.valueOf(), latestMs: searchBounds.max.valueOf(), diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index 4bfcb8e7fd98c..c4951b9041fc1 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -143,7 +143,7 @@ export class TimeSeriesExplorer extends React.Component { dataViewsService; toastNotificationService; - mlApiServices; + mlApi; mlForecastService; mlIndexUtils; mlJobService; @@ -157,19 +157,19 @@ export class TimeSeriesExplorer extends React.Component { this.toastNotificationService = toastNotificationServiceProvider( constructorContext.services.notifications.toasts ); - this.mlApiServices = constructorContext.services.mlServices.mlApiServices; - this.mlForecastService = forecastServiceFactory(this.mlApiServices); + this.mlApi = constructorContext.services.mlServices.mlApi; + this.mlForecastService = forecastServiceFactory(this.mlApi); this.mlIndexUtils = indexServiceFactory(this.dataViewsService); - this.mlJobService = mlJobServiceFactory(this.toastNotificationService, this.mlApiServices); - this.mlResultsService = mlResultsServiceProvider(this.mlApiServices); + this.mlJobService = mlJobServiceFactory(this.toastNotificationService, this.mlApi); + this.mlResultsService = mlResultsServiceProvider(this.mlApi); this.mlTimeSeriesExplorer = timeSeriesExplorerServiceFactory( constructorContext.services.uiSettings, - this.mlApiServices, + this.mlApi, this.mlResultsService ); this.mlTimeSeriesSearchService = timeSeriesSearchServiceFactory( this.mlResultsService, - this.mlApiServices + this.mlApi ); } @@ -331,8 +331,8 @@ export class TimeSeriesExplorer extends React.Component { const selectedJob = mlJobService.getJob(selectedJobId); const entityControls = this.getControlsForDetector(); - const ml = this.mlApiServices; - return ml.results + const mlApi = this.mlApi; + return mlApi.results .getAnomaliesTableData( [selectedJob.job_id], this.getCriteriaFields(selectedDetectorIndex, entityControls), diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js index c574e5d1ce741..3839c9831c86b 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_embeddable_chart/timeseriesexplorer_embeddable_chart.js @@ -272,7 +272,7 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component { } = this.props; const entityControls = this.getControlsForDetector(); - return this.context.services.mlServices.mlApiServices.results + return this.context.services.mlServices.mlApi.results .getAnomaliesTableData( [selectedJob.job_id], this.getCriteriaFields(selectedDetectorIndex, entityControls), @@ -641,10 +641,10 @@ export class TimeSeriesExplorerEmbeddableChart extends React.Component { this.mlTimeSeriesExplorer = timeSeriesExplorerServiceFactory( this.context.services.uiSettings, - this.context.services.mlServices.mlApiServices, + this.context.services.mlServices.mlApi, this.context.services.mlServices.mlResultsService ); - this.mlForecastService = forecastServiceFactory(this.context.services.mlServices.mlApiServices); + this.mlForecastService = forecastServiceFactory(this.context.services.mlServices.mlApi); // Listen for context chart updates. this.subscriptions.add( diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service.ts index 929ff04656a18..213d5e0bff575 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service.ts @@ -12,7 +12,7 @@ import { map } from 'rxjs'; import type { MlEntityField, ES_AGGREGATION } from '@kbn/ml-anomaly-utils'; import type { Job } from '../../../../common/types/anomaly_detection_jobs'; import type { ModelPlotOutput } from '../../services/results_service/result_service_rx'; -import type { MlApiServices } from '../../services/ml_api_service'; +import type { MlApi } from '../../services/ml_api_service'; import { type MlResultsService, mlResultsServiceProvider } from '../../services/results_service'; import { buildConfigFromDetector } from '../../util/chart_config_builder'; import { @@ -29,10 +29,7 @@ interface TimeSeriesExplorerChartDetails { }; } -export function timeSeriesSearchServiceFactory( - mlResultsService: MlResultsService, - mlApiServices: MlApiServices -) { +export function timeSeriesSearchServiceFactory(mlResultsService: MlResultsService, mlApi: MlApi) { function getMetricData( job: Job, detectorIndex: number, @@ -172,7 +169,7 @@ export function timeSeriesSearchServiceFactory( resolve(obj); } else { const entityFieldNames: string[] = blankEntityFields.map((f) => f.fieldName); - mlApiServices + mlApi .getCardinalityOfFields({ index: chartConfig.datafeedConfig.indices.join(','), fieldNames: entityFieldNames, @@ -211,15 +208,15 @@ export type MlTimeSeriesSearchService = ReturnType timeSeriesSearchServiceFactory(mlResultsService, mlApiServices), - [mlApiServices, mlResultsService] + () => timeSeriesSearchServiceFactory(mlResultsService, mlApi), + [mlApi, mlResultsService] ); return mlForecastService; } diff --git a/x-pack/plugins/ml/public/application/util/get_services.ts b/x-pack/plugins/ml/public/application/util/get_services.ts index 330bdc17c8fe9..031504509dff7 100644 --- a/x-pack/plugins/ml/public/application/util/get_services.ts +++ b/x-pack/plugins/ml/public/application/util/get_services.ts @@ -14,7 +14,7 @@ import { MlLicense } from '../../../common/license'; import { MlCapabilitiesService } from '../capabilities/check_capabilities'; import { fieldFormatServiceFactory } from '../services/field_format_service_factory'; import { HttpService } from '../services/http_service'; -import { mlApiServicesProvider } from '../services/ml_api_service'; +import { mlApiProvider } from '../services/ml_api_service'; import { mlUsageCollectionProvider } from '../services/usage_collection'; import { mlJobServiceFactory } from '../services/job_service'; import { toastNotificationServiceProvider } from '../services/toast_notification_service'; @@ -29,9 +29,9 @@ export function getMlGlobalServices( usageCollection?: UsageCollectionSetup ) { const httpService = new HttpService(coreStart.http); - const mlApiServices = mlApiServicesProvider(httpService); + const mlApi = mlApiProvider(httpService); const toastNotificationService = toastNotificationServiceProvider(coreStart.notifications.toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); // Note on the following services: // - `mlIndexUtils` is just instantiated here to be passed on to `mlFieldFormatService`, // but it's not being made available as part of global services. Since it's just @@ -42,14 +42,14 @@ export function getMlGlobalServices( // its own context or possibly without having a singleton like state at all, since the // way this manages its own state right now doesn't consider React component lifecycles. const mlIndexUtils = indexServiceFactory(dataViews); - const mlFieldFormatService = fieldFormatServiceFactory(mlApiServices, mlIndexUtils, mlJobService); + const mlFieldFormatService = fieldFormatServiceFactory(mlApi, mlIndexUtils, mlJobService); return { httpService, - mlApiServices, + mlApi, mlFieldFormatService, mlUsageCollection: mlUsageCollectionProvider(usageCollection), - mlCapabilities: new MlCapabilitiesService(mlApiServices), + mlCapabilities: new MlCapabilitiesService(mlApi), mlLicense: new MlLicense(), }; } diff --git a/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts b/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts index 05763f62d082c..c0c7995f1b310 100644 --- a/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts +++ b/x-pack/plugins/ml/public/application/util/time_series_explorer_service.ts @@ -29,11 +29,11 @@ import { MAX_SCHEDULED_EVENTS, TIME_FIELD_NAME, } from '../timeseriesexplorer/timeseriesexplorer_constants'; -import type { MlApiServices } from '../services/ml_api_service'; +import type { MlApi } from '../services/ml_api_service'; import { useMlResultsService, type MlResultsService } from '../services/results_service'; import { forecastServiceFactory } from '../services/forecast_service'; import { timeSeriesSearchServiceFactory } from '../timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service'; -import { useMlApiContext, useMlKibana } from '../contexts/kibana'; +import { useMlApi, useMlKibana } from '../contexts/kibana'; export interface Interval { asMilliseconds: () => number; @@ -59,12 +59,12 @@ export interface FocusData { export function timeSeriesExplorerServiceFactory( uiSettings: IUiSettingsClient, - mlApiServices: MlApiServices, + mlApi: MlApi, mlResultsService: MlResultsService ) { const timeBuckets = timeBucketsServiceFactory(uiSettings); - const mlForecastService = forecastServiceFactory(mlApiServices); - const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory(mlResultsService, mlApiServices); + const mlForecastService = forecastServiceFactory(mlApi); + const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory(mlResultsService, mlApi); function getAutoZoomDuration(bucketSpan: Job['analysis_config']['bucket_span']) { // function getAutoZoomDuration(selectedJob: Job) { @@ -511,7 +511,7 @@ export function timeSeriesExplorerServiceFactory( esFunctionToPlotIfMetric ), // Query 2 - load all the records across selected time range for the chart anomaly markers. - mlApiServices.results.getAnomalyRecords$( + mlApi.results.getAnomalyRecords$( [selectedJob.job_id], criteriaFields, 0, @@ -530,7 +530,7 @@ export function timeSeriesExplorerServiceFactory( MAX_SCHEDULED_EVENTS ), // Query 4 - load any annotations for the selected job. - mlApiServices.annotations + mlApi.annotations .getAnnotations$({ jobIds: [selectedJob.job_id], earliestMs: searchBounds.min.valueOf(), @@ -647,10 +647,10 @@ export function timeSeriesExplorerServiceFactory( export function useTimeSeriesExplorerService(): TimeSeriesExplorerService { const { services } = useMlKibana(); - const mlApiServices = useMlApiContext(); + const mlApi = useMlApi(); const mlResultsService = useMlResultsService(); return useMemo( - () => timeSeriesExplorerServiceFactory(services.uiSettings, mlApiServices, mlResultsService), + () => timeSeriesExplorerServiceFactory(services.uiSettings, mlApi, mlResultsService), // initialize only once // eslint-disable-next-line react-hooks/exhaustive-deps [] diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.test.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.test.tsx index 4c68437933175..c5dc902ed5264 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.test.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.test.tsx @@ -7,7 +7,7 @@ import { render, screen, act } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import type { MlApiServices } from '../../application/services/ml_api_service'; +import type { MlApi } from '../../application/services/ml_api_service'; import { AnomalyChartsInitializer } from './anomaly_charts_initializer'; import { I18nProvider } from '@kbn/i18n-react'; @@ -44,7 +44,7 @@ describe('AnomalyChartsInitializer', () => { initialInput={input} onCreate={(params) => onCreate(params)} onCancel={onCancel} - adJobsApiService={adJobsApiService as unknown as MlApiServices['jobs']} + adJobsApiService={adJobsApiService as unknown as MlApi['jobs']} /> , defaultOptions diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.tsx index 93bf3110b3776..862d0425523aa 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_initializer.tsx @@ -29,7 +29,7 @@ import { ML_PAGES } from '../../../common/constants/locator'; import { getDefaultExplorerChartsPanelTitle } from './utils'; import { useMlLink } from '../../application/contexts/kibana'; import { getJobSelectionErrors } from '../utils'; -import type { MlApiServices } from '../../application/services/ml_api_service'; +import type { MlApi } from '../../application/services/ml_api_service'; export const MAX_ANOMALY_CHARTS_ALLOWED = 50; export interface AnomalyChartsInitializerProps { @@ -42,7 +42,7 @@ export interface AnomalyChartsInitializerProps { maxSeriesToPlot?: number; }) => void; onCancel: () => void; - adJobsApiService: MlApiServices['jobs']; + adJobsApiService: MlApi['jobs']; } export const AnomalyChartsInitializer: FC = ({ diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/get_anomaly_charts_services_dependencies.ts b/x-pack/plugins/ml/public/embeddables/anomaly_charts/get_anomaly_charts_services_dependencies.ts index b7eec6ab24f5f..f5270ab01ef9f 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/get_anomaly_charts_services_dependencies.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/get_anomaly_charts_services_dependencies.ts @@ -19,7 +19,7 @@ export const getAnomalyChartsServiceDependencies = async ( { AnomalyDetectorService }, { fieldFormatServiceFactory }, { indexServiceFactory }, - { mlApiServicesProvider }, + { mlApiProvider }, { mlJobServiceFactory }, { mlResultsServiceProvider }, { toastNotificationServiceProvider }, @@ -34,13 +34,13 @@ export const getAnomalyChartsServiceDependencies = async ( ]); const httpService = new HttpService(coreStart.http); const anomalyDetectorService = new AnomalyDetectorService(httpService); - const mlApiServices = mlApiServicesProvider(httpService); + const mlApi = mlApiProvider(httpService); const toastNotificationService = toastNotificationServiceProvider(coreStart.notifications.toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); - const mlResultsService = mlResultsServiceProvider(mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); + const mlResultsService = mlResultsServiceProvider(mlApi); const anomalyExplorerService = new AnomalyExplorerChartsService( pluginsStart.data.query.timefilter.timefilter, - mlApiServices, + mlApi, mlResultsService ); @@ -54,7 +54,7 @@ export const getAnomalyChartsServiceDependencies = async ( // its own context or possibly without having a singleton like state at all, since the // way this manages its own state right now doesn't consider React component lifecycles. const mlIndexUtils = indexServiceFactory(pluginsStart.data.dataViews); - const mlFieldFormatService = fieldFormatServiceFactory(mlApiServices, mlIndexUtils, mlJobService); + const mlFieldFormatService = fieldFormatServiceFactory(mlApi, mlIndexUtils, mlJobService); const anomalyChartsEmbeddableServices: AnomalyChartsEmbeddableServices = [ coreStart, diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx index 6de07c5db851e..34390075f927b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable_factory.tsx @@ -59,7 +59,7 @@ export const getServices = async ( [coreStart, pluginsStart], { AnomalyDetectorService }, { AnomalyTimelineService }, - { mlApiServicesProvider }, + { mlApiProvider }, { mlResultsServiceProvider }, ] = await Promise.all([ getStartServices(), @@ -74,7 +74,7 @@ export const getServices = async ( const anomalyTimelineService = new AnomalyTimelineService( pluginsStart.data.query.timefilter.timefilter, coreStart.uiSettings, - mlResultsServiceProvider(mlApiServicesProvider(httpService)) + mlResultsServiceProvider(mlApiProvider(httpService)) ); return [ diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx index ceb22e0172c8d..21df1ad4f18bb 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_initializer.tsx @@ -26,7 +26,7 @@ import { i18n } from '@kbn/i18n'; import useMountedState from 'react-use/lib/useMountedState'; import { useMlLink } from '../../application/contexts/kibana'; import { ML_PAGES } from '../../../common/constants/locator'; -import type { MlApiServices } from '../../application/services/ml_api_service'; +import type { MlApi } from '../../application/services/ml_api_service'; import { extractInfluencers } from '../../../common/util/job_utils'; import { JobSelectorControl } from '../../alerting/job_selector'; import type { SwimlaneType } from '../../application/explorer/explorer_constants'; @@ -43,7 +43,7 @@ export interface AnomalySwimlaneInitializerProps { >; onCreate: (swimlaneProps: ExplicitInput) => void; onCancel: () => void; - adJobsApiService: MlApiServices['jobs']; + adJobsApiService: MlApi['jobs']; } export const AnomalySwimlaneInitializer: FC = ({ diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx index d52aed02d88a3..e4a3e0d05cbde 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx @@ -52,11 +52,11 @@ export const CreateJob: FC = ({ dataView, field, query, timeRange }) => { uiSettings, dashboardService, notifications: { toasts }, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlFromLensKibanaContext(); const toastNotificationService = toastNotificationServiceProvider(toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); const [categorizationType, setCategorizationType] = useState( CATEGORIZATION_TYPE.COUNT @@ -77,7 +77,7 @@ export const CreateJob: FC = ({ dataView, field, query, timeRange }) => { const toggleStopOnWarn = useCallback(() => setStopOnWarn(!stopOnWarn), [stopOnWarn]); useMemo(() => { - const newJobCapsService = new NewJobCapsService(mlApiServices); + const newJobCapsService = new NewJobCapsService(mlApi); newJobCapsService.initializeFromDataVIew(dataView).then(() => { const options: EuiComboBoxOptionOption[] = [ ...createFieldOptions(newJobCapsService.categoryFields, []), @@ -86,7 +86,7 @@ export const CreateJob: FC = ({ dataView, field, query, timeRange }) => { })); setCategoryFieldsOptions(options); }); - }, [dataView, mlApiServices]); + }, [dataView, mlApi]); const quickJobCreator = useMemo( () => @@ -96,10 +96,10 @@ export const CreateJob: FC = ({ dataView, field, query, timeRange }) => { data.query.timefilter.timefilter, dashboardService, data, - mlApiServices, + mlApi, mlJobService ), - [dashboardService, data, mlApiServices, mlJobService, uiSettings] + [dashboardService, data, mlApi, mlJobService, uiSettings] ); function createADJobInWizard() { diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx index 9c3ba23b57382..3bfa1a0caf799 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx @@ -80,7 +80,7 @@ export const JobDetails: FC> = ({ services: { share, application, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlFromLensKibanaContext(); @@ -185,7 +185,7 @@ export const JobDetails: FC> = ({ }) ); } else { - mlApiServices.jobs + mlApi.jobs .jobsExist([jobId]) .then((resp) => { if (resp[jobId].exists) { diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx index 47a410c2e6360..967a9dbb84304 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx @@ -37,11 +37,11 @@ export const CompatibleLayer: FC = ({ layer, layerIndex, embeddable }) => lens, dashboardService, notifications: { toasts }, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlFromLensKibanaContext(); const toastNotificationService = toastNotificationServiceProvider(toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); const quickJobCreator = useMemo( () => @@ -51,7 +51,7 @@ export const CompatibleLayer: FC = ({ layer, layerIndex, embeddable }) => uiSettings, data.query.timefilter.timefilter, dashboardService, - mlApiServices, + mlApi, mlJobService ), // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx index 76beaa6788f13..c91785e91573a 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx @@ -54,11 +54,11 @@ export const CompatibleLayer: FC = ({ embeddable, layer, layerIndex }) => uiSettings, dashboardService, notifications: { toasts }, - mlServices: { mlApiServices }, + mlServices: { mlApi }, }, } = useMlFromLensKibanaContext(); const toastNotificationService = toastNotificationServiceProvider(toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); const quickJobCreator = useMemo( () => @@ -67,7 +67,7 @@ export const CompatibleLayer: FC = ({ embeddable, layer, layerIndex }) => uiSettings, data.query.timefilter.timefilter, dashboardService, - mlApiServices, + mlApi, mlJobService ), // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/get_services.ts b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/get_services.ts index f4460331e6256..180b29dbd0d99 100644 --- a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/get_services.ts +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/get_services.ts @@ -25,7 +25,7 @@ export const getMlServices = async ( { fieldFormatServiceFactory }, { indexServiceFactory }, { timeSeriesExplorerServiceFactory }, - { mlApiServicesProvider }, + { mlApiProvider }, { mlJobServiceFactory }, { mlResultsServiceProvider }, { MlCapabilitiesService }, @@ -48,20 +48,20 @@ export const getMlServices = async ( const httpService = new HttpService(coreStart.http); const anomalyDetectorService = new AnomalyDetectorService(httpService); - const mlApiServices = mlApiServicesProvider(httpService); + const mlApi = mlApiProvider(httpService); const toastNotificationService = toastNotificationServiceProvider(coreStart.notifications.toasts); - const mlJobService = mlJobServiceFactory(toastNotificationService, mlApiServices); - const mlResultsService = mlResultsServiceProvider(mlApiServices); - const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory(mlResultsService, mlApiServices); + const mlJobService = mlJobServiceFactory(toastNotificationService, mlApi); + const mlResultsService = mlResultsServiceProvider(mlApi); + const mlTimeSeriesSearchService = timeSeriesSearchServiceFactory(mlResultsService, mlApi); const mlTimeSeriesExplorerService = timeSeriesExplorerServiceFactory( coreStart.uiSettings, - mlApiServices, + mlApi, mlResultsService ); - const mlCapabilities = new MlCapabilitiesService(mlApiServices); + const mlCapabilities = new MlCapabilitiesService(mlApi); const anomalyExplorerService = new AnomalyExplorerChartsService( pluginsStart.data.query.timefilter.timefilter, - mlApiServices, + mlApi, mlResultsService ); // Note on the following services: @@ -74,11 +74,11 @@ export const getMlServices = async ( // its own context or possibly without having a singleton like state at all, since the // way this manages its own state right now doesn't consider React component lifecycles. const mlIndexUtils = indexServiceFactory(pluginsStart.data.dataViews); - const mlFieldFormatService = fieldFormatServiceFactory(mlApiServices, mlIndexUtils, mlJobService); + const mlFieldFormatService = fieldFormatServiceFactory(mlApi, mlIndexUtils, mlJobService); return { anomalyDetectorService, anomalyExplorerService, - mlApiServices, + mlApi, mlCapabilities, mlFieldFormatService, mlJobService, diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx index 2655e78222746..8f81be21a8ccb 100644 --- a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_embeddable_factory.tsx @@ -74,13 +74,13 @@ export const getSingleMetricViewerEmbeddableFactory = ( const { resolveEmbeddableSingleMetricViewerUserInput } = await import( './single_metric_viewer_setup_flyout' ); - const [coreStart, { data, share }, { mlApiServices }] = services; + const [coreStart, { data, share }, { mlApi }] = services; const result = await resolveEmbeddableSingleMetricViewerUserInput( coreStart, parentApi, uuid, { data, share }, - mlApiServices, + mlApi, { ...serializeTitles(), ...serializeSingleMetricViewerState(), diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx index 9f21ca3f4af75..c14bfc1cb1744 100644 --- a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_initializer.tsx @@ -26,7 +26,7 @@ import useMountedState from 'react-use/lib/useMountedState'; import { extractErrorMessage } from '@kbn/ml-error-utils'; import type { MlJob } from '@elastic/elasticsearch/lib/api/types'; import type { TimeRangeBounds } from '@kbn/ml-time-buckets'; -import type { MlApiServices } from '../../application/services/ml_api_service'; +import type { MlApi } from '../../application/services/ml_api_service'; import type { SingleMetricViewerEmbeddableInput } from '..'; import { ML_PAGES } from '../../../common/constants/locator'; import { SeriesControls } from '../../application/timeseriesexplorer/components/series_controls'; @@ -42,7 +42,7 @@ import { getDefaultSingleMetricViewerPanelTitle } from './get_default_panel_titl export interface SingleMetricViewerInitializerProps { bounds: TimeRangeBounds; initialInput?: Partial; - mlApiServices: MlApiServices; + mlApi: MlApi; onCreate: (props: SingleMetricViewerEmbeddableUserInput) => void; onCancel: () => void; } @@ -52,7 +52,7 @@ export const SingleMetricViewerInitializer: FC { const isMounted = useMountedState(); const newJobUrl = useMlLink({ page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB }); @@ -79,7 +79,7 @@ export const SingleMetricViewerInitializer: FC { const errorMsg = extractErrorMessage(error); setErrorMessage(errorMsg); @@ -100,7 +100,7 @@ export const SingleMetricViewerInitializer: FC { diff --git a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx index 292ec390eb974..9fbb6fbd2b162 100644 --- a/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/single_metric_viewer/single_metric_viewer_setup_flyout.tsx @@ -14,14 +14,14 @@ import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { SingleMetricViewerEmbeddableUserInput, SingleMetricViewerEmbeddableInput } from '..'; import { SingleMetricViewerInitializer } from './single_metric_viewer_initializer'; -import type { MlApiServices } from '../../application/services/ml_api_service'; +import type { MlApi } from '../../application/services/ml_api_service'; export async function resolveEmbeddableSingleMetricViewerUserInput( coreStart: CoreStart, parentApi: unknown, focusedPanelId: string, services: { data: DataPublicPluginStart; share?: SharePluginStart }, - mlApiServices: MlApiServices, + mlApi: MlApi, input?: Partial ): Promise { const { http, overlays, ...startServices } = coreStart; @@ -35,7 +35,7 @@ export async function resolveEmbeddableSingleMetricViewerUserInput( toMountPoint( { diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts index 3a3353c24b4dd..b7d7dea505f0b 100644 --- a/x-pack/plugins/ml/public/embeddables/types.ts +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -33,7 +33,7 @@ import type { AnomalyExplorerChartsService } from '../application/services/anoma import type { AnomalyTimelineService } from '../application/services/anomaly_timeline_service'; import type { MlFieldFormatService } from '../application/services/field_format_service'; import type { MlJobService } from '../application/services/job_service'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; import type { MlResultsService } from '../application/services/results_service'; import type { MlTimeSeriesSearchService } from '../application/timeseriesexplorer/timeseriesexplorer_utils/time_series_search_service'; import type { TimeSeriesExplorerService } from '../application/util/time_series_explorer_service'; @@ -235,13 +235,13 @@ export interface AnomalyChartsServices { anomalyExplorerService: AnomalyExplorerChartsService; mlFieldFormatService: MlFieldFormatService; mlResultsService: MlResultsService; - mlApiServices?: MlApiServices; + mlApi?: MlApi; } export interface SingleMetricViewerServices { anomalyExplorerService: AnomalyExplorerChartsService; anomalyDetectorService: AnomalyDetectorService; - mlApiServices: MlApiServices; + mlApi: MlApi; mlCapabilities: MlCapabilitiesService; mlFieldFormatService: MlFieldFormatService; mlJobService: MlJobService; diff --git a/x-pack/plugins/ml/public/maps/anomaly_job_selector.tsx b/x-pack/plugins/ml/public/maps/anomaly_job_selector.tsx index 0b842d6c38b1f..75cd10b322fc8 100644 --- a/x-pack/plugins/ml/public/maps/anomaly_job_selector.tsx +++ b/x-pack/plugins/ml/public/maps/anomaly_job_selector.tsx @@ -11,12 +11,12 @@ import type { EuiComboBoxOptionOption } from '@elastic/eui'; import { EuiComboBox, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { isEqual } from 'lodash'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; import { AnomalyJobSelectorEmptyState } from './anomaly_job_selector_empty_state'; interface Props { onJobChange: (jobId: string) => void; - mlJobsService: MlApiServices['jobs']; + mlJobsService: MlApi['jobs']; jobsManagementPath?: string; canCreateJobs: boolean; } diff --git a/x-pack/plugins/ml/public/maps/anomaly_layer_wizard_factory.tsx b/x-pack/plugins/ml/public/maps/anomaly_layer_wizard_factory.tsx index f9cb8ba97fbb5..fdc4f532b8a4f 100644 --- a/x-pack/plugins/ml/public/maps/anomaly_layer_wizard_factory.tsx +++ b/x-pack/plugins/ml/public/maps/anomaly_layer_wizard_factory.tsx @@ -24,7 +24,7 @@ import { AnomalySource } from './anomaly_source'; import { HttpService } from '../application/services/http_service'; import type { MlPluginStart, MlStartDependencies } from '../plugin'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; export const ML_ANOMALY = 'ML_ANOMALIES'; @@ -41,7 +41,7 @@ export class AnomalyLayerWizardFactory { } private async getServices(): Promise<{ - mlJobsService: MlApiServices['jobs']; + mlJobsService: MlApi['jobs']; mlLocator?: LocatorPublic; }> { const [coreStart, pluginStart] = await this.getStartServices(); diff --git a/x-pack/plugins/ml/public/maps/anomaly_source.tsx b/x-pack/plugins/ml/public/maps/anomaly_source.tsx index 780ecd3cc7352..c426cdcd78919 100644 --- a/x-pack/plugins/ml/public/maps/anomaly_source.tsx +++ b/x-pack/plugins/ml/public/maps/anomaly_source.tsx @@ -35,7 +35,7 @@ import { ML_PAGES } from '../../common/constants/locator'; import type { MlAnomalyLayersType } from './util'; import { getResultsForJobId, ML_ANOMALY_LAYERS } from './util'; import { UpdateAnomalySourceEditor } from './update_anomaly_source_editor'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; const RESULT_LIMIT = 1000; @@ -45,7 +45,7 @@ export interface AnomalySourceDescriptor extends AbstractSourceDescriptor { } export class AnomalySource implements IVectorSource { - static mlResultsService: MlApiServices['results']; + static mlResultsService: MlApi['results']; static mlLocator?: LocatorPublic; static createDescriptor(descriptor: Partial) { diff --git a/x-pack/plugins/ml/public/maps/anomaly_source_factory.ts b/x-pack/plugins/ml/public/maps/anomaly_source_factory.ts index 6edd7839fbfae..60390e030a61b 100644 --- a/x-pack/plugins/ml/public/maps/anomaly_source_factory.ts +++ b/x-pack/plugins/ml/public/maps/anomaly_source_factory.ts @@ -12,7 +12,7 @@ import type { SerializableRecord } from '@kbn/utility-types'; import { HttpService } from '../application/services/http_service'; import type { MlPluginStart, MlStartDependencies } from '../plugin'; import { ML_APP_LOCATOR } from '../../common/constants/locator'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; export class AnomalySourceFactory { public readonly type = SOURCE_TYPES.ES_ML_ANOMALIES; @@ -22,15 +22,15 @@ export class AnomalySourceFactory { ) {} private async getServices(): Promise<{ - mlResultsService: MlApiServices['results']; + mlResultsService: MlApi['results']; mlLocator?: LocatorPublic; }> { const [coreStart, pluginStart] = await this.getStartServices(); - const { mlApiServicesProvider } = await import('../application/services/ml_api_service'); + const { mlApiProvider } = await import('../application/services/ml_api_service'); const mlLocator = pluginStart.share.url.locators.get(ML_APP_LOCATOR); const httpService = new HttpService(coreStart.http); - const mlResultsService = mlApiServicesProvider(httpService).results; + const mlResultsService = mlApiProvider(httpService).results; return { mlResultsService, mlLocator }; } diff --git a/x-pack/plugins/ml/public/maps/create_anomaly_source_editor.tsx b/x-pack/plugins/ml/public/maps/create_anomaly_source_editor.tsx index b57afdcfcb2db..48107a2ba3d3f 100644 --- a/x-pack/plugins/ml/public/maps/create_anomaly_source_editor.tsx +++ b/x-pack/plugins/ml/public/maps/create_anomaly_source_editor.tsx @@ -13,11 +13,11 @@ import { AnomalyJobSelector } from './anomaly_job_selector'; import { LayerSelector } from './layer_selector'; import type { MlAnomalyLayersType } from './util'; import { ML_ANOMALY_LAYERS } from './util'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; interface Props { onSourceConfigChange: (sourceConfig: Partial | null) => void; - mlJobsService: MlApiServices['jobs']; + mlJobsService: MlApi['jobs']; jobsManagementPath?: string; canCreateJobs: boolean; } diff --git a/x-pack/plugins/ml/public/maps/util.ts b/x-pack/plugins/ml/public/maps/util.ts index 7666552e40e93..f661c08b6c5f6 100644 --- a/x-pack/plugins/ml/public/maps/util.ts +++ b/x-pack/plugins/ml/public/maps/util.ts @@ -22,7 +22,7 @@ import { LAYER_TYPE, SOURCE_TYPES, SCALING_TYPES } from '@kbn/maps-plugin/common import { type MLAnomalyDoc, ML_SEVERITY_COLOR_RAMP } from '@kbn/ml-anomaly-utils'; import { formatHumanReadableDateTimeSeconds } from '@kbn/ml-date-utils'; import { SEARCH_QUERY_LANGUAGE } from '@kbn/ml-query-utils'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; import { tabColor } from '../../common/util/group_color_utils'; import { getIndexPattern } from '../application/explorer/reducers/explorer_reducer/get_index_pattern'; import { AnomalySource } from './anomaly_source'; @@ -162,7 +162,7 @@ export function getInitialSourceIndexFieldLayers(sourceIndexWithGeoFields: Sourc } export async function getResultsForJobId( - mlResultsService: MlApiServices['results'], + mlResultsService: MlApi['results'], jobId: string, locationType: MlAnomalyLayersType, searchFilters: VectorSourceRequestMeta diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 456259fd6d28d..7246f60337dd9 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -70,7 +70,7 @@ import { initExperimentalFeatures, } from '../common/constants/app'; import type { ElasticModels } from './application/services/elastic_models_service'; -import type { MlApiServices } from './application/services/ml_api_service'; +import type { MlApi } from './application/services/ml_api_service'; import type { MlCapabilities } from '../common/types/capabilities'; import { AnomalySwimLane } from './shared_components'; import { getMlServices } from './embeddables/single_metric_viewer/get_services'; @@ -314,13 +314,13 @@ export class MlPlugin implements Plugin { ): { locator?: LocatorPublic; elasticModels?: ElasticModels; - mlApi?: MlApiServices; + mlApi?: MlApi; components: { AnomalySwimLane: typeof AnomalySwimLane }; } { return { locator: this.locator, elasticModels: this.sharedMlServices?.elasticModels, - mlApi: this.sharedMlServices?.mlApiServices, + mlApi: this.sharedMlServices?.mlApi, components: { AnomalySwimLane, }, diff --git a/x-pack/plugins/ml/public/shared_components/single_metric_viewer/single_metric_viewer.tsx b/x-pack/plugins/ml/public/shared_components/single_metric_viewer/single_metric_viewer.tsx index 2cf5edfd0608d..96e678407f626 100644 --- a/x-pack/plugins/ml/public/shared_components/single_metric_viewer/single_metric_viewer.tsx +++ b/x-pack/plugins/ml/public/shared_components/single_metric_viewer/single_metric_viewer.tsx @@ -102,7 +102,7 @@ const SingleMetricViewerWrapper: FC = ({ >(); const isMounted = useMountedState(); - const { mlApiServices, mlTimeSeriesExplorerService, toastNotificationService } = mlServices; + const { mlApi, mlTimeSeriesExplorerService, toastNotificationService } = mlServices; const startServices = pick(coreStart, 'analytics', 'i18n', 'theme'); const datePickerDeps: DatePickerDependencies = { ...pick(coreStart, ['http', 'notifications', 'theme', 'uiSettings', 'i18n']), @@ -116,11 +116,11 @@ const SingleMetricViewerWrapper: FC = ({ useEffect( function setUpSelectedJob() { async function fetchSelectedJob() { - if (mlApiServices && selectedJobId !== undefined) { + if (mlApi && selectedJobId !== undefined) { try { const [{ jobs }, { jobs: jobStats }] = await Promise.all([ - mlApiServices.getJobs({ jobId: selectedJobId }), - mlApiServices.getJobStats({ jobId: selectedJobId }), + mlApi.getJobs({ jobId: selectedJobId }), + mlApi.getJobStats({ jobId: selectedJobId }), ]); setSelectedJobWrapper({ job: jobs[0], stats: jobStats[0] }); } catch (e) { @@ -135,7 +135,7 @@ const SingleMetricViewerWrapper: FC = ({ } fetchSelectedJob(); }, - [selectedJobId, mlApiServices, isMounted, onError] + [selectedJobId, mlApi, isMounted, onError] ); // eslint-disable-next-line react-hooks/exhaustive-deps const resizeHandler = useCallback( diff --git a/x-pack/plugins/ml/public/ui_actions/create_single_metric_viewer.tsx b/x-pack/plugins/ml/public/ui_actions/create_single_metric_viewer.tsx index ceae89e121fb7..721f830e01627 100644 --- a/x-pack/plugins/ml/public/ui_actions/create_single_metric_viewer.tsx +++ b/x-pack/plugins/ml/public/ui_actions/create_single_metric_viewer.tsx @@ -11,7 +11,7 @@ import type { EmbeddableApiContext } from '@kbn/presentation-publishing'; import type { UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { HttpService } from '../application/services/http_service'; -import type { MlApiServices } from '../application/services/ml_api_service'; +import type { MlApi } from '../application/services/ml_api_service'; import { ML_APP_NAME, PLUGIN_ICON, PLUGIN_ID } from '../../common/constants/app'; import { ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE } from '../embeddables'; import type { SingleMetricViewerEmbeddableApi } from '../embeddables/types'; @@ -66,16 +66,16 @@ export function createAddSingleMetricViewerPanelAction( const { resolveEmbeddableSingleMetricViewerUserInput } = await import( '../embeddables/single_metric_viewer/single_metric_viewer_setup_flyout' ); - const { mlApiServicesProvider } = await import('../application/services/ml_api_service'); + const { mlApiProvider } = await import('../application/services/ml_api_service'); const httpService = new HttpService(coreStart.http); - const mlApiServices: MlApiServices = mlApiServicesProvider(httpService); + const mlApi: MlApi = mlApiProvider(httpService); const initialState = await resolveEmbeddableSingleMetricViewerUserInput( coreStart, context.embeddable, context.embeddable.uuid, { data, share }, - mlApiServices + mlApi ); presentationContainerParent.addNewPanel({ diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/entities/charts/log_error_rate_chart.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/entities/charts/log_error_rate_chart.tsx index 68b41a6542a1a..419605236c8a8 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/entities/charts/log_error_rate_chart.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/entities/charts/log_error_rate_chart.tsx @@ -94,7 +94,7 @@ export function LogErrorRateChart({ height }: { height: number }) { formula={getMetricsFormula(ChartMetricType.LOG_ERROR_RATE)} description={ { try { - const controlGroupState = {}; + const builder = controlGroupInputBuilder; + const controlGroupInput = getDefaultControlGroupInput(); - await controlGroupStateBuilder.addDataControlFromField(controlGroupState, { + await builder.addDataControlFromField(controlGroupInput, { dataViewId: dataView.id ?? '', title: 'Node name', fieldName: 'service.node.name', @@ -90,7 +92,7 @@ async function getCreationOptions( getInitialInput: () => ({ viewMode: ViewMode.VIEW, panels, - controlGroupState, + controlGroupInput, }), }; } catch (error) { diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/multi_signal_inventory/table/get_service_columns.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/multi_signal_inventory/table/get_service_columns.tsx index 45e8a9ca859a0..ea67a4ab693b9 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/multi_signal_inventory/table/get_service_columns.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_inventory/multi_signal_inventory/table/get_service_columns.tsx @@ -228,12 +228,12 @@ export function getServiceColumns({ name: ( ); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/waterfall_context.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/waterfall_context.tsx index 41e96b636b9d9..1a19bff884e4f 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/waterfall_context.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/context/waterfall_context.tsx @@ -63,7 +63,7 @@ export function WaterfallContextProvider({ }, [tree]); const getErrorCount = useCallback( - (waterfallItemId) => waterfall.getErrorCount(waterfallItemId), + (waterfallItemId: string) => waterfall.getErrorCount(waterfallItemId), [waterfall] ); diff --git a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/helper/get_metrics_formulas.tsx b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/helper/get_metrics_formulas.tsx index 5e969d250e1dd..e5b694832c301 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/shared/charts/helper/get_metrics_formulas.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/shared/charts/helper/get_metrics_formulas.tsx @@ -12,7 +12,7 @@ export enum ChartMetricType { const metricsFormulasMap: Record = { [ChartMetricType.LOG_RATE]: `count(kql='log.level: *') / [PERIOD_IN_MINUTES]`, - [ChartMetricType.LOG_ERROR_RATE]: `count(kql='log.level: "error" OR log.level: "ERROR"') / count(kql='log.level: *')`, + [ChartMetricType.LOG_ERROR_RATE]: `count(kql='log.level: "error" OR log.level: "ERROR" OR error.log.level: "error"') / [PERIOD_IN_MINUTES]`, }; export function getMetricsFormula(chartMetricType: ChartMetricType) { diff --git a/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients.ts b/x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client.ts similarity index 100% rename from x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients.ts rename to x-pack/plugins/observability_solution/apm/server/lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client.ts diff --git a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/get_entities_with_dashboards.ts b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/get_entities_with_dashboards.ts index 0d5b443ae6d45..df1f785216367 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/get_entities_with_dashboards.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/get_entities_with_dashboards.ts @@ -9,7 +9,7 @@ import { kqlQuery, termQuery } from '@kbn/observability-plugin/server'; import { estypes } from '@elastic/elasticsearch'; import { SERVICE_NAME } from '../../../common/es_fields/apm'; import { SavedApmCustomDashboard } from '../../../common/custom_dashboards'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; function getSearchRequest(filters: estypes.QueryDslQueryContainer[]) { return { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts index 4fcc1508715d1..750bacb4ba455 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/custom_dashboards/route.ts @@ -14,7 +14,7 @@ import { getCustomDashboards } from './get_custom_dashboards'; import { getServicesWithDashboards } from './get_services_with_dashboards'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { rangeRt } from '../default_api_types'; -import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { getEntitiesWithDashboards } from './get_entities_with_dashboards'; const serviceDashboardSaveRoute = createApmServerRoute({ diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_entities.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_entities.ts index a69a906454ff7..e3a40b698eb13 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_entities.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_entities.ts @@ -14,7 +14,7 @@ import { } from '../../../common/es_fields/apm'; import { FIRST_SEEN, LAST_SEEN, ENTITY, ENTITY_TYPE } from '../../../common/es_fields/entities'; import { environmentQuery } from '../../../common/utils/environment_query'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { getServiceEntitiesHistoryMetrics } from './get_service_entities_history_metrics'; import { EntitiesRaw, EntityType, ServiceEntities } from './types'; import { isFiniteNumber } from '../../../common/utils/is_finite_number'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_metrics.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_metrics.ts index 606c1748aa0a0..5355cfd8b563c 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_metrics.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_metrics.ts @@ -16,7 +16,7 @@ import { ENTITY_METRICS_THROUGHPUT, LAST_SEEN, } from '../../../common/es_fields/entities'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; interface Params { entitiesESClient: EntitiesESClient; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_timeseries.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_timeseries.ts index 6e969b6022bf2..73811a544701b 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_timeseries.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entities_history_timeseries.ts @@ -17,7 +17,7 @@ import { LAST_SEEN, } from '../../../common/es_fields/entities'; import { SERVICE_NAME } from '../../../common/es_fields/apm'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { environmentQuery } from '../../../common/utils/environment_query'; interface Params { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entity_summary.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entity_summary.ts index 37e3ddef9ecc0..84886272ba54a 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entity_summary.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_entity_summary.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { withApmSpan } from '../../utils/with_apm_span'; import { getServiceLatestEntity } from './get_service_latest_entity'; import { ServiceEntities } from './types'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_latest_entity.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_latest_entity.ts index f4a4e4d1a81a4..71cead9a17301 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_latest_entity.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/get_service_latest_entity.ts @@ -14,7 +14,7 @@ import { import { ENTITY, ENTITY_TYPE } from '../../../common/es_fields/entities'; import { environmentQuery } from '../../../common/utils/environment_query'; import { isFiniteNumber } from '../../../common/utils/is_finite_number'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { entitiesRangeQuery } from './get_entities'; import { EntitiesRaw, EntityType, ServiceEntities } from './types'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/get_service_entities.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/get_service_entities.ts index 0f90afb214cbf..084fbbe438952 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/get_service_entities.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/get_service_entities.ts @@ -7,7 +7,7 @@ import { errors } from '@elastic/elasticsearch'; import { Logger } from '@kbn/core/server'; import { WrappedElasticsearchClientError } from '@kbn/observability-plugin/server'; -import { EntitiesESClient } from '../../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { withApmSpan } from '../../../utils/with_apm_span'; import { getEntities } from '../get_entities'; import { calculateAvgMetrics } from '../utils/calculate_avg_metrics'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts index 027bd5bd09c98..fad2e495e8c6e 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/entities/services/routes.ts @@ -9,7 +9,7 @@ import { jsonRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; import { EntityServiceListItem } from '../../../../common/entities/types'; import { environmentQuery } from '../../../../common/utils/environment_query'; -import { createEntitiesESClient } from '../../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { createEntitiesESClient } from '../../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { createApmServerRoute } from '../../apm_routes/create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from '../../default_api_types'; import { getServiceEntities } from './get_service_entities'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/has_historical_entities_data.ts b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/has_historical_entities_data.ts index 13c6ebcf7bfd9..f245c27a99036 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/has_historical_entities_data.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/has_historical_entities_data.ts @@ -7,7 +7,7 @@ import { WrappedElasticsearchClientError } from '@kbn/observability-plugin/server'; import { Logger } from '@kbn/core/server'; import { errors } from '@elastic/elasticsearch'; -import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { EntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; export async function hasEntitiesData(entitiesESClient: EntitiesESClient, logger: Logger) { const params = { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts index 484590a00a36e..94b7d40b84c2d 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/historical_data/route.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { hasHistoricalAgentData } from './has_historical_agent_data'; diff --git a/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts index f80c58c19ed93..1d4cbd0cef1c3 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/services/route.ts @@ -80,7 +80,7 @@ import { import { getThroughput, ServiceThroughputResponse } from './get_throughput'; import { getServiceEntitySummary } from '../entities/get_service_entity_summary'; import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; -import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_assets_es_client/create_assets_es_clients'; +import { createEntitiesESClient } from '../../lib/helpers/create_es_client/create_entities_es_client/create_entities_es_client'; const servicesRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services', diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/constants.ts b/x-pack/plugins/observability_solution/dataset_quality/common/constants.ts index 895381703742e..1b822c6c111d9 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/constants.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/constants.ts @@ -42,4 +42,4 @@ export const MAX_DEGRADED_FIELDS = 1000; export const MASKED_FIELD_PLACEHOLDER = ''; export const UNKOWN_FIELD_PLACEHOLDER = ''; -export const KNOWN_TYPES: DataStreamType[] = ['logs', 'metrics', 'traces']; +export const KNOWN_TYPES: DataStreamType[] = ['logs', 'metrics', 'traces', 'synthetics']; diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/test_helpers/create_dataset_quality_users/authentication.ts b/x-pack/plugins/observability_solution/dataset_quality/server/test_helpers/create_dataset_quality_users/authentication.ts index b5b177c644f59..bca3556b63771 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/test_helpers/create_dataset_quality_users/authentication.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/test_helpers/create_dataset_quality_users/authentication.ts @@ -10,20 +10,20 @@ export enum DatasetQualityUsername { viewerUser = 'viewer', readUser = 'readUser', editorUser = 'editor', - datasetQualityLogsUser = 'dataset_quality_logs_user', + datasetQualityMonitorUser = 'dataset_quality_monitor_user', } export enum DatasetQualityCustomRolename { - datasetQualityLogsUser = 'dataset_quality_logs_user', + datasetQualityMonitorUser = 'dataset_quality_monitor_user', datasetQualityReadUser = 'dataset_quality_read_user', } export const customRoles = { - [DatasetQualityCustomRolename.datasetQualityLogsUser]: { + [DatasetQualityCustomRolename.datasetQualityMonitorUser]: { elasticsearch: { indices: [ { - names: ['logs-*-*'], + names: ['logs-*-*', 'metrics-*-*', 'traces-*-*', 'synthetics-*-*'], privileges: ['monitor', 'view_index_metadata'], }, ], @@ -55,9 +55,9 @@ export const users: Record< [DatasetQualityUsername.editorUser]: { builtInRoleNames: ['editor'], }, - [DatasetQualityUsername.datasetQualityLogsUser]: { + [DatasetQualityUsername.datasetQualityMonitorUser]: { builtInRoleNames: ['editor'], - customRoleNames: [DatasetQualityCustomRolename.datasetQualityLogsUser], + customRoleNames: [DatasetQualityCustomRolename.datasetQualityMonitorUser], }, [DatasetQualityUsername.readUser]: { customRoleNames: [DatasetQualityCustomRolename.datasetQualityReadUser], diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts b/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts index 4c97d5cec72ed..78f6b9f4e6041 100644 --- a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts +++ b/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts @@ -20,7 +20,7 @@ const serviceTransactionFilter = (additionalFilters: string[] = []) => { export const builtInServicesFromLogsEntityDefinition: EntityDefinition = entityDefinitionSchema.parse({ - version: '1.0.0', + version: '1.0.1', id: `${BUILT_IN_ID_PREFIX}services_from_ecs_data`, name: 'Services from ECS data', description: @@ -104,17 +104,12 @@ export const builtInServicesFromLogsEntityDefinition: EntityDefinition = }, { name: 'logErrorRate', - equation: 'A / B', + equation: 'A', metrics: [ { name: 'A', aggregation: 'doc_count', - filter: 'log.level: "error" OR error.log.level: "error"', - }, - { - name: 'B', - aggregation: 'doc_count', - filter: 'log.level: * OR error.log.level: *', + filter: 'log.level: "error" OR log.level: "ERROR" OR error.log.level: "error"', }, ], }, diff --git a/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/metric.tsx b/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/metric.tsx index bed80c31066ab..e112001b7f662 100644 --- a/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/metric.tsx +++ b/x-pack/plugins/observability_solution/infra/public/alerting/inventory/components/metric.tsx @@ -126,7 +126,7 @@ export const MetricExpression = ({ }, [customMetricTabOpen, metric, customMetric, firstFieldOption]); const onChangeTab = useCallback( - (id) => { + (id: string) => { if (id === 'metric-popover-custom') { setCustomMetricTabOpen(true); onChange('custom'); @@ -139,7 +139,7 @@ export const MetricExpression = ({ ); const onAggregationChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const value = e.target.value; const aggValue: SnapshotCustomAggregation = SnapshotCustomAggregationRT.is(value) ? value @@ -166,7 +166,7 @@ export const MetricExpression = ({ const debouncedOnChangeCustom = debounce(onChangeCustom, 500); const onLabelChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setFieldDisplayedCustomLabel(e.target.value); const newCustomMetric = { ...customMetric, diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx index 6bb47cfff588d..7c0963aa2d9d3 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_analysis_setup/initial_configuration_step/analysis_setup_indices_form.tsx @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React, { useCallback, useMemo } from 'react'; import { ApplicationStart } from '@kbn/core-application-browser'; import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; -import { QualityWarning } from '../../../../../common/log_analysis'; +import { DatasetFilter, QualityWarning } from '../../../../../common/log_analysis'; import { LoadingOverlayWrapper } from '../../../loading_overlay_wrapper'; import { IndexSetupRow } from './index_setup_row'; import { AvailableIndex, ValidationIndicesError } from './validation'; @@ -58,7 +58,7 @@ export const AnalysisSetupIndicesForm: React.FunctionComponent<{ ); const changeDatasetFilter = useCallback( - (indexName: string, datasetFilter) => { + (indexName: string, datasetFilter: DatasetFilter) => { onChangeSelectedIndices( indices.map((index) => { return index.name === indexName ? { ...index, datasetFilter } : index; diff --git a/x-pack/plugins/observability_solution/infra/public/components/logging/log_highlights_menu.tsx b/x-pack/plugins/observability_solution/infra/public/components/logging/log_highlights_menu.tsx index 2d2b0680604bb..1e53d8125834f 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/logging/log_highlights_menu.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/logging/log_highlights_menu.tsx @@ -68,7 +68,7 @@ export const LogHighlightsMenu: React.FC = ({ [debouncedOnChange] ); const changeHighlightTerm = useCallback( - (e) => { + (e: React.ChangeEvent) => { const value = e.target.value; setHighlightTerm(value); }, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx index 170eaaeb9d4db..00da4640eb73f 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/inventory_view/components/waffle/metric_control/custom_metric_form.tsx @@ -87,7 +87,7 @@ export const CustomMetricForm = withTheme(({ theme, onCancel, onChange, metric } }, [metric, aggregation, field, onChange, label]); const handleLabelChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { setLabel(e.target.value); }, [setLabel] @@ -101,7 +101,7 @@ export const CustomMetricForm = withTheme(({ theme, onCancel, onChange, metric } ); const handleAggregationChange = useCallback( - (e) => { + (e: React.ChangeEvent) => { const value = e.target.value; const aggValue: SnapshotCustomAggregation = SnapshotCustomAggregationRT.is(value) ? value diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx new file mode 100644 index 0000000000000..c81ebec9c6ade --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx @@ -0,0 +1,259 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiEmptyPrompt } from '@elastic/eui'; +import type { DataView } from '@kbn/data-views-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { type GlobalWidgetParameters } from '@kbn/investigate-plugin/public'; +import React, { useEffect, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; + +import { + LensAttributes, + XYLayerOptions, + XYDataLayer, + XYReferenceLinesLayer, + XYByValueAnnotationsLayer, + LensAttributesBuilder, + XYChart, +} from '@kbn/lens-embeddable-utils'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { SerializedSearchSourceFields } from '@kbn/data-plugin/common'; +import { Query, Filter } from '@kbn/es-query'; +import type { Options } from '../register_items'; +import { useKibana } from '../../hooks/use_kibana'; + +interface GenericSearchSourceFields extends SerializedSearchSourceFields { + query?: Query; + filter?: Array>; +} + +interface Props { + timeRange: { + from: string; + to: string; + }; + searchConfiguration: GenericSearchSourceFields; + equation: string; + interval?: string; + filters?: Filter[]; + groupBy?: string[] | string; +} + +export interface RuleSearchSourceFields extends SerializedSearchSourceFields { + query?: Query; + filter?: Array>; +} + +interface LensItemParams { + type: string; + searchConfiguration: RuleSearchSourceFields; + equation: string; + interval?: string; + filters?: Filter[]; + groupBy?: string[] | string; +} + +const defaultQuery: Query = { + language: 'kuery', + query: '', +}; + +export const LensFieldFormat = { + NUMBER: 'number', + PERCENT: 'percent', + BITS: 'bits', +} as const; + +export function LensWidget({ + timeRange, + searchConfiguration, + equation, + interval, + filters, + groupBy, +}: Props) { + const { + dependencies: { + start: { lens, data }, + }, + } = useKibana(); + + const [attributes, setAttributes] = useState(); + const [chartLoading, setChartLoading] = useState(false); + + const formulaAsync = useAsync(() => { + return lens.stateHelperApi(); + }, [lens]); + + const [dataView, setDataView] = useState(); + const [, setDataViewError] = useState(); + + useEffect(() => { + const initDataView = async () => { + const ruleSearchConfiguration = searchConfiguration; + try { + const createdSearchSource = await data.search.searchSource.create(ruleSearchConfiguration); + setDataView(createdSearchSource.getField('index')); + } catch (error) { + setDataViewError(error); + } + }; + + initDataView(); + }, [data.search.searchSource, searchConfiguration]); + + // Handle Lens error + useEffect(() => { + // Lens does not expose or provide a way to check if there is an error in the chart, yet. + // To work around this, we check if the element with class 'lnsEmbeddedError' is found in the DOM. + setTimeout(function () { + const errorDiv = document.querySelector('.lnsEmbeddedError'); + if (errorDiv) { + const paragraphElements = errorDiv.querySelectorAll('p'); + if (!paragraphElements || paragraphElements.length < 2) return; + paragraphElements[0].innerText = i18n.translate( + 'xpack.investigateApp.defaultChart.error_equation.title', + { + defaultMessage: 'An error occurred while rendering the chart', + } + ); + paragraphElements[1].innerText = i18n.translate( + 'xpack.investigateApp.defaultChart.error_equation.description', + { + defaultMessage: 'Check the equation.', + } + ); + } + }); + }, [chartLoading, attributes]); + + useEffect(() => { + if (!formulaAsync.value || !dataView || !equation) { + return; + } + const baseLayer = { + type: 'formula', + value: equation, + label: equation, + groupBy, + }; + const xYDataLayerOptions: XYLayerOptions = { + buckets: { + type: 'date_histogram', + params: { + interval, + }, + }, + seriesType: 'bar', + }; + + if (groupBy && groupBy?.length) { + xYDataLayerOptions.breakdown = { + type: 'top_values', + field: groupBy[0], + params: { + size: 3, + secondaryFields: (groupBy as string[]).slice(1), + accuracyMode: false, + }, + }; + } + + const xyDataLayer = new XYDataLayer({ + data: [baseLayer].map((layer) => ({ + type: layer.type, + value: layer.value, + label: layer.label, + })), + options: xYDataLayerOptions, + }); + + const layers: Array = [ + xyDataLayer, + ]; + + const attributesLens = new LensAttributesBuilder({ + visualization: new XYChart({ + visualOptions: { + axisTitlesVisibilitySettings: { + x: false, + yLeft: false, + yRight: false, + }, + legend: { + isVisible: false, + position: 'right', + }, + }, + layers, + formulaAPI: formulaAsync.value.formula, + dataView, + }), + }).build(); + const lensBuilderAtt = { ...attributesLens, type: 'lens' }; + setAttributes(lensBuilderAtt); + }, [searchConfiguration, equation, groupBy, interval, dataView, formulaAsync.value]); + + if (!dataView || !attributes || !timeRange) { + return ( +
+ + } + /> +
+ ); + } + + return ( +
+ +
+ ); +} + +export function registerLensItem({ + dependencies: { + setup: { investigate }, + }, +}: Options) { + investigate.registerItemDefinition({ + type: 'lens', + generate: async () => { + return {}; + }, + render: (option: { itemParams: LensItemParams; globalParams: GlobalWidgetParameters }) => { + const { itemParams, globalParams } = option; + return ( + + ); + }, + }); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts b/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts index ff0304105a0b0..4ae017f5bbcdf 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/register_items.ts @@ -9,6 +9,7 @@ import type { InvestigateAppServices } from '../services/types'; import type { InvestigateAppSetupDependencies, InvestigateAppStartDependencies } from '../types'; import { registerEmbeddableItem } from './embeddable_item/register_embeddable_item'; import { registerEsqlItem } from './esql_item/register_esql_item'; +import { registerLensItem } from './lens_item/register_lens_item'; export interface Options { dependencies: { @@ -21,4 +22,5 @@ export interface Options { export function registerItems(options: Options) { registerEsqlItem(options); registerEmbeddableItem(options); + registerLensItem(options); } diff --git a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json index 29b4985896ee2..b452b80b821ca 100644 --- a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json @@ -56,5 +56,7 @@ "@kbn/shared-ux-router", "@kbn/investigation-shared", "@kbn/core-security-common", + "@kbn/lens-embeddable-utils", + "@kbn/i18n-react", ], } diff --git a/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx b/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx index f0c9c411249a9..a9c45828a7555 100644 --- a/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx +++ b/x-pack/plugins/observability_solution/logs_shared/public/components/log_stream/log_stream.tsx @@ -24,7 +24,7 @@ import { LogViewsClient } from '../../services/log_views'; import { LogColumnRenderConfiguration } from '../../utils/log_column_render_configuration'; import { useKibanaQuerySettings } from '../../utils/use_kibana_query_settings'; import { useLogEntryFlyout } from '../logging/log_entry_flyout'; -import { ScrollableLogTextStreamView } from '../logging/log_text_stream'; +import { ScrollableLogTextStreamView, VisibleInterval } from '../logging/log_text_stream'; import { LogStreamErrorBoundary } from './log_stream_error_boundary'; interface LogStreamPluginDeps { @@ -251,7 +251,7 @@ Read more at https://github.com/elastic/kibana/blob/main/src/plugins/kibana_reac // Pagination handler const handlePagination = useCallback( - ({ fromScroll, pagesBeforeStart, pagesAfterEnd }) => { + ({ fromScroll, pagesBeforeStart, pagesAfterEnd }: VisibleInterval) => { if (!fromScroll) { return; } diff --git a/x-pack/plugins/observability_solution/observability/public/navigation_tree.ts b/x-pack/plugins/observability_solution/observability/public/navigation_tree.ts index 65256a1584461..9a064af35d3e8 100644 --- a/x-pack/plugins/observability_solution/observability/public/navigation_tree.ts +++ b/x-pack/plugins/observability_solution/observability/public/navigation_tree.ts @@ -338,6 +338,135 @@ const navTree: NavigationTreeDefinition = { { link: 'fleet', }, + { + id: 'machine_learning-landing', + link: 'securitySolutionUI:machine_learning-landing', + renderAs: 'panelOpener', + spaceBefore: null, + children: [ + { + children: [ + { + link: 'ml:overview', + }, + { + link: 'ml:notifications', + }, + { + link: 'ml:memoryUsage', + }, + ], + }, + { + id: 'category-anomaly_detection', + title: i18n.translate('xpack.observability.obltNav.ml.anomaly_detection', { + defaultMessage: 'Anomaly detection', + }), + breadcrumbStatus: 'hidden', + children: [ + { + link: 'ml:anomalyDetection', + title: i18n.translate('xpack.observability.obltNav.ml.anomaly_detection.jobs', { + defaultMessage: 'Jobs', + }), + }, + { + link: 'ml:anomalyExplorer', + }, + { + link: 'ml:singleMetricViewer', + }, + { + link: 'ml:settings', + }, + ], + }, + { + id: 'category-data_frame analytics', + title: i18n.translate('xpack.observability.obltNav.ml.data_frame_analytics', { + defaultMessage: 'Data frame analytics', + }), + breadcrumbStatus: 'hidden', + children: [ + { + link: 'ml:dataFrameAnalytics', + title: i18n.translate( + 'xpack.observability.obltNav.ml.data_frame_analytics.jobs', + { + defaultMessage: 'Jobs', + } + ), + }, + { + link: 'ml:resultExplorer', + }, + { + link: 'ml:analyticsMap', + }, + ], + }, + { + id: 'category-model_management', + title: i18n.translate('xpack.observability.obltNav.ml.model_management', { + defaultMessage: 'Model management', + }), + breadcrumbStatus: 'hidden', + children: [ + { + link: 'ml:nodesOverview', + }, + ], + }, + { + id: 'category-data_visualizer', + title: i18n.translate('xpack.observability.obltNav.ml.data_visualizer', { + defaultMessage: 'Data visualizer', + }), + breadcrumbStatus: 'hidden', + children: [ + { + link: 'ml:fileUpload', + title: i18n.translate( + 'xpack.observability.obltNav.ml.data_visualizer.file_data_visualizer', + { + defaultMessage: 'File data visualizer', + } + ), + }, + { + link: 'ml:indexDataVisualizer', + title: i18n.translate( + 'xpack.observability.obltNav.ml.data_visualizer.file_data_visualizer', + { + defaultMessage: 'Data view data visualizer', + } + ), + }, + { + link: 'ml:dataDrift', + }, + ], + }, + { + id: 'category-aiops_labs', + title: i18n.translate('xpack.observability.obltNav.ml.aiops_labs', { + defaultMessage: 'Aiops labs', + }), + breadcrumbStatus: 'hidden', + children: [ + { + link: 'ml:logRateAnalysis', + }, + { + link: 'ml:logPatternAnalysis', + }, + { + link: 'ml:changePointDetections', + }, + ], + }, + ], + }, { id: 'cloudLinkUserAndRoles', cloudLink: 'userAndRoles', diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/header_actions.tsx b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/header_actions.tsx index 6ea43b165fe7a..5d20f8830799b 100644 --- a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/header_actions.tsx +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/components/header_actions.tsx @@ -30,10 +30,14 @@ import { ALERT_END, ALERT_RULE_TYPE_ID, OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + ALERT_GROUP, } from '@kbn/rule-data-utils'; import { v4 as uuidv4 } from 'uuid'; import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util'; +import { CreateInvestigationResponse } from '@kbn/investigation-shared'; +import { RuleTypeParams } from '@kbn/alerting-plugin/common'; +import { Group } from '@kbn/observability-alerting-rule-utils'; import { useKibana } from '../../../utils/kibana_react'; import { useFetchRule } from '../../../hooks/use_fetch_rule'; import type { TopAlert } from '../../../typings/alerts'; @@ -41,6 +45,9 @@ import { paths } from '../../../../common/locators/paths'; import { useBulkUntrackAlerts } from '../hooks/use_bulk_untrack_alerts'; import { useCreateInvestigation } from '../hooks/use_create_investigation'; import { useFetchInvestigationsByAlert } from '../hooks/use_fetch_investigations_by_alert'; +import { useAddInvestigationItem } from '../hooks/use_add_investigation_item'; +import { AlertParams } from '../../../components/custom_threshold/types'; +import { generateInvestigationItem } from '../../../utils/investigation_item_helper'; export interface HeaderActionsProps { alert: TopAlert | null; @@ -125,10 +132,36 @@ export function HeaderActions({ }; const { mutateAsync: createInvestigation } = useCreateInvestigation(); + const { mutateAsync: addInvestigationItem } = useAddInvestigationItem(); const alertStart = alert?.fields[ALERT_START]; const alertEnd = alert?.fields[ALERT_END]; + const addChartsToInvestigation = async (investigationDetails: CreateInvestigationResponse) => { + if ( + rule && + alert && + alert.fields[ALERT_RULE_TYPE_ID] === OBSERVABILITY_THRESHOLD_RULE_TYPE_ID + ) { + const ruleParams = rule.params as RuleTypeParams & AlertParams; + + for (let index = 0; index < ruleParams.criteria.length; index++) { + const criterion = ruleParams.criteria[index]; + const item = generateInvestigationItem( + criterion, + ruleParams.searchConfiguration, + alert.fields[ALERT_RULE_TYPE_ID], + ruleParams.groupBy, + alert.fields[ALERT_GROUP] as Group[] + ); + + if (item) { + await addInvestigationItem({ investigationId: investigationDetails.id, item }); + } + } + } + }; + const createOrOpenInvestigation = async () => { if (!alert) return; @@ -152,6 +185,8 @@ export function HeaderActions({ }, }); + await addChartsToInvestigation(investigationResponse); + navigateToApp('investigate', { path: `/${investigationResponse.id}`, replace: false }); } else { navigateToApp('investigate', { diff --git a/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_add_investigation_item.ts b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_add_investigation_item.ts new file mode 100644 index 0000000000000..bb783e202f156 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability/public/pages/alert_details/hooks/use_add_investigation_item.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public'; +import { + CreateInvestigationItemParams, + CreateInvestigationItemResponse, +} from '@kbn/investigation-shared'; +import { useMutation } from '@tanstack/react-query'; +import { useKibana } from '../../../utils/kibana_react'; + +type ServerError = IHttpFetchError; + +export function useAddInvestigationItem() { + const { + http, + notifications: { toasts }, + } = useKibana().services; + + return useMutation< + CreateInvestigationItemResponse, + ServerError, + { investigationId: string; item: CreateInvestigationItemParams }, + { investigationId: string } + >( + ['addInvestigationItem'], + ({ investigationId, item }) => { + const body = JSON.stringify(item); + return http.post( + `/api/observability/investigations/${investigationId}/items`, + { body, version: '2023-10-31' } + ); + }, + { + onSuccess: (response, {}) => { + toasts.addSuccess('Item added to investigation'); + }, + onError: (error, {}, context) => { + toasts.addError(new Error(error.body?.message ?? 'An error occurred'), { title: 'Error' }); + }, + } + ); +} diff --git a/x-pack/plugins/observability_solution/observability/public/utils/investigation_item_helper.ts b/x-pack/plugins/observability_solution/observability/public/utils/investigation_item_helper.ts new file mode 100644 index 0000000000000..5ffaa234b3d97 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability/public/utils/investigation_item_helper.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Group } from '@kbn/observability-alerting-rule-utils'; +import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; +import { + CustomThresholdExpressionMetric, + CustomThresholdSearchSourceFields, +} from '../../common/custom_threshold_rule/types'; +import { MetricExpression } from '../components/custom_threshold/types'; +import { getGroupFilters } from '..'; + +const AggMappingForLens: Record = { + avg: 'average', + cardinality: 'unique_count', +}; + +const genLensEqForCustomThresholdRule = (criterion: MetricExpression) => { + const metricNameResolver: Record = {}; + + criterion.metrics.forEach( + (metric: CustomThresholdExpressionMetric) => + (metricNameResolver[metric.name] = `${ + AggMappingForLens[metric.aggType] ? AggMappingForLens[metric.aggType] : metric.aggType + }(${metric.field ? metric.field : metric.filter ? metric.filter : ''})`) + ); + + let equation = criterion.equation + ? criterion.equation + : criterion.metrics.map((m) => m.name).join('+'); + + Object.keys(metricNameResolver) + .sort() + .reverse() + .forEach((metricName) => { + equation = equation.replaceAll(metricName, metricNameResolver[metricName]); + }); + + return equation; +}; + +export const generateInvestigationItem = ( + criterion: MetricExpression, + searchConfiguration: CustomThresholdSearchSourceFields, + ruleTypeId: string, + groupBy?: string | string[], + groups?: Group[] +) => { + if (ruleTypeId === OBSERVABILITY_THRESHOLD_RULE_TYPE_ID) { + const equation = genLensEqForCustomThresholdRule(criterion); + const filters = searchConfiguration.filter || []; + const additionalFilters = getGroupFilters(groups); + const interval = `${criterion.timeSize}${criterion.timeUnit}`; + + const item = { + title: equation, + type: 'lens', + params: { + filters: [...filters, ...additionalFilters], + equation, + interval, + searchConfiguration, + groupBy, + }, + }; + + return item; + } +}; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/types.ts index eb34e2bb2ee5e..7f8a2be739dd1 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/types.ts @@ -5,8 +5,9 @@ * 2.0. */ import { IconType } from '@elastic/eui'; +import type { ToolSchema } from '@kbn/inference-plugin/common'; import type { ObservabilityAIAssistantChatService } from '../public'; -import type { CompatibleJSONSchema, FunctionResponse } from './functions/types'; +import type { FunctionResponse } from './functions/types'; export enum MessageRole { System = 'system', @@ -122,7 +123,7 @@ export interface ObservabilityAIAssistantScreenContextRequest { description: string; value: any; }>; - actions?: Array<{ name: string; description: string; parameters?: CompatibleJSONSchema }>; + actions?: Array<{ name: string; description: string; parameters?: ToolSchema }>; } export type ScreenContextActionRespondFunction = ({}: { @@ -136,7 +137,7 @@ export type ScreenContextActionRespondFunction = ({}: { export interface ScreenContextActionDefinition { name: string; description: string; - parameters?: CompatibleJSONSchema; + parameters?: ToolSchema; respond: ScreenContextActionRespondFunction; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts index cbb833d0aeb76..9d6c0dba0b124 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.test.ts @@ -48,6 +48,7 @@ describe('chatFunctionClient', () => { }), messages: [], signal: new AbortController().signal, + connectorId: 'foo', }); }).rejects.toThrowError(`Function arguments are invalid`); @@ -107,6 +108,7 @@ describe('chatFunctionClient', () => { args: JSON.stringify({ data: ['my_dummy_data'] }), messages: [], signal: new AbortController().signal, + connectorId: 'foo', }); expect(result).toEqual({ diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts index fc90a4e0caa3d..fa1d0e5fd669d 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/chat_function_client/index.ts @@ -132,7 +132,7 @@ export class ChatFunctionClient { return matchingDefinitions.map((definition) => functionsByName[definition.name]); } - getActions() { + getActions(): Required['actions'] { return this.actions; } @@ -146,12 +146,14 @@ export class ChatFunctionClient { args, messages, signal, + connectorId, }: { chat: FunctionCallChatFunction; name: string; args: string | undefined; messages: Message[]; signal: AbortSignal; + connectorId: string; }): Promise { const fn = this.functionRegistry.get(name); @@ -169,6 +171,7 @@ export class ChatFunctionClient { messages, screenContexts: this.screenContexts, chat, + connectorId, }, signal ); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts index f5c6b79b21788..a0accea06370b 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.test.ts @@ -821,6 +821,7 @@ describe('Observability AI Assistant client', () => { chat: expect.any(Function), args: JSON.stringify({ foo: 'bar' }), signal: expect.any(AbortSignal), + connectorId: 'foo', messages: [ { '@timestamp': expect.any(String), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts index 45309911375d1..f5839b76effe8 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/index.ts @@ -298,6 +298,7 @@ export class ObservabilityAIAssistantClient { logger: this.dependencies.logger, disableFunctions, tracer: completeTracer, + connectorId, }) ); }), diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts index a06fca2e13278..da172c974e9e2 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/client/operators/continue_conversation.ts @@ -33,7 +33,7 @@ import { createFunctionResponseMessage } from '../../../../common/utils/create_f import { emitWithConcatenatedMessage } from '../../../../common/utils/emit_with_concatenated_message'; import { withoutTokenCountEvents } from '../../../../common/utils/without_token_count_events'; import type { ChatFunctionClient } from '../../chat_function_client'; -import type { ChatFunctionWithoutConnector } from '../../types'; +import type { AutoAbortedChatFunction } from '../../types'; import { createServerSideFunctionResponseError } from '../../util/create_server_side_function_response_error'; import { getSystemMessageFromInstructions } from '../../util/get_system_message_from_instructions'; import { replaceSystemMessage } from '../../util/replace_system_message'; @@ -53,15 +53,17 @@ function executeFunctionAndCatchError({ signal, logger, tracer, + connectorId, }: { name: string; args: string | undefined; functionClient: ChatFunctionClient; messages: Message[]; - chat: ChatFunctionWithoutConnector; + chat: AutoAbortedChatFunction; signal: AbortSignal; logger: Logger; tracer: LangTracer; + connectorId: string; }): Observable { // hide token count events from functions to prevent them from // having to deal with it as well @@ -75,11 +77,13 @@ function executeFunctionAndCatchError({ return chat(operationName, { ...params, tracer: nextTracer, + connectorId, }).pipe(hide()); }, args, signal, messages, + connectorId, }) ); @@ -176,10 +180,11 @@ export function continueConversation({ logger, disableFunctions, tracer, + connectorId, }: { messages: Message[]; functionClient: ChatFunctionClient; - chat: ChatFunctionWithoutConnector; + chat: AutoAbortedChatFunction; signal: AbortSignal; functionCallsLeft: number; adHocInstructions: AdHocInstruction[]; @@ -191,6 +196,7 @@ export function continueConversation({ except: string[]; }; tracer: LangTracer; + connectorId: string; }): Observable { let nextFunctionCallsLeft = functionCallsLeft; @@ -228,6 +234,7 @@ export function continueConversation({ messages: messagesWithUpdatedSystemMessage, functions: definitions, tracer, + connectorId, }).pipe(emitWithConcatenatedMessage(), catchFunctionNotFoundError(functionLimitExceeded)); } @@ -302,6 +309,7 @@ export function continueConversation({ signal, logger, tracer, + connectorId, }); } @@ -329,6 +337,7 @@ export function continueConversation({ logger, disableFunctions, tracer, + connectorId, }); }) ) diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts index cd8e25843ca59..9ae585af9071c 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/server/service/types.ts @@ -32,11 +32,11 @@ export type ChatFunction = ( params: Parameters[1] ) => Observable; -export type ChatFunctionWithoutConnector = ( +export type AutoAbortedChatFunction = ( name: string, params: Omit< Parameters[1], - 'connectorId' | 'simulateFunctionCalling' | 'signal' + 'simulateFunctionCalling' | 'signal' > ) => Observable; @@ -54,6 +54,7 @@ type RespondFunction = ( messages: Message[]; screenContexts: ObservabilityAIAssistantScreenContextRequest[]; chat: FunctionCallChatFunction; + connectorId: string; }, signal: AbortSignal ) => Promise; diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json index 56b34fc81ca46..cd314e65fec9a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json @@ -41,6 +41,7 @@ "@kbn/core-elasticsearch-server", "@kbn/core-ui-settings-server", "@kbn/server-route-repository-utils", + "@kbn/inference-plugin", ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/common/convert_messages_for_inference.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/common/convert_messages_for_inference.ts new file mode 100644 index 0000000000000..91d7f00467540 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/common/convert_messages_for_inference.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Message, MessageRole } from '@kbn/observability-ai-assistant-plugin/common'; +import { + AssistantMessage, + Message as InferenceMessage, + MessageRole as InferenceMessageRole, + generateFakeToolCallId, +} from '@kbn/inference-plugin/common'; + +export function convertMessagesForInference(messages: Message[]): InferenceMessage[] { + const inferenceMessages: InferenceMessage[] = []; + + messages.forEach((message) => { + if (message.message.role === MessageRole.Assistant) { + inferenceMessages.push({ + role: InferenceMessageRole.Assistant, + content: message.message.content ?? null, + ...(message.message.function_call + ? { + toolCalls: [ + { + function: { + name: message.message.function_call.name, + arguments: JSON.parse(message.message.function_call.arguments || '{}'), + }, + toolCallId: generateFakeToolCallId(), + }, + ], + } + : {}), + }); + return; + } + + const isUserMessage = message.message.role === MessageRole.User; + const isUserMessageWithToolCall = isUserMessage && !!message.message.name; + + if (isUserMessageWithToolCall) { + const toolCallRequest = inferenceMessages.findLast( + (msg) => + msg.role === InferenceMessageRole.Assistant && + msg.toolCalls?.[0]?.function.name === message.message.name + ) as AssistantMessage | undefined; + if (!toolCallRequest) { + throw new Error(`Could not find tool call request for ${message.message.name}`); + } + + inferenceMessages.push({ + role: InferenceMessageRole.Tool, + response: JSON.parse(message.message.content ?? '{}'), + toolCallId: toolCallRequest.toolCalls![0].toolCallId, + }); + + return; + } + + if (isUserMessage) { + inferenceMessages.push({ + role: InferenceMessageRole.User, + content: message.message.content ?? '', + }); + return; + } + + throw new Error(`Unsupported message type: ${message.message.role}`); + }); + + return inferenceMessages; +} diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc index 6e2ba07fb699c..1e02cbd1e7792 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc @@ -23,7 +23,8 @@ "licensing", "ml", "alerting", - "features" + "features", + "inference" ], "requiredBundles": ["kibanaReact", "esqlDataGrid"], "optionalPlugins": ["cloud"], diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts index d2fe20e022cae..61ed156530100 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/scripts/evaluation/kibana_client.ts @@ -577,7 +577,7 @@ export class KibanaClient { score: { type: 'number', description: - 'A score of either 0 (criterion failed) or 1 (criterion succeeded)', + 'A score between 0 (criterion failed) or 1 (criterion succeeded). Fractional results (e.g. 0.5) are allowed, if part of the criterion succeeded', }, reasoning: { type: 'string', diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-abs.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-abs.txt deleted file mode 100644 index c31ec9882e371..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-abs.txt +++ /dev/null @@ -1,30 +0,0 @@ -## ABS - -The `ABS` function in ES|QL returns the absolute value of a numeric expression. - -### Syntax - -`ABS(number)` - -#### Parameters - -`number`: Numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `ABS` function in ES|QL: - -```esql -ROW number = -1.0 -| EVAL abs_number = ABS(number) -``` - -In this example, the `ABS` function is used to calculate the absolute value of `-1.0`, which results in `1.0`. - -```esql -FROM employees -| KEEP first_name, last_name, height -| EVAL abs_height = ABS(0.0 - height) -``` - -In this example, the `ABS` function is used to calculate the absolute value of the height of employees. The height is subtracted from `0.0` to get a negative value, and then the `ABS` function is applied to get the absolute value. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-acos.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-acos.txt deleted file mode 100644 index 2a5dab6453787..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-acos.txt +++ /dev/null @@ -1,29 +0,0 @@ -## ACOS - -The `ACOS` function in ES|QL returns the arccosine of a number as an angle, expressed in radians. The number should be between -1 and 1. If the input is null, the function will return null. - -### Syntax - -`ACOS(number)` - -#### Parameters - -`number`: A number between -1 and 1. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `ACOS` function in ES|QL queries: - -```esql -ROW a=.9 -| EVAL acos = ACOS(a) -``` - -In this example, the `ACOS` function is used to calculate the arccosine of 0.9. - -```esql -ROW a=-.5 -| EVAL acos = ACOS(a) -``` - -In this example, the `ACOS` function is used to calculate the arccosine of -0.5. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-asin.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-asin.txt deleted file mode 100644 index 0c03646864a7a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-asin.txt +++ /dev/null @@ -1,21 +0,0 @@ -## ASIN - -The `ASIN` function in ES|QL returns the arcsine of the input numeric expression as an angle, expressed in radians. This function only accepts numbers between -1 and 1. If the input is null, the function will return null. - -### Examples - -Here are a couple of examples of how you can use the `ASIN` function in your ES|QL queries: - -```esql -ROW a=.9 -| EVAL asin = ASIN(a) -``` - -In this example, the `ASIN` function is used to calculate the arcsine of 0.9. The result is stored in the `asin` column. - -```esql -ROW a=-.5 -| EVAL asin_value = ASIN(a) -``` - -In this second example, the `ASIN` function is used to calculate the arcsine of -0.5. The result is stored in the `asin_value` column. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan.txt deleted file mode 100644 index 3c40607d25a82..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan.txt +++ /dev/null @@ -1,29 +0,0 @@ -## ATAN - -The `ATAN` function in ES|QL is used to calculate the arctangent of a given numeric expression. The result is expressed in radians. If the input is null, the function will return null. - -### Syntax - -`ATAN(number)` - -#### Parameters - -- `number`: A numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `ATAN` function in ES|QL: - -```esql -ROW a=12.9 -| EVAL atan = ATAN(a) -``` - -In this example, the `ATAN` function is used to calculate the arctangent of the number 12.9. - -```esql -ROW b=7.5 -| EVAL atan_value = ATAN(b) -``` - -In this second example, the `ATAN` function is used to calculate the arctangent of the number 7.5. The result is stored in the `atan_value` variable. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan2.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan2.txt deleted file mode 100644 index 9377a71c2eb6d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-atan2.txt +++ /dev/null @@ -1,30 +0,0 @@ -## ATAN2 - -ATAN2 is a function in ES|QL that calculates the angle between the positive x-axis and the ray from the origin to the point (x , y) in the Cartesian plane, expressed in radians. - -### Syntax - -`ATAN2(y_coordinate, x_coordinate)` - -#### Parameters - -- `y_coordinate`: The y coordinate. If null, the function returns null. -- `x_coordinate`: The x coordinate. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `ATAN2` function in ES|QL queries: - -```esql -ROW y=12.9, x=.6 -| EVAL atan2 = ATAN2(y, x) -``` - -In this example, the `ATAN2` function is used to calculate the angle between the positive x-axis and the ray from the origin to the point (0.6 , 12.9) in the Cartesian plane. - -```esql -ROW y=5, x=3 -| EVAL atan2 = ATAN2(y, x) -``` - -In this second example, the `ATAN2` function is used to calculate the angle between the positive x-axis and the ray from the origin to the point (3 , 5) in the Cartesian plane. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-avg.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-avg.txt deleted file mode 100644 index bfd9c161bba1f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-avg.txt +++ /dev/null @@ -1,21 +0,0 @@ -## AVG - -The `AVG` function in ES|QL calculates the average of a numeric expression. The result is always a double, regardless of the input type. - -### Examples - -Here are a couple of examples of how you can use the `AVG` function in ES|QL queries: - -1. Calculating the average height of employees: - - ```esql -FROM employees -| STATS AVG(height) -``` - -2. Calculating the average salary change, where the salary change is a multivalued column. In this case, the `MV_AVG` function is used to first average the multiple values per row, and then the `AVG` function is used on the result: - - ```esql -FROM employees -| STATS avg_salary_change = ROUND(AVG(MV_AVG(salary_change)), 10) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-bucket.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-bucket.txt deleted file mode 100644 index 2eed9008f6870..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-bucket.txt +++ /dev/null @@ -1,22 +0,0 @@ -## BUCKET - -BUCKET function creates groups of values - buckets - out of a datetime or numeric input. The size of the buckets can either be provided directly, or chosen based on a recommended count and values range. - -### Examples - -In this example, BUCKET function is used to create a histogram of salaries: - -```esql -FROM employees -| STATS COUNT(*) BY bs = BUCKET(salary, 20, 25324, 74999) -| SORT bs -``` - -In the following example, BUCKET function is used to create monthly buckets for the year 1985, and calculate the average salary by hiring month: - -```esql -FROM employees -| WHERE hire_date >= "1985-01-01T00:00:00Z" AND hire_date < "1986-01-01T00:00:00Z" -| STATS AVG(salary) BY bucket = BUCKET(hire_date, 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z") -| SORT bucket -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-case.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-case.txt deleted file mode 100644 index 010975157a7b4..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-case.txt +++ /dev/null @@ -1,38 +0,0 @@ -## CASE - -The `CASE` function in ES|QL accepts pairs of conditions and values. It returns the value that belongs to the first condition that evaluates to true. If the number of arguments is odd, the last argument is the default value which is returned when no condition matches. If the number of arguments is even, and no condition matches, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `CASE` function in ES|QL: - -1. Determine whether employees are monolingual, bilingual, or polyglot: - -```esql -FROM employees -| EVAL type = CASE( - languages <= 1, "monolingual", - languages <= 2, "bilingual", - "polyglot") -| KEEP emp_no, languages, type -``` - -2. Calculate the total connection success rate based on log messages: - -```esql -FROM sample_data -| EVAL successful = CASE( - STARTS_WITH(message, "Connected to"), 1, - message == "Connection error", 0 - ) -| STATS success_rate = AVG(successful) -``` - -3. Calculate an hourly error rate as a percentage of the total number of log messages: - -```esql -FROM sample_data -| EVAL error = CASE(message LIKE "*error*", 1, 0) -| STATS error_rate = AVG(error) BY BUCKET(@timestamp, 1 hour) -| SORT hour -``` diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cbrt.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cbrt.txt deleted file mode 100644 index 4a5af259aabeb..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cbrt.txt +++ /dev/null @@ -1,29 +0,0 @@ -## CBRT - -The `CBRT` function in ES|QL is used to calculate the cube root of a number. The input can be any numeric value and the return value is always a double. If the input is an infinity, the function returns null. - -### Syntax - -`CBRT(number)` - -#### Parameters - -- `number`: A numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `CBRT` function in ES|QL: - -```esql -ROW d = 27.0 -| EVAL c = CBRT(d) -``` - -In this example, the `CBRT` function is used to calculate the cube root of 27. The result would be 3. - -```esql -ROW d = 64.0 -| EVAL c = CBRT(d) -``` - -In this example, the `CBRT` function is used to calculate the cube root of 64. The result would be 4. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ceil.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ceil.txt deleted file mode 100644 index 3cac4dbf7c63b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ceil.txt +++ /dev/null @@ -1,21 +0,0 @@ -## CEIL - -The `CEIL` function in ES|QL is used to round a number up to the nearest integer. This function does not perform any operation for long (including unsigned) and integer types. For double, this function picks the closest double value to the integer, similar to the `Math.ceil` function in JavaScript. - -### Examples - -Here are a couple of examples of how you can use the `CEIL` function in ES|QL queries: - -```esql -ROW a=1.8 -| EVAL a = CEIL(a) -``` - -In this example, the `CEIL` function is used to round the value of `a` (1.8) up to the nearest integer (2). - -```esql -ROW b=3.3 -| EVAL b = CEIL(b) -``` - -In this second example, the `CEIL` function is used to round the value of `b` (3.3) up to the nearest integer (4). \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cidr_match.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cidr_match.txt deleted file mode 100644 index d66963e5efaaa..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cidr_match.txt +++ /dev/null @@ -1,32 +0,0 @@ -## CIDR_MATCH - -CIDR_MATCH is a function in ES|QL that checks if a provided IP address is contained in one or more provided CIDR blocks. It returns a boolean value - true if the IP is contained in the CIDR block(s), and false if it is not. - -### Syntax - -`CIDR_MATCH(ip, blockX)` - -### Parameters - -- `ip`: IP address of type ip (both IPv4 and IPv6 are supported). -- `blockX`: CIDR block to test the IP against. - -### Examples - -Here are a couple of examples of how you can use the CIDR_MATCH function in ES|QL queries: - -```esql -FROM hosts -| WHERE CIDR_MATCH(ip1, "127.0.0.2/32", "127.0.0.3/32") -| KEEP card, host, ip0, ip1 -``` - -In this example, the query checks if the `ip1` field of the `hosts` index is contained in either the "127.0.0.2/32" or "127.0.0.3/32" CIDR blocks. If it is, the `card`, `host`, `ip0`, and `ip1` fields are kept in the results. - -```esql -FROM network_logs -| WHERE CIDR_MATCH(source_ip, "192.168.1.0/24") -| KEEP timestamp, source_ip, destination_ip -``` - -In this second example, the query checks if the `source_ip` field of the `network_logs` index is contained in the "192.168.1.0/24" CIDR block. If it is, the `timestamp`, `source_ip`, and `destination_ip` fields are kept in the results. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-coalesce.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-coalesce.txt deleted file mode 100644 index f1fbc77e6c341..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-coalesce.txt +++ /dev/null @@ -1,30 +0,0 @@ -## COALESCE - -The `COALESCE` function in ES|QL is used to return the first of its arguments that is not null. If all arguments are null, it returns null. - -### Syntax - -`COALESCE(first, rest)` - -#### Parameters - -- `first`: The first expression to evaluate. -- `rest`: Other expressions to evaluate. - -### Examples - -Here are a couple of examples of how you can use the `COALESCE` function in ES|QL: - -```esql -ROW a=null, b="b" -| EVAL COALESCE(a, b) -``` - -In this example, the `COALESCE` function is used to evaluate the expressions `a` and `b`. Since `a` is null, the function returns the value of `b`, which is "b". - -```esql -ROW a=null, b=null, c="c" -| EVAL COALESCE(a, b, c) -``` - -In this second example, the `COALESCE` function evaluates the expressions `a`, `b`, and `c`. Since both `a` and `b` are null, the function returns the value of `c`, which is "c". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-concat.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-concat.txt deleted file mode 100644 index 60f1c33a6fa57..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-concat.txt +++ /dev/null @@ -1,22 +0,0 @@ -## CONCAT - -The `CONCAT` function in ES|QL is used to concatenate two or more strings together. - -### Examples - -Here are a couple of examples of how you can use the `CONCAT` function in ES|QL: - -```esql -FROM employees -| KEEP first_name, last_name -| EVAL fullname = CONCAT(first_name, " ", last_name) -``` - -In this example, the `CONCAT` function is used to combine the `first_name` and `last_name` fields from the `employees` index, with a space in between, to create a new field called `fullname`. - -```esql -FROM logs-* -| EVAL message = CONCAT("Error occurred at ", @timestamp, ": ", error_message) -``` - -In this second example, the `CONCAT` function is used to create a descriptive error message by combining a static string, the `@timestamp` field, and the `error_message` field from the `logs-*` index. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cos.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cos.txt deleted file mode 100644 index 1489bfcfedf7a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cos.txt +++ /dev/null @@ -1,21 +0,0 @@ -## COS - -The `COS` function in ES|QL is used to calculate the cosine of an angle. The angle should be provided in radians. - -### Examples - -Here are a couple of examples of how you can use the `COS` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL cos = COS(a) -``` - -In this example, the `COS` function is used to calculate the cosine of the angle `1.8` radians. The result is stored in the `cos` column. - -```esql -ROW a=3.14 -| EVAL cos_value = COS(a) -``` - -In this second example, the `COS` function is used to calculate the cosine of the angle `3.14` radians (which is approximately equal to π, the angle for which the cosine is `-1`). The result is stored in the `cos_value` column. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cosh.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cosh.txt deleted file mode 100644 index 903746bb07c02..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-cosh.txt +++ /dev/null @@ -1,21 +0,0 @@ -## COSH - -The `COSH` function in ES|QL returns the hyperbolic cosine of an angle. The angle should be provided in radians. If the provided angle is null, the function will return null. - -### Examples - -Here are a couple of examples of how you can use the `COSH` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL cosh = COSH(a) -``` - -In this example, the `COSH` function is used to calculate the hyperbolic cosine of the angle `1.8` radians. - -```esql -ROW a=0 -| EVAL cosh = COSH(a) -``` - -In this second example, the `COSH` function is used to calculate the hyperbolic cosine of the angle `0` radians. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count.txt deleted file mode 100644 index 97c49b44471a7..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count.txt +++ /dev/null @@ -1,35 +0,0 @@ -## COUNT - -The `COUNT` function in ES|QL returns the total number (count) of input values. It can take any field type as input. If the expression is omitted, it is equivalent to `COUNT(*)` which counts the number of rows. - -### Examples - -Here are a couple of examples of how you can use the `COUNT` function in ES|QL: - -1. Counting a specific field: - -```esql -FROM employees -| STATS COUNT(height) -``` - -In this example, the `COUNT` function is used to count the number of `height` values in the `employees` index. - -2. Counting the number of rows: - -```esql -FROM employees -| STATS count = COUNT(*) BY languages -| SORT languages DESC -``` - -In this example, the `COUNT(*)` function is used to count the number of rows in the `employees` index, grouped by `languages`. - -3. Using inline functions with `COUNT`: - -```esql -ROW words="foo;bar;baz;qux;quux;foo" -| STATS word_count = COUNT(SPLIT(words, ";")) -``` - -In this example, the `SPLIT` function is used to split a string into multiple values, and then the `COUNT` function is used to count these values. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count_distinct.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count_distinct.txt deleted file mode 100644 index bc977ed744b07..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-count_distinct.txt +++ /dev/null @@ -1,37 +0,0 @@ -## COUNT_DISTINCT - -The `COUNT_DISTINCT` function returns the approximate number of distinct values. It can take any field type as input. This function is based on the HyperLogLog++ algorithm, which counts based on the hashes of the values with some interesting properties such as configurable precision, excellent accuracy on low-cardinality sets, and fixed memory usage. - -### Syntax - -`COUNT_DISTINCT(expression[, precision_threshold])` - -#### Parameters - -- `expression`: Expression that outputs the values on which to perform a distinct count. -- `precision_threshold`: Precision threshold. The maximum supported value is 40000. Thresholds above this number will have the same effect as a threshold of 40000. The default value is 3000. - -### Examples - -Here are a couple of examples of how to use the `COUNT_DISTINCT` function in ES|QL queries: - -```esql -FROM hosts -| STATS COUNT_DISTINCT(ip0), COUNT_DISTINCT(ip1) -``` - -In this example, the `COUNT_DISTINCT` function is used to count the distinct values of `ip0` and `ip1` from the `hosts` index. - -```esql -FROM hosts -| STATS COUNT_DISTINCT(ip0, 80000), COUNT_DISTINCT(ip1, 5) -``` - -In this example, the `COUNT_DISTINCT` function is used with an optional second parameter to configure the precision threshold. - -```esql -ROW words="foo;bar;baz;qux;quux;foo" -| STATS distinct_word_count = COUNT_DISTINCT(SPLIT(words, ";")) -``` - -In this example, the `COUNT_DISTINCT` function is used with the `SPLIT` function to count the unique values in a string. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_diff.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_diff.txt deleted file mode 100644 index ef9ccdb30d44b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_diff.txt +++ /dev/null @@ -1,33 +0,0 @@ -## DATE_DIFF - -The `DATE_DIFF` function subtracts the `startTimestamp` from the `endTimestamp` and returns the difference in multiples of a specified unit. If `startTimestamp` is later than the `endTimestamp`, negative values are returned. - -Note that while there is an overlap between the function’s supported units and ES|QL’s supported time span literals, these sets are distinct and not interchangeable. Similarly, the supported abbreviations are conveniently shared with implementations of this function in other established products and not necessarily common with the date-time nomenclature used by Elasticsearch. - -### Syntax - -`DATE_DIFF(unit, startTimestamp, endTimestamp)` - -#### Parameters - -- `unit`: Time difference unit -- `startTimestamp`: A string representing a start timestamp -- `endTimestamp`: A string representing an end timestamp - -### Examples - -Here are a couple of examples of how to use the `DATE_DIFF` function in ES|QL queries: - -```esql -ROW date1 = TO_DATETIME("2023-12-02T11:00:00.000Z"), date2 = TO_DATETIME("2023-12-02T11:00:00.001Z") -| EVAL dd_ms = DATE_DIFF("microseconds", date1, date2) -``` - -In this example, the `DATE_DIFF` function is used to calculate the difference in microseconds between two timestamps. - -```esql -ROW date1 = TO_DATETIME("2023-12-02T11:00:00.000Z"), date2 = TO_DATETIME("2023-12-03T11:00:00.000Z") -| EVAL dd_days = DATE_DIFF("days", date1, date2) -``` - -In this second example, the `DATE_DIFF` function is used to calculate the difference in days between two timestamps. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_extract.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_extract.txt deleted file mode 100644 index 36c0272e3c479..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_extract.txt +++ /dev/null @@ -1,28 +0,0 @@ -## DATE_EXTRACT - -The `DATE_EXTRACT` function is used to extract specific parts of a date, such as the year, month, day, or hour. - -### Syntax - -`DATE_EXTRACT(datePart, date)` - -#### Parameters - -- `datePart`: Part of the date to extract. Can be: `aligned_day_of_week_in_month`, `aligned_day_of_week_in_year`, `aligned_week_of_month`, `aligned_week_of_year`, `ampm_of_day`, `clock_hour_of_ampm`, `clock_hour_of_day`, `day_of_month`, `day_of_week`, `day_of_year`, `epoch_day`, `era`, `hour_of_ampm`, `hour_of_day`, `instant_seconds`, `micro_of_day`, `micro_of_second`, `milli_of_day`, `milli_of_second`, `minute_of_day`, `minute_of_hour`, `month_of_year`, `nano_of_day`, `nano_of_second`, `offset_seconds`, `proleptic_month`, `second_of_day`, `second_of_minute`, `year`, or `year_of_era`. Refer to `java.time.temporal.ChronoField` for a description of these values. If null, the function returns null. -- `date`: Date expression. If null, the function returns null. - -### Examples - -The following ES|QL query uses the `DATE_EXTRACT` function to extract the year from a date: - -```esql -ROW date = DATE_PARSE("yyyy-MM-dd", "2022-05-06") -| EVAL year = DATE_EXTRACT("year", date) -``` - -This ES|QL query uses the `DATE_EXTRACT` function to find all events that occurred outside of business hours (before 9 AM or after 5 PM), on any given date: - -```esql -FROM sample_data -| WHERE DATE_EXTRACT("hour_of_day", @timestamp) < 9 AND DATE_EXTRACT("hour_of_day", @timestamp) >= 17 -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_format.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_format.txt deleted file mode 100644 index c2221c5add437..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_format.txt +++ /dev/null @@ -1,32 +0,0 @@ -## DATE_FORMAT - -The `DATE_FORMAT` function in ES|QL is used to return a string representation of a date, in the provided format. If no format is specified, the `yyyy-MM-dd'T'HH:mm:ss.SSSZ` format is used. - -### Syntax - -`DATE_FORMAT(dateFormat, date)` - -#### Parameters - -- `dateFormat`: Date format (optional). If no format is specified, the `yyyy-MM-dd'T'HH:mm:ss.SSSZ` format is used. If null, the function returns null. -- `date`: Date expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `DATE_FORMAT` function in your ES|QL queries: - -```esql -FROM employees -| KEEP first_name, last_name, hire_date -| EVAL hired = DATE_FORMAT("YYYY-MM-dd", hire_date) -``` - -In this example, the `DATE_FORMAT` function is used to format the `hire_date` field in the "YYYY-MM-dd" format. - -```esql -FROM logs-* -| WHERE @timestamp <= NOW() -| EVAL log_date = DATE_FORMAT("YYYY-MM-dd HH:mm:ss", @timestamp) -``` - -In this second example, the `DATE_FORMAT` function is used to format the `@timestamp` field in the "YYYY-MM-dd HH:mm:ss" format. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_parse.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_parse.txt deleted file mode 100644 index 0eab64ed4fcf2..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_parse.txt +++ /dev/null @@ -1,30 +0,0 @@ -## DATE_PARSE - -DATE_PARSE is a function in ES|QL that allows you to parse a date string using a specified format. This function is useful when you need to convert a string into a date format for further processing or analysis. - -### Syntax - -`DATE_PARSE(datePattern, dateString)` - -#### Parameters - -- `datePattern`: The date format. Refer to the DateTimeFormatter documentation for the syntax. If null, the function returns null. -- `dateString`: Date expression as a string. If null or an empty string, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the DATE_PARSE function in ES|QL queries: - -```esql -ROW date_string = "2022-05-06" -| EVAL date = DATE_PARSE("yyyy-MM-dd", date_string) -``` - -In this example, the DATE_PARSE function is used to convert the string "2022-05-06" into a date format using the "yyyy-MM-dd" pattern. - -```esql -ROW date_string = "06-05-2022" -| EVAL date = DATE_PARSE("dd-MM-yyyy", date_string) -``` - -In this second example, the DATE_PARSE function is used to convert the string "06-05-2022" into a date format using the "dd-MM-yyyy" pattern. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_trunc.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_trunc.txt deleted file mode 100644 index 5e8c1318fc2c3..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-date_trunc.txt +++ /dev/null @@ -1,43 +0,0 @@ -## DATE_TRUNC - -The `DATE_TRUNC` function in ES|QL rounds down a date to the closest interval. This can be useful for creating date histograms or calculating rates over specific time intervals. - -### Syntax - -`DATE_TRUNC(interval, date)` - -#### Parameters - -- `interval`: Interval; expressed using the timespan literal syntax. -- `date`: Date expression - -### Examples - -Here are a couple of examples of how you can use the `DATE_TRUNC` function in ES|QL queries: - -1. To round down the hire date of employees to the closest year and keep the first name, last name, and hire date: - -```esql -FROM employees -| KEEP first_name, last_name, hire_date -| EVAL year_hired = DATE_TRUNC(1 year, hire_date) -``` - -2. To create a date histogram showing the number of hires per year: - -```esql -FROM employees -| EVAL year = DATE_TRUNC(1 year, hire_date) -| STATS hires = COUNT(emp_no) BY year -| SORT year -``` - -3. To calculate an hourly error rate: - -```esql -FROM sample_data -| EVAL error = CASE(message LIKE "*error*", 1, 0) -| EVAL hour = DATE_TRUNC(1 hour, @timestamp) -| STATS error_rate = AVG(error) BY hour -| SORT hour -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-dissect.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-dissect.txt deleted file mode 100644 index ec764da51518b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-dissect.txt +++ /dev/null @@ -1,47 +0,0 @@ -## DISSECT - -The `DISSECT` command in ES|QL allows you to extract structured data from a string. It matches the string against a delimiter-based pattern and extracts the specified keys as columns. This can be particularly useful when you need to parse a string that contains multiple pieces of information, such as a timestamp, some text, and an IP address. - -### Syntax - -The syntax for the `DISSECT` command is as follows: - - -`DISSECT input "pattern" [APPEND_SEPARATOR=""]` - -Here, `input` is the column that contains the string you want to structure. If the column has multiple values, `DISSECT` will process each value. `pattern` is a dissect pattern that you want to match against the string. `` is an optional string used as the separator between appended values when using the append modifier. - -### Examples - -Here are some examples of how you can use the `DISSECT` command in ES|QL: - -**Example 1:** - -```esql -ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" -| DISSECT a "%{date} - %{msg} - %{ip}" -| KEEP date, msg, ip -``` - -In this example, the `DISSECT` command is used to parse a string that contains a timestamp, some text, and an IP address. The command matches the string against the pattern `"%{date} - %{msg} - %{ip}"` and extracts the date, message, and IP address as separate columns. - -**Example 2:** - -```esql -ROW a = "2023-01-23T12:15:00.000Z - some text - 127.0.0.1" -| DISSECT a "%{date} - %{msg} - %{ip}" -| KEEP date, msg, ip -| EVAL date = TO_DATETIME(date) -``` - -This example is similar to the first one, but it also includes a `TO_DATETIME` function to convert the `date` column to a datetime type. - -**Example 3:** - -```esql -ROW a = "John Doe - john.doe@example.com - 123 Main St" -| DISSECT a "%{name} - %{email} - %{address}" -| KEEP name, email, address -``` - -In this example, the `DISSECT` command is used to parse a string that contains a name, email address, and physical address. The command matches the string against the pattern `"%{name} - %{email} - %{address}"` and extracts the name, email, and address as separate columns. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-drop.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-drop.txt deleted file mode 100644 index 5484d69dd191e..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-drop.txt +++ /dev/null @@ -1,46 +0,0 @@ -## DROP - -The `DROP` command in ES|QL is used to remove one or more columns from the data. This can be useful in scenarios where certain columns are not needed for further data processing or analysis. - -The command supports the use of wildcards, allowing for the removal of all columns that match a specific pattern. This can be particularly useful when dealing with large datasets with numerous columns. - -### Syntax - -The syntax for the `DROP` command is as follows: - -``` -DROP columns -``` - -Here, `columns` is a comma-separated list of columns to be removed. Wildcards are supported. - -### Examples - -Here are some examples of how the `DROP` command can be used in ES|QL queries: - -1. Removing a single column: - -```esql -FROM employees -| DROP height -``` - -In this example, the `height` column is removed from the `employees` data. - -2. Removing multiple columns: - -```esql -FROM employees -| DROP height, weight, age -``` - -Here, the `height`, `weight`, and `age` columns are all removed from the `employees` data. - -3. Using wildcards to remove all columns that match a pattern: - -```esql -FROM employees -| DROP height* -``` - -In this example, all columns that start with `height` are removed from the `employees` data. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-e.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-e.txt deleted file mode 100644 index 10bb5d6cd667b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-e.txt +++ /dev/null @@ -1,19 +0,0 @@ -## E - -The `E` function in ES|QL returns Euler's number. - -### Examples - -Here are a couple of examples of how you can use the `E` function in ES|QL queries: - -```esql -ROW E() -``` - -This query simply returns the Euler's number. - -```esql -ROW a = E() -``` - -This query assigns the Euler's number to a variable `a`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ends_with.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ends_with.txt deleted file mode 100644 index 0ea4ca64a5245..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ends_with.txt +++ /dev/null @@ -1,33 +0,0 @@ -## ENDS_WITH - -The `ENDS_WITH` function in ES|QL is used to check if a keyword string ends with another string. It returns a boolean value indicating the result of this check. - -### Syntax - -The syntax for using the `ENDS_WITH` function is as follows: - -`ENDS_WITH(str, suffix)` - -#### Parameters - -- `str`: This is a string expression. If null, the function returns null. -- `suffix`: This is a string expression. If null, the function returns null. - -### Examples - -Here are a couple of examples showing how to use the `ENDS_WITH` function in ES|QL queries: - -```esql -FROM employees -| KEEP last_name -| EVAL ln_E = ENDS_WITH(last_name, "d") -``` - -In this example, the `ENDS_WITH` function is used to check if the `last_name` of employees ends with the letter "d". The result is stored in the `ln_E` field. - -```esql -FROM logs-* -| WHERE ENDS_WITH(file_path, ".log") -``` - -In this second example, the `ENDS_WITH` function is used in a `WHERE` clause to filter out logs that don't have a file path ending with ".log". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-enrich.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-enrich.txt deleted file mode 100644 index c18a8cddbcb86..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-enrich.txt +++ /dev/null @@ -1,50 +0,0 @@ -## ENRICH - -The `ENRICH` command in ES|QL allows you to add data from existing indices as new columns using an enrich policy. This can be particularly useful when you need to supplement your query data with additional information stored in other indices. - -Before you can use `ENRICH`, you need to create and execute an enrich policy. Refer to the [Data enrichment](https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html) documentation for information about setting up a policy. - -Please note that in case of name collisions, the newly created columns will override existing columns. - -### Syntax - -`ENRICH policy [ON match_field] [WITH [new_name1 = ]field1, [new_name2 = ]field2, ...]` - -#### Parameters - -- `policy`: The name of the enrich policy. You need to create and execute the enrich policy first. -- `match_field`: The match field. ENRICH uses its value to look for records in the enrich index. If not specified, the match will be performed on the column with the same name as the match_field defined in the enrich policy. -- `fieldX`: The enrich fields from the enrich index that are added to the result as new columns. If a column with the same name as the enrich field already exists, the existing column will be replaced by the new column. If not specified, each of the enrich fields defined in the policy is added. -- `new_nameX`: Enables you to change the name of the column that’s added for each of the enrich fields. Defaults to the enrich field name. - -### Examples - -The following examples showcase different usages of the `ENRICH` command: - -1. Using the `languages_policy` enrich policy to add a new column for each enrich field defined in the policy. The match is performed using the `match_field` defined in the enrich policy and requires that the input table has a column with the same name (`language_code` in this example). - -```esql -ROW language_code = "1" -| ENRICH languages_policy -``` - -2. Using a column with a different name than the `match_field` defined in the policy as the match field: - -```esql -ROW a = "1" -| ENRICH languages_policy ON a -``` - -3. Explicitly selecting the enrich fields that are added using `WITH , , ...`: - -```esql -ROW a = "1" -| ENRICH languages_policy ON a WITH language_name -``` - -4. Renaming the columns that are added using `WITH new_name=`: - -```esql -ROW a = "1" -| ENRICH languages_policy ON a WITH name = language_name -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-eval.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-eval.txt deleted file mode 100644 index f98b4987a9e06..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-eval.txt +++ /dev/null @@ -1,44 +0,0 @@ -## EVAL - -The `EVAL` command in ES|QL allows you to append new columns with calculated values to your data. It supports various functions for calculating these values. This command is particularly useful when you need to perform calculations on your data and store the results in new columns for further analysis or visualization. - -However, it's important to note that if the specified column already exists, the existing column will be dropped, and the new column will be appended to the table. - -### Examples - -Here are some examples of how you can use the `EVAL` command in ES|QL: - -1. Calculate the height of employees in feet and centimeters and store the results in new columns: - - ```esql -FROM employees -| SORT emp_no -| KEEP first_name, last_name, height -| EVAL height_feet = height * 3.281, height_cm = height * 100 -``` - -2. Overwrite an existing column with new calculated values: - - ```esql -FROM employees -| SORT emp_no -| KEEP first_name, last_name, height -| EVAL height = height * 3.281 -``` - -3. Add a new column with a name that is equal to the expression: - - ```esql -FROM employees -| SORT emp_no -| KEEP first_name, last_name, height -| EVAL height * 3.281 -``` - - Since this name contains special characters, it needs to be quoted with backticks (`) when using it in subsequent commands: - - ```esql -FROM employees -| EVAL height * 3.281 -| STATS avg_height_feet = AVG(`height * 3.281`) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-floor.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-floor.txt deleted file mode 100644 index 7daabcc3954f3..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-floor.txt +++ /dev/null @@ -1,29 +0,0 @@ -## FLOOR - -The `FLOOR` function in ES|QL is used to round a number down to the nearest integer. This operation is a no-op for long (including unsigned) and integer types. For double types, this function picks the closest double value to the integer, similar to the `Math.floor` function in JavaScript. - -### Syntax - -`FLOOR(number)` - -#### Parameters - -- `number`: Numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `FLOOR` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL a = FLOOR(a) -``` - -In this example, the `FLOOR` function is used to round down the value of `a` (1.8) to the nearest integer (1). - -```esql -ROW b=3.14159 -| EVAL b = FLOOR(b) -``` - -In this second example, the `FLOOR` function is used to round down the value of `b` (3.14159) to the nearest integer (3). \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from.txt deleted file mode 100644 index 98548000a334e..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from.txt +++ /dev/null @@ -1,53 +0,0 @@ -## FROM - -The `FROM` command in ES|QL is a source command that returns a table with data from a data stream, index, or alias. Each row in the resulting table represents a document, and each column corresponds to a field, which can be accessed by the name of that field. - -By default, an ES|QL query without an explicit `LIMIT` uses an implicit limit of 1000. This applies to `FROM` too. For example, a `FROM` command without `LIMIT`: - -```esql -FROM employees -``` - -is executed as: - -```esql -FROM employees -| LIMIT 1000 -``` - -You can use date math to refer to indices, aliases and data streams, which can be useful for time series data. For example, to access today’s index: - -```esql -FROM -``` - -You can use comma-separated lists or wildcards to query multiple data streams, indices, or aliases: - -```esql -FROM employees-00001,other-employees-* -``` - -You can also use the format `:` to query data streams and indices on remote clusters: - -```esql -FROM cluster_one:employees-00001,cluster_two:other-employees-* -``` - -The optional `METADATA` directive can be used to enable metadata fields: - -```esql -FROM employees METADATA _id -``` - -### Syntax - -`FROM index_pattern [METADATA fields]` - -#### Parameters - -- `index_pattern`: A list of indices, data streams or aliases. Supports wildcards and date math. -- `fields`: A comma-separated list of metadata fields to retrieve. - -### Limitations - -Please note that the `FROM` command does not support querying time series data streams (TSDS). For more details on the limitations of ES|QL, refer to the [ES|QL limitations](https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-limitations.html) documentation. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from_base64.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from_base64.txt deleted file mode 100644 index 7e7c6b8ee3ab7..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-from_base64.txt +++ /dev/null @@ -1,19 +0,0 @@ -## FROM_BASE64 - -FROM_BASE64 function decodes a base64 string. - -### Examples - -Here are a couple of examples of full ES|QL queries using the FROM_BASE64 function: - -Example 1: -```esql -ROW a = "ZWxhc3RpYw==" -| EVAL d = FROM_BASE64(a) -``` - -Example 2: -```esql -ROW b = "SGVsbG8gd29ybGQ=" -| EVAL e = FROM_BASE64(b) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-greatest.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-greatest.txt deleted file mode 100644 index 5ab87d292bea4..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-greatest.txt +++ /dev/null @@ -1,30 +0,0 @@ -## GREATEST - -The `GREATEST` function in ES|QL returns the maximum value from multiple columns. This function is similar to `MV_MAX` but is intended to run on multiple columns at once. When run on keyword or text fields, this function returns the last string in alphabetical order. When run on boolean columns, this function will return true if any values are true. - -### Syntax - -`GREATEST(first, rest)` - -#### Parameters - -- `first`: First of the columns to evaluate. -- `rest`: The rest of the columns to evaluate. - -### Examples - -Here are a couple of examples of how to use the `GREATEST` function in ES|QL: - -```esql -ROW a = 10, b = 20 -| EVAL g = GREATEST(a, b) -``` - -In this example, the `GREATEST` function is used to find the maximum value between the columns `a` and `b`. - -```esql -ROW a = 10, b = 20, c = 30, d = 40 -| EVAL g = GREATEST(a, b, c, d) -``` - -In this example, the `GREATEST` function is used to find the maximum value among the columns `a`, `b`, `c`, and `d`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-grok.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-grok.txt deleted file mode 100644 index 9c5e1354e681c..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-grok.txt +++ /dev/null @@ -1,42 +0,0 @@ -## GROK - -The `GROK` command in ES|QL enables you to extract structured data out of a string. It matches the string against patterns, based on regular expressions, and extracts the specified patterns as columns. This can be particularly useful when you need to parse a string that contains multiple pieces of information, such as a timestamp, an IP address, an email address, and a number. - -### Limitations - -By default, `GROK` outputs keyword string columns. Integer (`int`) and float types can be converted by appending `:type` to the semantics in the pattern. For other type conversions, you need to use Type conversion functions. - -### Examples - -Here are some examples of how you can use the `GROK` command in ES|QL: - -**Example 1: Parsing a string with multiple pieces of information** - -```esql -ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" -| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num}" -| KEEP date, ip, email, num -``` - -In this example, the `GROK` command is used to parse a string that contains a timestamp, an IP address, an email address, and a number. The `KEEP` command is then used to keep only the extracted date, IP, email, and number columns. - -**Example 2: Converting types with GROK** - -```esql -ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" -| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}" -| KEEP date, ip, email, num -``` - -In this example, the `GROK` command is used similarly to the first example, but with an additional `:int` appended to the `NUMBER` semantic in the pattern. This converts the extracted number to an integer type. - -**Example 3: Using type conversion functions with GROK** - -```esql -ROW a = "2023-01-23T12:15:00.000Z 127.0.0.1 some.email@foo.com 42" -| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}" -| KEEP date, ip, email, num -| EVAL date = TO_DATETIME(date) -``` - -In this example, the `GROK` command is used to parse a string and convert the extracted number to an integer type. Then, the `EVAL` command is used with the `TO_DATETIME` function to convert the extracted date string to a datetime type. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-keep.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-keep.txt deleted file mode 100644 index d51104612b7cb..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-keep.txt +++ /dev/null @@ -1,48 +0,0 @@ -## KEEP - -The `KEEP` command in ES|QL allows you to specify which columns are returned and the order in which they are returned. This can be particularly useful when you want to focus on specific data in your Elasticsearch indices and ignore the rest. - -The command supports wildcards, allowing you to match and return all columns with a name that fits a certain pattern. Precedence rules are applied when a field name matches multiple expressions. If a field matches two expressions with the same precedence, the right-most expression wins. - -### Limitations - -There are no known limitations for the `KEEP` command in ES|QL. - -### Examples - -Here are some examples of how you can use the `KEEP` command in ES|QL: - -1. Return specified columns in the order they are listed: - -```esql -FROM employees -| KEEP emp_no, first_name, last_name, height -``` - -2. Use wildcards to return all columns with a name that matches a pattern: - -```esql -FROM employees -| KEEP h* -``` - -3. Use the asterisk wildcard by itself to return all columns that do not match the other arguments: - -```esql -FROM employees -| KEEP h*, * -``` - -4. Show how precedence rules work when a field name matches multiple expressions: - -```esql -FROM employees -| KEEP first_name*, last_name, first_na* -``` - -5. Use a simple wildcard expression `*` which has the lowest precedence: - -```esql -FROM employees -| KEEP *, first_name -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-least.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-least.txt deleted file mode 100644 index 4c34db4d38e01..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-least.txt +++ /dev/null @@ -1,30 +0,0 @@ -## LEAST - -The `LEAST` function in ES|QL is used to return the minimum value from multiple columns. This function is similar to `MV_MIN` but is intended to run on multiple columns at once. - -### Syntax - -`LEAST(first, rest)` - -#### Parameters - -- `first`: The first column to evaluate. -- `rest`: The rest of the columns to evaluate. - -### Examples - -Here are a couple of examples of how to use the `LEAST` function in ES|QL: - -```esql -ROW a = 10, b = 20 -| EVAL l = LEAST(a, b) -``` - -In this example, the `LEAST` function is used to find the minimum value between the columns `a` and `b`. - -```esql -ROW a = 10, b = 20, c = 30, d = 40 -| EVAL l = LEAST(a, b, c, d) -``` - -In this second example, the `LEAST` function is used to find the minimum value among four columns: `a`, `b`, `c`, and `d`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-left.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-left.txt deleted file mode 100644 index e62a50ae7a273..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-left.txt +++ /dev/null @@ -1,33 +0,0 @@ -## LEFT - -The `LEFT` function in ES|QL is used to extract a substring from a string, starting from the left. The number of characters to return is specified by the `length` parameter. - -### Syntax - -`LEFT(string, length)` - -#### Parameters - -- `string`: The string from which to return a substring. -- `length`: The number of characters to return. - -### Examples - -Here are a couple of examples of how to use the `LEFT` function in ES|QL: - -```esql -FROM employees -| KEEP last_name -| EVAL left = LEFT(last_name, 3) -| SORT last_name ASC -| LIMIT 5 -``` - -In this example, the `LEFT` function is used to extract the first three characters from the `last_name` field of the `employees` index. The query then sorts the results in ascending order by `last_name` and limits the output to the first 5 records. - -```esql -FROM logs-* -| EVAL left_chars = LEFT(message, 10) -``` - -In this second example, the `LEFT` function is used to extract the first 10 characters from the `message` field of the `logs-*` index. The result is stored in the `left_chars` field. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-length.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-length.txt deleted file mode 100644 index 8ed8bf3f31a2c..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-length.txt +++ /dev/null @@ -1,29 +0,0 @@ -## LENGTH - -The `LENGTH` function in ES|QL is used to return the character length of a string. - -### Syntax - -`LENGTH(string)` - -#### Parameters - -- `string`: This is a string expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `LENGTH` function in ES|QL: - -```esql -FROM employees -| EVAL name_length = LENGTH(first_name) -``` - -In this example, the `LENGTH` function is used to calculate the length of the `first_name` field for each record in the `employees` index. - -```esql -FROM logs-* -| EVAL message_length = LENGTH(message) -``` - -In this second example, the `LENGTH` function is used to calculate the length of the `message` field for each record in the `logs-*` index. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-limit.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-limit.txt deleted file mode 100644 index 4d0dce6fe6edd..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-limit.txt +++ /dev/null @@ -1,42 +0,0 @@ -## LIMIT - -The `LIMIT` command in ES|QL is a processing command that allows you to limit the number of rows that are returned in a query. This can be particularly useful in scenarios where you only need a specific number of rows from a larger dataset. - -However, it's important to note that queries do not return more than 10,000 rows, regardless of the `LIMIT` command’s value. This limit only applies to the number of rows that are retrieved by the query. Queries and aggregations run on the full data set. - -To overcome this limitation, you can: - -- Reduce the result set size by modifying the query to only return relevant data. Use `WHERE` to select a smaller subset of the data. -- Shift any post-query processing to the query itself. You can use the ES|QL `STATS ... BY` command to aggregate data in the query. - -The default and maximum limits can be changed using these dynamic cluster settings: - -- `esql.query.result_truncation_default_size` -- `esql.query.result_truncation_max_size` - -### Examples - -Here are some examples of how you can use the `LIMIT` command in ES|QL: - -1. Limit the number of rows returned to 5, sorted by employee number in ascending order: - - ```esql -FROM employees -| SORT emp_no ASC -| LIMIT 5 -``` - -2. Retrieve only the top 10 employees with the highest salary: - - ```esql -FROM employees -| SORT salary DESC -| LIMIT 10 -``` - -3. Get the first 100 rows from a logs data stream: - - ```esql -FROM logs-* -| LIMIT 100 -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-locate.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-locate.txt deleted file mode 100644 index 605a287841440..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-locate.txt +++ /dev/null @@ -1,35 +0,0 @@ -## LOCATE - -LOCATE function in ES|QL returns an integer that indicates the position of a keyword substring within another string. - -### Syntax - -`LOCATE(string, substring, start)` - -#### Parameters - -- `string`: An input string -- `substring`: A substring to locate in the input string -- `start`: The start index - -### Examples - -Here are a couple of examples of how you can use the LOCATE function in ES|QL: - -Example 1: - -```esql -ROW a = "hello" -| EVAL a_ll = LOCATE(a, "ll") -``` - -In this example, the LOCATE function is used to find the position of the substring "ll" in the string "hello". The result would be `3` as "ll" starts at the third position in the string "hello". - -Example 2: - -```esql -ROW a = "Elasticsearch Query Language" -| EVAL a_ll = LOCATE(a, "Query", 5) -``` - -In this example, the LOCATE function is used to find the position of the substring "Query" in the string "Elasticsearch Query Language", starting from the fifth position. The result would be `14` as "Query" starts at the fourteenth position in the string "Elasticsearch Query Language". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log.txt deleted file mode 100644 index 69a19c5578f14..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log.txt +++ /dev/null @@ -1,30 +0,0 @@ -## LOG - -The `LOG` function in ES|QL returns the logarithm of a value to a base. The input can be any numeric value, and the return value is always a double. Logs of zero, negative numbers, and base of one return null as well as a warning. - -### Syntax - -`LOG(base, number)` - -#### Parameters - -- `base`: Base of logarithm. If null, the function returns null. If not provided, this function returns the natural logarithm (base e) of a value. -- `number`: Numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `LOG` function: - -```esql -ROW base = 2.0, value = 8.0 -| EVAL s = LOG(base, value) -``` - -In this example, the `LOG` function is used to calculate the logarithm of `8.0` to the base `2.0`. - -```esql -ROW value = 100 -| EVAL s = LOG(value) -``` - -In this example, the `LOG` function is used to calculate the natural logarithm (base e) of `100` as no base is provided. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log10.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log10.txt deleted file mode 100644 index 78a0b43a087a8..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-log10.txt +++ /dev/null @@ -1,21 +0,0 @@ -## LOG10 - -The `LOG10` function in ES|QL is used to calculate the logarithm of a value to the base 10. The input can be any numeric value and the return value is always a double. If the input is 0 or a negative number, the function returns null and a warning. - -### Examples - -Here are a couple of examples of how you can use the `LOG10` function in ES|QL queries: - -```esql -ROW d = 1000.0 -| EVAL s = LOG10(d) -``` - -In this example, the `LOG10` function is used to calculate the base 10 logarithm of the value 1000. The result is stored in the variable `s`. - -```esql -ROW d = 100.0 -| EVAL s = LOG10(d) -``` - -In this example, the `LOG10` function is used to calculate the base 10 logarithm of the value 100. The result is stored in the variable `s`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-lookup.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-lookup.txt deleted file mode 100644 index 46dc960ac1332..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-lookup.txt +++ /dev/null @@ -1,82 +0,0 @@ -## LOOKUP - -The `LOOKUP` command in ES|QL is a highly experimental feature that is currently only available in SNAPSHOT versions. This command is used to match values from the input against a table provided in the request, adding the other fields from the table to the output. - -### Use Cases and Limitations - -The `LOOKUP` command is particularly useful when you need to match and compare data from different sources or tables. It allows you to enrich your query results with additional data from a separate table based on matching fields. - -However, it's important to note that this command is still in the experimental stage and may not be fully stable or support all use cases. It's recommended to use this command in testing environments and not in production. - -### Examples - -Here are some examples of how to use the `LOOKUP` command in ES|QL: - -**Example 1:** - -``` -POST /_query?format=txt -{ - "query": """ - FROM library - | SORT page_count DESC - | KEEP name, author - | LOOKUP era ON author - | LIMIT 5 - """ - "tables": { - "era": { - "author:keyword": ["Frank Herbert", "Peter F. Hamilton", "Vernor Vinge", "Alastair Reynolds", "James S.A. Corey"], - "era:keyword" : [ "The New Wave", "Diamond", "Diamond", "Diamond", "Hadron"] - } - } -} -``` - -In this example, the `LOOKUP` command is used to match the `author` field from the `library` index with the `author` field in the `era` table. The matched data is then added to the output. - -**Example 2:** - -``` -POST /_query?format=txt -{ - "query": """ - FROM employees - | SORT salary DESC - | KEEP name, department - | LOOKUP departments ON department - | LIMIT 10 - """ - "tables": { - "departments": { - "department:keyword": ["Sales", "Marketing", "HR", "Engineering"], - "location:keyword" : [ "New York", "San Francisco", "London", "Berlin"] - } - } -} -``` - -In this example, the `LOOKUP` command is used to match the `department` field from the `employees` index with the `department` field in the `departments` table. The matched data is then added to the output. - -**Example 3:** - -``` -POST /_query?format=txt -{ - "query": """ - FROM orders - | SORT order_date DESC - | KEEP order_id, product_id - | LOOKUP products ON product_id - | LIMIT 20 - """ - "tables": { - "products": { - "product_id:keyword": ["P001", "P002", "P003", "P004"], - "product_name:keyword" : [ "Product 1", "Product 2", "Product 3", "Product 4"] - } - } -} -``` - -In this example, the `LOOKUP` command is used to match the `product_id` field from the `orders` index with the `product_id` field in the `products` table. The matched data is then added to the output. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ltrim.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ltrim.txt deleted file mode 100644 index 9a6b50d702a98..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-ltrim.txt +++ /dev/null @@ -1,29 +0,0 @@ -## LTRIM - -The `LTRIM` function is used to remove leading whitespaces from a string. - -### Syntax - -`LTRIM(string)` - -#### Parameters - -- `string`: String expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `LTRIM` function in ES|QL queries: - -```esql -ROW message = " some text " -| EVAL trimmed_message = LTRIM(message) -``` - -In this example, the `LTRIM` function is used to remove the leading whitespaces from the `message` string. - -```esql -ROW color = " red " -| EVAL trimmed_color = LTRIM(color) -``` - -In this example, the `LTRIM` function is used to remove the leading whitespace from the `color` string. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-max.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-max.txt deleted file mode 100644 index 32dad967274d8..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-max.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MAX - -The `MAX` function in ES|QL is used to return the maximum value of a numeric expression. - -### Syntax - -`MAX(expression)` - -#### Parameters - -`expression`: The expression from which to return the maximum value. - -### Examples - -Here are a couple of examples of how the `MAX` function can be used in ES|QL queries: - -1. To find the maximum value in the `languages` field from the `employees` index, you can use the following query: - -```esql -FROM employees -| STATS MAX(languages) -``` - -2. The `MAX` function can also be used with inline functions. For instance, to calculate the maximum over an average of a multivalued column, you can first use the `MV_AVG` function to average the multiple values per row, and then use the result with the `MAX` function: - -```esql -FROM employees -| STATS max_avg_salary_change = MAX(MV_AVG(salary_change)) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median.txt deleted file mode 100644 index b4a8810047d41..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median.txt +++ /dev/null @@ -1,21 +0,0 @@ -## MEDIAN - -The `MEDIAN` function in ES|QL returns the value that is greater than half of all values and less than half of all values, also known as the 50% PERCENTILE. Like `PERCENTILE`, `MEDIAN` is usually approximate and is also non-deterministic. This means you can get slightly different results using the same data. - -### Examples - -Here are a couple of examples of how to use the `MEDIAN` function in ES|QL: - -```esql -FROM employees -| STATS MEDIAN(salary), PERCENTILE(salary, 50) -``` - -In this example, the `MEDIAN` function is used to calculate the median salary from the `employees` data stream or index. - -```esql -FROM employees -| STATS median_max_salary_change = MEDIAN(MV_MAX(salary_change)) -``` - -In this example, the `MEDIAN` function is used in conjunction with the `MV_MAX` function to calculate the median of the maximum values of a multivalued column `salary_change`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median_absolute_deviation.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median_absolute_deviation.txt deleted file mode 100644 index 1ef1732218e11..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-median_absolute_deviation.txt +++ /dev/null @@ -1,33 +0,0 @@ -## MEDIAN_ABSOLUTE_DEVIATION - -The `MEDIAN_ABSOLUTE_DEVIATION` function is a robust statistic that is useful for describing data that may have outliers or may not be normally distributed. It provides a measure of variability by calculating the median of each data point’s deviation from the median of the entire sample. - -This function is usually approximate and non-deterministic, meaning that you can get slightly different results using the same data. - -### Syntax: - -`MEDIAN_ABSOLUTE_DEVIATION(expression)` - -#### Parameters: - -- `expression`: Expression from which to return the median absolute deviation. - -### Examples: - -Here is an example of a complete ES|QL query using the `MEDIAN_ABSOLUTE_DEVIATION` function: - -```esql -FROM employees -| STATS MEDIAN(salary), MEDIAN_ABSOLUTE_DEVIATION(salary) -``` - -In this query, the `MEDIAN_ABSOLUTE_DEVIATION` function is used to calculate the median absolute deviation of the `salary` field for the `employees` index. - -The `MEDIAN_ABSOLUTE_DEVIATION` function can also be used with inline functions. Here is an example where it is used with the `MV_MAX` function to calculate the median absolute deviation of the maximum values of a multivalued column: - -```esql -FROM employees -| STATS m_a_d_max_salary_change = MEDIAN_ABSOLUTE_DEVIATION(MV_MAX(salary_change)) -``` - -In this query, the `MV_MAX` function is first used to get the maximum value per row of the `salary_change` field. The result is then used with the `MEDIAN_ABSOLUTE_DEVIATION` function to calculate the median absolute deviation. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-min.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-min.txt deleted file mode 100644 index 737a21bb6cd99..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-min.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MIN - -The `MIN` function in ES|QL is used to return the minimum value of a numeric expression. - -### Syntax: - -`MIN(expression)` - -#### Parameters: - -`expression`: The expression from which to return the minimum value. - -### Examples: - -Here are a couple of examples of how you can use the `MIN` function in ES|QL: - -1. To find the minimum value of a field, you can use the `MIN` function directly. For example, the following query returns the minimum value of the `languages` field from the `employees` index: - -```esql -FROM employees -| STATS MIN(languages) -``` - -2. You can also use the `MIN` function with other functions like `MV_AVG` to perform more complex calculations. For example, the following query calculates the average of a multivalued column `salary_change` for each row, and then finds the minimum of these averages: - -```esql -FROM employees -| STATS min_avg_salary_change = MIN(MV_AVG(salary_change)) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_avg.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_avg.txt deleted file mode 100644 index 1dcdf012ef0db..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_avg.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MV_AVG - -The `MV_AVG` function in ES|QL converts a multivalued field into a single valued field containing the average of all of the values. - -### Syntax - -`MV_AVG(number)` - -#### Parameters - -`number`: Multivalue expression. - -### Examples - -Here are a couple of examples of how you can use the `MV_AVG` function in your ES|QL queries: - -```esql -ROW a=[3, 5, 1, 6] -| EVAL avg_a = MV_AVG(a) -``` - -In this example, the `MV_AVG` function is used to calculate the average of the values in the multivalued field `a`. - -```esql -ROW b=[10, 20, 30, 40] -| EVAL avg_b = MV_AVG(b) -``` - -In this second example, the `MV_AVG` function is used to calculate the average of the values in the multivalued field `b`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_concat.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_concat.txt deleted file mode 100644 index f2699a0ac7a87..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_concat.txt +++ /dev/null @@ -1,23 +0,0 @@ -## MV_CONCAT - -The `MV_CONCAT` function in ES|QL converts a multivalued string expression into a single valued column. It does this by concatenating all values separated by a specified delimiter. - -### Examples - -Here are a couple of examples of how you can use the `MV_CONCAT` function in your ES|QL queries: - -```esql -ROW a=["foo", "zoo", "bar"] -| EVAL j = MV_CONCAT(a, ", ") -``` - -In this example, the `MV_CONCAT` function is used to concatenate the values in the array `a` with a comma separator. The result is a single string `"foo, zoo, bar"`. - -If you need to concatenate non-string columns, you can use the `TO_STRING` function first: - -```esql -ROW a=[10, 9, 8] -| EVAL j = MV_CONCAT(TO_STRING(a), ", ") -``` - -In this case, the numeric values in the array `a` are first converted to strings using the `TO_STRING` function. Then, the `MV_CONCAT` function concatenates these string values with a comma separator. The result is a single string `"10, 9, 8"`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_count.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_count.txt deleted file mode 100644 index 1ba65c3d81fbf..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_count.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MV_COUNT - -The `MV_COUNT` function in ES|QL is used to convert a multivalued expression into a single valued column containing a count of the number of values. - -### Syntax - -The syntax for using the `MV_COUNT` function is as follows: - -`MV_COUNT(field)` - -Here, `field` is a multivalue expression. - -### Examples - -Here are a couple of examples demonstrating the use of the `MV_COUNT` function: - -```esql -ROW a=["foo", "zoo", "bar"] -| EVAL count_a = MV_COUNT(a) -``` - -In this example, the `MV_COUNT` function is used to count the number of values in the array `["foo", "zoo", "bar"]`, and the result is stored in the `count_a` column. - -```esql -ROW b=[1, 2, 3, 4, 5] -| EVAL count_b = MV_COUNT(b) -``` - -In this second example, the `MV_COUNT` function is used to count the number of values in the array `[1, 2, 3, 4, 5]`, and the result is stored in the `count_b` column. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_dedupe.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_dedupe.txt deleted file mode 100644 index 32726e09767dd..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_dedupe.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MV_DEDUPE - -The `MV_DEDUPE` function is used to remove duplicate values from a multivalued field. It's important to note that while `MV_DEDUPE` may sort the values in the column, it's not guaranteed to always do so. - -### Syntax - -`MV_DEDUPE(field)` - -#### Parameters - -- `field`: Multivalue expression. - -### Examples - -Here are a couple of examples of how you can use the `MV_DEDUPE` function in your ES|QL queries: - -```esql -ROW a=["foo", "foo", "bar", "foo"] -| EVAL dedupe_a = MV_DEDUPE(a) -``` - -In this example, the `MV_DEDUPE` function is used to remove duplicate values from the multivalued field `a`. The resulting `dedupe_a` field will contain the values `["foo", "bar"]`. - -```esql -ROW b=["apple", "banana", "apple", "orange", "banana"] -| EVAL dedupe_b = MV_DEDUPE(b) -``` - -In this second example, the `MV_DEDUPE` function is used to remove duplicate values from the multivalued field `b`. The resulting `dedupe_b` field will contain the values `["apple", "banana", "orange"]`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_expand.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_expand.txt deleted file mode 100644 index 9a3195a115713..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_expand.txt +++ /dev/null @@ -1,41 +0,0 @@ -## MV_EXPAND - -The `MV_EXPAND` command in ES|QL is a processing command that expands multivalued columns into one row per value, duplicating other columns. This command is particularly useful when dealing with data that contains multivalued fields and you want to create a separate row for each value in the multivalued field. - -This functionality is currently 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 - -`MV_EXPAND column` - -#### Parameters - -`column` -The multivalued column to expand. - -### Examples - -Here are some examples of how you can use the `MV_EXPAND` command in ES|QL: - -1. Expanding a multivalued column 'a': - -```esql -ROW a=[1,2,3], b="b" -| MV_EXPAND a -``` - -2. Expanding a multivalued column 'languages': - -```esql -FROM employees -| MV_EXPAND languages -``` - -3. Expanding a multivalued column 'tags': - -```esql -FROM blog_posts -| MV_EXPAND tags -``` - -In each of these examples, the `MV_EXPAND` command creates a new row for each value in the specified multivalued column. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_first.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_first.txt deleted file mode 100644 index fc901d41319e8..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_first.txt +++ /dev/null @@ -1,31 +0,0 @@ -## MV_FIRST - -The `MV_FIRST` function in ES|QL is used to convert a multivalued expression into a single valued column containing the first value. This function is most useful when reading from a function that emits multivalued columns in a known order like `SPLIT`. - -It's important to note that the order that multivalued fields are read from underlying storage is not guaranteed. It is frequently ascending, but this should not be relied upon. If you need the minimum value, use `MV_MIN` instead of `MV_FIRST`. `MV_MIN` has optimizations for sorted values so there isn’t a performance benefit to `MV_FIRST`. - -### Syntax: - -`MV_FIRST(field)` - -#### Parameters: - -- `field`: Multivalue expression. - -### Examples: - -Here are a couple of examples of how you can use the `MV_FIRST` function in your ES|QL queries: - -```esql -ROW a="foo;bar;baz" -| EVAL first_a = MV_FIRST(SPLIT(a, ";")) -``` - -In this example, the `SPLIT` function is used to split the string "foo;bar;baz" into a multivalued field. The `MV_FIRST` function is then used to select the first value from this multivalued field. - -```esql -ROW numbers=[10, 20, 30, 40, 50] -| EVAL first_num = MV_FIRST(numbers) -``` - -In this second example, the `MV_FIRST` function is used to select the first value from the multivalued field "numbers". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_last.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_last.txt deleted file mode 100644 index 2abfbb5a65ee1..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_last.txt +++ /dev/null @@ -1,23 +0,0 @@ -## MV_LAST - -The `MV_LAST` function in ES|QL is used to convert a multivalue expression into a single valued column containing the last value. This function is most useful when reading from a function that emits multivalued columns in a known order like `SPLIT`. - -It's important to note that the order that multivalued fields are read from underlying storage is not guaranteed. It is frequently ascending, but this should not be relied upon. If you need the maximum value, it is recommended to use `MV_MAX` instead of `MV_LAST`. `MV_MAX` has optimizations for sorted values so there isn’t a performance benefit to `MV_LAST`. - -### Examples - -Here are a couple of examples of how you can use the `MV_LAST` function in your ES|QL queries: - -```esql -ROW a="foo;bar;baz" -| EVAL last_a = MV_LAST(SPLIT(a, ";")) -``` - -In this example, the `SPLIT` function is used to split the string "foo;bar;baz" into a multivalue expression. The `MV_LAST` function is then used to select the last value from this multivalue expression. - -```esql -ROW numbers="1;2;3;4;5" -| EVAL last_number = MV_LAST(SPLIT(numbers, ";")) -``` - -In this second example, the `SPLIT` function is used to split the string "1;2;3;4;5" into a multivalue expression. The `MV_LAST` function is then used to select the last value from this multivalue expression. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_max.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_max.txt deleted file mode 100644 index 709a1e1b747c5..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_max.txt +++ /dev/null @@ -1,23 +0,0 @@ -## MV_MAX - -The `MV_MAX` function in ES|QL is used to convert a multivalued expression into a single valued column containing the maximum value. This function can be used with any column type, including keyword columns. In the case of keyword columns, it picks the last string, comparing their utf-8 representation byte by byte. - -### Examples - -Here are a couple of examples of how you can use the `MV_MAX` function in ES|QL: - -1. To find the maximum value in a multivalued numeric field: - -```esql -ROW a=[3, 5, 1] -| EVAL max_a = MV_MAX(a) -``` - -2. To find the last string in a multivalued keyword field: - -```esql -ROW a=["foo", "zoo", "bar"] -| EVAL max_a = MV_MAX(a) -``` - -In both examples, the `MV_MAX` function is used to find the maximum value in the multivalued field `a`. The result is stored in the new field `max_a`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_median.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_median.txt deleted file mode 100644 index 5b66fa243c009..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_median.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MV_MEDIAN - -The `MV_MEDIAN` function in ES|QL converts a multivalued field into a single valued field containing the median value. If the row has an even number of values for a column, the result will be the average of the middle two entries. If the column is not floating point, the average rounds down. - -### Syntax - -`MV_MEDIAN(number)` - -#### Parameters - -`number`: Multivalue expression. - -### Examples - -Here are a couple of examples of how you can use the `MV_MEDIAN` function in ES|QL queries: - -```esql -ROW a=[3, 5, 1] -| EVAL median_a = MV_MEDIAN(a) -``` - -In this example, the `MV_MEDIAN` function calculates the median of the values in the `a` array, which are `[3, 5, 1]`. The median value is `3`. - -```esql -ROW a=[3, 7, 1, 6] -| EVAL median_a = MV_MEDIAN(a) -``` - -In this example, the `MV_MEDIAN` function calculates the median of the values in the `a` array, which are `[3, 7, 1, 6]`. Since there is an even number of values, the function calculates the average of the middle two entries, which results in `4`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_min.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_min.txt deleted file mode 100644 index aff39c9ddbba7..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_min.txt +++ /dev/null @@ -1,21 +0,0 @@ -## MV_MIN - -The `MV_MIN` function in ES|QL is used to convert a multivalued expression into a single valued column containing the minimum value. This function can be used with any column type, including keyword columns. In the case of keyword columns, it picks the first string, comparing their utf-8 representation byte by byte. - -### Examples - -Here are a couple of examples of how to use the `MV_MIN` function in ES|QL: - -```esql -ROW a=[2, 1] -| EVAL min_a = MV_MIN(a) -``` - -In this example, the `MV_MIN` function is used to find the minimum value in the array `[2, 1]`. The result is stored in the `min_a` column. - -```esql -ROW a=["foo", "bar"] -| EVAL min_a = MV_MIN(a) -``` - -In this example, the `MV_MIN` function is used to find the minimum value in the array `["foo", "bar"]`. Since these are string values, the function compares their utf-8 representation byte by byte. The result is stored in the `min_a` column. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_slice.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_slice.txt deleted file mode 100644 index 12e98a93550c1..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_slice.txt +++ /dev/null @@ -1,31 +0,0 @@ -## MV_SLICE - -MV_SLICE is a function in ES|QL that returns a subset of a multivalued field using the start and end index values. - -### Syntax - -`MV_SLICE(field, start, end)` - -#### Parameters - -- `field`: Multivalue expression. If null, the function returns null. -- `start`: Start position. If null, the function returns null. The start argument can be negative. An index of -1 is used to specify the last value in the list. -- `end`: End position(included). Optional; if omitted, the position at start is returned. The end argument can be negative. An index of -1 is used to specify the last value in the list. - -### Examples - -Here are a couple of examples of how to use the MV_SLICE function in ES|QL: - -```esql -row a = [1, 2, 2, 3] -| eval a1 = mv_slice(a, 1), a2 = mv_slice(a, 2, 3) -``` - -In this example, the MV_SLICE function is used to get subsets of the multivalued field `a`. The subsets are stored in the new fields `a1` and `a2`. - -```esql -row a = [1, 2, 2, 3] -| eval a1 = mv_slice(a, -2), a2 = mv_slice(a, -3, -1) -``` - -In this example, the MV_SLICE function is used with negative start and end positions to get subsets of the multivalued field `a` from the end of the list. The subsets are stored in the new fields `a1` and `a2`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sort.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sort.txt deleted file mode 100644 index 41480eb81afa1..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sort.txt +++ /dev/null @@ -1,30 +0,0 @@ -## MV_SORT - -The `MV_SORT` function is used to sort a multivalued field in lexicographical order. - -### Syntax - -`MV_SORT(field, order)` - -#### Parameters - -- `field`: A multivalue expression. If null, the function returns null. -- `order`: Sort order. The valid options are `ASC` and `DESC`, the default is `ASC`. - -### Examples - -Here are a couple of examples of how you can use the `MV_SORT` function in ES|QL queries: - -```esql -ROW a = [4, 2, -3, 2] -| EVAL sa = MV_SORT(a) -``` - -In this example, the `MV_SORT` function is used to sort the values in the `a` field in ascending order. - -```esql -ROW a = [4, 2, -3, 2] -| EVAL sd = MV_SORT(a, "DESC") -``` - -In this example, the `MV_SORT` function is used to sort the values in the `a` field in descending order. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sum.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sum.txt deleted file mode 100644 index d5476aedffa4a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_sum.txt +++ /dev/null @@ -1,29 +0,0 @@ -## MV_SUM - -The `MV_SUM` function in ES|QL is used to convert a multivalued field into a single valued field containing the sum of all the values. - -### Syntax - -`MV_SUM(number)` - -#### Parameters - -- `number`: A multivalued expression. - -### Examples - -Here are a couple of examples of how you can use the `MV_SUM` function in ES|QL: - -```esql -ROW a=[3, 5, 6] -| EVAL sum_a = MV_SUM(a) -``` - -In this example, the `MV_SUM` function is used to calculate the sum of the values in the multivalued field `a`. - -```esql -ROW b=[10, 20, 30, 40] -| EVAL sum_b = MV_SUM(b) -``` - -In this second example, the `MV_SUM` function is used to calculate the sum of the values in the multivalued field `b`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_zip.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_zip.txt deleted file mode 100644 index f5028c4207da9..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-mv_zip.txt +++ /dev/null @@ -1,33 +0,0 @@ -## MV_ZIP - -The `MV_ZIP` function in ES|QL combines the values from two multivalued fields with a delimiter that joins them together. - -### Syntax - -`MV_ZIP(string1, string2, delim)` - -#### Parameters - -- `string1`: Multivalue expression. -- `string2`: Multivalue expression. -- `delim`: Delimiter. Optional; if omitted, `,` is used as a default delimiter. - -### Examples - -Here are a couple of examples of how you can use the `MV_ZIP` function in your ES|QL queries: - -```esql -ROW a = ["x", "y", "z"], b = ["1", "2"] -| EVAL c = MV_ZIP(a, b, "-") -| KEEP a, b, c -``` - -In this example, the `MV_ZIP` function is used to combine the values from the `a` and `b` fields with a `-` delimiter. The result is stored in the `c` field. - -```esql -ROW a = ["apple", "banana", "cherry"], b = ["red", "yellow", "red"] -| EVAL fruit_color = MV_ZIP(a, b, " is ") -| KEEP a, b, fruit_color -``` - -In this second example, the `MV_ZIP` function is used to combine the values from the `a` and `b` fields with ` is ` as the delimiter. The result is stored in the `fruit_color` field. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-now.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-now.txt deleted file mode 100644 index 632e698e7008a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-now.txt +++ /dev/null @@ -1,20 +0,0 @@ -## NOW - -The `NOW` function in ES|QL returns the current date and time. - -### Examples - -Here are a couple of examples of how you can use the `NOW` function in ES|QL queries: - -1. To get the current date and time, you can use the `NOW` function in a `ROW` command: - -```esql -ROW current_date = NOW() -``` - -2. To retrieve logs from the last hour, you can use the `NOW` function in a `WHERE` clause: - -```esql -FROM sample_data -| WHERE @timestamp > NOW() - 1 hour -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-operators.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-operators.txt deleted file mode 100644 index e6d88e78993b4..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-operators.txt +++ /dev/null @@ -1,170 +0,0 @@ -# ES|QL Operators - -ES|QL supports a variety of operators that can be used in queries. These operators can be categorized into binary operators, unary operators, logical operators, and others. - -## Binary Operators - -Binary operators in ES|QL include equality, inequality, less than, less than or equal to, greater than, greater than or equal to, add, subtract, multiply, divide, and modulus. - -### Equality - -The equality operator (`==`) checks if two values are equal. - -```esql -FROM employees -| WHERE first_name == "John" -``` - -### Inequality - -The inequality operator (`!=`) checks if two values are not equal. - -```esql -FROM employees -| WHERE salary != 50000 -``` - -### Less Than - -The less than operator (`<`) checks if one value is less than another. - -```esql -FROM employees -| WHERE age < 30 -``` - -### Less Than or Equal To - -The less than or equal to operator (`<=`) checks if one value is less than or equal to another. - -```esql -FROM employees -| WHERE years_of_experience <= 5 -``` - -### Greater Than - -The greater than operator (`>`) checks if one value is greater than another. - -```esql -FROM employees -| WHERE salary > 50000 -``` - -### Greater Than or Equal To - -The greater than or equal to operator (`>=`) checks if one value is greater than or equal to another. - -```esql -FROM employees -| WHERE age >= 30 -``` - -### Add - -The add operator (`+`) adds two values together. - -```esql -FROM employees -| EVAL total_compensation = salary + bonus -``` - -### Subtract - -The subtract operator (`-`) subtracts one value from another. - -```esql -FROM employees -| EVAL years_until_retirement = 65 - age -``` - -### Multiply - -The multiply operator (`*`) multiplies two values. - -```esql -FROM employees -| EVAL yearly_bonus = monthly_bonus * 12 -``` - -### Divide - -The divide operator (`/`) divides one value by another. - -```esql -FROM employees -| EVAL hourly_wage = salary / 2080 -``` - -### Modulus - -The modulus operator (`%`) returns the remainder of a division operation. - -```esql -FROM employees -| EVAL odd_or_even = employee_id % 2 -``` - -## Unary Operators - -ES|QL supports one unary operator, negation (`-`), which negates a value. - -```esql -FROM employees -| EVAL negative_salary = -salary -``` - -## Logical Operators - -ES|QL supports the logical operators `AND`, `OR`, and `NOT`. - -```esql -FROM employees -| WHERE salary > 50000 AND years_of_experience <= 5 -``` - -## Other Operators - -### IS NULL and IS NOT NULL - -The `IS NULL` and `IS NOT NULL` predicates check if a value is null or not null, respectively. - -```esql -FROM employees -| WHERE birth_date IS NULL -``` - -### Cast (::) - -The `::` operator provides a convenient alternative syntax to the `TO_` conversion functions. - -```esql -ROW ver = CONCAT(("0"::INT + 1)::STRING, ".2.3")::VERSION -``` - -### IN - -The `IN` operator checks if a field or expression equals an element in a list of literals, fields, or expressions. - -```esql -ROW a = 1, b = 4, c = 3 -| WHERE c-a IN (3, b / 2, a) -``` - -### LIKE - -The `LIKE` operator filters data based on string patterns using wildcards. - -```esql -FROM employees -| WHERE first_name LIKE "?b*" -``` - -### RLIKE - -The `RLIKE` operator filters data based on string patterns using regular expressions. - -```esql -FROM employees -| WHERE first_name RLIKE ".leja.*" -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-overview.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-overview.txt deleted file mode 100644 index 36036e92ea093..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-overview.txt +++ /dev/null @@ -1,52 +0,0 @@ -# Elasticsearch Query Language (ES|QL) - -The Elasticsearch Query Language (ES|QL) is a powerful language designed to filter, transform, and analyze data stored in Elasticsearch. It is designed to be user-friendly and can be used by end users, SRE teams, application developers, and administrators. - -Users can author ES|QL queries to find specific events, perform statistical analysis, and generate visualizations. It supports a wide range of commands and functions that enable users to perform various data operations, such as filtering, aggregation, time-series analysis, and more. - -ES|QL uses "pipes" (|) to manipulate and transform data in a step-by-step fashion. This approach allows users to compose a series of operations, where the output of one operation becomes the input for the next, enabling complex data transformations and analysis. - -## ES|QL Compute Engine - -ES|QL is more than just a language. It represents a significant investment in new compute capabilities within Elasticsearch. To achieve both the functional and performance requirements for ES|QL, a new compute architecture was built. ES|QL search, aggregation, and transformation functions are directly executed within Elasticsearch itself. Query expressions are not transpiled to Query DSL for execution. This approach allows ES|QL to be extremely performant and versatile. - -The new ES|QL execution engine was designed with performance in mind. It operates on blocks at a time instead of per row, targets vectorization and cache locality, and embraces specialization and multi-threading. It is a separate component from the existing Elasticsearch aggregation framework with different performance characteristics. - -## Limitations - -There are some known limitations to ES|QL: - -- ES|QL only supports the UTC timezone. -- Full-text search is not yet supported. -- ES|QL does not support querying time series data streams (TSDS). -- Date math expressions work well when the leftmost expression is a datetime, but using parentheses or putting the datetime to the right is not always supported yet. -- ES|QL does not support configurations where the _source field is disabled. - -## Using ES|QL - -ES|QL can be used through the REST API, in Kibana, in Elastic Security, and across clusters. - -### REST API - -You can use the REST API to execute ES|QL queries. Here's an example of how to use the REST API: - -``` -POST /_query -{ - "query": """ - FROM library - | EVAL year = DATE_TRUNC(1 YEARS, release_date) - | STATS MAX(page_count) BY year - | SORT year - | LIMIT 5 - """ -} -``` - -### Kibana - -In Kibana, ES|QL can be used to query and aggregate your data, create visualizations, and set up alerts. However, there are some limitations when using ES|QL in Kibana. For example, the user interface to filter data is not enabled when Discover is in ES|QL mode. To filter data, you need to write a query that uses the `WHERE` command instead. - -### Cross Cluster - -ES|QL also supports executing a single query across multiple clusters. This can be useful for querying data from different geographical locations or separate Elasticsearch clusters. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-percentile.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-percentile.txt deleted file mode 100644 index 0057bd045ffac..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-percentile.txt +++ /dev/null @@ -1,34 +0,0 @@ -## PERCENTILE - -The `PERCENTILE` function in ES|QL returns the value at which a certain percentage of observed values occur. For example, the 95th percentile is the value which is greater than 95% of the observed values and the 50th percentile is the median. - -### Syntax - -`PERCENTILE(expression, percentile)` - -#### Parameters - -- `expression`: Expression from which to return a percentile. -- `percentile`: A constant numeric expression. - -### Examples - -Here are a couple of examples of how to use the `PERCENTILE` function in ES|QL: - -```esql -FROM employees -| STATS p0 = PERCENTILE(salary, 0), p50 = PERCENTILE(salary, 50), p99 = PERCENTILE(salary, 99) -``` - -In this example, the `PERCENTILE` function is used to calculate the 0th, 50th, and 99th percentiles of the `salary` field in the `employees` index. - -```esql -FROM employees -| STATS p80_max_salary_change = PERCENTILE(MV_MAX(salary_change), 80) -``` - -In this example, the `PERCENTILE` function is used in conjunction with the `MV_MAX` function to calculate the 80th percentile of the maximum values of the `salary_change` field in the `employees` index. - -### Note - -The `PERCENTILE` function is usually approximate. There are many different algorithms to calculate percentiles and the naive implementation does not scale. To calculate percentiles across potentially billions of values in an Elasticsearch cluster, approximate percentiles are calculated using the TDigest algorithm. This means you can get slightly different results using the same data. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pi.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pi.txt deleted file mode 100644 index b62f6e50831c0..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pi.txt +++ /dev/null @@ -1,20 +0,0 @@ -## PI - -The `PI` function in ES|QL returns the mathematical constant Pi, which is the ratio of a circle's circumference to its diameter. - -### Examples - -Here are a couple of examples of how you can use the `PI` function in ES|QL queries: - -```esql -ROW PI() -``` - -In this example, the `PI` function is used to simply return the value of Pi. - -```esql -FROM employees -| EVAL circle_area = PI() * POW(radius, 2) -``` - -In this second example, the `PI` function is used in a calculation to determine the area of a circle, given the radius stored in the `radius` field of the `employees` index. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pow.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pow.txt deleted file mode 100644 index 7107b2f715aa3..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-pow.txt +++ /dev/null @@ -1,21 +0,0 @@ -## POW - -The `POW` function in ES|QL returns the value of a base raised to the power of an exponent. It takes two numeric expressions as parameters: the base and the exponent. If either of these parameters is null, the function will return null. It's important to note that it is still possible to overflow a double result here; in that case, null will be returned. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `POW` function: - -1. This query calculates the result of 2.0 raised to the power of 2: - -```esql -ROW base = 2.0, exponent = 2 -| EVAL result = POW(base, exponent) -``` - -2. This query calculates the square root of 4 by raising 4 to the power of 0.5: - -```esql -ROW base = 4, exponent = 0.5 -| EVAL s = POW(base, exponent) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rename.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rename.txt deleted file mode 100644 index 5275d2f2c846c..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rename.txt +++ /dev/null @@ -1,46 +0,0 @@ -## RENAME - -The `RENAME` command in ES|QL is used to rename one or more columns in a table. If a column with the new name already exists, it will be replaced by the new column. This command can be useful in scenarios where you want to make column names more descriptive or to conform to a certain naming convention. - -However, it's important to note that if a column with the new name already exists, it will be replaced by the new column. Therefore, caution should be exercised to avoid unintentionally overwriting existing columns. - -### Syntax - -``` -RENAME old_name1 AS new_name1[, ..., old_nameN AS new_nameN] -``` - -#### Parameters - -- `old_nameX`: The name of a column you want to rename. -- `new_nameX`: The new name of the column. - -### Examples - -Here are some examples of how the `RENAME` command can be used in ES|QL queries: - -1. Renaming a single column: - - ```esql -FROM employees -| KEEP first_name, last_name, still_hired -| RENAME still_hired AS employed -``` - -2. Renaming multiple columns with a single `RENAME` command: - - ```esql -FROM employees -| KEEP first_name, last_name -| RENAME first_name AS fn, last_name AS ln -``` - -3. Renaming a column and using the new name in a subsequent command: - - ```esql -FROM employees -| RENAME salary AS annual_income -| WHERE annual_income > 50000 -``` - -In the third example, after renaming the `salary` column to `annual_income`, we can use the new column name in subsequent commands in the query. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-repeat.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-repeat.txt deleted file mode 100644 index 8face87f51dff..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-repeat.txt +++ /dev/null @@ -1,30 +0,0 @@ -## REPEAT - -The `REPEAT` function in ES|QL is used to construct a string by concatenating a given string with itself a specified number of times. - -### Syntax - -`REPEAT(string, number)` - -#### Parameters - -- `string`: The string expression that you want to repeat. -- `number`: The number of times you want to repeat the string. - -### Examples - -Here are a couple of examples of how you can use the `REPEAT` function in ES|QL: - -```esql -ROW a = "Hello!" -| EVAL triple_a = REPEAT(a, 3) -``` - -In this example, the string "Hello!" is repeated 3 times, resulting in "Hello!Hello!Hello!". - -```esql -ROW b = "ES|QL " -| EVAL five_b = REPEAT(b, 5) -``` - -In this example, the string "ES|QL " is repeated 5 times, resulting in "ES|QL ES|QL ES|QL ES|QL ES|QL ". diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-replace.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-replace.txt deleted file mode 100644 index b2abc79c2d76b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-replace.txt +++ /dev/null @@ -1,33 +0,0 @@ -## REPLACE - -The `REPLACE` function substitutes any match of a regular expression within a string with a replacement string. - -### Syntax - -`REPLACE(string, regex, newString)` - -#### Parameters - -- `string`: String expression. -- `regex`: Regular expression. -- `newString`: Replacement string. - -### Examples - -Here are a couple of examples of how to use the `REPLACE` function in ES|QL queries: - -```esql -ROW str = "Hello World" -| EVAL str = REPLACE(str, "World", "Universe") -| KEEP str -``` - -In this example, the `REPLACE` function is used to replace any occurrence of the word "World" with the word "Universe" in the string "Hello World". - -```esql -ROW str = "Elasticsearch is awesome" -| EVAL str = REPLACE(str, "awesome", "fantastic") -| KEEP str -``` - -In this example, the `REPLACE` function is used to replace the word "awesome" with "fantastic" in the string "Elasticsearch is awesome". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-right.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-right.txt deleted file mode 100644 index c3e2fd9303e68..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-right.txt +++ /dev/null @@ -1,33 +0,0 @@ -## RIGHT - -The `RIGHT` function in ES|QL is used to extract a substring from a string, starting from the right. The number of characters to return is specified by the `length` parameter. - -### Syntax - -`RIGHT(string, length)` - -#### Parameters - -- `string`: The string from which to return a substring. -- `length`: The number of characters to return. - -### Examples - -Here are a couple of examples of how to use the `RIGHT` function in ES|QL: - -```esql -FROM employees -| KEEP last_name -| EVAL right = RIGHT(last_name, 3) -| SORT last_name ASC -| LIMIT 5 -``` - -In this example, the `RIGHT` function is used to extract the last three characters from the `last_name` field of each record in the `employees` index. The resulting substring is then stored in a new field called `right`. The query then sorts the results in ascending order by `last_name` and limits the output to the first 5 records. - -```esql -FROM logs-* -| EVAL file_extension = RIGHT(file_name, 3) -``` - -In this second example, the `RIGHT` function is used to extract the file extension from a `file_name` field in a `logs-*` index. The resulting substring is stored in a new field called `file_extension`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-round.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-round.txt deleted file mode 100644 index aaef24b83a673..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-round.txt +++ /dev/null @@ -1,31 +0,0 @@ -## ROUND - -The `ROUND` function in ES|QL is used to round a number to a specified number of decimal places. By default, it rounds to 0 decimal places, returning the nearest integer. If the precision is a negative number, it rounds to the number of digits left of the decimal point. - -### Syntax: - -`ROUND(number, decimals)` - -#### Parameters: - -- `number`: The numeric value to round. If null, the function returns null. -- `decimals`: The number of decimal places to round to. Defaults to 0. If null, the function returns null. - -### Examples: - -Here are a couple of examples of how to use the `ROUND` function in ES|QL queries: - -```esql -FROM employees -| KEEP first_name, last_name, height -| EVAL height_ft = ROUND(height * 3.281, 1) -``` - -In this example, the `ROUND` function is used to round the result of the multiplication of the `height` field and `3.281` to `1` decimal place. The result is stored in the `height_ft` field. - -```esql -FROM sales_data -| EVAL rounded_sales = ROUND(sales * 1.2) -``` - -In this second example, the `ROUND` function is used to round the result of the multiplication of the `sales` field and `1.2` to the nearest integer (since no decimal places are specified). The result is stored in the `rounded_sales` field. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-row.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-row.txt deleted file mode 100644 index 48aaa65963786..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-row.txt +++ /dev/null @@ -1,42 +0,0 @@ -## ROW - -The `ROW` command in ES|QL is used to produce a row with one or more columns with specified values. This can be particularly useful for testing purposes. - -### Syntax - -The syntax for the `ROW` command is as follows: - -``` -ROW column1 = value1[, ..., columnN = valueN] -``` - -#### Parameters - -- `columnX`: The name of the column. -- `valueX`: The value for the column. This can be a literal, an expression, or a function. - -### Examples - -Here are some examples of how the `ROW` command can be used in ES|QL: - -1. Creating a row with specified values: - - ```esql -ROW a = 1, b = "two", c = null -``` - -2. Using square brackets to create multi-value columns: - - ```esql -ROW a = [2, 1] -``` - -3. Using functions within the `ROW` command: - - ```esql -ROW a = ROUND(1.23, 0) -``` - -### Limitations - -There are no known limitations for the `ROW` command in ES|QL. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rtrim.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rtrim.txt deleted file mode 100644 index 9e92e45629f70..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-rtrim.txt +++ /dev/null @@ -1,23 +0,0 @@ -## RTRIM - -The `RTRIM` function in ES|QL is used to remove trailing whitespaces from a string. If the string expression is null, the function will return null. - -### Examples - -Here are a couple of examples of how you can use the `RTRIM` function in ES|QL queries: - -```esql -ROW message = " some text " -| EVAL message = RTRIM(message) -| EVAL message = CONCAT("'", message, "'") -``` - -In this example, the `RTRIM` function is used to remove trailing whitespaces from the `message` string. The `CONCAT` function is then used to concatenate the modified `message` string with single quotes. - -```esql -ROW color = " red " -| EVAL color = RTRIM(color) -| EVAL color = CONCAT("'", color, "'") -``` - -In this second example, the `RTRIM` function is used to remove trailing whitespaces from the `color` string. The `CONCAT` function is then used to concatenate the modified `color` string with single quotes. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-show.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-show.txt deleted file mode 100644 index 80f92061f141f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-show.txt +++ /dev/null @@ -1,19 +0,0 @@ -## SHOW - -The `SHOW` command in ES|QL is used to return information about the deployment and its capabilities. Currently, the only supported item for this command is `INFO`, which returns the deployment’s version, build date, and hash. - -### Examples - -Here are some examples of how to use the `SHOW` command in ES|QL: - -1. To get the deployment's version, build date, and hash: - -```esql -SHOW INFO -``` - -Please note that the `SHOW` command can only be used with `INFO` as its parameter. Any other parameters will not be recognized by the command. - -### Limitations - -Currently, the `SHOW` command only supports `INFO` as its parameter. It does not support any other parameters or options. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-signum.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-signum.txt deleted file mode 100644 index bab747ef9b185..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-signum.txt +++ /dev/null @@ -1,29 +0,0 @@ -## SIGNUM - -The `SIGNUM` function in ES|QL returns the sign of a given number. It returns `-1` for negative numbers, `0` for `0`, and `1` for positive numbers. - -### Syntax - -The syntax for the `SIGNUM` function is as follows: - -`SIGNUM(number)` - -Here, `number` is a numeric expression. If `null`, the function returns `null`. - -### Examples - -Here are a couple of examples of how you can use the `SIGNUM` function in ES|QL: - -```esql -ROW d = 100.0 -| EVAL s = SIGNUM(d) -``` - -In this example, the `SIGNUM` function is used to determine the sign of the number `100.0`. Since `100.0` is a positive number, the function returns `1`. - -```esql -ROW d = -50.0 -| EVAL s = SIGNUM(d) -``` - -In this example, the `SIGNUM` function is used to determine the sign of the number `-50.0`. Since `-50.0` is a negative number, the function returns `-1`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sin.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sin.txt deleted file mode 100644 index 730df58969234..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sin.txt +++ /dev/null @@ -1,21 +0,0 @@ -## SIN - -The `SIN` function in ES|QL is used to calculate the sine of an angle. The angle should be provided in radians. If the provided angle is null, the function will return null. - -### Examples - -Here are a couple of examples of how you can use the `SIN` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL sin = SIN(a) -``` - -In this example, the `SIN` function is used to calculate the sine of the angle `1.8` radians. The result is stored in the `sin` variable. - -```esql -ROW a=3.14 -| EVAL sin_value = SIN(a) -``` - -In this second example, the `SIN` function is used to calculate the sine of the angle `3.14` radians (approximately equal to π, the angle for a half circle in the unit circle). The result is stored in the `sin_value` variable. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sinh.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sinh.txt deleted file mode 100644 index 62a1d8e089b06..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sinh.txt +++ /dev/null @@ -1,21 +0,0 @@ -## SINH - -The `SINH` function in ES|QL returns the hyperbolic sine of an angle. The angle should be provided in radians. If the provided angle is null, the function will return null. - -### Examples - -Here are a couple of examples of how you can use the `SINH` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL sinh = SINH(a) -``` - -In this example, the `SINH` function is used to calculate the hyperbolic sine of the angle `1.8` radians. - -```esql -ROW a=3.14 -| EVAL sinh_value = SINH(a) -``` - -In this second example, the `SINH` function is used to calculate the hyperbolic sine of the angle `3.14` radians. The result is stored in the `sinh_value` variable. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sort.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sort.txt deleted file mode 100644 index 68bc7790a033c..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sort.txt +++ /dev/null @@ -1,45 +0,0 @@ -## SORT - -The `SORT` command in ES|QL is a processing command that sorts a table based on one or more columns. The default sort order is ascending, but you can specify an explicit sort order using `ASC` or `DESC`. - -In cases where two rows have the same sort key, they are considered equal. However, you can provide additional sort expressions to act as tie breakers. When sorting on multivalued columns, the lowest value is used when sorting in ascending order and the highest value when sorting in descending order. - -By default, null values are treated as being larger than any other value. This means that with an ascending sort order, null values are sorted last, and with a descending sort order, null values are sorted first. You can change this by providing `NULLS FIRST` or `NULLS LAST`. - -### Examples - -Here are some examples of how to use the `SORT` command in ES|QL: - -1. Sorting by height in ascending order (default): - - ```esql -FROM employees -| KEEP first_name, last_name, height -| SORT height -``` - -2. Explicitly sorting in descending order with `DESC`: - - ```esql -FROM employees -| KEEP first_name, last_name, height -| SORT height DESC -``` - -3. Providing additional sort expressions to act as tie breakers: - - ```esql -FROM employees -| KEEP first_name, last_name, height -| SORT height DESC, first_name ASC -``` - -4. Sorting null values first using `NULLS FIRST`: - - ```esql -FROM employees -| KEEP first_name, last_name, height -| SORT first_name ASC NULLS FIRST -``` - -Please note that the `SORT` command does not support sorting on spatial types (`geo_point`, `geo_shape`, `cartesian_point`, `cartesian_shape`). \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-split.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-split.txt deleted file mode 100644 index 658c161292b64..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-split.txt +++ /dev/null @@ -1,30 +0,0 @@ -## SPLIT - -The `SPLIT` function in ES|QL is used to split a single valued string into multiple strings based on a specified delimiter. - -### Syntax - -`SPLIT(string, delim)` - -#### Parameters - -- `string`: This is the string expression that you want to split. If null, the function returns null. -- `delim`: This is the delimiter that will be used to split the string. Only single byte delimiters are currently supported. - -### Examples - -Here are a couple of examples of how you can use the `SPLIT` function in ES|QL: - -```esql -ROW words="foo;bar;baz;qux;quux;corge" -| EVAL word = SPLIT(words, ";") -``` - -In this example, the string "foo;bar;baz;qux;quux;corge" is split into multiple strings using the semicolon (;) as the delimiter. - -```esql -ROW data="John,Doe,30" -| EVAL details = SPLIT(data, ",") -``` - -In this second example, the string "John,Doe,30" is split into multiple strings using the comma (,) as the delimiter. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sqrt.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sqrt.txt deleted file mode 100644 index 6e1820242b468..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sqrt.txt +++ /dev/null @@ -1,29 +0,0 @@ -## SQRT - -The `SQRT` function in ES|QL is used to calculate the square root of a number. The input can be any numeric value and the return value is always a double. If the input is a negative number or infinity, the function returns null. - -### Syntax - -`SQRT(number)` - -#### Parameters - -`number`: Numeric expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `SQRT` function in ES|QL: - -```esql -ROW d = 100.0 -| EVAL s = SQRT(d) -``` - -In this example, the `SQRT` function is used to calculate the square root of 100. The result is stored in the variable `s`. - -```esql -ROW d = 16.0 -| EVAL s = SQRT(d) -``` - -In this example, the `SQRT` function is used to calculate the square root of 16. The result is stored in the variable `s`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_centroid_agg.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_centroid_agg.txt deleted file mode 100644 index f76bbdbf54e8f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_centroid_agg.txt +++ /dev/null @@ -1,21 +0,0 @@ -## ST_CENTROID_AGG - -ST_CENTROID_AGG is a function that calculates the spatial centroid over a field with spatial point geometry type. This functionality is currently in technical preview and may be changed or removed in a future release. - -### Examples - -Here are a couple of examples of full ES|QL queries using the ST_CENTROID_AGG function: - -```esql -FROM airports -| STATS centroid = ST_CENTROID_AGG(location) -``` - -In this example, the ST_CENTROID_AGG function is used to calculate the spatial centroid over the 'location' field from the 'airports' index. - -```esql -FROM geo_data -| STATS geo_centroid = ST_CENTROID_AGG(geo_point) -``` - -In this second example, the ST_CENTROID_AGG function is used to calculate the spatial centroid over the 'geo_point' field from the 'geo_data' index. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_contains.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_contains.txt deleted file mode 100644 index da7c244d57d76..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_contains.txt +++ /dev/null @@ -1,34 +0,0 @@ -## ST_CONTAINS - -ST_CONTAINS is a function in ES|QL that checks whether the first geometry contains the second geometry. This function is the inverse of the ST_WITHIN function. - -### Syntax - -The syntax for the ST_CONTAINS function is as follows: - -`ST_CONTAINS(geomA, geomB)` - -#### Parameters - -- `geomA`: An expression of type geo_point, cartesian_point, geo_shape or cartesian_shape. If null, the function returns null. -- `geomB`: An expression of type geo_point, cartesian_point, geo_shape or cartesian_shape. If null, the function returns null. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine geo_* and cartesian_* parameters. - -### Examples - -Here are a couple of examples of how to use the ST_CONTAINS function in ES|QL queries: - -```esql -FROM airport_city_boundaries -| WHERE ST_CONTAINS(city_boundary, TO_GEOSHAPE("POLYGON((109.35 18.3, 109.45 18.3, 109.45 18.4, 109.35 18.4, 109.35 18.3))")) -| KEEP abbrev, airport, region, city, city_location -``` - -In this example, the ST_CONTAINS function is used to check if the `city_boundary` contains the specified polygon. The query then keeps the `abbrev`, `airport`, `region`, `city`, and `city_location` fields. - -```esql -FROM geo_shapes -| WHERE ST_CONTAINS(shape_field, TO_GEOSHAPE("POINT(10 20)")) -| KEEP id, name, shape_field -``` - -In this second example, the ST_CONTAINS function is used to check if the `shape_field` contains the specified point. The query then keeps the `id`, `name`, and `shape_field` fields. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_disjoint.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_disjoint.txt deleted file mode 100644 index c1b8cc165ac7d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_disjoint.txt +++ /dev/null @@ -1,31 +0,0 @@ -## ST_DISJOINT - -ST_DISJOINT is a function in ES|QL that checks whether two geometries or geometry columns are disjoint. In other words, it verifies if the two geometries do not intersect at any point. This function is the inverse of the ST_INTERSECTS function. In mathematical terms, if A and B are two geometries, they are disjoint if their intersection is an empty set (A ⋂ B = ∅). - -### Syntax - -`ST_DISJOINT(geomA, geomB)` - -#### Parameters - -- `geomA`: An expression of type geo_point, cartesian_point, geo_shape, or cartesian_shape. If null, the function returns null. -- `geomB`: An expression of type geo_point, cartesian_point, geo_shape, or cartesian_shape. If null, the function returns null. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine geo_* and cartesian_* parameters. - -### Examples - -Here are a couple of examples of how to use the ST_DISJOINT function in ES|QL queries: - -```esql -FROM airport_city_boundaries -| WHERE ST_DISJOINT(city_boundary, TO_GEOSHAPE("POLYGON((-10 -60, 120 -60, 120 60, -10 60, -10 -60))")) -| KEEP abbrev, airport, region, city, city_location -``` - -In this example, the query checks if the city_boundary is disjoint from the specified polygon. If they are disjoint, the query returns the abbrev, airport, region, city, and city_location fields. - -```esql -FROM geo_shapes -| WHERE ST_DISJOINT(shape1, shape2) -``` - -In this example, the query checks if shape1 and shape2 are disjoint. If they are, the query returns all the fields of the matching documents. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_intersects.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_intersects.txt deleted file mode 100644 index 1682fcaccc014..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_intersects.txt +++ /dev/null @@ -1,30 +0,0 @@ -## ST_INTERSECTS - -The `ST_INTERSECTS` function returns `true` if two geometries intersect. They intersect if they have any point in common, including their interior points (points along lines or within polygons). This is the inverse of the `ST_DISJOINT` function. In mathematical terms: `ST_Intersects(A, B) ⇔ A ⋂ B ≠ ∅`. - -### Syntax - -`ST_INTERSECTS(geomA, geomB)` - -#### Parameters - -- `geomA`: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. -- `geomB`: Expression of type `geo_point`, `cartesian_point`, `geo_shape` or `cartesian_shape`. If `null`, the function returns `null`. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine `geo_*` and `cartesian_*` parameters. - -### Examples - -Here are a couple of examples of how to use the `ST_INTERSECTS` function in ES|QL queries: - -```esql -FROM airports -| WHERE ST_INTERSECTS(location, TO_GEOSHAPE("POLYGON((42 14, 43 14, 43 15, 42 15, 42 14))")) -``` - -In this example, the `ST_INTERSECTS` function is used to find airports that are located within a specific polygon. - -```esql -FROM geo_shapes -| WHERE ST_INTERSECTS(shape_field, TO_GEOSHAPE("POINT(42 14)")) -``` - -In this second example, the `ST_INTERSECTS` function is used to find geo shapes that intersect with a specific point. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_within.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_within.txt deleted file mode 100644 index 027f5b1eae393..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_within.txt +++ /dev/null @@ -1,34 +0,0 @@ -## ST_WITHIN - -ST_WITHIN is a function in ES|QL that checks whether the first geometry is within the second geometry. This function is the inverse of the ST_CONTAINS function. - -### Syntax - -The syntax for the ST_WITHIN function is as follows: - -`ST_WITHIN(geomA, geomB)` - -#### Parameters - -- `geomA`: This is an expression of type geo_point, cartesian_point, geo_shape, or cartesian_shape. If null, the function returns null. -- `geomB`: This is an expression of type geo_point, cartesian_point, geo_shape, or cartesian_shape. If null, the function returns null. The second parameter must also have the same coordinate system as the first. This means it is not possible to combine geo_* and cartesian_* parameters. - -### Examples - -Here are a couple of examples of how to use the ST_WITHIN function in ES|QL: - -```esql -FROM airport_city_boundaries -| WHERE ST_WITHIN(city_boundary, TO_GEOSHAPE("POLYGON((109.1 18.15, 109.6 18.15, 109.6 18.65, 109.1 18.65, 109.1 18.15))")) -| KEEP abbrev, airport, region, city, city_location -``` - -In this example, the ST_WITHIN function is used to check if the `city_boundary` is within the specified polygon. The query then keeps the `abbrev`, `airport`, `region`, `city`, and `city_location` fields from the `airport_city_boundaries` index. - -```esql -FROM my_index -| WHERE ST_WITHIN(my_geo_point, TO_GEOSHAPE("POLYGON((10 10, 20 20, 30 30, 10 10))")) -| KEEP field1, field2 -``` - -In this second example, the ST_WITHIN function is used to check if the `my_geo_point` field is within the specified polygon. The query then keeps the `field1` and `field2` fields from the `my_index` index. diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_x.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_x.txt deleted file mode 100644 index 820ec0176ad9d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_x.txt +++ /dev/null @@ -1,21 +0,0 @@ -## ST_X - -The `ST_X` function is used to extract the x coordinate from a provided point. If the point is of type `geo_point`, this is equivalent to extracting the longitude value. - -### Examples - -Here are a couple of examples of how you can use the `ST_X` function in ES|QL queries: - -```esql -ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)") -| EVAL x = ST_X(point) -``` - -In this example, the `ST_X` function is used to extract the x coordinate (or longitude) from a `geo_point` that is created using the `TO_GEOPOINT` function. - -```esql -ROW point = TO_GEOPOINT("POINT(50.8503 4.3517)") -| EVAL x = ST_X(point) -``` - -In this second example, the `ST_X` function is used to extract the x coordinate (or longitude) from a different `geo_point`. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_y.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_y.txt deleted file mode 100644 index 4e7daf35db08d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-st_y.txt +++ /dev/null @@ -1,26 +0,0 @@ -## ST_Y - -The `ST_Y` function extracts the y coordinate from the supplied point. If the points is of type `geo_point` this is equivalent to extracting the latitude value. - -### Syntax - -`ST_Y(point)` - -### Parameters - -- `point`: Expression of type `geo_point` or `cartesian_point`. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `ST_Y` function in ES|QL queries: - -```esql -ROW point = TO_GEOPOINT("POINT(42.97109629958868 14.7552534006536)") -| EVAL y = ST_Y(point) -``` - -```esql -FROM geo_data -| EVAL latitude = ST_Y(location) -| WHERE latitude > 50 -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-starts_with.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-starts_with.txt deleted file mode 100644 index bee2a57300a25..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-starts_with.txt +++ /dev/null @@ -1,33 +0,0 @@ -## STARTS_WITH - -The `STARTS_WITH` function in ES|QL is used to check if a keyword string starts with another string. It returns a boolean value indicating the result of this comparison. - -### Syntax - -The syntax for using the `STARTS_WITH` function is as follows: - -`STARTS_WITH(str, prefix)` - -#### Parameters - -- `str`: This is a string expression. If null, the function returns null. -- `prefix`: This is another string expression. If null, the function returns null. - -### Examples - -Here are a couple of examples showing how to use the `STARTS_WITH` function in ES|QL queries: - -```esql -FROM employees -| KEEP last_name -| EVAL ln_S = STARTS_WITH(last_name, "B") -``` - -In this example, the `STARTS_WITH` function is used to check if the `last_name` of employees starts with the letter "B". The result is stored in the `ln_S` field. - -```esql -FROM logs-* -| WHERE STARTS_WITH(log_message, "ERROR") -``` - -In this second example, the `STARTS_WITH` function is used in a `WHERE` clause to filter out log messages that start with the word "ERROR". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-stats.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-stats.txt deleted file mode 100644 index 4369353daa3cb..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-stats.txt +++ /dev/null @@ -1,92 +0,0 @@ -# STATS - -The `STATS` command in ES|QL is a processing command that groups rows according to a common value and calculates one or more aggregated values over the grouped rows. If `BY` is omitted, the output table contains exactly one row with the aggregations applied over the entire dataset. - -The following aggregation functions are supported: - -- `AVG` -- `COUNT` -- `COUNT_DISTINCT` -- `MAX` -- `MEDIAN` -- `MEDIAN_ABSOLUTE_DEVIATION` -- `MIN` -- `PERCENTILE` -- `ST_CENTROID_AGG` (This functionality is in technical preview and may be changed or removed in a future release) -- `SUM` -- `VALUES` - -It's important to note that `STATS` without any groups is much faster than adding a group. Grouping on a single expression is currently much more optimized than grouping on many expressions. - -## Examples - -Here are some examples of how you can use the `STATS` command in ES|QL: - -1. Calculating a statistic and grouping by the values of another column: - - ```esql -FROM employees -| STATS count = COUNT(emp_no) BY languages -| SORT languages -``` - -2. Omitting `BY` returns one row with the aggregations applied over the entire dataset: - - ```esql -FROM employees -| STATS avg_lang = AVG(languages) -``` - -3. It’s possible to calculate multiple values: - - ```esql -FROM employees -| STATS avg_lang = AVG(languages), max_lang = MAX(languages) -``` - -4. It’s also possible to group by multiple values (only supported for long and keyword family fields): - - ```esql -FROM employees -| EVAL hired = DATE_FORMAT("YYYY", hire_date) -| STATS avg_salary = AVG(salary) BY hired, languages.long -| EVAL avg_salary = ROUND(avg_salary) -| SORT hired, languages.long -``` - -5. Both the aggregating functions and the grouping expressions accept other functions. This is useful for using `STATS...BY` on multivalue columns. For example, to calculate the average salary change, you can use `MV_AVG` to first average the multiple values per employee, and use the result with the `AVG` function: - - ```esql -FROM employees -| STATS avg_salary_change = ROUND(AVG(MV_AVG(salary_change)), 10) -``` - -6. An example of grouping by an expression is grouping employees on the first letter of their last name: - - ```esql -FROM employees -| STATS my_count = COUNT() BY LEFT(last_name, 1) -| SORT `LEFT(last_name, 1)` -``` - -7. Specifying the output column name is optional. If not specified, the new column name is equal to the expression. The following query returns a column named `AVG(salary)`: - - ```esql -FROM employees -| STATS AVG(salary) -| EVAL avg_salary_rounded = ROUND(`AVG(salary)`) -``` - -## Limitations - -- `STATS` does not support configurations where the `_source` field is disabled. -- Full-text search is not supported. -- `text` fields behave like `keyword` fields. -- Time series data streams are not supported. -- Date math expressions work well when the leftmost expression is a datetime. -- Enrich limitations: The ES|QL `ENRICH` command only supports enrich policies of type `match`. Furthermore, `ENRICH` only supports enriching on a column of type `keyword`. -- Dissect limitations: The `DISSECT` command does not support reference keys. -- Grok limitations: The `GROK` command does not support configuring custom patterns, or multiple patterns. The `GROK` command is not subject to Grok watchdog settings. -- Multivalue limitations: ES|QL supports multivalued fields, but functions return `null` when applied to a multivalued field, unless documented otherwise. -- Timezone support: ES|QL only supports the UTC timezone. -- Kibana limitations: The user interface to filter data is not enabled when Discover is in ES|QL mode. To filter data, write a query that uses the `WHERE` command instead. Discover shows no more than 10,000 rows. This limit only applies to the number of rows that are retrieved by the query and displayed in Discover. Queries and aggregations run on the full data set. Discover shows no more than 50 columns. If a query returns more than 50 columns, Discover only shows the first 50. CSV export from Discover shows no more than 10,000 rows. This limit only applies to the number of rows that are retrieved by the query and displayed in Discover. Queries and aggregations run on the full data set. Querying many indices at once without any filters can cause an error in kibana which looks like `[esql] > Unexpected error from Elasticsearch: The content length (536885793) is bigger than the maximum allowed string (536870888)`. The response from ES|QL is too long. Use `DROP` or `KEEP` to limit the number of fields returned. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-substring.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-substring.txt deleted file mode 100644 index 53aedd96c3466..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-substring.txt +++ /dev/null @@ -1,41 +0,0 @@ -## SUBSTRING - -The `SUBSTRING` function in ES|QL is used to extract a specific portion of a string. It is specified by a start position and an optional length. If the length is not provided, the function returns all positions after the start. - -### Syntax: - -`SUBSTRING(string, start, [length])` - -#### Parameters: - -- `string`: The string expression from which to extract the substring. If null, the function returns null. -- `start`: The starting position for the substring. -- `length`: The length of the substring from the start position. This is optional; if omitted, all positions after start are returned. - -### Examples: - -Here are a couple of examples of how to use the `SUBSTRING` function in ES|QL: - -1. Extracting the first three characters of every last name: - - ```esql -FROM employees -| KEEP last_name -| EVAL ln_sub = SUBSTRING(last_name, 1, 3) -``` - -2. Extracting the last three characters of every last name: - - ```esql -FROM employees -| KEEP last_name -| EVAL ln_sub = SUBSTRING(last_name, -3, 3) -``` - -3. Extracting all characters except for the first: - - ```esql -FROM employees -| KEEP last_name -| EVAL ln_sub = SUBSTRING(last_name, 2) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sum.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sum.txt deleted file mode 100644 index 2e555961c553f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-sum.txt +++ /dev/null @@ -1,21 +0,0 @@ -## SUM - -The `SUM` function in ES|QL is used to calculate the sum of a numeric expression. - -### Examples - -Here are a couple of examples of how you can use the `SUM` function in ES|QL: - -1. To calculate the sum of a field named `languages` in an index named `employees`, you can use the following query: - -```esql -FROM employees -| STATS SUM(languages) -``` - -2. You can also use the `SUM` function with other functions like `MV_MAX`. In the following example, the `MV_MAX` function is applied to each row of the `salary_change` field to get the maximum salary change for each employee. The `SUM` function then calculates the total of these maximum salary changes: - -```esql -FROM employees -| STATS total_salary_changes = SUM(MV_MAX(salary_change)) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-syntax.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-syntax.txt deleted file mode 100644 index dac9e93b7ea14..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-syntax.txt +++ /dev/null @@ -1,121 +0,0 @@ -# ES|QL Syntax - -ES|QL (Elasticsearch Query Language) uses a simple yet powerful syntax that allows you to filter, transform, and analyze data stored in Elasticsearch. The syntax is composed of a source command followed by an optional series of processing commands, separated by a pipe character (`|`). - -## Basic Syntax - -An ES|QL query typically looks like this: - -source-command -| processing-command1 -| processing-command2 - -The result of a query is the table produced by the final processing command. For an overview of all supported commands, functions, and operators, refer to Commands and Functions and operators. - -You can also write an ES|QL query as a single line. For example: - -source-command -| processing-command1 -| processing-command2 - -## Identifiers - -Identifiers in ES|QL need to be quoted with backticks (```) if they don’t start with a letter, `_` or `@` or if any of the other characters is not a letter, number, or `_`. For example: - -```esql -FROM index -| KEEP `1.field` -``` - -When referencing a function alias that itself uses a quoted identifier, the backticks of the quoted identifier need to be escaped with another backtick. For example: - -```esql -FROM index -| STATS COUNT(`1.field`) -| EVAL my_count = `COUNT(``1.field``)` -``` - -## Literals - -ES|QL currently supports numeric and string literals. - -### String Literals - -A string literal is a sequence of unicode characters delimited by double quotes (`"`). If the literal string itself contains quotes, these need to be escaped (`\\"`). ES|QL also supports the triple-quotes (`"""`) delimiter, for convenience. Special characters CR, LF and TAB can be provided with the usual escaping: `\r`, `\n`, `\t`, respectively. - -```esql -FROM index -| WHERE first_name == "Georgi" -``` - -### Numerical Literals - -The numeric literals are accepted in decimal and in the scientific notation with the exponent marker (`e` or `E`), starting either with a digit, decimal point `.` or the negative sign `-`. The integer numeric literals are implicitly converted to the `integer`, `long` or the `double` type, whichever can first accommodate the literal’s value. The floating point literals are implicitly converted the `double` type. - -1969 -- integer notation -3.14 -- decimal notation -.1234 -- decimal notation starting with decimal point -4E5 -- scientific notation (with exponent marker) -1.2e-3 -- scientific notation with decimal point --.1e2 -- scientific notation starting with the negative sign - -## Comments - -ES|QL uses C++ style comments: double slash `//` for single line comments and `/*` and `*/` for block comments. - -```esql -// Query the employees index -FROM employees -| WHERE height > 2 -``` - -## Timespan Literals - -Datetime intervals and timespans can be expressed using timespan literals. Timespan literals are a combination of a number and a qualifier. These qualifiers are supported: `millisecond`/`milliseconds`/`ms`, `second`/`seconds`/`sec`/`s`, `minute`/`minutes`/`min`, `hour`/`hours`/`h`, `day`/`days`/`d`, `week`/`weeks`/`w`, `month`/`months`/`mo`, `quarter`/`quarters`/`q`, `year`/`years`/`yr`/`y`. Timespan literals are not whitespace sensitive. - -1day -1 day -1 day - -## Example Queries with Timespan Literals - -Here are some example queries using timespan literals: - -1. Querying data from the last 7 days: - -```esql -FROM logs -| WHERE @timestamp >= NOW() - 7d -``` - -2. Aggregating data on an hourly basis for the past 24 hours: - -```esql -FROM logs -| STATS COUNT(*) BY timestamp = BUCKET(@timestamp, 1h) -| WHERE timestamp >= NOW() - 24h -``` - -3. Finding the average response time per minute for the last hour: - -```esql -FROM logs -| STATS AVG(response_time) BY minute = BUCKET(@timestamp, 1m) -| WHERE @timestamp >= NOW() - 1h -``` - -4. Aggregating data on a weekly basis for the past year: - -```esql -FROM logs -| STATS COUNT(*) BY week = BUCKET(@timestamp, 1w) -| WHERE @timestamp >= NOW() - 1y -``` - -5. Finding the maximum response time per second for the last minute: - -```esql -FROM logs -| STATS MAX(response_time) BY second = BUCKET(@timestamp, 1s) -| WHERE @timestamp >= NOW() - 1m -``` diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tan.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tan.txt deleted file mode 100644 index 7f1280c10f536..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tan.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TAN - -The `TAN` function in ES|QL is used to calculate the Tangent of an angle. The angle should be provided in radians. - -### Syntax - -The syntax for using the `TAN` function is as follows: - -`TAN(angle)` - -Here, `angle` is the angle in radians for which you want to calculate the Tangent. If `angle` is null, the function will return null. - -### Examples - -Here are a couple of examples showing how to use the `TAN` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL tan = TAN(a) -``` - -In this example, the `TAN` function is used to calculate the Tangent of the angle `1.8` radians. - -```esql -ROW a=3.14 -| EVAL tan = TAN(a) -``` - -In this example, the `TAN` function is used to calculate the Tangent of the angle `3.14` radians. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tanh.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tanh.txt deleted file mode 100644 index d1412a7016bd6..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tanh.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TANH - -The `TANH` function in ES|QL returns the Tangent hyperbolic function of an angle. The angle should be provided in radians. If the angle is null, the function will return null. - -### Syntax - -`TANH(angle)` - -#### Parameters - -- `angle`: An angle, in radians. If null, the function returns null. - -### Examples - -Here are a couple of examples of how to use the `TANH` function in ES|QL: - -```esql -ROW a=1.8 -| EVAL tanh = TANH(a) -``` - -In this example, the `TANH` function is used to calculate the Tangent hyperbolic function of the angle `1.8` radians. - -```esql -ROW a=3.14 -| EVAL tanh_result = TANH(a) -``` - -In this second example, the `TANH` function is used to calculate the Tangent hyperbolic function of the angle `3.14` radians. The result is stored in the `tanh_result` variable. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tau.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tau.txt deleted file mode 100644 index c7e0a5211d48f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-tau.txt +++ /dev/null @@ -1,20 +0,0 @@ -## TAU - -TAU function in ES|QL returns the ratio of a circle’s circumference to its radius. - -### Examples - -Here are a couple of examples of how to use the TAU function in ES|QL: - -```esql -ROW TAU() -``` - -In this example, the TAU function is used to return the ratio of a circle’s circumference to its radius. - -```esql -FROM my-index -| EVAL tau_ratio = TAU() -``` - -In this example, the TAU function is used within an EVAL function to create a new column `tau_ratio` in the result set, which contains the ratio of a circle’s circumference to its radius. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_base64.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_base64.txt deleted file mode 100644 index 4069711b9524f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_base64.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TO_BASE64 - -The `TO_BASE64` function in ES|QL is used to encode a string to a base64 string. - -### Syntax - -`TO_BASE64(string)` - -#### Parameters - -- `string`: The string you want to encode. - -### Examples - -Here are a couple of examples of how you can use the `TO_BASE64` function in ES|QL: - -```esql -ROW a = "elastic" -| EVAL e = TO_BASE64(a) -``` - -In this example, the string "elastic" is encoded to a base64 string. - -```esql -ROW b = "Elasticsearch Query Language" -| EVAL encoded = TO_BASE64(b) -``` - -In this example, the string "Elasticsearch Query Language" is encoded to a base64 string. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_boolean.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_boolean.txt deleted file mode 100644 index 34868efa9ccab..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_boolean.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TO_BOOLEAN - -The `TO_BOOLEAN` function converts an input value to a boolean value. A string value of true will be case-insensitive converted to the Boolean true. For anything else, including the empty string, the function will return false. The numerical value of 0 will be converted to false, anything else will be converted to true. - -### Syntax - -`TO_BOOLEAN(field)` - -#### Parameters - -- `field`: Input value. The input can be a single- or multi-valued column or an expression. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `TO_BOOLEAN` function: - -```esql -ROW str = ["true", "TRuE", "false", "", "yes", "1"] -| EVAL bool = TO_BOOLEAN(str) -``` - -In this example, the `TO_BOOLEAN` function is used to convert a list of string values to boolean. The resulting `bool` column will contain boolean values corresponding to the input strings. - -```esql -ROW str = ["0", "1", "2", "-1", "0.5"] -| EVAL bool = TO_BOOLEAN(str) -``` - -In this second example, the `TO_BOOLEAN` function is used to convert a list of numeric strings to boolean. The resulting `bool` column will contain boolean values corresponding to the input strings. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianpoint.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianpoint.txt deleted file mode 100644 index 35310b547f32d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_cartesianpoint.txt +++ /dev/null @@ -1,22 +0,0 @@ -## TO_CARTESIANPOINT - -The `TO_CARTESIANPOINT` function converts an input value to a `cartesian_point` value. This conversion will only be successful if the input string respects the WKT Point format. - -### Examples - -Here are a couple of examples of how you can use the `TO_CARTESIANPOINT` function in ES|QL queries: - -```esql -ROW wkt = ["POINT(4297.11 -1475.53)", "POINT(7580.93 2272.77)"] -| MV_EXPAND wkt -| EVAL pt = TO_CARTESIANPOINT(wkt) -``` - -In this example, the `TO_CARTESIANPOINT` function is used to convert the values in the `wkt` field (which are in WKT Point format) to `cartesian_point` values. The `MV_EXPAND` function is used to expand the multi-valued `wkt` field into individual rows, and then the `TO_CARTESIANPOINT` function is applied to each row. - -```esql -ROW wkt = "POINT(4297.11 -1475.53)" -| EVAL pt = TO_CARTESIANPOINT(wkt) -``` - -In this second example, the `TO_CARTESIANPOINT` function is used to convert a single WKT Point string to a `cartesian_point` value. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_datetime.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_datetime.txt deleted file mode 100644 index b23b9cb6934bd..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_datetime.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_DATETIME - -The `TO_DATETIME` function converts an input value to a date value. A string will only be successfully converted if it’s respecting the format `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. To convert dates in other formats, use `DATE_PARSE`. - -### Examples - -Here are a couple of examples of how to use the `TO_DATETIME` function in ES|QL queries: - -```esql -ROW string = ["1953-09-02T00:00:00.000Z", "1964-06-02T00:00:00.000Z", "1964-06-02 00:00:00"] -| EVAL datetime = TO_DATETIME(string) -``` - -In this example, the last value in the source multi-valued field has not been converted. This is because if the date format is not respected, the conversion will result in a null value. When this happens a Warning header is added to the response. The header will provide information on the source of the failure. - -```esql -ROW int = [0, 1] -| EVAL dt = TO_DATETIME(int) -``` - -In this example, if the input parameter is of a numeric type, its value will be interpreted as milliseconds since the Unix epoch. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_degrees.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_degrees.txt deleted file mode 100644 index d82a65148947f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_degrees.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TO_DEGREES - -The `TO_DEGREES` function in ES|QL is used to convert a number in radians to degrees. - -### Syntax - -`TO_DEGREES(number)` - -#### Parameters - -- `number`: This is the input value. It can be a single or multi-valued column or an expression. - -### Examples - -Here are a couple of examples of how you can use the `TO_DEGREES` function in ES|QL: - -```esql -ROW rad = [1.57, 3.14, 4.71] -| EVAL deg = TO_DEGREES(rad) -``` - -In this example, the `TO_DEGREES` function is used to convert the values in the `rad` array from radians to degrees. - -```esql -FROM my_index -| EVAL angle_deg = TO_DEGREES(angle_rad) -``` - -In this example, the `TO_DEGREES` function is used to convert the values in the `angle_rad` field from radians to degrees and the result is stored in the `angle_deg` field. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_double.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_double.txt deleted file mode 100644 index 22567ab279190..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_double.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_DOUBLE - -TO_DOUBLE function converts an input value to a double value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to double. Boolean true will be converted to double 1.0, false to 0.0. - -### Examples - -Here are a couple of examples of how to use the `TO_DOUBLE` function in ES|QL: - -```esql -ROW str1 = "5.20128E11" -| EVAL dbl = TO_DOUBLE("520128000000"), dbl1 = TO_DOUBLE(str1) -``` - -In this example, the string "5.20128E11" is converted to a double value. - -```esql -ROW str2 = "foo" -| EVAL dbl2 = TO_DOUBLE(str2) -``` - -In this example, the string "foo" cannot be converted to a double value, resulting in a null value. A warning header is added to the response indicating the source of the failure. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geopoint.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geopoint.txt deleted file mode 100644 index e3db60a8fcf5d..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geopoint.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_GEOPOINT - -The `TO_GEOPOINT` function in ES|QL is used to convert an input value to a `geo_point` value. This function is successful in conversion only if the input string respects the WKT (Well-Known Text) Point format. - -### Examples - -Here are a couple of examples of how you can use the `TO_GEOPOINT` function in your ES|QL queries: - -```esql -ROW wkt = "POINT(42.97109630194 14.7552534413725)" -| EVAL pt = TO_GEOPOINT(wkt) -``` - -In this example, the `TO_GEOPOINT` function is used to convert the WKT representation of a point to a `geo_point` value. - -```esql -ROW wkt = "POINT(34.052235 -118.243683)" -| EVAL location = TO_GEOPOINT(wkt) -``` - -In this second example, the `TO_GEOPOINT` function is used to convert the WKT representation of a different point to a `geo_point` value. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geoshape.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geoshape.txt deleted file mode 100644 index d3b6bb198040f..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_geoshape.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_GEOSHAPE - -The `TO_GEOSHAPE` function in ES|QL is used to convert an input value to a `geo_shape` value. The conversion will be successful only if the input string respects the Well-Known Text (WKT) format. - -### Examples - -Here are a couple of examples of how you can use the `TO_GEOSHAPE` function in your ES|QL queries: - -```esql -ROW wkt = "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))" -| EVAL geom = TO_GEOSHAPE(wkt) -``` - -In this example, the `TO_GEOSHAPE` function is used to convert a WKT representation of a polygon into a `geo_shape` value. - -```esql -ROW wkt = "POINT (30 10)" -| EVAL geom = TO_GEOSHAPE(wkt) -``` - -In this second example, the `TO_GEOSHAPE` function is used to convert a WKT representation of a point into a `geo_shape` value. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_integer.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_integer.txt deleted file mode 100644 index f0881133c7d8a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_integer.txt +++ /dev/null @@ -1,24 +0,0 @@ -## TO_INTEGER - -The `TO_INTEGER` function converts an input value to an integer value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to integer. Boolean `true` will be converted to integer `1`, `false` to `0`. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `TO_INTEGER` function: - -```esql -ROW long = [5013792, 2147483647, 501379200000] -| EVAL int = TO_INTEGER(long) -``` - -In this example, the last value of the multi-valued field cannot be converted as an integer. When this happens, the result is a null value. A Warning header is added to the response providing information on the source of the failure: - -```esql -"Line 1:61: evaluation of [TO_INTEGER(long)] failed, treating result as null. Only first 20 failures recorded." -``` - -A following header will contain the failure reason and the offending value: - -``` -"org.elasticsearch.xpack.esql.core.InvalidArgumentException: [501379200000] out of [integer] range" -``` diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_ip.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_ip.txt deleted file mode 100644 index ddd8e0eeaee39..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_ip.txt +++ /dev/null @@ -1,22 +0,0 @@ -## TO_IP - -The `TO_IP` function in ES|QL is used to convert an input string to an IP value. - -### Examples - -Here are a couple of examples of how you can use the `TO_IP` function in your ES|QL queries: - -```esql -ROW str1 = "1.1.1.1" -| EVAL ip1 = TO_IP(str1) -| WHERE CIDR_MATCH(ip1, "1.0.0.0/8") -``` - -In this example, the `TO_IP` function is used to convert the string "1.1.1.1" to an IP value. The `WHERE` clause then uses the `CIDR_MATCH` function to check if the IP value falls within the specified CIDR range. - -```esql -ROW str2 = "foo" -| EVAL ip2 = TO_IP(str2) -``` - -In this second example, the `TO_IP` function attempts to convert the string "foo" to an IP value. However, since "foo" is not a valid IP string literal, the function returns a null value and a warning is added to the response header. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_long.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_long.txt deleted file mode 100644 index 4e23ae659f17a..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_long.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_LONG - -The `TO_LONG` function converts an input value to a long value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to long. Boolean true will be converted to long 1, false to 0. - -### Examples - -Here are a couple of examples of how you can use the `TO_LONG` function in ES|QL queries: - -```esql -ROW str1 = "2147483648" -| EVAL long1 = TO_LONG(str1) -``` - -In this example, the string "2147483648" is converted to a long value. - -```esql -ROW str2 = "2147483648.2", str3 = "foo" -| EVAL long2 = TO_LONG(str2), long3 = TO_LONG(str3) -``` - -In this example, the string "2147483648.2" is converted to a long value. However, the string "foo" cannot be converted to a long value, resulting in a null value and a warning header added to the response. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_lower.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_lower.txt deleted file mode 100644 index ccfdf623a83bf..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_lower.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TO_LOWER - -The `TO_LOWER` function in ES|QL is used to convert an input string to lower case. - -### Syntax - -`TO_LOWER(str)` - -#### Parameters - -- `str`: String expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `TO_LOWER` function in ES|QL queries: - -```esql -ROW message = "HELLO WORLD" -| EVAL lower_message = TO_LOWER(message) -``` - -In this example, the `TO_LOWER` function is used to convert the string "HELLO WORLD" to lower case. The result would be "hello world". - -```esql -ROW name = "John Doe" -| EVAL lower_name = TO_LOWER(name) -``` - -In this example, the `TO_LOWER` function is used to convert the string "John Doe" to lower case. The result would be "john doe". \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_radians.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_radians.txt deleted file mode 100644 index dbf3ef1e2aa62..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_radians.txt +++ /dev/null @@ -1,29 +0,0 @@ -## TO_RADIANS - -The `TO_RADIANS` function in ES|QL is used to convert a number in degrees to radians. - -### Syntax - -`TO_RADIANS(number)` - -#### Parameters - -- `number`: This is the input value. It can be a single or multi-valued column or an expression. - -### Examples - -Here are a couple of examples of how you can use the `TO_RADIANS` function in ES|QL: - -```esql -ROW deg = [90.0, 180.0, 270.0] -| EVAL rad = TO_RADIANS(deg) -``` - -In this example, the `TO_RADIANS` function is used to convert an array of degree values into radians. - -```esql -ROW deg = 45 -| EVAL rad = TO_RADIANS(deg) -``` - -In this example, the `TO_RADIANS` function is used to convert a single degree value into radians. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_string.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_string.txt deleted file mode 100644 index ed7aad31edd8b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_string.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_STRING - -The `TO_STRING` function in ES|QL is used to convert an input value into a string. The input can be a single or multi-valued column or an expression. - -### Examples - -Here are a couple of examples of how you can use the `TO_STRING` function in your ES|QL queries: - -```esql -ROW a=10 -| EVAL j = TO_STRING(a) -``` - -In this example, the function is used to convert the numeric value `10` into a string. - -```esql -ROW a=[10, 9, 8] -| EVAL j = TO_STRING(a) -``` - -In this example, the function is used to convert the values in a multi-valued field into strings. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_unsigned_long.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_unsigned_long.txt deleted file mode 100644 index afba5be08f5cd..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_unsigned_long.txt +++ /dev/null @@ -1,21 +0,0 @@ -## TO_UNSIGNED_LONG - -The `TO_UNSIGNED_LONG` function converts an input value to an unsigned long value. If the input parameter is of a date type, its value will be interpreted as milliseconds since the Unix epoch, converted to unsigned long. Boolean true will be converted to unsigned long 1, false to 0. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `TO_UNSIGNED_LONG` function: - -```esql -ROW str1 = "2147483648", str2 = "2147483648.2", str3 = "foo" -| EVAL long1 = TO_UNSIGNED_LONG(str1), long2 = TO_ULONG(str2), long3 = TO_UL(str3) -``` - -In this example, the `TO_UNSIGNED_LONG` function is used to convert string values to unsigned long. Note that the last conversion of the string isn’t possible. When this happens, the result is a null value. - -```esql -ROW date = "2022-01-01T00:00:00Z" -| EVAL timestamp = TO_UNSIGNED_LONG(date) -``` - -In this example, the `TO_UNSIGNED_LONG` function is used to convert a date string to an unsigned long value, representing the milliseconds since the Unix epoch. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_upper.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_upper.txt deleted file mode 100644 index 9f703c69c167e..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_upper.txt +++ /dev/null @@ -1,34 +0,0 @@ -## TO_UPPER - -The `TO_UPPER` function in ES|QL is used to convert an input string to upper case. - -### Syntax - -`TO_UPPER(str)` - -#### Parameters - -- `str`: This is a string expression. If null, the function returns null. - -### Description - -The function returns a new string representing the input string converted to upper case. - -### Examples - -Here are a couple of examples of full ES|QL queries using the `TO_UPPER` function: - -```esql -ROW message = "Hello World" -| EVAL upper_message = TO_UPPER(message) -``` - -In this example, the `TO_UPPER` function is used to convert the string "Hello World" to upper case. - -```esql -FROM employees -| EVAL upper_last_name = TO_UPPER(last_name) -| KEEP emp_no, upper_last_name -``` - -In this example, the `TO_UPPER` function is used to convert the `last_name` field of each record in the `employees` index to upper case. The query then keeps the `emp_no` and the upper case `last_name` for each record. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_version.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_version.txt deleted file mode 100644 index b560d15edc942..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-to_version.txt +++ /dev/null @@ -1,19 +0,0 @@ -## TO_VERSION - -TO_VERSION function converts an input string to a version value. - -### Examples - -Here are a couple of examples of how you can use the TO_VERSION function in ES|QL queries: - -```esql -ROW v = TO_VERSION("1.2.3") -``` - -In this example, the TO_VERSION function is used to convert the string "1.2.3" to a version value. - -```esql -ROW v = TO_VERSION("2.3.4") -``` - -In this example, the TO_VERSION function is used to convert the string "2.3.4" to a version value. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-trim.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-trim.txt deleted file mode 100644 index faaad56be6f8b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-trim.txt +++ /dev/null @@ -1,30 +0,0 @@ -## TRIM - -The `TRIM` function in ES|QL is used to remove leading and trailing whitespaces from a string. If the string expression is null, the function will return null. - -### Syntax - -`TRIM(string)` - -#### Parameters - -`string`: A string expression. If null, the function returns null. - -### Examples - -Here are a couple of examples of how you can use the `TRIM` function in ES|QL: - -```esql -ROW message = " some text ", color = " red " -| EVAL message = TRIM(message) -| EVAL color = TRIM(color) -``` - -In this example, the `TRIM` function is used to remove the leading and trailing whitespaces from the `message` and `color` strings. - -```esql -ROW name = " John Doe " -| EVAL trimmed_name = TRIM(name) -``` - -In this second example, the `TRIM` function is used to remove the leading and trailing whitespaces from the `name` string. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-values.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-values.txt deleted file mode 100644 index edc92663a03b8..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-values.txt +++ /dev/null @@ -1,24 +0,0 @@ -## VALUES - -The `VALUES` function in ES|QL is used to return all values in a group as a multivalued field. The order of the returned values isn’t guaranteed. If you need the values returned in order, you can use `MV_SORT`. This function can use a significant amount of memory and ES|QL doesn’t yet grow aggregations beyond memory. So this aggregation will work until it is used to collect more values than can fit into memory. Once it collects too many values it will fail the query with a Circuit Breaker Error. - -### Syntax - -`VALUES(expression)` - -Where `expression` is an expression of any type except `geo_point`, `cartesian_point`, `geo_shape`, or `cartesian_shape`. - -### Examples - -Here are a couple of examples of how you can use the `VALUES` function in ES|QL queries: - -```esql -FROM employees -| EVAL first_letter = SUBSTRING(first_name, 0, 1) -| STATS first_name = MV_SORT(VALUES(first_name)) BY first_letter -| SORT first_letter -``` - -In this example, the `VALUES` function is used to return all values of the `first_name` field in a group as a multivalued field. The `MV_SORT` function is then used to sort these values. - -Please note that this function is in technical preview and may be changed or removed in a future release. It is not recommended to use `VALUES` on production environments. \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-where.txt b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-where.txt deleted file mode 100644 index 3c8e9ab1bd14b..0000000000000 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/esql_docs/esql-where.txt +++ /dev/null @@ -1,65 +0,0 @@ -## WHERE - -The `WHERE` command in ES|QL is a processing command that produces a table containing all the rows from the input table for which the provided condition evaluates to true. This command is particularly useful in filtering data based on specific conditions. - -The `WHERE` command supports various functions and operators, including date math for retrieving data from a specific time range, `LIKE` and `RLIKE` for filtering data based on string patterns, and the `IN` operator for testing whether a field or expression equals an element in a list of literals, fields, or expressions. - -However, it's important to note that the `WHERE` command has certain limitations. For instance, it does not support configurations where the `_source` field is disabled. Also, full-text search is not yet supported because of the way ES|QL treats `text` values. - -### Syntax: - -`WHERE expression` - -#### Parameters: - -- `expression`: A boolean expression. - -### Examples: - -Here are some examples of how the `WHERE` command can be used in different scenarios: - -1. Filtering employees who are still hired: - - ```esql -FROM employees -| KEEP first_name, last_name, still_hired -| WHERE still_hired == true -``` - -2. Retrieving the last hour of logs: - - ```esql -FROM sample_data -| WHERE @timestamp > NOW() - 1 hour -``` - -3. Filtering employees based on the length of their first name: - - ```esql -FROM employees -| KEEP first_name, last_name, height -| WHERE LENGTH(first_name) < 4 -``` - -4. Filtering data based on string patterns using `LIKE`: - - ```esql -FROM employees -| WHERE first_name LIKE "?b*" -| KEEP first_name, last_name -``` - -5. Filtering data based on string patterns using `RLIKE`: - - ```esql -FROM employees -| WHERE first_name RLIKE ".leja.*" -| KEEP first_name, last_name -``` - -6. Using the `IN` operator to test whether a field or expression equals an element in a list: - - ```esql -ROW a = 1, b = 4, c = 3 -| WHERE c-a IN (3, b / 2, a) -``` \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/get_errors_with_commands.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/get_errors_with_commands.ts index b25c79161f79b..636a37ba14fe2 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/get_errors_with_commands.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/get_errors_with_commands.ts @@ -6,7 +6,7 @@ */ import type { EditorError, ESQLMessage } from '@kbn/esql-ast'; -import { splitIntoCommands } from './correct_common_esql_mistakes'; +import { splitIntoCommands } from '@kbn/inference-plugin/common'; export function getErrorsWithCommands(query: string, errors: Array) { const asCommands = splitIntoCommands(query); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts index 797d85fc10341..13c2bee278c8a 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/index.ts @@ -5,73 +5,29 @@ * 2.0. */ -import Fs from 'fs'; -import { keyBy, mapValues, once, pick } from 'lodash'; -import pLimit from 'p-limit'; -import Path from 'path'; -import { lastValueFrom, startWith } from 'rxjs'; -import { promisify } from 'util'; -import { FunctionVisibility, MessageRole } from '@kbn/observability-ai-assistant-plugin/common'; +import { isChatCompletionChunkEvent, isOutputEvent } from '@kbn/inference-plugin/common'; +import { naturalLanguageToEsql } from '@kbn/inference-plugin/server'; import { - VisualizeESQLUserIntention, - VISUALIZE_ESQL_USER_INTENTIONS, -} from '@kbn/observability-ai-assistant-plugin/common/functions/visualize_esql'; -import { - concatenateChatCompletionChunks, - ConcatenatedMessage, -} from '@kbn/observability-ai-assistant-plugin/common/utils/concatenate_chat_completion_chunks'; -import { emitWithConcatenatedMessage } from '@kbn/observability-ai-assistant-plugin/common/utils/emit_with_concatenated_message'; + FunctionVisibility, + MessageAddEvent, + MessageRole, + StreamingChatResponseEventType, +} from '@kbn/observability-ai-assistant-plugin/common'; import { createFunctionResponseMessage } from '@kbn/observability-ai-assistant-plugin/common/utils/create_function_response_message'; +import { map } from 'rxjs'; +import { v4 } from 'uuid'; import type { FunctionRegistrationParameters } from '..'; -import { correctCommonEsqlMistakes } from './correct_common_esql_mistakes'; import { runAndValidateEsqlQuery } from './validate_esql_query'; -import { INLINE_ESQL_QUERY_REGEX } from './constants'; +import { convertMessagesForInference } from '../../../common/convert_messages_for_inference'; export const QUERY_FUNCTION_NAME = 'query'; export const EXECUTE_QUERY_NAME = 'execute_query'; -const readFile = promisify(Fs.readFile); -const readdir = promisify(Fs.readdir); - -const loadSystemMessage = once(async () => { - const data = await readFile(Path.join(__dirname, './system_message.txt')); - return data.toString('utf-8'); -}); - -const loadEsqlDocs = once(async () => { - const dir = Path.join(__dirname, './esql_docs'); - const files = (await readdir(dir)).filter((file) => Path.extname(file) === '.txt'); - - if (!files.length) { - return {}; - } - - const limiter = pLimit(10); - return keyBy( - await Promise.all( - files.map((file) => - limiter(async () => { - const data = (await readFile(Path.join(dir, file))).toString('utf-8'); - const filename = Path.basename(file, '.txt'); - - const keyword = filename - .replace('esql-', '') - .replace('agg-', '') - .replaceAll('-', '_') - .toUpperCase(); - - return { - keyword: keyword === 'STATS_BY' ? 'STATS' : keyword, - data, - }; - }) - ) - ), - 'keyword' - ); -}); - -export function registerQueryFunction({ functions, resources }: FunctionRegistrationParameters) { +export function registerQueryFunction({ + functions, + resources, + pluginsStart, +}: FunctionRegistrationParameters) { functions.registerInstruction(({ availableFunctionNames }) => availableFunctionNames.includes(QUERY_FUNCTION_NAME) ? `You MUST use the "${QUERY_FUNCTION_NAME}" function when the user wants to: @@ -97,8 +53,16 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra functions.registerFunction( { name: EXECUTE_QUERY_NAME, - visibility: FunctionVisibility.UserOnly, - description: 'Display the results of an ES|QL query.', + visibility: FunctionVisibility.Internal, + description: `Execute a generated ES|QL query on behalf of the user. The results + will be returned to you. + + You must use this function if the user is asking for the result of a query, + such as a metric or list of things, but does not want to visualize it in + a table or chart. You do NOT need to ask permission to execute the query + after generating it, use the "${EXECUTE_QUERY_NAME}" function directly instead. + + Do not use when the user just asks for an example.`, parameters: { type: 'object', properties: { @@ -137,345 +101,83 @@ export function registerQueryFunction({ functions, resources }: FunctionRegistra functions.registerFunction( { name: QUERY_FUNCTION_NAME, - description: `This function generates, executes and/or visualizes a query based on the user's request. It also explains how ES|QL works and how to convert queries from one language to another. Make sure you call one of the get_dataset functions first if you need index or field names. This function takes no input.`, + description: `This function generates, executes and/or visualizes a query + based on the user's request. It also explains how ES|QL works and how to + convert queries from one language to another. Make sure you call one of + the get_dataset functions first if you need index or field names. This + function takes no input.`, visibility: FunctionVisibility.AssistantOnly, }, - async ({ messages, chat }, signal) => { - const [systemMessage, esqlDocs] = await Promise.all([loadSystemMessage(), loadEsqlDocs()]); - - const withEsqlSystemMessage = (message?: string) => [ - { - '@timestamp': new Date().toISOString(), - message: { role: MessageRole.System, content: `${systemMessage}\n${message ?? ''}` }, - }, - // remove the query function request - ...messages.filter((msg) => msg.message.role !== MessageRole.System), - ]; - - const userQuestion = messages - .concat() - .reverse() - .find((message) => message.message.role === MessageRole.User && !message.message.name); + async ({ messages, connectorId }, signal) => { + const esqlFunctions = functions + .getFunctions() + .filter( + (fn) => + fn.definition.name === EXECUTE_QUERY_NAME || fn.definition.name === 'visualize_query' + ) + .map((fn) => fn.definition); + + const actions = functions.getActions(); + + const events$ = naturalLanguageToEsql({ + client: pluginsStart.inference.getClient({ request: resources.request }), + connectorId, + messages: convertMessagesForInference( + // remove system message and query function request + messages.filter((message) => message.message.role !== MessageRole.System).slice(0, -1) + ), + logger: resources.logger, + tools: Object.fromEntries( + actions + .concat(esqlFunctions) + .map((fn) => [fn.name, { description: fn.description, schema: fn.parameters }]) + ), + }); - const abbreviatedUserQuestion = userQuestion!.message.content!.substring(0, 50); + const chatMessageId = v4(); - const source$ = ( - await chat('classify_esql', { - messages: withEsqlSystemMessage().concat( - createFunctionResponseMessage({ - name: QUERY_FUNCTION_NAME, + return events$.pipe( + map((event) => { + if (isOutputEvent(event)) { + return createFunctionResponseMessage({ content: {}, - }).message, - { - '@timestamp': new Date().toISOString(), + name: QUERY_FUNCTION_NAME, + data: event.output, + }); + } + if (isChatCompletionChunkEvent(event)) { + return { + id: chatMessageId, + type: StreamingChatResponseEventType.ChatCompletionChunk, message: { - role: MessageRole.User, - content: `Use the classify_esql tool attached to this conversation - to classify the user's request in the user message before this ("${abbreviatedUserQuestion}..."). - and get more information about specific functions and commands - you think are candidates for answering the question. - - Examples for functions and commands: - Do you need to group data? Request \`STATS\`. - Extract data? Request \`DISSECT\` AND \`GROK\`. - Convert a column based on a set of conditionals? Request \`EVAL\` and \`CASE\`. - - ONLY use ${VisualizeESQLUserIntention.executeAndReturnResults} if you are absolutely sure - it is executable. If one of the get_dataset_info functions were not called before, OR if - one of the get_dataset_info functions returned no data, opt for an explanation only and - mention that there is no data for these indices. You can still use - ${VisualizeESQLUserIntention.generateQueryOnly} and generate an example ES|QL query. - - For determining the intention of the user, the following options are available: - - ${VisualizeESQLUserIntention.generateQueryOnly}: the user only wants to generate the query, - but not run it, or they ask a general question about ES|QL. - - ${VisualizeESQLUserIntention.executeAndReturnResults}: the user wants to execute the query, - and have the assistant return/analyze/summarize the results. they don't need a - visualization. - - ${VisualizeESQLUserIntention.visualizeAuto}: The user wants to visualize the data from the - query, but wants us to pick the best visualization type, or their preferred - visualization is unclear. - - These intentions will display a specific visualization: - ${VisualizeESQLUserIntention.visualizeBar} - ${VisualizeESQLUserIntention.visualizeDonut} - ${VisualizeESQLUserIntention.visualizeHeatmap} - ${VisualizeESQLUserIntention.visualizeLine} - ${VisualizeESQLUserIntention.visualizeArea} - ${VisualizeESQLUserIntention.visualizeTable} - ${VisualizeESQLUserIntention.visualizeTagcloud} - ${VisualizeESQLUserIntention.visualizeTreemap} - ${VisualizeESQLUserIntention.visualizeWaffle} - ${VisualizeESQLUserIntention.visualizeXy} - - Some examples: - - "I want a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} - "... Just show me the query" => ${VisualizeESQLUserIntention.generateQueryOnly} - "Create a query that ..." => ${VisualizeESQLUserIntention.generateQueryOnly} - - "Show me the avg of x" => ${VisualizeESQLUserIntention.executeAndReturnResults} - "Show me the results of y" => ${VisualizeESQLUserIntention.executeAndReturnResults} - "Display the sum of z" => ${VisualizeESQLUserIntention.executeAndReturnResults} - - "Show me the avg of x over time" => ${VisualizeESQLUserIntention.visualizeAuto} - "I want a bar chart of ... " => ${VisualizeESQLUserIntention.visualizeBar} - "I want to see a heat map of ..." => ${VisualizeESQLUserIntention.visualizeHeatmap} - `, + content: event.content, }, - } - ), - signal, - functions: [ - { - name: 'classify_esql', - description: `Use this function to determine: - - what ES|QL functions and commands are candidates for answering the user's question - - whether the user has requested a query, and if so, it they want it to be executed, or just shown. - - All parameters are required. Make sure the functions and commands you request are available in the - system message. - `, - parameters: { - type: 'object', - properties: { - commands: { - type: 'array', - items: { - type: 'string', - }, - description: - 'A list of processing or source commands that are referenced in the list of commands in this conversation', - }, - functions: { - type: 'array', - items: { - type: 'string', - }, - description: - 'A list of functions that are referenced in the list of functions in this conversation', - }, - intention: { - type: 'string', - description: `What the user\'s intention is.`, - enum: VISUALIZE_ESQL_USER_INTENTIONS, - }, - }, - required: ['commands', 'functions', 'intention'], - }, - }, - ], - functionCall: 'classify_esql', - }) - ).pipe(concatenateChatCompletionChunks()); - - const response = await lastValueFrom(source$); - - if (!response.message.function_call.arguments) { - resources.logger.debug( - () => - `LLM should have called "classify_esql", but instead responded with the following message: ${JSON.stringify( - response.message - )}` - ); - throw new Error( - 'LLM did not call classify_esql function during query generation, execute the "query" function and try again' - ); - } - - const args = JSON.parse(response.message.function_call.arguments) as { - commands?: string[]; - functions?: string[]; - intention: VisualizeESQLUserIntention; - }; - - const keywords = [ - ...(args.commands ?? []), - ...(args.functions ?? []), - 'SYNTAX', - 'OVERVIEW', - 'OPERATORS', - ].map((keyword) => keyword.toUpperCase()); - - const messagesToInclude = mapValues(pick(esqlDocs, keywords), ({ data }) => data); - - let userIntentionMessage: string; - - switch (args.intention) { - case VisualizeESQLUserIntention.executeAndReturnResults: - userIntentionMessage = `When you generate a query, it will automatically be executed and its results returned to you. The user does not need to do anything for this.`; - break; - - case VisualizeESQLUserIntention.generateQueryOnly: - userIntentionMessage = `Any generated query will not be executed automatically, the user needs to do this themselves.`; - break; - - default: - userIntentionMessage = `The generated query will automatically be visualized to the user, displayed below your message. The user does not need to do anything for this.`; - break; - } - - const queryFunctionResponseMessage = createFunctionResponseMessage({ - name: QUERY_FUNCTION_NAME, - content: {}, - data: { - // add the included docs for debugging - documentation: { - intention: args.intention, - keywords, - files: messagesToInclude, - }, - }, - }); + }; + } - const esqlResponse$ = await chat('answer_esql_question', { - messages: [ - ...withEsqlSystemMessage().concat(queryFunctionResponseMessage.message), - { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.Assistant, - content: '', - function_call: { - name: 'get_esql_info', - arguments: JSON.stringify(args), + const fnCall = event.toolCalls[0] + ? { + name: event.toolCalls[0].function.name, + arguments: JSON.stringify(event.toolCalls[0].function.arguments), trigger: MessageRole.Assistant as const, - }, - }, - }, - { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.User, - name: 'get_esql_info', - content: JSON.stringify({ - documentation: messagesToInclude, - }), - }, - }, - { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.Assistant, - content: 'Thank you for providing the ES|QL info. What can I help you with?', - }, - }, - { - '@timestamp': new Date().toISOString(), - message: { - role: MessageRole.User, - content: `Answer the user's question that was previously asked ("${abbreviatedUserQuestion}...") using the attached documentation. Take into account any previous errors from the \`${EXECUTE_QUERY_NAME}\` or \`visualize_query\` function. - - Format any ES|QL query as follows: - \`\`\`esql - - \`\`\` - - Respond in plain text. Do not attempt to use a function. - - You must use commands and functions for which you have requested documentation. - - ${ - args.intention !== VisualizeESQLUserIntention.generateQueryOnly - ? `DO NOT UNDER ANY CIRCUMSTANCES generate more than a single query. - If multiple queries are needed, do it as a follow-up step. Make this clear to the user. For example: - - Human: plot both yesterday's and today's data. - - Assistant: Here's how you can plot yesterday's data: - \`\`\`esql - - \`\`\` - - Let's see that first. We'll look at today's data next. - - Human: - - Assistant: Let's look at today's data: - - \`\`\`esql - - \`\`\` - ` - : '' - } - - ${userIntentionMessage} - - DO NOT UNDER ANY CIRCUMSTANCES use commands or functions that are not a capability of ES|QL - as mentioned in the system message and documentation. When converting queries from one language - to ES|QL, make sure that the functions are available and documented in ES|QL. - E.g., for SPL's LEN, use LENGTH. For IF, use CASE. - - `, - }, - }, - ], - signal, - functions: functions.getActions(), - }); - - return esqlResponse$.pipe( - emitWithConcatenatedMessage(async (msg) => { - msg.message.content = msg.message.content.replaceAll( - INLINE_ESQL_QUERY_REGEX, - (_match, query) => { - const correction = correctCommonEsqlMistakes(query); - if (correction.isCorrection) { - resources.logger.debug( - `Corrected query, from: \n${correction.input}\nto:\n${correction.output}` - ); } - return '```esql\n' + correction.output + '\n```'; - } - ); - - if (msg.message.function_call.name) { - return msg; - } + : undefined; - const esqlQuery = msg.message.content.match( - new RegExp(INLINE_ESQL_QUERY_REGEX, 'ms') - )?.[1]; - - let functionCall: ConcatenatedMessage['message']['function_call'] | undefined; - - if ( - !args.intention || - !esqlQuery || - args.intention === VisualizeESQLUserIntention.generateQueryOnly - ) { - functionCall = undefined; - } else if (args.intention === VisualizeESQLUserIntention.executeAndReturnResults) { - functionCall = { - name: EXECUTE_QUERY_NAME, - arguments: JSON.stringify({ query: esqlQuery }), - trigger: MessageRole.Assistant as const, - }; - } else { - functionCall = { - name: 'visualize_query', - arguments: JSON.stringify({ query: esqlQuery, intention: args.intention }), - trigger: MessageRole.Assistant as const, - }; - } - - return { - ...msg, + const messageAddEvent: MessageAddEvent = { + type: StreamingChatResponseEventType.MessageAdd, + id: chatMessageId, message: { - ...msg.message, - ...(functionCall - ? { - function_call: functionCall, - } - : {}), + '@timestamp': new Date().toISOString(), + message: { + content: event.content, + role: MessageRole.Assistant, + function_call: fnCall, + }, }, }; - }), - startWith(queryFunctionResponseMessage) + + return messageAddEvent; + }) ); } ); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts index 0b72dfd1de32d..ac26846f940e6 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/query/validate_esql_query.ts @@ -11,7 +11,7 @@ import type { ElasticsearchClient } from '@kbn/core/server'; import { ESQLSearchResponse, ESQLRow } from '@kbn/es-types'; import { esFieldTypeToKibanaFieldType } from '@kbn/field-types'; import { DatatableColumn, DatatableColumnType } from '@kbn/expressions-plugin/common'; -import { splitIntoCommands } from './correct_common_esql_mistakes'; +import { splitIntoCommands } from '@kbn/inference-plugin/common'; export async function runAndValidateEsqlQuery({ query, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts index 30cce3f0b37b3..320459d203f9e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts @@ -35,6 +35,7 @@ import type { import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import type { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; +import type { InferenceServerStart, InferenceServerSetup } from '@kbn/inference-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ObservabilityAIAssistantAppServerStart {} @@ -53,6 +54,7 @@ export interface ObservabilityAIAssistantAppPluginStartDependencies { dataViews: DataViewsServerPluginStart; cloud?: CloudStart; serverless?: ServerlessPluginStart; + inference: InferenceServerStart; } export interface ObservabilityAIAssistantAppPluginSetupDependencies { @@ -68,4 +70,5 @@ export interface ObservabilityAIAssistantAppPluginSetupDependencies { observability: ObservabilityPluginSetup; cloud?: CloudSetup; serverless?: ServerlessPluginSetup; + inference: InferenceServerSetup; } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json index 282363e50ec3f..bc92d37d3cd70 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json @@ -70,7 +70,8 @@ "@kbn/cloud-plugin", "@kbn/observability-plugin", "@kbn/esql-datagrid", - "@kbn/alerting-comparators" + "@kbn/alerting-comparators", + "@kbn/inference-plugin" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/constants.ts b/x-pack/plugins/observability_solution/observability_shared/common/embeddable_grouping.ts similarity index 68% rename from x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/constants.ts rename to x-pack/plugins/observability_solution/observability_shared/common/embeddable_grouping.ts index bfb65b58f3158..dba342aa71306 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/common/constants.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/embeddable_grouping.ts @@ -4,17 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { i18n } from '@kbn/i18n'; -export const COMMON_SLO_GROUPING = [ +export const COMMON_OBSERVABILITY_GROUPING = [ { - id: 'slos', + id: 'observability', getDisplayName: () => - i18n.translate('xpack.slo.common.constants.grouping.legacy', { + i18n.translate('xpack.observabilityShared.common.constants.grouping', { defaultMessage: 'Observability', }), getIconType: () => { - return 'visGauge'; + return 'online'; }, + order: -1, }, ]; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/index.ts index 7889eda66bd4a..083bcdd2debde 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/index.ts @@ -188,3 +188,5 @@ export { TopNFunctionsLocatorDefinition, HOSTS_LOCATOR_ID, } from './locators'; + +export { COMMON_OBSERVABILITY_GROUPING } from './embeddable_grouping'; diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_alerts_panel_action.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_alerts_panel_action.tsx index 63926aa24cd82..68e985d7d5580 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_alerts_panel_action.tsx +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_alerts_panel_action.tsx @@ -12,21 +12,21 @@ import { type UiActionsActionDefinition, } from '@kbn/ui-actions-plugin/public'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { ADD_SLO_ALERTS_ACTION_ID, SLO_ALERTS_EMBEDDABLE_ID, } from '../embeddable/slo/alerts/constants'; import { SloPublicPluginsStart, SloPublicStart } from '..'; -import { COMMON_SLO_GROUPING } from '../embeddable/slo/common/constants'; export function createAddAlertsPanelAction( getStartServices: CoreSetup['getStartServices'] ): UiActionsActionDefinition { return { id: ADD_SLO_ALERTS_ACTION_ID, - grouping: COMMON_SLO_GROUPING, + grouping: COMMON_OBSERVABILITY_GROUPING, getIconType: () => 'alert', - order: 20, + order: 10, isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); }, diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_burn_rate_panel_action.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_burn_rate_panel_action.tsx index 0b00d33b4cf6a..02490cf1bf7f8 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_burn_rate_panel_action.tsx +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_burn_rate_panel_action.tsx @@ -12,20 +12,20 @@ import { IncompatibleActionError, type UiActionsActionDefinition, } from '@kbn/ui-actions-plugin/public'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { SloPublicPluginsStart, SloPublicStart } from '..'; import { ADD_BURN_RATE_ACTION_ID, SLO_BURN_RATE_EMBEDDABLE_ID, } from '../embeddable/slo/burn_rate/constants'; -import { COMMON_SLO_GROUPING } from '../embeddable/slo/common/constants'; export function createBurnRatePanelAction( getStartServices: CoreSetup['getStartServices'] ): UiActionsActionDefinition { return { id: ADD_BURN_RATE_ACTION_ID, - grouping: COMMON_SLO_GROUPING, - order: 30, + grouping: COMMON_OBSERVABILITY_GROUPING, + order: 20, getIconType: () => 'visGauge', isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx index 8d311bfdce70b..9ba0b7a7a8677 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_error_budget_action.tsx @@ -12,19 +12,19 @@ import { type UiActionsActionDefinition, } from '@kbn/ui-actions-plugin/public'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { ADD_SLO_ERROR_BUDGET_ACTION_ID, SLO_ERROR_BUDGET_ID, } from '../embeddable/slo/error_budget/constants'; import { SloPublicPluginsStart, SloPublicStart } from '..'; -import { COMMON_SLO_GROUPING } from '../embeddable/slo/common/constants'; export function createAddErrorBudgetPanelAction( getStartServices: CoreSetup['getStartServices'] ): UiActionsActionDefinition { return { id: ADD_SLO_ERROR_BUDGET_ACTION_ID, - grouping: COMMON_SLO_GROUPING, - order: 10, + grouping: COMMON_OBSERVABILITY_GROUPING, + order: 6, getIconType: () => 'visLine', isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_overview_panel_action.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_overview_panel_action.tsx index 49d2d269d4cdd..c4b6e5009382d 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/create_overview_panel_action.tsx +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/create_overview_panel_action.tsx @@ -12,20 +12,20 @@ import { type UiActionsActionDefinition, } from '@kbn/ui-actions-plugin/public'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { ADD_SLO_OVERVIEW_ACTION_ID, SLO_OVERVIEW_EMBEDDABLE_ID, } from '../embeddable/slo/overview/constants'; import { SloPublicPluginsStart, SloPublicStart } from '..'; -import { COMMON_SLO_GROUPING } from '../embeddable/slo/common/constants'; export function createOverviewPanelAction( getStartServices: CoreSetup['getStartServices'] ): UiActionsActionDefinition { return { id: ADD_SLO_OVERVIEW_ACTION_ID, - grouping: COMMON_SLO_GROUPING, - order: 30, + grouping: COMMON_OBSERVABILITY_GROUPING, + order: 20, getIconType: () => 'visGauge', isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); diff --git a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/rest_api.ts b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/rest_api.ts index 0003360c707b6..23ac30a5ff7b1 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/rest_api.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/rest_api.ts @@ -26,6 +26,7 @@ export enum SYNTHETICS_API_URLS { SYNTHETICS_OVERVIEW = '/internal/synthetics/overview', PINGS = '/internal/synthetics/pings', PING_STATUSES = '/internal/synthetics/ping_statuses', + OVERVIEW_TRENDS = '/internal/synthetics/overview_trends', OVERVIEW_STATUS = `/internal/synthetics/overview_status`, INDEX_SIZE = `/internal/synthetics/index_size`, AGENT_POLICIES = `/internal/synthetics/agent_policies`, diff --git a/x-pack/plugins/observability_solution/synthetics/common/runtime_types/monitor_management/monitor_types.ts b/x-pack/plugins/observability_solution/synthetics/common/runtime_types/monitor_management/monitor_types.ts index 6f0ef862137e1..c0383eaea8b39 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/runtime_types/monitor_management/monitor_types.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/runtime_types/monitor_management/monitor_types.ts @@ -395,6 +395,7 @@ export const MonitorOverviewItemCodec = t.intersection([ schedule: t.string, }), t.partial({ + status: t.string, projectId: t.string, }), ]); diff --git a/x-pack/plugins/observability_solution/synthetics/common/types/index.ts b/x-pack/plugins/observability_solution/synthetics/common/types/index.ts index be369427c47e7..6544898d54a64 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/types/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/types/index.ts @@ -8,3 +8,4 @@ export * from './synthetics_monitor'; export * from './monitor_validation'; export * from './default_alerts'; +export * from './overview'; diff --git a/x-pack/plugins/observability_solution/synthetics/common/types/overview.ts b/x-pack/plugins/observability_solution/synthetics/common/types/overview.ts new file mode 100644 index 0000000000000..4982f0f408fcf --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/common/types/overview.ts @@ -0,0 +1,32 @@ +/* + * 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. + */ + +export interface TrendKey { + configId: string; + locationId: string; +} + +export type TrendRequest = TrendKey & { schedule: string }; + +export interface TrendDatum { + x: number; + y: number; +} + +export interface OverviewTrend { + configId: string; + locationId: string; + data: TrendDatum[]; + count: number; + min: number; + max: number; + avg: number; + sum: number; + median: number; +} + +export type TrendTable = Record; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/constants.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/constants.ts index 5afcf2d3026b4..2299452f4accd 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/constants.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/constants.ts @@ -5,22 +5,7 @@ * 2.0. */ -import { i18n } from '@kbn/i18n'; - export const SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE = 'SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE'; export const SYNTHETICS_MONITORS_EMBEDDABLE = 'SYNTHETICS_MONITORS_EMBEDDABLE'; -export const COMMON_SYNTHETICS_GROUPING = [ - { - id: 'synthetics', - getDisplayName: () => - i18n.translate('xpack.synthetics.common.constants.grouping.legacy', { - defaultMessage: 'Synthetics', - }), - getIconType: () => { - return 'online'; - }, - }, -]; - export const ALL_VALUE = '*'; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_monitors_overview_panel_action.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_monitors_overview_panel_action.tsx index aa7355c4e1fec..c3f935add49c4 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_monitors_overview_panel_action.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_monitors_overview_panel_action.tsx @@ -12,8 +12,9 @@ import { } from '@kbn/ui-actions-plugin/public'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import type { StartServicesAccessor } from '@kbn/core-lifecycle-browser'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { ClientPluginsStart } from '../../../plugin'; -import { COMMON_SYNTHETICS_GROUPING, SYNTHETICS_MONITORS_EMBEDDABLE } from '../constants'; +import { SYNTHETICS_MONITORS_EMBEDDABLE } from '../constants'; export const ADD_SYNTHETICS_MONITORS_OVERVIEW_ACTION_ID = 'CREATE_SYNTHETICS_MONITORS_OVERVIEW_EMBEDDABLE'; @@ -23,8 +24,8 @@ export function createMonitorsOverviewPanelAction( ): UiActionsActionDefinition { return { id: ADD_SYNTHETICS_MONITORS_OVERVIEW_ACTION_ID, - grouping: COMMON_SYNTHETICS_GROUPING, - order: 30, + grouping: COMMON_OBSERVABILITY_GROUPING, + order: 5, getIconType: () => 'play', isCompatible: async ({ embeddable }) => { return apiIsPresentationContainer(embeddable); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_stats_overview_panel_action.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_stats_overview_panel_action.tsx index a3b2c67be88fe..9f88e38c3640c 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_stats_overview_panel_action.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/embeddables/ui_actions/create_stats_overview_panel_action.tsx @@ -11,8 +11,9 @@ import { } from '@kbn/ui-actions-plugin/public'; import { EmbeddableApiContext } from '@kbn/presentation-publishing'; import type { StartServicesAccessor } from '@kbn/core-lifecycle-browser'; +import { COMMON_OBSERVABILITY_GROUPING } from '@kbn/observability-shared-plugin/common'; import { ClientPluginsStart } from '../../../plugin'; -import { COMMON_SYNTHETICS_GROUPING, SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE } from '../constants'; +import { SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE } from '../constants'; export const ADD_SYNTHETICS_OVERVIEW_ACTION_ID = 'CREATE_SYNTHETICS_STATS_OVERVIEW_EMBEDDABLE'; @@ -21,8 +22,8 @@ export function createStatusOverviewPanelAction( ): UiActionsActionDefinition { return { id: ADD_SYNTHETICS_OVERVIEW_ACTION_ID, - grouping: COMMON_SYNTHETICS_GROUPING, - order: 30, + grouping: COMMON_OBSERVABILITY_GROUPING, + order: 5, getIconType: () => 'online', isCompatible: async ({ embeddable }) => { const { compatibilityCheck } = await import('./compatibility_check'); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_group_item.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_group_item.tsx index 7fea62b348edd..5b024f3c70331 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_group_item.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_group_item.tsx @@ -23,8 +23,9 @@ import { useKey } from 'react-use'; import { OverviewLoader } from '../overview_loader'; import { useFilteredGroupMonitors } from './use_filtered_group_monitors'; import { MonitorOverviewItem } from '../../types'; -import { FlyoutParamProps, OverviewGridItem } from '../overview_grid_item'; import { selectOverviewStatus } from '../../../../../state/overview_status'; +import { MetricItem } from '../metric_item'; +import { FlyoutParamProps } from '../types'; const PER_ROW = 4; const DEFAULT_ROW_SIZE = 2; @@ -163,7 +164,7 @@ export const GroupGridItem = ({ key={`${monitor.id}-${monitor.location?.id}`} data-test-subj="syntheticsOverviewGridItem" > - + ))} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx index e9069d6dfdf7c..ad7d406d76946 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/grid_by_group/grid_items_by_group.tsx @@ -18,8 +18,8 @@ import { import { useFilters } from '../../../common/monitor_filters/use_filters'; import { GroupGridItem } from './grid_group_item'; import { ConfigKey, MonitorOverviewItem } from '../../../../../../../../common/runtime_types'; -import { FlyoutParamProps } from '../overview_grid_item'; import { selectOverviewState, selectServiceLocationsState } from '../../../../../state'; +import { FlyoutParamProps } from '../types'; export const GridItemsByGroup = ({ loaded, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx index 516c545f3e680..57c50bc54a5bf 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/metric_item.tsx @@ -6,16 +6,21 @@ */ import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; import { Chart, Settings, Metric, MetricTrendShape } from '@elastic/charts'; -import { EuiPanel } from '@elastic/eui'; +import { EuiPanel, EuiSpacer } from '@elastic/eui'; import { DARK_THEME } from '@elastic/charts'; import { useTheme } from '@kbn/observability-shared-plugin/public'; -import { useDispatch, useSelector } from 'react-redux'; import moment from 'moment'; +import { useSelector, useDispatch } from 'react-redux'; + import { MetricItemBody } from './metric_item/metric_item_body'; -import { MetricItemExtra } from './metric_item/metric_item_extra'; -import { selectErrorPopoverState, toggleErrorPopoverOpen } from '../../../../state'; +import { + selectErrorPopoverState, + selectOverviewTrends, + toggleErrorPopoverOpen, +} from '../../../../state'; import { useLocationName, useStatusByLocationOverview } from '../../../../hooks'; import { formatDuration } from '../../../../utils/formatting'; import { MonitorOverviewItem } from '../../../../../../../common/runtime_types'; @@ -26,6 +31,9 @@ import { toggleTestNowFlyoutAction, } from '../../../../state/manual_test_runs'; import { MetricItemIcon } from './metric_item_icon'; +import { MetricItemExtra } from './metric_item/metric_item_extra'; + +const METRIC_ITEM_HEIGHT = 160; export const getColor = ( theme: ReturnType, @@ -49,20 +57,14 @@ export const getColor = ( export const MetricItem = ({ monitor, - stats, - data, onClick, + style, }: { monitor: MonitorOverviewItem; - data: Array<{ x: number; y: number }>; - stats: { - medianDuration: number; - avgDuration: number; - minDuration: number; - maxDuration: number; - }; + style?: React.CSSProperties; onClick: (params: { id: string; configId: string; location: string; locationId: string }) => void; }) => { + const trendData = useSelector(selectOverviewTrends)[monitor.configId + monitor.location.id]; const [isPopoverOpen, setIsPopoverOpen] = useState(false); const isErrorPopoverOpen = useSelector(selectErrorPopoverState); const locationName = useLocationName(monitor); @@ -77,7 +79,10 @@ export const MetricItem = ({ const dispatch = useDispatch(); return ( -
+
, + trend: trendData?.data ?? [], + extra: trendData ? ( + + ) : ( +
+ +
+ ), valueFormatter: (d: number) => formatDuration(d), color: getColor(theme, monitor.isEnabled, status), body: , @@ -167,6 +188,7 @@ export const MetricItem = ({ /> )}
+
); }; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx deleted file mode 100644 index 3ea7d5e0ba5b3..0000000000000 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.test.tsx +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { render } from '../../../../utils/testing/rtl_helpers'; -import { waitFor } from '@testing-library/react'; -import { MonitorOverviewItem } from '../types'; -import { OverviewGrid } from './overview_grid'; -import * as hooks from '../../../../hooks/use_last_50_duration_chart'; - -describe('Overview Grid', () => { - const locationIdToName: Record = { - us_central: 'Us Central', - us_east: 'US East', - }; - const getMockData = (): MonitorOverviewItem[] => { - const data: MonitorOverviewItem[] = []; - for (let i = 0; i < 20; i++) { - data.push({ - id: `${i}`, - configId: `${i}`, - location: { - id: 'us_central', - isServiceManaged: true, - }, - name: `Monitor ${i}`, - isEnabled: true, - isStatusAlertEnabled: true, - type: 'browser', - tags: [], - schedule: '60', - }); - data.push({ - id: `${i}`, - configId: `${i}`, - location: { - id: 'us_east', - isServiceManaged: true, - }, - name: `Monitor ${i}`, - isEnabled: true, - isStatusAlertEnabled: true, - type: 'browser', - tags: [], - schedule: '60', - }); - } - return data; - }; - - const getMockChart = (): Array<{ x: number; y: number }> => { - const hits = []; - for (let i = 0; i < 20; i++) { - hits.push({ - x: i, - y: i, - }); - } - return hits; - }; - - const perPage = 20; - - it('renders correctly', async () => { - jest.spyOn(hooks, 'useLast50DurationChart').mockReturnValue({ - data: getMockChart(), - avgDuration: 30000, - minDuration: 0, - maxDuration: 50000, - medianDuration: 15000, - loading: false, - }); - - const { getByText, getAllByTestId, queryByText } = render(, { - state: { - overview: { - pageState: { - perPage, - }, - data: { - monitors: getMockData(), - allMonitorIds: [], // not critical for this test - total: getMockData().length, - }, - loaded: true, - loading: false, - }, - overviewStatus: { - status: { - downConfigs: {}, - upConfigs: {}, - allConfigs: getMockData().reduce((acc, cur) => { - acc[`${cur.id}-${locationIdToName[cur.location.id]}`] = { - configId: cur.configId, - monitorQueryId: cur.id, - location: locationIdToName[cur.location.id], - status: 'down', - }; - return acc; - }, {} as Record), - }, - }, - serviceLocations: { - locations: [ - { - id: 'us_central', - label: 'Us Central', - }, - { - id: 'us_east', - label: 'US East', - }, - ], - locationsLoaded: true, - loading: false, - }, - }, - }); - - await waitFor(() => { - expect(getByText('Showing')).toBeInTheDocument(); - expect(getByText('40')).toBeInTheDocument(); - expect(getByText('Monitors')).toBeInTheDocument(); - expect(queryByText('Showing all monitors')).not.toBeInTheDocument(); - expect(getAllByTestId('syntheticsOverviewGridItem').length).toEqual(perPage); - }); - }); - - it('displays showing all monitors label when reaching the end of the list', async () => { - jest.spyOn(hooks, 'useLast50DurationChart').mockReturnValue({ - data: getMockChart(), - avgDuration: 30000, - minDuration: 0, - maxDuration: 50000, - medianDuration: 15000, - loading: false, - }); - - const { getByText } = render(, { - state: { - overview: { - pageState: { - perPage, - }, - data: { - monitors: getMockData().slice(0, 16), - allMonitorIds: [], // not critical for this test - total: getMockData().length, - }, - loaded: true, - loading: false, - }, - overviewStatus: { - status: { - downConfigs: {}, - upConfigs: {}, - allConfigs: getMockData().reduce((acc, cur) => { - acc[`${cur.id}-${locationIdToName[cur.location.id]}`] = { - configId: cur.configId, - monitorQueryId: cur.id, - location: locationIdToName[cur.location.id], - status: 'down', - }; - return acc; - }, {} as Record), - }, - }, - serviceLocations: { - locations: [ - { - id: 'us_central', - label: 'Us Central', - }, - { - id: 'us_east', - label: 'US East', - }, - ], - locationsLoaded: true, - loading: false, - }, - }, - }); - - expect(getByText('Showing all monitors')).toBeInTheDocument(); - }); -}); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx index 3da7b03f3ad9e..76e52685736b1 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/overview_grid.tsx @@ -4,55 +4,77 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useState, useRef, memo, useCallback, useEffect } from 'react'; +import React, { useState, memo, useCallback, useEffect, useMemo } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; +import InfiniteLoader from 'react-window-infinite-loader'; +import { FixedSizeList, ListChildComponentProps } from 'react-window'; import { EuiFlexGroup, EuiFlexItem, - EuiFlexGrid, EuiSpacer, EuiButtonEmpty, EuiText, - EuiProgress, + EuiAutoSizer, + EuiAutoSize, } from '@elastic/eui'; +import type { TrendRequest } from '../../../../../../../common/types'; import { SYNTHETICS_MONITORS_EMBEDDABLE } from '../../../../../embeddables/constants'; import { AddToDashboard } from '../../../common/components/add_to_dashboard'; import { useOverviewStatus } from '../../hooks/use_overview_status'; -import { useInfiniteScroll } from './use_infinite_scroll'; import { GridItemsByGroup } from './grid_by_group/grid_items_by_group'; import { GroupFields } from './grid_by_group/group_fields'; import { fetchMonitorOverviewAction, quietFetchOverviewAction, + refreshOverviewTrends, selectOverviewState, + selectOverviewTrends, setFlyoutConfig, + trendStatsBatch, } from '../../../../state/overview'; -import { useMonitorsSortedByStatus } from '../../../../hooks/use_monitors_sorted_by_status'; import { OverviewLoader } from './overview_loader'; import { OverviewPaginationInfo } from './overview_pagination_info'; -import { FlyoutParamProps, OverviewGridItem } from './overview_grid_item'; import { SortFields } from './sort_fields'; import { NoMonitorsFound } from '../../common/no_monitors_found'; import { MonitorDetailFlyout } from './monitor_detail_flyout'; +import { useSyntheticsRefreshContext } from '../../../../contexts'; +import { MetricItem } from './metric_item'; +import { FlyoutParamProps } from './types'; +import { MonitorOverviewItem } from '../types'; +import { useMonitorsSortedByStatus } from '../../../../hooks/use_monitors_sorted_by_status'; + +const ITEM_HEIGHT = 172; +const ROW_COUNT = 4; +const MAX_LIST_HEIGHT = 800; +const MIN_BATCH_SIZE = 20; +const LIST_THRESHOLD = 12; + +interface ListItem { + configId: string; + location: { id: string }; +} export const OverviewGrid = memo(() => { const { status } = useOverviewStatus({ scopeStatusByLocation: true }); + const monitorsSortedByStatus: MonitorOverviewItem[] = + useMonitorsSortedByStatus().monitorsSortedByStatus; const { data: { monitors }, flyoutConfig, loaded, - loading, pageState, groupBy: { field: groupField }, } = useSelector(selectOverviewState); + const trendData = useSelector(selectOverviewTrends); const { perPage } = pageState; + const [page, setPage] = useState(1); + const [maxItem, setMaxItem] = useState(0); + const [currentIndex, setCurrentIndex] = useState(0); const dispatch = useDispatch(); - const intersectionRef = useRef(null); - const { monitorsSortedByStatus } = useMonitorsSortedByStatus(); // fetch overview for all other page state changes useEffect(() => { @@ -64,12 +86,46 @@ export const OverviewGrid = memo(() => { [dispatch] ); const hideFlyout = useCallback(() => dispatch(setFlyoutConfig(null)), [dispatch]); + const { lastRefresh } = useSyntheticsRefreshContext(); const forceRefreshCallback = useCallback( () => dispatch(quietFetchOverviewAction.get(pageState)), [dispatch, pageState] ); - const { currentMonitors } = useInfiniteScroll({ intersectionRef, monitorsSortedByStatus }); + useEffect(() => { + if (monitorsSortedByStatus.length && maxItem) { + const batch: TrendRequest[] = []; + const chunk = monitorsSortedByStatus.slice(0, (maxItem + 1) * ROW_COUNT); + for (const item of chunk) { + if (trendData[item.configId + item.location.id] === undefined) { + batch.push({ + configId: item.configId, + locationId: item.location.id, + schedule: item.schedule, + }); + } + } + if (batch.length) dispatch(trendStatsBatch.get(batch)); + } + }, [dispatch, maxItem, monitorsSortedByStatus, trendData]); + + const listHeight = Math.min( + ITEM_HEIGHT * Math.ceil(monitorsSortedByStatus.length / ROW_COUNT), + MAX_LIST_HEIGHT + ); + + const listItems: ListItem[][] = useMemo(() => { + const acc: ListItem[][] = []; + for (let i = 0; i < monitorsSortedByStatus.length; i += ROW_COUNT) { + acc.push(monitorsSortedByStatus.slice(i, i + ROW_COUNT)); + } + return acc; + }, [monitorsSortedByStatus]); + + const listRef: React.LegacyRef> | undefined = React.createRef(); + useEffect(() => { + dispatch(refreshOverviewTrends.get()); + }, [dispatch, lastRefresh]); // Display no monitors found when down, up, or disabled filter produces no results if (status && !monitorsSortedByStatus.length && loaded) { @@ -102,63 +158,111 @@ export const OverviewGrid = memo(() => { - - {loading && } - - <> + +
{groupField === 'none' ? ( - loaded && currentMonitors.length ? ( - - {currentMonitors.map((monitor) => ( - + {({ width }: EuiAutoSize) => ( + + listItems[idx].every((m) => !!trendData[m.configId + m.location.id]) + } + itemCount={listItems.length} + loadMoreItems={(_start: number, stop: number) => + setMaxItem(Math.max(maxItem, stop)) + } + minimumBatchSize={MIN_BATCH_SIZE} + threshold={LIST_THRESHOLD} > - - - ))} - + {({ onItemsRendered }) => ( + + {({ + index: listIndex, + style, + data: listData, + }: React.PropsWithChildren>) => { + setCurrentIndex(listIndex); + return ( + + {listData[listIndex].map((_, idx) => ( + + + + ))} + {listData[listIndex].length % ROW_COUNT !== 0 && + // Adds empty items to fill out row + Array.from({ + length: ROW_COUNT - listData[listIndex].length, + }).map((_, idx) => )} + + ); + }} + + )} + + )} + ) : ( ) ) : ( )} - -
-
- {groupField === 'none' && ( - - {currentMonitors.length === monitors.length && ( - - {SHOWING_ALL_MONITORS_LABEL} - - )} - {currentMonitors.length === monitors.length && currentMonitors.length > perPage && ( - - window.scrollTo(0, 0)} - iconType="sortUp" - iconSide="right" - size="xs" - > - {SCROLL_TO_TOP_LABEL} - - - )} - - )} + {groupField === 'none' && + loaded && + // display this footer when user scrolls to end of list + currentIndex * ROW_COUNT + ROW_COUNT >= monitorsSortedByStatus.length && ( + <> + + + {monitorsSortedByStatus.length === monitors.length && ( + + {SHOWING_ALL_MONITORS_LABEL} + + )} + {monitorsSortedByStatus.length === monitors.length && + monitorsSortedByStatus.length > perPage && ( + + { + window.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); + listRef.current?.scrollToItem(0); + }} + iconType="sortUp" + iconSide="right" + size="xs" + > + {SCROLL_TO_TOP_LABEL} + + + )} + + + )} {flyoutConfig?.configId && flyoutConfig?.location && ( void; -}) => { - const { timestamp } = useStatusByLocationOverview({ - configId: monitor.configId, - locationId: monitor.location.id, - }); - - const { data, medianDuration, maxDuration, avgDuration, minDuration } = useLast50DurationChart({ - locationId: monitor.location?.id, - monitorId: monitor.id, - timestamp, - schedule: monitor.schedule, - }); - return ( - - ); -}; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/types.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/types.ts new file mode 100644 index 0000000000000..a2e7d8581e657 --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitors_page/overview/overview/types.ts @@ -0,0 +1,13 @@ +/* + * 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. + */ + +export interface FlyoutParamProps { + id: string; + configId: string; + location: string; + locationId: string; +} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/index.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/index.ts index 2e5d9e2f76d66..ce0163ff74fb9 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/index.ts @@ -10,8 +10,6 @@ export * from './use_url_params'; export * from './use_breadcrumbs'; export * from './use_enablement'; export * from './use_locations'; -export * from './use_last_x_checks'; -export * from './use_last_50_duration_chart'; export * from './use_location_name'; export * from './use_status_by_location'; export * from './use_status_by_location_overview'; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.test.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.test.ts deleted file mode 100644 index 4c149ce74667f..0000000000000 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.test.ts +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook } from '@testing-library/react-hooks'; -import * as hooks from './use_last_x_checks'; -import { useLast50DurationChart } from './use_last_50_duration_chart'; -import { WrappedHelper } from '../utils/testing'; - -describe('useLast50DurationChart', () => { - const getMockHits = (): Array<{ 'monitor.duration.us': number[] | undefined }> => { - const hits = []; - for (let i = 0; i < 10; i++) { - hits.push({ - 'monitor.duration.us': [i], - }); - } - return hits; - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('returns expected results', () => { - jest.spyOn(hooks, 'useLastXChecks').mockReturnValue({ hits: getMockHits(), loading: false }); - - const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '1' }), - { wrapper: WrappedHelper } - ); - expect(result.current).toEqual({ - medianDuration: 5, - maxDuration: 9, - minDuration: 0, - avgDuration: 4.5, - data: [ - { - x: 0, - y: 9, - }, - { - x: 1, - y: 8, - }, - { - x: 2, - y: 7, - }, - { - x: 3, - y: 6, - }, - { - x: 4, - y: 5, - }, - { - x: 5, - y: 4, - }, - { - x: 6, - y: 3, - }, - { - x: 7, - y: 2, - }, - { - x: 8, - y: 1, - }, - { - x: 9, - y: 0, - }, - ], - loading: false, - }); - }); - - it('handles undefined monitor duration', () => { - const hitsWithAnUndefinedDuration = [...getMockHits()]; - hitsWithAnUndefinedDuration[1] = { 'monitor.duration.us': undefined }; - - jest - .spyOn(hooks, 'useLastXChecks') - .mockReturnValue({ hits: hitsWithAnUndefinedDuration, loading: false }); - const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '10' }), - { wrapper: WrappedHelper } - ); - - const data = [ - { - x: 0, - y: 9, - }, - { - x: 1, - y: 8, - }, - { - x: 2, - y: 7, - }, - { - x: 3, - y: 6, - }, - { - x: 4, - y: 5, - }, - { - x: 5, - y: 4, - }, - { - x: 6, - y: 3, - }, - { - x: 7, - y: 2, - }, - { - x: 9, - y: 0, - }, - ]; - - expect(result.current).toEqual({ - medianDuration: [...data].sort((a, b) => a.y - b.y)[Math.floor(data.length / 2)].y, - maxDuration: 9, - minDuration: 0, - avgDuration: 4.4, - data, - loading: false, - }); - }); - - it('passes proper params to useLastXChecks', () => { - const hitsWithAnUndefinedDuration = [...getMockHits()]; - hitsWithAnUndefinedDuration[1] = { 'monitor.duration.us': undefined }; - const monitorId = 'mock-id'; - const locationId = 'loc'; - - const spy = jest - .spyOn(hooks, 'useLastXChecks') - .mockReturnValue({ hits: hitsWithAnUndefinedDuration, loading: false }); - renderHook(() => useLast50DurationChart({ monitorId, locationId, schedule: '120' }), { - wrapper: WrappedHelper, - }); - - expect(spy).toBeCalledTimes(1); - expect(spy).toBeCalledWith({ - monitorId, - locationId, - fields: ['monitor.duration.us'], - size: 50, - schedule: '120', - }); - }); - - it('returns loading properly', () => { - const loading = true; - - jest.spyOn(hooks, 'useLastXChecks').mockReturnValue({ hits: getMockHits(), loading }); - const { result } = renderHook( - () => useLast50DurationChart({ monitorId: 'mock-id', locationId: 'loc', schedule: '3' }), - { wrapper: WrappedHelper } - ); - renderHook( - () => useLast50DurationChart({ monitorId: 'test-id', locationId: 'loc', schedule: '5' }), - { - wrapper: WrappedHelper, - } - ); - expect(result.current.loading).toEqual(loading); - }); -}); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts deleted file mode 100644 index f08e025a48540..0000000000000 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_50_duration_chart.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useMemo } from 'react'; -import { useLastXChecks } from './use_last_x_checks'; - -const fields = ['monitor.duration.us']; - -export function useLast50DurationChart({ - monitorId, - locationId, - timestamp, - schedule, -}: { - monitorId: string; - timestamp?: string; - locationId: string; - schedule: string; -}) { - const { hits, loading } = useLastXChecks<{ - 'monitor.duration.us': number[] | undefined; - }>({ - monitorId, - locationId, - fields, - size: 50, - timestamp, - schedule, - }); - const { data, median, min, max, avg } = useMemo(() => { - if (loading) { - return { - data: [], - median: 0, - avg: 0, - min: 0, - max: 0, - }; - } - - // calculate min, max, average duration and median - - const coords = hits - .reverse() // results are returned in desc order by timestamp. Reverse to ensure the data is in asc order by timestamp - .map((hit, index) => { - const duration = hit?.['monitor.duration.us']?.[0]; - if (duration === undefined) { - return null; - } - return { - x: index, - y: duration, - }; - }) - .filter((item) => item !== null); - - const sortedByDuration = [...hits].sort( - (a, b) => (a?.['monitor.duration.us']?.[0] || 0) - (b?.['monitor.duration.us']?.[0] || 0) - ); - - return { - data: coords as Array<{ x: number; y: number }>, - median: sortedByDuration[Math.floor(hits.length / 2)]?.['monitor.duration.us']?.[0] || 0, - avg: - sortedByDuration.reduce((acc, curr) => acc + (curr?.['monitor.duration.us']?.[0] || 0), 0) / - hits.length, - min: sortedByDuration[0]?.['monitor.duration.us']?.[0] || 0, - max: sortedByDuration[sortedByDuration.length - 1]?.['monitor.duration.us']?.[0] || 0, - }; - }, [hits, loading]); - - return useMemo( - () => ({ - data, - medianDuration: median, - avgDuration: avg, - minDuration: min, - maxDuration: max, - loading, - }), - [data, median, avg, min, max, loading] - ); -} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx deleted file mode 100644 index 8c16902357273..0000000000000 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.test.tsx +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { renderHook } from '@testing-library/react-hooks'; -import { getTimeRangeFilter, useLastXChecks } from './use_last_x_checks'; -import { WrappedHelper } from '../utils/testing'; -import * as searchHooks from './use_redux_es_search'; -import { SYNTHETICS_INDEX_PATTERN } from '../../../../common/constants'; - -describe('useLastXChecks', () => { - const getMockHits = (): Array<{ fields: { 'monitor.duration.us': number[] | undefined } }> => { - const hits = []; - for (let i = 0; i < 10; i++) { - hits.push({ - fields: { - 'monitor.duration.us': [i], - }, - }); - } - return hits; - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('returns expected results', () => { - jest.spyOn(searchHooks, 'useReduxEsSearch').mockReturnValue({ - data: { hits: { hits: getMockHits() } }, - } as any); - - const { result } = renderHook( - () => - useLastXChecks({ - monitorId: 'mock-id', - locationId: 'loc', - size: 30, - fields: ['monitor.duration.us'], - schedule: '10', - }), - { wrapper: WrappedHelper } - ); - expect(result.current).toEqual({ - hits: [ - { - 'monitor.duration.us': [0], - }, - { - 'monitor.duration.us': [1], - }, - { - 'monitor.duration.us': [2], - }, - { - 'monitor.duration.us': [3], - }, - { - 'monitor.duration.us': [4], - }, - { - 'monitor.duration.us': [5], - }, - { - 'monitor.duration.us': [6], - }, - { - 'monitor.duration.us': [7], - }, - { - 'monitor.duration.us': [8], - }, - { - 'monitor.duration.us': [9], - }, - ], - loading: false, - }); - }); - - it('passes proper params', () => { - const spy = jest.spyOn(searchHooks, 'useReduxEsSearch').mockReturnValue({ - data: { hits: { hits: getMockHits() } }, - } as any); - - const fields = ['monitor.summary']; - const size = 30; - - renderHook( - () => - useLastXChecks({ - monitorId: 'mock-id', - locationId: 'loc', - size, - fields, - schedule: '120', - }), - { wrapper: WrappedHelper } - ); - expect(spy).toBeCalledTimes(1); - expect(spy).toBeCalledWith( - expect.objectContaining({ body: expect.objectContaining({ fields, size }) }), - expect.anything(), - expect.anything() - ); - }); - - it('returns loading properly', () => { - jest.spyOn(searchHooks, 'useReduxEsSearch').mockReturnValue({ - data: { hits: { hits: getMockHits() } }, - } as any); - - const { result } = renderHook( - () => - useLastXChecks({ - monitorId: 'mock-id', - locationId: 'loc', - size: 30, - fields: ['monitor.duration.us'], - schedule: '240', - }), - { wrapper: WrappedHelper } - ); - expect(result.current.loading).toEqual(false); - }); - - it('returns loading true when there is no data', () => { - jest.spyOn(searchHooks, 'useReduxEsSearch').mockReturnValue({ - data: undefined, - } as any); - - const { result } = renderHook( - () => - useLastXChecks({ - monitorId: 'mock-id', - locationId: 'loc', - size: 30, - fields: ['monitor.duration.us'], - schedule: '1', - }), - { wrapper: WrappedHelper } - ); - expect(result.current.loading).toEqual(true); - }); - - it('calls useEsSearch with correct index', () => { - const spy = jest.spyOn(searchHooks, 'useReduxEsSearch').mockReturnValue({ - data: { hits: { hits: getMockHits() } }, - } as any); - - const WrapperWithState = ({ children }: { children: React.ReactElement }) => { - return ( - - {children} - - ); - }; - - renderHook( - () => - useLastXChecks({ - monitorId: 'mock-id', - locationId: 'loc', - size: 30, - fields: ['monitor.duration.us'], - schedule: '3', - }), - { wrapper: WrapperWithState } - ); - expect(spy).toBeCalledWith( - expect.objectContaining({ index: SYNTHETICS_INDEX_PATTERN }), - expect.anything(), - expect.anything() - ); - }); -}); - -describe('getTimeRangeFilter', () => { - it.each([ - [1, 'now-1h'], - [3, 'now-3h'], - [5, 'now-5h'], - [10, 'now-9h'], - [60, 'now-50h'], - [120, 'now-100h'], - [240, 'now-200h'], - ])('returns expected filter', (val, res) => { - const filter = getTimeRangeFilter(String(val)); - expect(filter).toEqual({ - range: { - '@timestamp': { - gte: res, - lte: 'now', - }, - }, - }); - }); -}); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts deleted file mode 100644 index 7b155f53272dd..0000000000000 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_last_x_checks.ts +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useMemo } from 'react'; -import { useSelector } from 'react-redux'; -import { createEsParams } from '@kbn/observability-shared-plugin/public'; -import { useReduxEsSearch } from './use_redux_es_search'; -import { Ping } from '../../../../common/runtime_types'; - -import { - EXCLUDE_RUN_ONCE_FILTER, - getLocationFilter, - FINAL_SUMMARY_FILTER, -} from '../../../../common/constants/client_defaults'; -import { selectServiceLocationsState } from '../state'; -import { useSyntheticsRefreshContext } from '../contexts/synthetics_refresh_context'; -import { SYNTHETICS_INDEX_PATTERN, UNNAMED_LOCATION } from '../../../../common/constants'; - -export const getTimeRangeFilter = (schedule: string) => { - const inMinutes = Number(schedule); - const fiftyChecksInMinutes = inMinutes * 50; - const hours = Math.ceil(fiftyChecksInMinutes / 60); - return { - range: { - '@timestamp': { - gte: `now-${hours}h`, - lte: 'now', - }, - }, - }; -}; - -export function useLastXChecks({ - monitorId, - locationId, - fields = ['*'], - size = 50, - timestamp, - schedule, -}: { - monitorId: string; - schedule: string; - locationId: string; - timestamp?: string; - fields?: string[]; - size?: number; -}) { - const { lastRefresh } = useSyntheticsRefreshContext(); - const { locationsLoaded, locations } = useSelector(selectServiceLocationsState); - - const params = createEsParams({ - index: SYNTHETICS_INDEX_PATTERN, - body: { - size, - query: { - bool: { - filter: [ - FINAL_SUMMARY_FILTER, - EXCLUDE_RUN_ONCE_FILTER, - getTimeRangeFilter(schedule), - { - term: { - 'monitor.id': monitorId, - }, - }, - ], - ...getLocationFilter({ - locationId, - locationName: - locations.find((location) => location.id === locationId)?.label || UNNAMED_LOCATION, - }), - }, - }, - _source: false, - sort: [{ '@timestamp': 'desc' }], - fields, - }, - }); - - const { data } = useReduxEsSearch(params, [lastRefresh], { - name: `zGetLastXChecks/${monitorId}/${locationId}`, - isRequestReady: locationsLoaded && Boolean(timestamp), // don't run query until locations are loaded - }); - - const dataAsJSON = JSON.stringify(data?.hits?.hits); - - return useMemo(() => { - return { - hits: (data?.hits?.hits.map((hit) => hit.fields) as Fields[]) || [], - loading: !data, - }; - }, [dataAsJSON]); // eslint-disable-line react-hooks/exhaustive-deps -} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx index 73f9644749351..c0a59c31a8760 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/hooks/use_monitors_sorted_by_status.tsx @@ -12,7 +12,10 @@ import { MonitorOverviewItem } from '../../../../common/runtime_types'; import { selectOverviewState } from '../state/overview'; import { useGetUrlParams } from './use_url_params'; -export function useMonitorsSortedByStatus() { +export function useMonitorsSortedByStatus(): { + monitorsSortedByStatus: MonitorOverviewItem[]; + downMonitors: Record | null; +} { const { statusFilter } = useGetUrlParams(); const { status } = useSelector(selectOverviewStatus); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/actions.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/actions.ts index 73e24e6ece6c9..b5098aaa7cbf6 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/actions.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/actions.ts @@ -5,9 +5,10 @@ * 2.0. */ import { createAction } from '@reduxjs/toolkit'; +import { TrendRequest, TrendTable } from '../../../../../common/types'; import { createAsyncAction } from '../utils/actions'; -import { +import type { MonitorOverviewFlyoutConfig, MonitorOverviewPageState, MonitorOverviewState, @@ -33,3 +34,11 @@ export const quietFetchOverviewAction = createAsyncAction< MonitorOverviewPageState, MonitorOverviewResult >('quietFetchOverviewAction'); + +export const refreshOverviewTrends = createAsyncAction( + 'refreshOverviewTrendStats' +); + +export const trendStatsBatch = createAsyncAction( + 'batchTrendStats' +); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/api.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/api.ts index cc496074332b0..2a8e782013651 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/api.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/api.ts @@ -13,8 +13,9 @@ import { OverviewStatus, OverviewStatusCodec, } from '../../../../../common/runtime_types'; +import type { TrendRequest, TrendTable } from '../../../../../common/types'; import { apiService } from '../../../../utils/api_service'; -import { MonitorOverviewPageState } from './models'; +import type { MonitorOverviewPageState } from './models'; function toMonitorOverviewQueryArgs( pageState: MonitorOverviewPageState @@ -58,3 +59,6 @@ export const fetchOverviewStatus = async ( const params = toStatusOverviewQueryArgs(pageState); return apiService.get(SYNTHETICS_API_URLS.OVERVIEW_STATUS, params, OverviewStatusCodec); }; + +export const fetchOverviewTrendStats = async (monitors: TrendRequest[]): Promise => + monitors.length ? apiService.post(SYNTHETICS_API_URLS.OVERVIEW_TRENDS, monitors) : {}; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.test.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.test.ts new file mode 100644 index 0000000000000..ceef406ebbd1b --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.test.ts @@ -0,0 +1,178 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import sagaHelper from 'redux-saga-testing'; +import { call, put, select } from 'redux-saga/effects'; +import { TrendKey, TrendRequest, TrendTable } from '../../../../../common/types'; +import { TRENDS_CHUNK_SIZE, fetchTrendEffect, refreshTrends } from './effects'; +import { trendStatsBatch } from './actions'; +import { fetchOverviewTrendStats as trendsApi } from './api'; +import { selectOverviewState, selectOverviewTrends } from '.'; + +const TEST_TRENDS_LENGTH = 80; + +const generateTrendRequests = () => { + const ar: TrendRequest[] = []; + for (let i = 0; i < TEST_TRENDS_LENGTH; i++) + ar.push({ configId: `configId${i}`, locationId: 'location', schedule: '3' }); + return ar; +}; + +const responseReducer = (acc: Record, curr: TrendKey) => ({ + ...acc, + [curr.configId + curr.locationId]: null, +}); + +describe('overview effects', () => { + describe('fetchTrendEffect', () => { + const trendRequests = generateTrendRequests(); + const firstChunk = trendRequests.slice( + trendRequests.length - TRENDS_CHUNK_SIZE, + trendRequests.length + ); + const secondChunk = trendRequests.slice(0, TEST_TRENDS_LENGTH - TRENDS_CHUNK_SIZE); + const firstChunkResponse = firstChunk.reduce(responseReducer, {}); + const secondChunkResponse = secondChunk.reduce(responseReducer, {}); + + const it = sagaHelper( + fetchTrendEffect(trendStatsBatch.get(trendRequests)) as IterableIterator + ); + + it('calls the `trendsApi` with the first chunk of trend requests', (callResult) => { + expect(callResult).toEqual(call(trendsApi, firstChunk)); + return firstChunkResponse; + }); + + it('sends trends stats success action', (putResult) => { + expect(putResult).toEqual(put(trendStatsBatch.success(firstChunkResponse))); + }); + + it('calls the api for the second chunk', (callResult) => { + expect(callResult).toEqual(call(trendsApi, secondChunk)); + return secondChunkResponse; + }); + + it('sends trends stats success action', (putResult) => { + expect(putResult).toEqual(put(trendStatsBatch.success(secondChunkResponse))); + }); + + it('terminates', (result) => { + expect(result).toBeUndefined(); + }); + }); + + describe('refreshTrends with no data', () => { + const it = sagaHelper(refreshTrends() as IterableIterator); + + it('selects the trends in the table', (selectResult) => { + expect(selectResult).toEqual(select(selectOverviewTrends)); + return { monitor1: null, monitor2: null, monitor3: null }; + }); + + it('selects the overview state', (selectResult) => { + expect(selectResult).toEqual(select(selectOverviewState)); + return { data: { monitors: [] } }; + }); + + it('skips the API if the data is null', (result) => { + expect(result).toBeUndefined(); + }); + }); + + describe('refreshTrends with data', () => { + const it = sagaHelper(refreshTrends() as IterableIterator); + const table: TrendTable = { + monitor1: { + configId: 'monitor1', + locationId: 'location', + data: [{ x: 0, y: 1 }], + count: 1, + median: 1, + min: 0, + max: 0, + avg: 0, + sum: 0, + }, + monitor2: null, + monitor3: { + configId: 'monitor3', + locationId: 'location', + data: [{ x: 0, y: 1 }], + count: 1, + median: 1, + min: 0, + max: 0, + avg: 0, + sum: 0, + }, + }; + + const apiResponse: TrendTable = { + monitor1: { + configId: 'monitor1', + locationId: 'location', + data: [ + { x: 0, y: 1 }, + { x: 1, y: 2 }, + ], + count: 2, + median: 2, + min: 1, + max: 1, + avg: 1, + sum: 1, + }, + monitor2: { + configId: 'monitor2', + locationId: 'location', + data: [ + { x: 0, y: 1 }, + { x: 1, y: 2 }, + ], + count: 2, + median: 2, + min: 1, + max: 1, + avg: 1, + sum: 1, + }, + }; + + it('selects the trends in the table', (selectResult) => { + expect(selectResult).toEqual(select(selectOverviewTrends)); + + return table; + }); + + it('selects the overview state', (selectResults) => { + expect(selectResults).toEqual(select(selectOverviewState)); + return { + data: { + monitors: [ + { configId: 'monitor1', schedule: '3' }, + { configId: 'monitor3', schedule: '3' }, + ], + }, + }; + }); + + it('calls the api for the first chunk', (callResult) => { + expect(callResult).toEqual( + call(trendsApi, [ + { configId: 'monitor1', locationId: 'location', schedule: '3' }, + { configId: 'monitor3', locationId: 'location', schedule: '3' }, + ]) + ); + + return apiResponse; + }); + + it('sends trends stats success action', (putResult) => { + expect(putResult).toEqual(put(trendStatsBatch.success(apiResponse))); + }); + }); +}); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.ts index 71821c46665c7..930c729bde4f7 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/effects.ts @@ -5,10 +5,18 @@ * 2.0. */ -import { debounce } from 'redux-saga/effects'; +import { debounce, call, takeLeading, takeEvery, put, select } from 'redux-saga/effects'; +import type { TrendTable } from '../../../../../common/types'; import { fetchEffectFactory } from '../utils/fetch_effect'; -import { fetchMonitorOverviewAction, quietFetchOverviewAction } from './actions'; -import { fetchMonitorOverview } from './api'; +import { selectOverviewState, selectOverviewTrends } from './selectors'; +import { + fetchMonitorOverviewAction, + quietFetchOverviewAction, + refreshOverviewTrends, + trendStatsBatch, +} from './actions'; +import { fetchMonitorOverview, fetchOverviewTrendStats as trendsApi } from './api'; +import { MonitorOverviewState } from '.'; export function* fetchMonitorOverviewEffect() { yield debounce( @@ -21,3 +29,63 @@ export function* fetchMonitorOverviewEffect() { ) ); } + +export const TRENDS_CHUNK_SIZE = 50; + +export function* fetchTrendEffect( + action: ReturnType +): Generator { + try { + // batch requests LIFO as the user scrolls + for (let i = action.payload.length; i > 0; i -= TRENDS_CHUNK_SIZE) { + const chunk = action.payload.slice(Math.max(i - TRENDS_CHUNK_SIZE, 0), i); + if (chunk.length > 0) { + const trendStats = yield call(trendsApi, chunk); + yield put(trendStatsBatch.success(trendStats)); + } + } + } catch (e: any) { + yield put(trendStatsBatch.fail(e)); + } +} + +export function* fetchOverviewTrendStats() { + yield takeEvery(trendStatsBatch.get, fetchTrendEffect); +} + +export function* refreshTrends(): Generator { + const existingTrends: TrendTable = yield select(selectOverviewTrends); + const overviewState: MonitorOverviewState = yield select(selectOverviewState); + + let acc = {}; + const keys = Object.keys(existingTrends); + while (keys.length) { + const chunk = keys + .splice(0, keys.length < 10 ? keys.length : 40) + .filter( + (key: string) => + existingTrends[key] !== null && + overviewState.data.monitors.some( + ({ configId }) => configId === existingTrends[key]!.configId + ) + ) + .map((key: string) => ({ + configId: existingTrends[key]!.configId, + locationId: existingTrends[key]!.locationId, + schedule: overviewState.data.monitors.find( + ({ configId }) => configId === existingTrends[key]!.configId + )!.schedule, + })); + if (chunk.length) { + const res = yield call(trendsApi, chunk); + acc = { ...acc, ...res }; + } + } + if (Object.keys(acc).length) { + yield put(trendStatsBatch.success(acc)); + } +} + +export function* refreshOverviewTrendStats() { + yield takeLeading(refreshOverviewTrends.get, refreshTrends); +} diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/index.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/index.ts index 665a92aeaf773..74ad8bb7a2a57 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/index.ts @@ -16,6 +16,7 @@ import { setOverviewGroupByAction, setOverviewPageStateAction, toggleErrorPopoverOpen, + trendStatsBatch, } from './actions'; import { enableMonitorAlertAction } from '../monitor_list/actions'; import { ConfigKey } from '../../components/monitor_add_edit/types'; @@ -31,6 +32,7 @@ const initialState: MonitorOverviewState = { sortOrder: 'asc', sortField: 'status', }, + trendStats: {}, groupBy: { field: 'none', order: 'asc' }, flyoutConfig: null, loading: false, @@ -93,6 +95,18 @@ export const monitorOverviewReducer = createReducer(initialState, (builder) => { }) .addCase(toggleErrorPopoverOpen, (state, action) => { state.isErrorPopoverOpen = action.payload; + }) + .addCase(trendStatsBatch.get, (state, action) => { + for (const { configId, locationId } of action.payload) { + if (!state.trendStats[configId + locationId]) { + state.trendStats[configId + locationId] = null; + } + } + }) + .addCase(trendStatsBatch.success, (state, action) => { + for (const key of Object.keys(action.payload)) { + state.trendStats[key] = action.payload[key]; + } }); }); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/models.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/models.ts index 8706ca519d49f..0dbc2100c2fee 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/models.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/models.ts @@ -4,6 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + +import type { TrendTable } from '../../../../../common/types'; import type { MonitorListSortField } from '../../../../../common/runtime_types/monitor_management/sort_field'; import { ConfigKey, MonitorOverviewResult } from '../../../../../common/runtime_types'; @@ -32,6 +34,7 @@ export interface MonitorOverviewState { isErrorPopoverOpen?: string | null; error: IHttpSerializedFetchError | null; groupBy: GroupByState; + trendStats: TrendTable; } export interface GroupByState { diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/selectors.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/selectors.ts index 677b7cc8208d9..98286a3da118f 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/selectors.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/overview/selectors.ts @@ -16,3 +16,7 @@ export const selectErrorPopoverState = createSelector( selectOverviewState, (state) => state.isErrorPopoverOpen ); +export const selectOverviewTrends = createSelector( + selectOverviewState, + ({ trendStats }) => trendStats +); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/root_effect.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/root_effect.ts index 62d671d8e98fd..424c6fa70eed6 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/root_effect.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/root_effect.ts @@ -33,7 +33,11 @@ import { upsertMonitorEffect, fetchMonitorFiltersEffect, } from './monitor_list'; -import { fetchMonitorOverviewEffect } from './overview'; +import { + fetchMonitorOverviewEffect, + fetchOverviewTrendStats, + refreshOverviewTrendStats, +} from './overview'; import { fetchServiceLocationsEffect } from './service_locations'; import { browserJourneyEffects, fetchJourneyStepsEffect } from './browser_journey'; import { fetchPingStatusesEffect } from './ping_status'; @@ -71,5 +75,7 @@ export const rootEffect = function* root(): Generator { fork(getCertsListEffect), fork(getDefaultAlertingEffect), fork(enableDefaultAlertingSilentlyEffect), + fork(fetchOverviewTrendStats), + fork(refreshOverviewTrendStats), ]); }; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts index abfc08919b33a..897be8c4ad970 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts @@ -100,6 +100,7 @@ export const mockState: SyntheticsAppState = { sortOrder: 'asc', sortField: 'name.keyword', }, + trendStats: {}, data: { total: 0, allMonitorIds: [], diff --git a/x-pack/plugins/observability_solution/synthetics/server/lib.ts b/x-pack/plugins/observability_solution/synthetics/server/lib.ts index 12f08d679c89e..63d511a2d2063 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/lib.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/lib.ts @@ -122,8 +122,8 @@ export class SyntheticsEsClient { } async msearch< - TDocument = unknown, - TSearchRequest extends estypes.SearchRequest = estypes.SearchRequest + TSearchRequest extends estypes.SearchRequest = estypes.SearchRequest, + TDocument = unknown >( requests: MsearchMultisearchBody[] ): Promise<{ responses: Array> }> { diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/index.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/index.ts index c97abe44a6c5a..ba3bc0b443fb9 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/routes/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/index.ts @@ -60,6 +60,7 @@ import { getAllSyntheticsMonitorRoute } from './monitor_cruds/get_monitors_list' import { getLocationMonitors } from './settings/private_locations/get_location_monitors'; import { addSyntheticsParamsRoute } from './settings/params/add_param'; import { deleteSyntheticsParamsRoute } from './settings/params/delete_param'; +import { createOverviewTrendsRoute } from './overview_trends/overview_trends'; export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ addSyntheticsProjectMonitorRoute, @@ -101,6 +102,7 @@ export const syntheticsAppRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ getConnectorTypesRoute, createGetDynamicSettingsRoute, createPostDynamicSettingsRoute, + createOverviewTrendsRoute, ]; export const syntheticsAppPublicRestApiRoutes: SyntheticsRestApiRouteFactory[] = [ diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/fetch_trends.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/fetch_trends.ts new file mode 100644 index 0000000000000..b57c634c1bddd --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/fetch_trends.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EXCLUDE_RUN_ONCE_FILTER, SUMMARY_FILTER } from '../../../common/constants/client_defaults'; +import { createEsParams } from '../../lib'; + +export const getFetchTrendsQuery = (configId: string, locationIds: string[], interval: number) => + createEsParams({ + body: { + size: 0, + query: { + bool: { + filter: [ + SUMMARY_FILTER, + EXCLUDE_RUN_ONCE_FILTER, + { + terms: { + 'observer.name': locationIds, + }, + }, + { + term: { + config_id: configId, + }, + }, + { + range: { + '@timestamp': { + gte: `now-${interval}m`, + lte: 'now', + }, + }, + }, + ], + }, + }, + aggs: { + byId: { + terms: { + field: 'config_id', + }, + aggs: { + byLocation: { + terms: { + field: 'observer.name', + }, + aggs: { + last50: { + histogram: { + field: '@timestamp', + interval: interval * 1000, + min_doc_count: 1, + }, + aggs: { + max: { + avg: { + field: 'monitor.duration.us', + }, + }, + }, + }, + stats: { + stats: { + field: 'monitor.duration.us', + }, + }, + median: { + percentiles: { + field: 'monitor.duration.us', + percents: [50], + }, + }, + }, + }, + }, + }, + }, + _source: false, + sort: [ + { + '@timestamp': 'desc', + }, + ], + fields: ['monitor.duration.us'], + }, + }); + +export type TrendsQuery = ReturnType; diff --git a/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/overview_trends.ts b/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/overview_trends.ts new file mode 100644 index 0000000000000..e3d7589160c02 --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/server/routes/overview_trends/overview_trends.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ObjectType, schema } from '@kbn/config-schema'; +import { SYNTHETICS_API_URLS } from '../../../common/constants'; +import { TrendRequest, TrendTable } from '../../../common/types'; +import { getFetchTrendsQuery, TrendsQuery } from './fetch_trends'; +import { SyntheticsRestApiRouteFactory } from '../types'; + +export const getIntervalForCheckCount = (schedule: string, numChecks = 50) => + Number(schedule) * numChecks; + +export const createOverviewTrendsRoute: SyntheticsRestApiRouteFactory = () => ({ + method: 'POST', + path: SYNTHETICS_API_URLS.OVERVIEW_TRENDS, + validate: { + body: schema.arrayOf( + schema.object({ + configId: schema.string(), + locationId: schema.string(), + schedule: schema.string(), + }) + ) as unknown as ObjectType, + }, + handler: async (routeContext): Promise => { + const esClient = routeContext.syntheticsEsClient; + const body = routeContext.request.body as TrendRequest[]; + + const configs = body.reduce( + ( + acc: Record, + { configId, locationId, schedule } + ) => { + if (!acc[configId]) { + acc[configId] = { locations: [locationId], interval: getIntervalForCheckCount(schedule) }; + } else { + acc[configId].locations.push(locationId); + } + return acc; + }, + {} + ); + + const requests = Object.keys(configs).map( + (key) => getFetchTrendsQuery(key, configs[key].locations, configs[key].interval).body + ); + const results = await esClient.msearch(requests); + + let main = {}; + for (const res of results.responses) { + res.aggregations?.byId.buckets.map(({ key, byLocation }) => { + const ret: Record = {}; + for (const location of byLocation.buckets) { + ret[String(key) + String(location.key)] = { + configId: key, + locationId: location.key, + data: location.last50.buckets.map((durationBucket, x) => ({ + x, + y: durationBucket.max.value, + })), + ...location.stats, + median: location.median.values['50.0'], + }; + } + main = { ...main, ...ret }; + }); + } + return main; + }, +}); diff --git a/x-pack/plugins/observability_solution/uptime/common/constants/client_defaults.ts b/x-pack/plugins/observability_solution/uptime/common/constants/client_defaults.ts index 41a5f7c64abed..f627180991025 100644 --- a/x-pack/plugins/observability_solution/uptime/common/constants/client_defaults.ts +++ b/x-pack/plugins/observability_solution/uptime/common/constants/client_defaults.ts @@ -12,9 +12,9 @@ export const CLIENT_DEFAULTS = { // 15 minutes ABSOLUTE_DATE_RANGE_END: 1000 * 60 * 15, /** - * The application auto refreshes every 60s by default. + * The application auto refreshes every 5mins by default. */ - AUTOREFRESH_INTERVAL: 60 * 1000, + AUTOREFRESH_INTERVAL: 5 * 60 * 1000, /** * The application's autorefresh feature is enabled. */ diff --git a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap index 8cc0e164a7e48..9ac11e14be2a7 100644 --- a/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap +++ b/x-pack/plugins/observability_solution/uptime/public/legacy_uptime/hooks/__snapshots__/use_url_params.test.tsx.snap @@ -81,7 +81,7 @@ exports[`useUrlParams deletes keys that do not have truthy values 1`] = ` } >
- {"pagination":"foo","absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":60000,"autorefreshIsPaused":false,"dateRangeStart":"now-12","dateRangeEnd":"now","filters":"","excludedFilters":"","search":"","statusFilter":"","focusConnectorField":false,"query":""} + {"pagination":"foo","absoluteDateRangeStart":20,"absoluteDateRangeEnd":20,"autorefreshInterval":300000,"autorefreshIsPaused":false,"dateRangeStart":"now-12","dateRangeEnd":"now","filters":"","excludedFilters":"","search":"","statusFilter":"","focusConnectorField":false,"query":""}