From 138c0417a7818097a4167cbb7d3057d9714a0cfe Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 17 Jul 2020 12:11:15 +0100 Subject: [PATCH 01/24] skip flaky suite (#60865) --- x-pack/test/api_integration/apis/fleet/agents/enroll.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts b/x-pack/test/api_integration/apis/fleet/agents/enroll.ts index e9f7471f6437e..8a21fbcf24c7d 100644 --- a/x-pack/test/api_integration/apis/fleet/agents/enroll.ts +++ b/x-pack/test/api_integration/apis/fleet/agents/enroll.ts @@ -21,7 +21,8 @@ export default function (providerContext: FtrProviderContext) { let apiKey: { id: string; api_key: string }; let kibanaVersion: string; - describe('fleet_agents_enroll', () => { + // Flaky: https://github.com/elastic/kibana/issues/60865 + describe.skip('fleet_agents_enroll', () => { before(async () => { await esArchiver.loadIfNeeded('fleet/agents'); From 19def177f4806710897e8d148cb06ac4b103a981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Fri, 17 Jul 2020 12:15:15 +0100 Subject: [PATCH 02/24] replacing hard coded links for ela.st (#72240) --- .../observability/public/components/app/header/index.tsx | 5 +---- .../public/components/app/ingest_manager_panel/index.tsx | 2 +- .../observability/public/components/app/resources/index.tsx | 6 +++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/observability/public/components/app/header/index.tsx b/x-pack/plugins/observability/public/components/app/header/index.tsx index 1c6ce766d0901..531e6abf3d236 100644 --- a/x-pack/plugins/observability/public/components/app/header/index.tsx +++ b/x-pack/plugins/observability/public/components/app/header/index.tsx @@ -69,10 +69,7 @@ export const Header = ({ {showGiveFeedback && ( - + {i18n.translate('xpack.observability.home.feedback', { defaultMessage: 'Give us feedback', })} diff --git a/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx b/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx index f7a1deb83fbe4..41bcfa1da7fa1 100644 --- a/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx +++ b/x-pack/plugins/observability/public/components/app/ingest_manager_panel/index.tsx @@ -40,7 +40,7 @@ export const IngestManagerPanel = () => { - + {i18n.translate('xpack.observability.ingestManafer.button', { defaultMessage: 'Try Ingest Manager Beta', })} diff --git a/x-pack/plugins/observability/public/components/app/resources/index.tsx b/x-pack/plugins/observability/public/components/app/resources/index.tsx index c330c358d022a..929802df3329b 100644 --- a/x-pack/plugins/observability/public/components/app/resources/index.tsx +++ b/x-pack/plugins/observability/public/components/app/resources/index.tsx @@ -13,21 +13,21 @@ const resources = [ label: i18n.translate('xpack.observability.resources.documentation', { defaultMessage: 'Documentation', }), - href: 'https://www.elastic.co/guide/en/observability/current/observability-ui.html', + href: 'https://ela.st/observability-documentation', }, { iconType: 'editorComment', label: i18n.translate('xpack.observability.resources.forum', { defaultMessage: 'Discuss forum', }), - href: 'https://discuss.elastic.co/c/observability/', + href: 'https://ela.st/observability-discuss', }, { iconType: 'training', label: i18n.translate('xpack.observability.resources.training', { defaultMessage: 'Observability fundamentals', }), - href: 'https://www.elastic.co/training/observability-fundamentals', + href: 'https://ela.st/observability-training', }, ]; From b4f07de564892c6460acd9f45d9db9e0f57d9b0d Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 17 Jul 2020 15:00:34 +0300 Subject: [PATCH 03/24] [Security Solution][Case] Fix connector's dropdown with conflicting requests (#72037) --- .../cases/components/case_view/index.test.tsx | 28 ++++++++++ .../cases/components/case_view/index.tsx | 54 ++++++++++++++----- .../components/edit_connector/index.test.tsx | 27 +++++++++- .../cases/components/edit_connector/index.tsx | 13 +++-- .../user_action_tree/index.test.tsx | 2 +- .../components/user_action_tree/index.tsx | 5 +- .../cases/containers/use_update_case.test.tsx | 7 +++ .../cases/containers/use_update_case.tsx | 19 ++++++- .../events_viewer/events_viewer.test.tsx | 43 ++++----------- .../ml/anomaly/use_anomalies_table_data.ts | 4 +- .../public/common/containers/source/index.tsx | 4 +- .../rules/fetch_index_patterns.tsx | 4 +- .../timelines/store/timeline/helpers.ts | 4 +- 13 files changed, 154 insertions(+), 60 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx index b93df325b5a8b..4e29db4022e65 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.test.tsx @@ -409,4 +409,32 @@ describe('CaseView ', () => { wrapper.find('button[data-test-subj="push-to-external-service"]').first().prop('disabled') ).toBeTruthy(); }); + + it('should revert to the initial connector in case of failure', async () => { + updateCaseProperty.mockImplementation(({ onError }) => { + onError(); + }); + const wrapper = mount( + + + + + + ); + await wait(); + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); + wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); + wrapper.update(); + await wait(); + wrapper.update(); + expect( + wrapper.find('[data-test-subj="dropdown-connectors"]').at(0).prop('valueOfSelected') + ).toBe('servicenow-1'); + }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx index 3718249479b63..b23169af6ceb3 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx @@ -44,6 +44,13 @@ interface Props { userCanCrud: boolean; } +export interface OnUpdateFields { + key: keyof Case; + value: Case[keyof Case]; + onSuccess?: () => void; + onError?: () => void; +} + const MyWrapper = styled.div` padding: ${({ theme, @@ -88,12 +95,12 @@ export const CaseComponent = React.memo( // Update Fields const onUpdateField = useCallback( - (newUpdateKey: keyof Case, updateValue: Case[keyof Case]) => { + ({ key, value, onSuccess, onError }: OnUpdateFields) => { const handleUpdateNewCase = (newCase: Case) => updateCase({ ...newCase, comments: caseData.comments }); - switch (newUpdateKey) { + switch (key) { case 'title': - const titleUpdate = getTypedPayload(updateValue); + const titleUpdate = getTypedPayload(value); if (titleUpdate.length > 0) { updateCaseProperty({ fetchCaseUserActions, @@ -101,11 +108,13 @@ export const CaseComponent = React.memo( updateValue: titleUpdate, updateCase: handleUpdateNewCase, version: caseData.version, + onSuccess, + onError, }); } break; case 'connectorId': - const connectorId = getTypedPayload(updateValue); + const connectorId = getTypedPayload(value); if (connectorId.length > 0) { updateCaseProperty({ fetchCaseUserActions, @@ -113,11 +122,13 @@ export const CaseComponent = React.memo( updateValue: connectorId, updateCase: handleUpdateNewCase, version: caseData.version, + onSuccess, + onError, }); } break; case 'description': - const descriptionUpdate = getTypedPayload(updateValue); + const descriptionUpdate = getTypedPayload(value); if (descriptionUpdate.length > 0) { updateCaseProperty({ fetchCaseUserActions, @@ -125,28 +136,34 @@ export const CaseComponent = React.memo( updateValue: descriptionUpdate, updateCase: handleUpdateNewCase, version: caseData.version, + onSuccess, + onError, }); } break; case 'tags': - const tagsUpdate = getTypedPayload(updateValue); + const tagsUpdate = getTypedPayload(value); updateCaseProperty({ fetchCaseUserActions, updateKey: 'tags', updateValue: tagsUpdate, updateCase: handleUpdateNewCase, version: caseData.version, + onSuccess, + onError, }); break; case 'status': - const statusUpdate = getTypedPayload(updateValue); - if (caseData.status !== updateValue) { + const statusUpdate = getTypedPayload(value); + if (caseData.status !== value) { updateCaseProperty({ fetchCaseUserActions, updateKey: 'status', updateValue: statusUpdate, updateCase: handleUpdateNewCase, version: caseData.version, + onSuccess, + onError, }); } default: @@ -191,15 +208,28 @@ export const CaseComponent = React.memo( }); const onSubmitConnector = useCallback( - (connectorId) => onUpdateField('connectorId', connectorId), + (connectorId, onSuccess, onError) => + onUpdateField({ + key: 'connectorId', + value: connectorId, + onSuccess, + onError, + }), [onUpdateField] ); - const onSubmitTags = useCallback((newTags) => onUpdateField('tags', newTags), [onUpdateField]); - const onSubmitTitle = useCallback((newTitle) => onUpdateField('title', newTitle), [ + const onSubmitTags = useCallback((newTags) => onUpdateField({ key: 'tags', value: newTags }), [ onUpdateField, ]); + const onSubmitTitle = useCallback( + (newTitle) => onUpdateField({ key: 'title', value: newTitle }), + [onUpdateField] + ); const toggleStatusCase = useCallback( - (e) => onUpdateField('status', e.target.checked ? 'closed' : 'open'), + (e) => + onUpdateField({ + key: 'status', + value: e.target.checked ? 'closed' : 'open', + }), [onUpdateField] ); const handleRefresh = useCallback(() => { diff --git a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx index 251d0b6e81bf8..564ce2e19df00 100644 --- a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.test.tsx @@ -69,10 +69,35 @@ describe('EditConnector ', () => { await act(async () => { wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); await wait(); - expect(onSubmit).toBeCalledWith(sampleConnector); + expect(onSubmit.mock.calls[0][0]).toBe(sampleConnector); }); }); + it('Revert to initial external service on error', async () => { + onSubmit.mockImplementation((connector, onSuccess, onError) => { + onError(new Error('An error has occurred')); + }); + const wrapper = mount( + + + + ); + + wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); + wrapper.update(); + wrapper.find('button[data-test-subj="dropdown-connector-servicenow-2"]').simulate('click'); + wrapper.update(); + + expect(wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().exists()).toBeTruthy(); + + await act(async () => { + wrapper.find(`[data-test-subj="edit-connectors-submit"]`).last().simulate('click'); + await wait(); + wrapper.update(); + }); + expect(formHookMock.setFieldValue).toHaveBeenCalledWith('connector', 'none'); + }); + it('Resets selector on cancel', async () => { const props = { ...defaultProps, diff --git a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx index 11938a55181d3..95ef3353a025f 100644 --- a/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/edit_connector/index.tsx @@ -15,6 +15,8 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import styled, { css } from 'styled-components'; +import { noop } from 'lodash/fp'; + import * as i18n from '../../translations'; import { Form, UseField, useForm } from '../../../shared_imports'; import { schema } from './schema'; @@ -25,7 +27,7 @@ interface EditConnectorProps { connectors: Connector[]; disabled?: boolean; isLoading: boolean; - onSubmit: (a: string[]) => void; + onSubmit: (a: string[], onSuccess: () => void, onError: () => void) => void; selectedConnector: string; } @@ -61,6 +63,11 @@ export const EditConnector = React.memo( [selectedConnector] ); + const onError = useCallback(() => { + setFieldValue('connector', selectedConnector); + setConnectorHasChanged(false); + }, [setFieldValue, selectedConnector]); + const onCancelConnector = useCallback(() => { setFieldValue('connector', selectedConnector); setConnectorHasChanged(false); @@ -69,10 +76,10 @@ export const EditConnector = React.memo( const onSubmitConnector = useCallback(async () => { const { isValid, data: newData } = await submit(); if (isValid && newData.connector) { - onSubmit(newData.connector); + onSubmit(newData.connector, noop, onError); setConnectorHasChanged(false); } - }, [submit, onSubmit]); + }, [submit, onSubmit, onError]); return ( diff --git a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx index 285584cf2233c..23f1fb222a841 100644 --- a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.test.tsx @@ -277,7 +277,7 @@ describe('UserActionTree ', () => { ) .exists() ).toEqual(false); - expect(onUpdateField).toBeCalledWith('description', sampleData.content); + expect(onUpdateField).toBeCalledWith({ key: 'description', value: sampleData.content }); }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx index 52c2779a93fc0..0c1da8694bf1a 100644 --- a/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/user_action_tree/index.tsx @@ -21,6 +21,7 @@ import { UserActionMarkdown } from './user_action_markdown'; import { Connector } from '../../../../../case/common/api/cases'; import { CaseServices } from '../../containers/use_get_case_user_actions'; import { parseString } from '../../containers/utils'; +import { OnUpdateFields } from '../case_view'; export interface UserActionTreeProps { caseServices: CaseServices; @@ -30,7 +31,7 @@ export interface UserActionTreeProps { fetchUserActions: () => void; isLoadingDescription: boolean; isLoadingUserActions: boolean; - onUpdateField: (updateKey: keyof Case, updateValue: string | string[]) => void; + onUpdateField: ({ key, value, onSuccess, onError }: OnUpdateFields) => void; updateCase: (newCase: Case) => void; userCanCrud: boolean; } @@ -138,7 +139,7 @@ export const UserActionTree = React.memo( content={caseData.description} isEditable={manageMarkdownEditIds.includes(DESCRIPTION_ID)} onSaveContent={(content: string) => { - onUpdateField(DESCRIPTION_ID, content); + onUpdateField({ key: DESCRIPTION_ID, value: content }); }} onChangeEditable={handleManageMarkdownEditId} /> diff --git a/x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx index 86cfc3459c595..01e64fa780d52 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.test.tsx @@ -16,12 +16,17 @@ describe('useUpdateCase', () => { const fetchCaseUserActions = jest.fn(); const updateCase = jest.fn(); const updateKey: UpdateKey = 'description'; + const onSuccess = jest.fn(); + const onError = jest.fn(); + const sampleUpdate = { fetchCaseUserActions, updateKey, updateValue: 'updated description', updateCase, version: basicCase.version, + onSuccess, + onError, }; beforeEach(() => { jest.clearAllMocks(); @@ -79,6 +84,7 @@ describe('useUpdateCase', () => { }); expect(fetchCaseUserActions).toBeCalledWith(basicCase.id); expect(updateCase).toBeCalledWith(basicCase); + expect(onSuccess).toHaveBeenCalled(); }); }); @@ -114,6 +120,7 @@ describe('useUpdateCase', () => { isError: true, updateCaseProperty: result.current.updateCaseProperty, }); + expect(onError).toHaveBeenCalled(); }); }); }); diff --git a/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx index 18dd9f5278503..6ede91b572dba 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_update_case.tsx @@ -5,6 +5,7 @@ */ import { useReducer, useCallback } from 'react'; + import { displaySuccessToast, errorToToaster, @@ -33,6 +34,8 @@ export interface UpdateByKey { fetchCaseUserActions?: (caseId: string) => void; updateCase?: (newCase: Case) => void; version: string; + onSuccess?: () => void; + onError?: () => void; } type Action = @@ -81,7 +84,15 @@ export const useUpdateCase = ({ caseId }: { caseId: string }): UseUpdateCase => const [, dispatchToaster] = useStateToaster(); const dispatchUpdateCaseProperty = useCallback( - async ({ fetchCaseUserActions, updateKey, updateValue, updateCase, version }: UpdateByKey) => { + async ({ + fetchCaseUserActions, + updateKey, + updateValue, + updateCase, + version, + onSuccess, + onError, + }: UpdateByKey) => { let cancel = false; const abortCtrl = new AbortController(); @@ -102,6 +113,9 @@ export const useUpdateCase = ({ caseId }: { caseId: string }): UseUpdateCase => } dispatch({ type: 'FETCH_SUCCESS' }); displaySuccessToast(i18n.UPDATED_CASE(response[0].title), dispatchToaster); + if (onSuccess) { + onSuccess(); + } } } catch (error) { if (!cancel) { @@ -111,6 +125,9 @@ export const useUpdateCase = ({ caseId }: { caseId: string }): UseUpdateCase => dispatchToaster, }); dispatch({ type: 'FETCH_FAILURE' }); + if (onError) { + onError(); + } } } return () => { diff --git a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx index 8c1f69279d31c..2a7cbff5ee149 100644 --- a/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.test.tsx @@ -32,18 +32,18 @@ mockUseResizeObserver.mockImplementation(() => ({})); const from = '2019-08-26T22:10:56.791Z'; const to = '2019-08-27T22:10:56.794Z'; +const defaultMocks = { + browserFields: mockBrowserFields, + indexPatterns: mockIndexPattern, + docValueFields: mockDocValueFields, + isLoading: false, +}; + describe('EventsViewer', () => { const mount = useMountAppended(); beforeEach(() => { - mockUseFetchIndexPatterns.mockImplementation(() => [ - { - browserFields: mockBrowserFields, - indexPatterns: mockIndexPattern, - docValueFields: mockDocValueFields, - isLoading: false, - }, - ]); + mockUseFetchIndexPatterns.mockImplementation(() => [{ ...defaultMocks }]); }); test('it renders the "Showing..." subtitle with the expected event count', async () => { @@ -69,14 +69,7 @@ describe('EventsViewer', () => { }); test('it does NOT render fetch index pattern is loading', async () => { - mockUseFetchIndexPatterns.mockImplementation(() => [ - { - browserFields: mockBrowserFields, - indexPatterns: mockIndexPattern, - docValueFields: mockDocValueFields, - isLoading: true, - }, - ]); + mockUseFetchIndexPatterns.mockImplementation(() => [{ ...defaultMocks, isLoading: true }]); const wrapper = mount( @@ -98,14 +91,7 @@ describe('EventsViewer', () => { }); test('it does NOT render when start is empty', async () => { - mockUseFetchIndexPatterns.mockImplementation(() => [ - { - browserFields: mockBrowserFields, - indexPatterns: mockIndexPattern, - docValueFields: mockDocValueFields, - isLoading: true, - }, - ]); + mockUseFetchIndexPatterns.mockImplementation(() => [{ ...defaultMocks, isLoading: true }]); const wrapper = mount( @@ -127,14 +113,7 @@ describe('EventsViewer', () => { }); test('it does NOT render when end is empty', async () => { - mockUseFetchIndexPatterns.mockImplementation(() => [ - { - browserFields: mockBrowserFields, - indexPatterns: mockIndexPattern, - docValueFields: mockDocValueFields, - isLoading: true, - }, - ]); + mockUseFetchIndexPatterns.mockImplementation(() => [{ ...defaultMocks, isLoading: true }]); const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts index a6bbdee79cf04..6fbb308672e5d 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/anomaly/use_anomalies_table_data.ts @@ -129,8 +129,8 @@ export const useAnomaliesTableData = ({ influencersOrCriteriaToString(influencers), // eslint-disable-next-line react-hooks/exhaustive-deps influencersOrCriteriaToString(criteriaFields), - startDate, - endDate, + startDateMs, + endDateMs, skip, userPermissions, // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx index 8c03ab7b9f508..cc43dd6f42772 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.tsx @@ -81,7 +81,7 @@ export const getBrowserFields = memoizeOne( (newArgs, lastArgs) => newArgs[0] === lastArgs[0] ); -export const getdocValueFields = memoizeOne( +export const getDocValueFields = memoizeOne( (_title: string, fields: IndexField[]): DocValueFields[] => fields && fields.length > 0 ? fields.reduce((accumulator: DocValueFields[], field: IndexField) => { @@ -177,7 +177,7 @@ export const useWithSource = ( defaultIndex.join(), get('data.source.status.indexFields', result) ), - docValueFields: getdocValueFields( + docValueFields: getDocValueFields( defaultIndex.join(), get('data.source.status.indexFields', result) ), diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx index ab12f045cddbc..9a2f43bb475b1 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -12,7 +12,7 @@ import { IIndexPattern } from '../../../../../../../../src/plugins/data/public'; import { BrowserFields, getBrowserFields, - getdocValueFields, + getDocValueFields, getIndexFields, sourceQuery, DocValueFields, @@ -89,7 +89,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => indices.join(), get('data.source.status.indexFields', result) ), - docValueFields: getdocValueFields( + docValueFields: getDocValueFields( indices.join(), get('data.source.status.indexFields', result) ), diff --git a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts index 2d16892329e19..a6b78269cff2f 100644 --- a/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts +++ b/x-pack/plugins/security_solution/public/timelines/store/timeline/helpers.ts @@ -154,7 +154,7 @@ interface AddNewTimelineParams { export const addNewTimeline = ({ columns, dataProviders = [], - dateRange: mayDateRange, + dateRange: maybeDateRange, excludedRowRendererIds = [], filters = timelineDefaults.filters, id, @@ -167,7 +167,7 @@ export const addNewTimeline = ({ timelineType, }: AddNewTimelineParams): TimelineById => { const { from: startDateRange, to: endDateRange } = normalizeTimeRange({ from: '', to: '' }); - const dateRange = mayDateRange ?? { start: startDateRange, end: endDateRange }; + const dateRange = maybeDateRange ?? { start: startDateRange, end: endDateRange }; const templateTimelineInfo = timelineType === TimelineType.template ? { From f31d592e611d3c13f6846a904d3953693806979c Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Fri, 17 Jul 2020 14:35:26 +0200 Subject: [PATCH 04/24] updates 'External alerts' tab text (#72237) --- .../public/detections/pages/detection_engine/translations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts index bfe5dfc012530..92dc02ac8478c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/translations.ts @@ -29,7 +29,7 @@ export const SIGNAL = i18n.translate('xpack.securitySolution.detectionEngine.sig }); export const ALERT = i18n.translate('xpack.securitySolution.detectionEngine.alertTitle', { - defaultMessage: 'External alerts', + defaultMessage: 'Detection alerts', }); export const BUTTON_MANAGE_RULES = i18n.translate( From 45a4393459e0400171564f1d096784ebc97cc8ed Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 17 Jul 2020 13:55:51 +0100 Subject: [PATCH 05/24] skip flaky suite (#72146) --- test/functional/apps/dashboard/dashboard_error_handling.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/dashboard/dashboard_error_handling.ts b/test/functional/apps/dashboard/dashboard_error_handling.ts index 6bd8327a110b9..38803739ff129 100644 --- a/test/functional/apps/dashboard/dashboard_error_handling.ts +++ b/test/functional/apps/dashboard/dashboard_error_handling.ts @@ -28,7 +28,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { /** * Common test suite for testing exception scenarious within dashboard */ - describe('dashboard error handling', () => { + // Flaky: https://github.com/elastic/kibana/issues/72146 + describe.skip('dashboard error handling', () => { before(async () => { await esArchiver.loadIfNeeded('dashboard/current/kibana'); await PageObjects.common.navigateToApp('dashboard'); From 93be1cff8d509658ed270bf5843df6311bb2e711 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Fri, 17 Jul 2020 08:58:10 -0400 Subject: [PATCH 06/24] [SECURITY] Bug truncation on timeline (#72221) * bring back truncated ceil + only show menu context hover text * update unit test --- .../index.test.tsx | 4 +++- .../drag_and_drop/draggable_wrapper.test.tsx | 4 ++-- .../components/with_hover_actions/index.tsx | 17 ++++++++++------- .../fields_browser/field_name.test.tsx | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx index 9c08e05ddfa39..2af6569394e8f 100644 --- a/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/add_filter_to_global_search_bar/index.test.tsx @@ -157,8 +157,10 @@ describe('AddFilterToGlobalSearchBar Component', () => { ); + wrapper.find('[data-test-subj="withHoverActionsButton"]').simulate('mouseenter'); + wrapper.update(); + wrapper - .simulate('mouseenter') .find('[data-test-subj="hover-actions-container"] [data-euiicon-type]') .first() .simulate('click'); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index da68280ed760c..e17fc7b9ef9bd 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -65,7 +65,7 @@ describe('DraggableWrapper', () => { expect(wrapper.find('[data-test-subj="copy-to-clipboard"]').exists()).toBe(false); }); - test('it renders hover actions when the mouse is over the draggable wrapper', () => { + test('it renders hover actions when the mouse is over the text of draggable wrapper', () => { const wrapper = mount( @@ -76,7 +76,7 @@ describe('DraggableWrapper', () => { ); - wrapper.simulate('mouseenter'); + wrapper.find('[data-test-subj="withHoverActionsButton"]').simulate('mouseenter'); wrapper.update(); expect(wrapper.find('[data-test-subj="copy-to-clipboard"]').exists()).toBe(true); }); diff --git a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx index 97705533689e9..e6577bd040e25 100644 --- a/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/with_hover_actions/index.tsx @@ -17,10 +17,6 @@ const WithHoverActionsPopover = (styled(EuiPopover as any)` } ` as unknown) as typeof EuiPopover; -const Container = styled.div` - width: fit-content; -`; - interface Props { /** * Always show the hover menu contents (default: false) @@ -68,7 +64,14 @@ export const WithHoverActions = React.memo( setShowHoverContent(false); }, []); - const content = useMemo(() => <>{render(showHoverContent)}, [render, showHoverContent]); + const content = useMemo( + () => ( +
+ {render(showHoverContent)} +
+ ), + [onMouseEnter, render, showHoverContent] + ); useEffect(() => { setIsOpen(hoverContent != null && (showHoverContent || alwaysShow)); @@ -79,7 +82,7 @@ export const WithHoverActions = React.memo( }, [closePopOverTrigger]); return ( - +
( > {isOpen ? <>{hoverContent} : null} - +
); } ); diff --git a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx index 44e4818830acd..ddd5c6f07e8b5 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/fields_browser/field_name.test.tsx @@ -46,7 +46,7 @@ describe('FieldName', () => {
); - wrapper.find('div').at(1).simulate('mouseenter'); + wrapper.find('[data-test-subj="withHoverActionsButton"]').at(0).simulate('mouseenter'); wrapper.update(); expect(wrapper.find('[data-test-subj="copy-to-clipboard"]').exists()).toBe(true); }); From 44888d3536ae365c7395f07e2757004e8f9cba7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Fri, 17 Jul 2020 15:08:38 +0200 Subject: [PATCH 07/24] [Logs UI] Fix display of dataset values in anomaly and category example rows (#71693) This removes an unnecessary JSON encoding step of values before they are passed to the field column component used in the log entry example rows in both the Anomalies and Categories tabs. --- .../top_categories/category_example_message.tsx | 12 ++++-------- .../sections/anomalies/log_entry_example.tsx | 10 +++------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx index 21c7f48eb80f8..908e52f01cbcc 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/sections/top_categories/category_example_message.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useMemo, useState, useCallback, useContext } from 'react'; +import React, { useState, useCallback, useContext } from 'react'; import { i18n } from '@kbn/i18n'; import { encode } from 'rison-node'; import moment from 'moment'; @@ -40,12 +40,8 @@ export const CategoryExampleMessage: React.FunctionComponent<{ context: LogEntryContext; }> = ({ id, dataset, message, timestamp, timeRange, tiebreaker, context }) => { const [, { setContextEntry }] = useContext(ViewLogInContext.Context); - // the dataset must be encoded for the field column and the empty value must - // be turned into a user-friendly value - const encodedDatasetFieldValue = useMemo( - () => JSON.stringify(getFriendlyNameForPartitionId(dataset)), - [dataset] - ); + // handle special cases for the dataset value + const humanFriendlyDataset = getFriendlyNameForPartitionId(dataset); const [isHovered, setIsHovered] = useState(false); const setHovered = useCallback(() => setIsHovered(true), []); @@ -100,7 +96,7 @@ export const CategoryExampleMessage: React.FunctionComponent<{ columnValue={{ columnId: datasetColumnId, field: 'event.dataset', - value: encodedDatasetFieldValue, + value: humanFriendlyDataset, highlights: [], }} highlights={noHighlights} diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx index 2965e1fede822..fece2522de574 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx @@ -80,12 +80,8 @@ export const LogEntryExampleMessage: React.FunctionComponent = ({ const setItemIsHovered = useCallback(() => setIsHovered(true), []); const setItemIsNotHovered = useCallback(() => setIsHovered(false), []); - // the dataset must be encoded for the field column and the empty value must - // be turned into a user-friendly value - const encodedDatasetFieldValue = useMemo( - () => JSON.stringify(getFriendlyNameForPartitionId(dataset)), - [dataset] - ); + // handle special cases for the dataset value + const humanFriendlyDataset = getFriendlyNameForPartitionId(dataset); const viewInStreamLinkProps = useLinkProps({ app: 'logs', @@ -158,7 +154,7 @@ export const LogEntryExampleMessage: React.FunctionComponent = ({ columnValue={{ columnId: datasetColumnId, field: 'event.dataset', - value: encodedDatasetFieldValue, + value: humanFriendlyDataset, highlights: [], }} highlights={noHighlights} From 86629d76b05eb87ded25de66019f0f2d4fe253cb Mon Sep 17 00:00:00 2001 From: Sandra Gonzales Date: Fri, 17 Jul 2020 09:24:32 -0400 Subject: [PATCH 08/24] [Ingest Manager] Fix failing test conflict error (#72149) * save kibana installation references after other updates have completed to avoid conflict error * unskip tests * uncomment out line * add back await to not change things * unskip fleet_unenroll_agent Co-authored-by: Elastic Machine --- .../services/epm/kibana/assets/install.ts | 22 ++++++++++--------- .../server/services/epm/packages/install.ts | 9 +++++--- .../test/api_integration/apis/fleet/setup.ts | 3 +-- .../apis/fleet/unenroll_agent.ts | 3 +-- .../apis/epm/install.ts | 3 +-- .../apps/endpoint/policy_details.ts | 3 +-- .../apps/endpoint/policy_list.ts | 3 +-- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/ingest_manager/server/services/epm/kibana/assets/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/kibana/assets/install.ts index 2a743f244e64d..a3fe444b19b1a 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/kibana/assets/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/kibana/assets/install.ts @@ -11,10 +11,14 @@ import { } from 'src/core/server'; import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../../common'; import * as Registry from '../../registry'; -import { AssetType, KibanaAssetType, AssetReference } from '../../../../types'; +import { + AssetType, + KibanaAssetType, + AssetReference, + KibanaAssetReference, +} from '../../../../types'; import { deleteKibanaSavedObjectsAssets } from '../../packages/remove'; import { getInstallationObject, savedObjectTypes } from '../../packages'; -import { saveInstalledKibanaRefs } from '../../packages/install'; type SavedObjectToBe = Required & { type: AssetType }; export type ArchiveAsset = Pick< @@ -49,7 +53,7 @@ export async function installKibanaAssets(options: { pkgName: string; paths: string[]; isUpdate: boolean; -}): Promise { +}): Promise { const { savedObjectsClient, paths, pkgName, isUpdate } = options; if (isUpdate) { @@ -65,16 +69,14 @@ export async function installKibanaAssets(options: { // install the new assets and save installation references const kibanaAssetTypes = Object.values(KibanaAssetType); - const installationPromises = kibanaAssetTypes.map((assetType) => - installKibanaSavedObjects({ savedObjectsClient, assetType, paths }) + const installedAssets = await Promise.all( + kibanaAssetTypes.map((assetType) => + installKibanaSavedObjects({ savedObjectsClient, assetType, paths }) + ) ); // installKibanaSavedObjects returns AssetReference[], so .map creates AssetReference[][] // call .flat to flatten into one dimensional array - const newInstalledKibanaAssets = await Promise.all(installationPromises).then((results) => - results.flat() - ); - await saveInstalledKibanaRefs(savedObjectsClient, pkgName, newInstalledKibanaAssets); - return newInstalledKibanaAssets; + return installedAssets.flat(); } export const deleteKibanaInstalledRefs = async ( savedObjectsClient: SavedObjectsClientContract, diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index cd4259a0c30d7..a69daae6e0410 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -169,17 +169,20 @@ export async function installPackage(options: { ); } - // update to newly installed version when all assets are successfully installed - if (isUpdate) await updateVersion(savedObjectsClient, pkgName, pkgVersion); // get template refs to save const installedTemplateRefs = installedTemplates.map((template) => ({ id: template.templateName, type: ElasticsearchAssetType.indexTemplate, })); + const [installedKibanaAssets] = await Promise.all([ installKibanaAssetsPromise, installIndexPatternPromise, ]); + + await saveInstalledKibanaRefs(savedObjectsClient, pkgName, installedKibanaAssets); + // update to newly installed version when all assets are successfully installed + if (isUpdate) await updateVersion(savedObjectsClient, pkgName, pkgVersion); return [...installedKibanaAssets, ...installedPipelines, ...installedTemplateRefs]; } const updateVersion = async ( @@ -230,7 +233,7 @@ export async function createInstallation(options: { export const saveInstalledKibanaRefs = async ( savedObjectsClient: SavedObjectsClientContract, pkgName: string, - installedAssets: AssetReference[] + installedAssets: KibanaAssetReference[] ) => { await savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, { installed_kibana: installedAssets, diff --git a/x-pack/test/api_integration/apis/fleet/setup.ts b/x-pack/test/api_integration/apis/fleet/setup.ts index 82e494b0ab28c..4fcf39886e202 100644 --- a/x-pack/test/api_integration/apis/fleet/setup.ts +++ b/x-pack/test/api_integration/apis/fleet/setup.ts @@ -11,8 +11,7 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const es = getService('es'); - // FLAKY: https://github.com/elastic/kibana/issues/72053 - describe.skip('fleet_setup', () => { + describe('fleet_setup', () => { beforeEach(async () => { try { await es.security.deleteUser({ diff --git a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts b/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts index 4e1443ad1fc68..bc6c44e590cc4 100644 --- a/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts +++ b/x-pack/test/api_integration/apis/fleet/unenroll_agent.ts @@ -16,8 +16,7 @@ export default function (providerContext: FtrProviderContext) { const supertest = getService('supertest'); const esClient = getService('es'); - // FLAKY: https://github.com/elastic/kibana/issues/64696 - describe.skip('fleet_unenroll_agent', () => { + describe('fleet_unenroll_agent', () => { let accessAPIKeyId: string; let outputAPIKeyId: string; before(async () => { diff --git a/x-pack/test/ingest_manager_api_integration/apis/epm/install.ts b/x-pack/test/ingest_manager_api_integration/apis/epm/install.ts index b6807b2fd3414..f73ba56c172c4 100644 --- a/x-pack/test/ingest_manager_api_integration/apis/epm/install.ts +++ b/x-pack/test/ingest_manager_api_integration/apis/epm/install.ts @@ -21,8 +21,7 @@ export default function ({ getService }: FtrProviderContext) { const mappingsPackage = 'overrides-0.1.0'; const server = dockerServers.get('registry'); - // FLAKY: https://github.com/elastic/kibana/issues/71939 - describe.skip('installs packages that include settings and mappings overrides', async () => { + describe('installs packages that include settings and mappings overrides', async () => { after(async () => { if (server.enabled) { // remove the package just in case it being installed will affect other tests diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts index d57bd32441454..cf76f297d83be 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_details.ts @@ -19,8 +19,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const testSubjects = getService('testSubjects'); const policyTestResources = getService('policyTestResources'); - // FLAKY: https://github.com/elastic/kibana/issues/72102 - describe.skip('When on the Endpoint Policy Details Page', function () { + describe('When on the Endpoint Policy Details Page', function () { this.tags(['ciGroup7']); describe('with an invalid policy id', () => { diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts index b91f0647487ff..57321ab4cd911 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts @@ -19,8 +19,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const policyTestResources = getService('policyTestResources'); const RELATIVE_DATE_FORMAT = /\d (?:seconds|minutes) ago/i; - // FLAKY: https://github.com/elastic/kibana/issues/71951 - describe.skip('When on the Endpoint Policy List', function () { + describe('When on the Endpoint Policy List', function () { this.tags(['ciGroup7']); before(async () => { await pageObjects.policy.navigateToPolicyList(); From 5160c7ee459b564b6b116790f3728778d53dfab7 Mon Sep 17 00:00:00 2001 From: Tre Date: Fri, 17 Jul 2020 07:56:59 -0600 Subject: [PATCH 09/24] [QA][Code Coverage] Drop flaky integration tests (#72089) --- .../integration_tests/ingest_coverage.test.js | 92 ------------------- 1 file changed, 92 deletions(-) diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index 95056d9f0d8d7..ba73922ec508a 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -69,96 +69,4 @@ describe('Ingesting coverage', () => { expect(folderStructure.test(actualUrl)).ok(); }); }); - describe(`vcsInfo`, () => { - let stdOutWithVcsInfo = ''; - describe(`without a commit msg in the vcs info file`, () => { - beforeAll(async () => { - const args = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO_missing_commit_msg.txt', - '--path', - ]; - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - stdOutWithVcsInfo = stdout; - }); - - it(`should be an obj w/o a commit msg`, () => { - const commitMsgRE = /"commitMsg"/; - expect(commitMsgRE.test(stdOutWithVcsInfo)).to.not.be.ok(); - }); - }); - describe(`including previous sha`, () => { - let stdOutWithPrevious = ''; - beforeAll(async () => { - const opts = [...verboseArgs, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - stdOutWithPrevious = stdout; - }); - - it(`should have a vcsCompareUrl`, () => { - const previousCompareUrlRe = /vcsCompareUrl.+\s*.*https.+compare\/FAKE_PREVIOUS_SHA\.\.\.f07b34f6206/; - expect(previousCompareUrlRe.test(stdOutWithPrevious)).to.be.ok(); - }); - }); - describe(`with a commit msg in the vcs info file`, () => { - beforeAll(async () => { - const args = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - '--path', - ]; - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - stdOutWithVcsInfo = stdout; - }); - - it(`should be an obj w/ a commit msg`, () => { - const commitMsgRE = /commitMsg/; - expect(commitMsgRE.test(stdOutWithVcsInfo)).to.be.ok(); - }); - }); - }); - describe(`team assignment`, () => { - let shouldNotHavePipelineOut = ''; - let shouldIndeedHavePipelineOut = ''; - - const args = [ - 'scripts/ingest_coverage.js', - '--verbose', - '--vcsInfoPath', - 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', - '--path', - ]; - - const teamAssignRE = /pipeline:/; - - beforeAll(async () => { - const summaryPath = 'jest-combined/coverage-summary-just-total.json'; - const resolved = resolve(MOCKS_DIR, summaryPath); - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - shouldNotHavePipelineOut = stdout; - }); - beforeAll(async () => { - const summaryPath = 'jest-combined/coverage-summary-manual-mix.json'; - const resolved = resolve(MOCKS_DIR, summaryPath); - const opts = [...args, resolved]; - const { stdout } = await execa(process.execPath, opts, { cwd: ROOT_DIR, env }); - shouldIndeedHavePipelineOut = stdout; - }); - - it(`should not occur when going to the totals index`, () => { - const actual = teamAssignRE.test(shouldNotHavePipelineOut); - expect(actual).to.not.be.ok(); - }); - it(`should indeed occur when going to the coverage index`, () => { - const actual = /ingest-pipe=>team_assignment/.test(shouldIndeedHavePipelineOut); - expect(actual).to.be.ok(); - }); - }); }); From f9baaa267d75558decd7ada45258d4ecced182e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Fri, 17 Jul 2020 15:11:41 +0100 Subject: [PATCH 10/24] Observability landing page title (#72088) * updating window title based on breadcrumbs * updating window title based on breadcrumbs * updating window title based on breadcrumbs --- .../public/application/index.tsx | 35 ++++++++++++------- .../observability/public/routes/index.tsx | 2 ++ 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/observability/public/application/index.tsx b/x-pack/plugins/observability/public/application/index.tsx index 8cfbca37e8d05..d76c033a41756 100644 --- a/x-pack/plugins/observability/public/application/index.tsx +++ b/x-pack/plugins/observability/public/application/index.tsx @@ -3,18 +3,31 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; import { createHashHistory } from 'history'; import React, { useEffect } from 'react'; import ReactDOM from 'react-dom'; import { Route, Router, Switch } from 'react-router-dom'; -import { i18n } from '@kbn/i18n'; -import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; import { AppMountParameters, CoreStart } from '../../../../../src/core/public'; +import { RedirectAppLinks } from '../../../../../src/plugins/kibana_react/public'; import { EuiThemeProvider } from '../../../../legacy/common/eui_styled_components'; import { PluginContext } from '../context/plugin_context'; -import { useRouteParams } from '../hooks/use_route_params'; -import { routes } from '../routes'; import { usePluginContext } from '../hooks/use_plugin_context'; +import { useRouteParams } from '../hooks/use_route_params'; +import { Breadcrumbs, routes } from '../routes'; + +const observabilityLabelBreadcrumb = { + text: i18n.translate('xpack.observability.observability.breadcrumb.', { + defaultMessage: 'Observability', + }), +}; + +function getTitleFromBreadCrumbs(breadcrumbs: Breadcrumbs) { + return breadcrumbs + .map(({ text }) => text) + .reverse() + .join(' | '); +} const App = () => { return ( @@ -25,16 +38,12 @@ const App = () => { const route = routes[path]; const Wrapper = () => { const { core } = usePluginContext(); + + const breadcrumb = [observabilityLabelBreadcrumb, ...route.breadcrumb]; useEffect(() => { - core.chrome.setBreadcrumbs([ - { - text: i18n.translate('xpack.observability.observability.breadcrumb.', { - defaultMessage: 'Observability', - }), - }, - ...route.breadcrumb, - ]); - }, [core]); + core.chrome.setBreadcrumbs(breadcrumb); + document.title = getTitleFromBreadCrumbs(breadcrumb); + }, [core, breadcrumb]); const { query, path: pathParams } = useRouteParams(route.params); return route.handler({ query, path: pathParams }); diff --git a/x-pack/plugins/observability/public/routes/index.tsx b/x-pack/plugins/observability/public/routes/index.tsx index 10f9b4dc42723..bee6a4dd7133a 100644 --- a/x-pack/plugins/observability/public/routes/index.tsx +++ b/x-pack/plugins/observability/public/routes/index.tsx @@ -17,6 +17,8 @@ type DecodeParams = { [key in keyof TParams]: TParams[key] extends t.Any ? t.TypeOf : never; }; +export type Breadcrumbs = Array<{ text: string }>; + export interface Params { query?: t.HasProps; path?: t.HasProps; From 937314ad1111d904e9538015d2676368acb0ac54 Mon Sep 17 00:00:00 2001 From: Mikhail Shustov Date: Fri, 17 Jul 2020 17:14:55 +0300 Subject: [PATCH 11/24] Bump @elastic/elasticsearch to v7.9.0-rc1 (#72231) * bump @elastic/elasticsearch to 7.9.0-rc1 * bump other packages using @elastic/elasticsearch --- package.json | 2 +- packages/kbn-es/package.json | 2 +- x-pack/plugins/apm/scripts/package.json | 2 +- yarn.lock | 35 ++++--------------------- 4 files changed, 8 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 593e8f82f0541..a22871e314bae 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "@elastic/apm-rum": "^5.2.0", "@elastic/charts": "19.8.1", "@elastic/datemath": "5.0.3", - "@elastic/elasticsearch": "7.8.0", + "@elastic/elasticsearch": "7.9.0-rc.1", "@elastic/ems-client": "7.9.3", "@elastic/eui": "26.3.1", "@elastic/filesaver": "1.1.2", diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json index 271b4a3dc661b..f53eb694ec712 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "private": true, "dependencies": { - "@elastic/elasticsearch": "^7.4.0", + "@elastic/elasticsearch": "7.9.0-rc.1", "@kbn/dev-utils": "1.0.0", "abort-controller": "^2.0.3", "chalk": "^2.4.2", diff --git a/x-pack/plugins/apm/scripts/package.json b/x-pack/plugins/apm/scripts/package.json index c5a9df792f856..4d0906514b5e1 100644 --- a/x-pack/plugins/apm/scripts/package.json +++ b/x-pack/plugins/apm/scripts/package.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "dependencies": { - "@elastic/elasticsearch": "^7.6.1", + "@elastic/elasticsearch": "7.9.0-rc.1", "@octokit/rest": "^16.35.0", "@types/console-stamp": "^0.2.32", "console-stamp": "^0.2.9", diff --git a/yarn.lock b/yarn.lock index a5066b51f3198..580e436a60282 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2172,10 +2172,10 @@ redux-immutable-state-invariant "^2.1.0" redux-logger "^3.0.6" -"@elastic/elasticsearch@7.8.0": - version "7.8.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.8.0.tgz#3f9ee54fe8ef79874ebd231db03825fa500a7111" - integrity sha512-rUOTNN1At0KoN0Fcjd6+J7efghuURnoMTB/od9EMK6Mcdebi6N3z5ulShTsKRn6OanS9Eq3l/OmheQY1Y+WLcg== +"@elastic/elasticsearch@7.9.0-rc.1": + version "7.9.0-rc.1" + resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.9.0-rc.1.tgz#50205507ec84ccb95cb7a6d36e5570808749fee9" + integrity sha512-rVjiVj7VPLCusJPfywpb3gvcaA99uylYSum1Frcq4vi2Iqg118KXgYW6GOis2Y70oDZ6w6XRlT0ze5NA6SBa+g== dependencies: debug "^4.1.1" decompress-response "^4.2.0" @@ -2183,18 +2183,6 @@ pump "^3.0.0" secure-json-parse "^2.1.0" -"@elastic/elasticsearch@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.4.0.tgz#57f4066acf25e9d4e9b4f6376088433aae6f25d4" - integrity sha512-HpEKHH6mHQRvea3lw4NNJw9ZUS1KmkpwWKHucaHi1svDn+/fEAwY0wD8egL1vZJo4ZmWfCQMjVqGL+Hoy1HYRw== - dependencies: - debug "^4.1.1" - decompress-response "^4.2.0" - into-stream "^5.1.0" - ms "^2.1.1" - once "^1.4.0" - pump "^3.0.0" - "@elastic/ems-client@7.9.3": version "7.9.3" resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.9.3.tgz#71b79914f76e347f050ead8474ad65d761e94a8a" @@ -15294,7 +15282,7 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from2@^2.1.0, from2@^2.1.1, from2@^2.3.0: +from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= @@ -18081,14 +18069,6 @@ into-stream@^3.1.0: from2 "^2.1.1" p-is-promise "^1.1.0" -into-stream@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-5.1.0.tgz#b05f37d8fed05c06a0b43b556d74e53e5af23878" - integrity sha512-cbDhb8qlxKMxPBk/QxTtYg1DQ4CwXmadu7quG3B7nrJsgSncEreF2kwWKZFdnjc/lSNNIkFPsjI7SM0Cx/QXPw== - dependencies: - from2 "^2.3.0" - p-is-promise "^2.0.0" - invariant@2.2.4, invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -23776,11 +23756,6 @@ p-is-promise@^1.1.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" From 8f442f8318dfe0613fd51660cc7b4370b3ca2a29 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Fri, 17 Jul 2020 16:37:10 +0200 Subject: [PATCH 12/24] [ML] Fix HTML named characters encoding (#72060) * [ML] improve special characters encoding * [ML] update renovate.json5 --- renovate.json5 | 8 +++++++ x-pack/package.json | 2 ++ .../application/util/string_utils.test.ts | 7 +++++-- .../public/application/util/string_utils.ts | 21 +++++++++++-------- yarn.lock | 7 ++++++- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/renovate.json5 b/renovate.json5 index 6424894622c9f..ae32043daaf5f 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -418,6 +418,14 @@ '@types/has-ansi', ], }, + { + groupSlug: 'he', + groupName: 'he related packages', + packageNames: [ + 'he', + '@types/he', + ], + }, { groupSlug: 'history', groupName: 'history related packages', diff --git a/x-pack/package.json b/x-pack/package.json index 6715fa132c1b5..1de009ae1232f 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -72,6 +72,7 @@ "@types/graphql": "^0.13.2", "@types/gulp": "^4.0.6", "@types/hapi__wreck": "^15.0.1", + "@types/he": "^1.1.1", "@types/hoist-non-react-statics": "^3.3.1", "@types/history": "^4.7.3", "@types/jest": "^25.2.3", @@ -265,6 +266,7 @@ "graphql-tools": "^3.0.2", "h2o2": "^8.1.2", "handlebars": "4.7.6", + "he": "^1.2.0", "history": "4.9.0", "history-extra": "^5.0.1", "i18n-iso-countries": "^4.3.1", diff --git a/x-pack/plugins/ml/public/application/util/string_utils.test.ts b/x-pack/plugins/ml/public/application/util/string_utils.test.ts index d7ed30065219a..80e318629d352 100644 --- a/x-pack/plugins/ml/public/application/util/string_utils.test.ts +++ b/x-pack/plugins/ml/public/application/util/string_utils.test.ts @@ -126,8 +126,11 @@ describe('ML - string utils', () => { expect(mlEscape('foobar')).toBe('foo>bar'); expect(mlEscape('foo"bar')).toBe('foo"bar'); - expect(mlEscape("foo'bar")).toBe('foo'bar'); - expect(mlEscape('foo/bar')).toBe('foo/bar'); + expect(mlEscape("foo'bar")).toBe('foo'bar'); + expect(mlEscape('foo/bar')).toBe('foo/bar'); + expect(mlEscape('escape © everything ≠ / 𝌆 \\')).toBe( + 'escape © everything ≠ / �� \' + ); }); }); diff --git a/x-pack/plugins/ml/public/application/util/string_utils.ts b/x-pack/plugins/ml/public/application/util/string_utils.ts index f659f8fdc1be1..55dd16082a07c 100644 --- a/x-pack/plugins/ml/public/application/util/string_utils.ts +++ b/x-pack/plugins/ml/public/application/util/string_utils.ts @@ -9,6 +9,7 @@ */ import _ from 'lodash'; import d3 from 'd3'; +import he from 'he'; import { CustomUrlAnomalyRecordDoc } from '../../../common/types/custom_urls'; import { Detector } from '../../../common/types/anomaly_detection_jobs'; @@ -105,15 +106,17 @@ export function toLocaleString(x: number | undefined | null): string { // escape html characters export function mlEscape(str: string): string { - const entityMap: { [escapeChar: string]: string } = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - }; - return String(str).replace(/[&<>"'\/]/g, (s) => entityMap[s]); + // It's not possible to use "he" encoding directly + // because \ and / characters are not going to be replaced without + // encodeEverything option. But with this option enabled + // each word character is encoded as well. + return String(str).replace(/\W/g, (s) => + he.encode(s, { + useNamedReferences: true, + encodeEverything: true, + allowUnsafeSymbols: false, + }) + ); } // Escapes reserved characters for use in Elasticsearch query terms. diff --git a/yarn.lock b/yarn.lock index 580e436a60282..e5975efe0b7d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5141,6 +5141,11 @@ resolved "https://registry.yarnpkg.com/@types/has-ansi/-/has-ansi-3.0.0.tgz#636403dc4e0b2649421c4158e5c404416f3f0330" integrity sha512-H3vFOwfLlFEC0MOOrcSkus8PCnMCzz4N0EqUbdJZCdDhBTfkAu86aRYA+MTxjKW6jCpUvxcn4715US8g+28BMA== +"@types/he@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/he/-/he-1.1.1.tgz#19e14033c4ee8f1a702c74dcc6182664839ac2b7" + integrity sha512-jpzrsR1ns0n3kyWt92QfOUQhIuJGQ9+QGa7M62rO6toe98woQjnsnzjdMtsQXCdvjjmqjS2ZBCC7xKw0cdzU+Q== + "@types/history@*": version "4.7.2" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.2.tgz#0e670ea254d559241b6eeb3894f8754991e73220" @@ -17063,7 +17068,7 @@ hawk@~6.0.2: hoek "4.x.x" sntp "2.x.x" -he@1.2.0, he@1.2.x, he@^1.1.1: +he@1.2.0, he@1.2.x, he@^1.1.1, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== From ac9178ab9a2537ce2468593d86d4c21b622db9cf Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Fri, 17 Jul 2020 16:41:44 +0200 Subject: [PATCH 13/24] updates advanced settings text (#72249) --- .../detections/components/rules/step_about_rule/schema.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx index f178923df5915..fbd03850eee75 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/schema.tsx @@ -34,7 +34,7 @@ export const schema: FormSchema = { 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAuthorHelpText', { defaultMessage: - 'Type one or more author for this rule. Press enter after each author to add a new one.', + 'Type one or more authors for this rule. Press enter after each author to add a new one.', } ), labelAppend: OptionalFieldLabel, @@ -280,7 +280,7 @@ export const schema: FormSchema = { 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.guideHelpText', { defaultMessage: - 'Provide helpful information for analysts that are performing a signal investigation. This guide will appear on both the rule details page and in timelines created from alerts generated by this rule.', + 'Provide helpful information for analysts that are investigating detection alerts. This guide will appear on the rule details page and in timelines (as notes) created from detection alerts generated by this rule.', } ), labelAppend: OptionalFieldLabel, From 260eb139f86f2621edc7fd85417ca0aa71c82955 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Fri, 17 Jul 2020 10:56:02 -0400 Subject: [PATCH 14/24] re-enable tests. retry on fail (#72061) --- .../components/configuration_step/analysis_fields_table.tsx | 1 + .../test/functional/apps/ml/data_frame_analytics/index.ts | 3 +-- .../functional/services/ml/data_frame_analytics_creation.ts | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx index ff8797bc523c1..a229a79d316d7 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/analysis_fields_table.tsx @@ -172,6 +172,7 @@ export const AnalysisFieldsTable: FC<{ return ( { + await testSubjects.existOrFail('mlAnalyticsCreateJobWizardIncludesSelect'); + }); }, // async assertIncludedFieldsSelection(expectedSelection: string[]) { From 6a03e8b5b8b54c2f96e1fefb41cd29d81ecf22df Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Fri, 17 Jul 2020 11:08:57 -0400 Subject: [PATCH 15/24] Add a few asciidoc readmes (#72082) * Add a few asciidoc readmes * add updated code-exploration. Need to fix the script in another go to add asciidoc support. The snippet didn't show up anyway. --- docs/developer/architecture/code-exploration.asciidoc | 5 ++++- examples/{README.md => README.asciidoc} | 8 +++++--- src/dev/precommit_hook/casing_check_config.js | 1 + src/plugins/dashboard/README.asciidoc | 5 +++++ x-pack/plugins/embeddable_enhanced/README.asciidoc | 6 ++++++ x-pack/plugins/embeddable_enhanced/README.md | 1 - 6 files changed, 21 insertions(+), 5 deletions(-) rename examples/{README.md => README.asciidoc} (68%) create mode 100644 src/plugins/dashboard/README.asciidoc create mode 100644 x-pack/plugins/embeddable_enhanced/README.asciidoc delete mode 100644 x-pack/plugins/embeddable_enhanced/README.md diff --git a/docs/developer/architecture/code-exploration.asciidoc b/docs/developer/architecture/code-exploration.asciidoc index 23ba1c54d27d3..bed54277c82b4 100644 --- a/docs/developer/architecture/code-exploration.asciidoc +++ b/docs/developer/architecture/code-exploration.asciidoc @@ -365,7 +365,10 @@ WARNING: Missing README. WARNING: Missing README. -- {kib-repo}blob/{branch}/x-pack/plugins/embeddable_enhanced/README.md[embeddableEnhanced] +- {kib-repo}blob/{branch}/x-pack/plugins/embeddable_enhanced[embeddableEnhanced] + +WARNING: Missing README. + - {kib-repo}blob/{branch}/x-pack/plugins/encrypted_saved_objects/README.md[encryptedSavedObjects] diff --git a/examples/README.md b/examples/README.asciidoc similarity index 68% rename from examples/README.md rename to examples/README.asciidoc index 2b214a8d1eb52..d33c5e825ce12 100644 --- a/examples/README.md +++ b/examples/README.asciidoc @@ -1,7 +1,9 @@ -## Example plugins +[[example-plugins]] +== Example plugins This folder contains example plugins. To run the plugins in this folder, use the `--run-examples` flag, via -``` +[source,bash] +---- yarn start --run-examples -``` +---- diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 6b1f1dfaeabb4..929de8c6701d4 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -30,6 +30,7 @@ export const IGNORE_FILE_GLOBS = [ 'docs/**/*', '**/bin/**/*', '**/+([A-Z_]).md', + '**/+([A-Z_]).asciidoc', '**/LICENSE', '**/*.txt', '**/Gruntfile.js', diff --git a/src/plugins/dashboard/README.asciidoc b/src/plugins/dashboard/README.asciidoc new file mode 100644 index 0000000000000..78163b14c14d6 --- /dev/null +++ b/src/plugins/dashboard/README.asciidoc @@ -0,0 +1,5 @@ +[[kibana-dashboard-plugin]] +== Dashboard plugin + +- Registers the dashboard application. +- Adds a dashboard embeddable that can be used in other applications. \ No newline at end of file diff --git a/x-pack/plugins/embeddable_enhanced/README.asciidoc b/x-pack/plugins/embeddable_enhanced/README.asciidoc new file mode 100644 index 0000000000000..9a7fe9c2669d9 --- /dev/null +++ b/x-pack/plugins/embeddable_enhanced/README.asciidoc @@ -0,0 +1,6 @@ +[[enhanced-embeddables-plugin]] +== Enhanced embeddables plugin + +Enhances Embeddables by registering a custom factory provider. The enhanced factory provider +adds dynamic actions to every embeddables state, in order to support drilldowns. + diff --git a/x-pack/plugins/embeddable_enhanced/README.md b/x-pack/plugins/embeddable_enhanced/README.md deleted file mode 100644 index a0be90731fdb0..0000000000000 --- a/x-pack/plugins/embeddable_enhanced/README.md +++ /dev/null @@ -1 +0,0 @@ -# X-Pack part of `embeddable` plugin From 2ad4328fda8a5eb35a3a82bfb010a27202f196a2 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Fri, 17 Jul 2020 17:09:18 +0200 Subject: [PATCH 16/24] [ML] Remove DragSelect event handlers and selectors on the swim lane unmount (#72250) * [ML] remove selector element on unmount * [ML] stop handler on mount * [ML] remove throttling --- .../application/explorer/explorer_swimlane.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx index 926f38ac8b552..2590ab2f1cb23 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer_swimlane.tsx @@ -204,6 +204,8 @@ export class ExplorerSwimlane extends React.Component { }); this.renderSwimlane(); + + this.dragSelect.stop(); } componentDidUpdate() { @@ -211,11 +213,11 @@ export class ExplorerSwimlane extends React.Component { } componentWillUnmount() { - if (this.dragSelectSubscriber !== null) { - this.dragSelectSubscriber.unsubscribe(); - } - const element = d3.select(this.rootNode.current!); - element.html(''); + this.dragSelectSubscriber!.unsubscribe(); + // Remove selector element from DOM + this.dragSelect.selector.remove(); + // removes all mousedown event handlers + this.dragSelect.stop(true); } selectCell(cellsToSelect: any[], { laneLabels, bucketScore, times }: SelectedData) { From 39381ca3c849a9c9b3d486d9552f51e52cb942d9 Mon Sep 17 00:00:00 2001 From: igoristic Date: Fri, 17 Jul 2020 11:13:40 -0400 Subject: [PATCH 17/24] [Monitoring] Added a case for Alerting if security/ssl is disabled (#71846) * Added a case for Alerting if security/ssl is disabled * Code feedback * Fixed types --- x-pack/plugins/monitoring/kibana.json | 3 +- .../public/alerts/lib/security_toasts.tsx | 137 ++++++++++++++++++ .../monitoring/public/services/clusters.js | 4 +- .../elasticsearch/verify_alerting_security.ts | 49 +++++++ x-pack/plugins/monitoring/server/plugin.ts | 1 + .../server/routes/api/v1/alerts/enable.ts | 25 +++- x-pack/plugins/monitoring/server/types.ts | 3 + 7 files changed, 216 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx create mode 100644 x-pack/plugins/monitoring/server/lib/elasticsearch/verify_alerting_security.ts diff --git a/x-pack/plugins/monitoring/kibana.json b/x-pack/plugins/monitoring/kibana.json index 3b9e60124b034..2b8756ea0cb46 100644 --- a/x-pack/plugins/monitoring/kibana.json +++ b/x-pack/plugins/monitoring/kibana.json @@ -11,7 +11,8 @@ "kibanaLegacy", "triggers_actions_ui", "alerts", - "actions" + "actions", + "encryptedSavedObjects" ], "optionalPlugins": ["infra", "telemetryCollectionManager", "usageCollection", "home", "cloud"], "server": true, diff --git a/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx b/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx new file mode 100644 index 0000000000000..918c0b5c9b609 --- /dev/null +++ b/x-pack/plugins/monitoring/public/alerts/lib/security_toasts.tsx @@ -0,0 +1,137 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiSpacer, EuiLink, EuiCode, EuiText } from '@elastic/eui'; +import { Legacy } from '../../legacy_shims'; +import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; + +export interface AlertingFrameworkHealth { + isSufficientlySecure: boolean; + hasPermanentEncryptionKey: boolean; +} + +const showTlsAndEncryptionError = () => { + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; + + Legacy.shims.toastNotifications.addWarning({ + title: toMountPoint( + + ), + text: toMountPoint( +
+

+ {i18n.translate('xpack.monitoring.healthCheck.tlsAndEncryptionError', { + defaultMessage: `You must enable Transport Layer Security between Kibana and Elasticsearch + and configure an encryption key in your kibana.yml file to use the Alerting feature.`, + })} +

+ + + {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorAction', { + defaultMessage: 'Learn how.', + })} + +
+ ), + }); +}; + +const showEncryptionError = () => { + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; + + Legacy.shims.toastNotifications.addWarning( + { + title: toMountPoint( + + ), + text: toMountPoint( +
+ {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorBeforeKey', { + defaultMessage: 'To create an alert, set a value for ', + })} + + {'xpack.encryptedSavedObjects.encryptionKey'} + + {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorAfterKey', { + defaultMessage: ' in your kibana.yml file. ', + })} + + {i18n.translate('xpack.monitoring.healthCheck.encryptionErrorAction', { + defaultMessage: 'Learn how.', + })} + +
+ ), + }, + {} + ); +}; + +const showTlsError = () => { + const { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } = Legacy.shims.docLinks; + + Legacy.shims.toastNotifications.addWarning({ + title: toMountPoint( + + ), + text: toMountPoint( +
+ {i18n.translate('xpack.monitoring.healthCheck.tlsError', { + defaultMessage: + 'Alerting relies on API keys, which require TLS between Elasticsearch and Kibana. ', + })} + + {i18n.translate('xpack.monitoring.healthCheck.tlsErrorAction', { + defaultMessage: 'Learn how to enable TLS.', + })} + +
+ ), + }); +}; + +export const showSecurityToast = (alertingHealth: AlertingFrameworkHealth) => { + const { isSufficientlySecure, hasPermanentEncryptionKey } = alertingHealth; + if ( + Array.isArray(alertingHealth) || + (!alertingHealth.hasOwnProperty('isSufficientlySecure') && + !alertingHealth.hasOwnProperty('hasPermanentEncryptionKey')) + ) { + return; + } + + if (!isSufficientlySecure && !hasPermanentEncryptionKey) { + showTlsAndEncryptionError(); + } else if (!isSufficientlySecure) { + showTlsError(); + } else if (!hasPermanentEncryptionKey) { + showEncryptionError(); + } +}; diff --git a/x-pack/plugins/monitoring/public/services/clusters.js b/x-pack/plugins/monitoring/public/services/clusters.js index f3eadcaf9831b..5173984dbe868 100644 --- a/x-pack/plugins/monitoring/public/services/clusters.js +++ b/x-pack/plugins/monitoring/public/services/clusters.js @@ -7,6 +7,7 @@ import { ajaxErrorHandlersProvider } from '../lib/ajax_error_handler'; import { Legacy } from '../legacy_shims'; import { STANDALONE_CLUSTER_CLUSTER_UUID } from '../../common/constants'; +import { showSecurityToast } from '../alerts/lib/security_toasts'; function formatClusters(clusters) { return clusters.map(formatCluster); @@ -66,7 +67,8 @@ export function monitoringClustersProvider($injector) { return getClusters().then((clusters) => { if (clusters.length) { return ensureAlertsEnabled() - .then(() => { + .then(({ data }) => { + showSecurityToast(data); once = true; return clusters; }) diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_alerting_security.ts b/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_alerting_security.ts new file mode 100644 index 0000000000000..047b14bd37fbc --- /dev/null +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_alerting_security.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RequestHandlerContext } from 'kibana/server'; +import { EncryptedSavedObjectsPluginSetup } from '../../../../encrypted_saved_objects/server'; + +export interface AlertingFrameworkHealth { + isSufficientlySecure: boolean; + hasPermanentEncryptionKey: boolean; +} + +export interface XPackUsageSecurity { + security?: { + enabled?: boolean; + ssl?: { + http?: { + enabled?: boolean; + }; + }; + }; +} + +export class AlertingSecurity { + public static readonly getSecurityHealth = async ( + context: RequestHandlerContext, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup + ): Promise => { + const { + security: { + enabled: isSecurityEnabled = false, + ssl: { http: { enabled: isTLSEnabled = false } = {} } = {}, + } = {}, + }: XPackUsageSecurity = await context.core.elasticsearch.legacy.client.callAsInternalUser( + 'transport.request', + { + method: 'GET', + path: '/_xpack/usage', + } + ); + + return { + isSufficientlySecure: !isSecurityEnabled || (isSecurityEnabled && isTLSEnabled), + hasPermanentEncryptionKey: !encryptedSavedObjects.usingEphemeralEncryptionKey, + }; + }; +} diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 5f358badde401..39ec5fe1ffaa7 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -203,6 +203,7 @@ export class Plugin { requireUIRoutes(this.monitoringCore, { router, licenseService: this.licenseService, + encryptedSavedObjects: plugins.encryptedSavedObjects, }); initInfraSource(config, plugins.infra); } diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts index b7cc088d2716c..64beb5c58dc07 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/enable.ts @@ -10,18 +10,36 @@ import { AlertsFactory } from '../../../../alerts'; import { RouteDependencies } from '../../../../types'; import { ALERT_ACTION_TYPE_LOG } from '../../../../../common/constants'; import { ActionResult } from '../../../../../../actions/common'; -// import { fetchDefaultEmailAddress } from '../../../../lib/alerts/fetch_default_email_address'; +import { AlertingSecurity } from '../../../../lib/elasticsearch/verify_alerting_security'; const DEFAULT_SERVER_LOG_NAME = 'Monitoring: Write to Kibana log'; -export function enableAlertsRoute(server: any, npRoute: RouteDependencies) { +export function enableAlertsRoute(_server: unknown, npRoute: RouteDependencies) { npRoute.router.post( { path: '/api/monitoring/v1/alerts/enable', validate: false, }, - async (context, request, response) => { + async (context, _request, response) => { try { + const alerts = AlertsFactory.getAll().filter((a) => a.isEnabled(npRoute.licenseService)); + + if (alerts.length) { + const { + isSufficientlySecure, + hasPermanentEncryptionKey, + } = await AlertingSecurity.getSecurityHealth(context, npRoute.encryptedSavedObjects); + + if (!isSufficientlySecure || !hasPermanentEncryptionKey) { + return response.ok({ + body: { + isSufficientlySecure, + hasPermanentEncryptionKey, + }, + }); + } + } + const alertsClient = context.alerting?.getAlertsClient(); const actionsClient = context.actions?.getActionsClient(); const types = context.actions?.listTypes(); @@ -57,7 +75,6 @@ export function enableAlertsRoute(server: any, npRoute: RouteDependencies) { }, ]; - const alerts = AlertsFactory.getAll().filter((a) => a.isEnabled(npRoute.licenseService)); const createdAlerts = await Promise.all( alerts.map( async (alert) => await alert.createIfDoesNotExist(alertsClient, actionsClient, actions) diff --git a/x-pack/plugins/monitoring/server/types.ts b/x-pack/plugins/monitoring/server/types.ts index 0c346c8082475..1e7a5acb33644 100644 --- a/x-pack/plugins/monitoring/server/types.ts +++ b/x-pack/plugins/monitoring/server/types.ts @@ -16,6 +16,7 @@ import { import { InfraPluginSetup } from '../../infra/server'; import { LicensingPluginSetup } from '../../licensing/server'; import { PluginSetupContract as FeaturesPluginSetupContract } from '../../features/server'; +import { EncryptedSavedObjectsPluginSetup } from '../../encrypted_saved_objects/server'; export interface MonitoringLicenseService { refresh: () => Promise; @@ -36,6 +37,7 @@ export interface LegacyAPI { } export interface PluginsSetup { + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; telemetryCollectionManager?: TelemetryCollectionManagerPluginSetup; usageCollection?: UsageCollectionSetup; licensing: LicensingPluginSetup; @@ -56,6 +58,7 @@ export interface MonitoringCoreConfig { export interface RouteDependencies { router: IRouter; licenseService: MonitoringLicenseService; + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; } export interface MonitoringCore { From 825c16875ea9dab3168c8177abde685d808250d1 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 17 Jul 2020 17:16:28 +0200 Subject: [PATCH 18/24] register graph usage (#72041) --- x-pack/plugins/graph/server/lib/license_state.ts | 13 +++++++++++++ x-pack/plugins/graph/server/plugin.ts | 10 +++++++--- x-pack/plugins/graph/server/routes/explore.ts | 1 + x-pack/plugins/graph/server/routes/search.ts | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/graph/server/lib/license_state.ts b/x-pack/plugins/graph/server/lib/license_state.ts index d86cb5380a2e1..8d64c826d8fa1 100644 --- a/x-pack/plugins/graph/server/lib/license_state.ts +++ b/x-pack/plugins/graph/server/lib/license_state.ts @@ -7,6 +7,7 @@ import Boom from 'boom'; import { map } from 'rxjs/operators'; import { Observable, Subscription } from 'rxjs'; +import { LicensingPluginStart } from '../../../licensing/server'; import { ILicense } from '../../../licensing/common/types'; import { checkLicense, GraphLicenseInformation } from '../../common/check_license'; @@ -14,6 +15,7 @@ export class LicenseState { private licenseInformation: GraphLicenseInformation = checkLicense(undefined); private subscription: Subscription | null = null; private observable: Observable | null = null; + private _notifyUsage: LicensingPluginStart['featureUsage']['notifyUsage'] | null = null; private updateInformation(licenseInformation: GraphLicenseInformation) { this.licenseInformation = licenseInformation; @@ -24,6 +26,17 @@ export class LicenseState { this.subscription = this.observable.subscribe(this.updateInformation.bind(this)); } + public setNotifyUsage(notifyUsage: LicensingPluginStart['featureUsage']['notifyUsage']) { + this._notifyUsage = notifyUsage; + } + + // 'Graph' is the only allowed feature here at the moment, if this gets extended in the future, add to the union type + public notifyUsage(featureName: 'Graph') { + if (this._notifyUsage) { + this._notifyUsage(featureName); + } + } + public stop() { if (this.subscription) { this.subscription.unsubscribe(); diff --git a/x-pack/plugins/graph/server/plugin.ts b/x-pack/plugins/graph/server/plugin.ts index 141d5d0ea8db4..b2b825fa4683b 100644 --- a/x-pack/plugins/graph/server/plugin.ts +++ b/x-pack/plugins/graph/server/plugin.ts @@ -5,8 +5,8 @@ */ import { i18n } from '@kbn/i18n'; -import { Plugin, CoreSetup } from 'src/core/server'; -import { LicensingPluginSetup } from '../../licensing/server'; +import { Plugin, CoreSetup, CoreStart } from 'src/core/server'; +import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/server'; import { LicenseState } from './lib/license_state'; import { registerSearchRoute } from './routes/search'; import { registerExploreRoute } from './routes/explore'; @@ -34,6 +34,7 @@ export class GraphPlugin implements Plugin { licenseState.start(licensing.license$); this.licenseState = licenseState; core.savedObjects.registerType(graphWorkspace); + licensing.featureUsage.register('Graph', 'platinum'); if (home) { registerSampleData(home.sampleData, licenseState); @@ -79,7 +80,10 @@ export class GraphPlugin implements Plugin { registerExploreRoute({ licenseState, router }); } - public start() {} + public start(core: CoreStart, { licensing }: { licensing: LicensingPluginStart }) { + this.licenseState!.setNotifyUsage(licensing.featureUsage.notifyUsage); + } + public stop() { if (this.licenseState) { this.licenseState.stop(); diff --git a/x-pack/plugins/graph/server/routes/explore.ts b/x-pack/plugins/graph/server/routes/explore.ts index b0b8cf14ff699..c436fbd1c79af 100644 --- a/x-pack/plugins/graph/server/routes/explore.ts +++ b/x-pack/plugins/graph/server/routes/explore.ts @@ -42,6 +42,7 @@ export function registerExploreRoute({ response ) => { verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); try { return response.ok({ body: { diff --git a/x-pack/plugins/graph/server/routes/search.ts b/x-pack/plugins/graph/server/routes/search.ts index 645e6b520013f..e1d430eeb311a 100644 --- a/x-pack/plugins/graph/server/routes/search.ts +++ b/x-pack/plugins/graph/server/routes/search.ts @@ -42,6 +42,7 @@ export function registerSearchRoute({ response ) => { verifyApiAccess(licenseState); + licenseState.notifyUsage('Graph'); const includeFrozen = await uiSettings.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); try { return response.ok({ From 44fc2a828c755f77e14713c0484e541cfcecaf1b Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Fri, 17 Jul 2020 12:04:18 -0400 Subject: [PATCH 19/24] Fix indentation level in code exploration doc (#72274) * fix indentation level in code exploration doc * run the script to update the file --- docs/developer/architecture/code-exploration.asciidoc | 8 ++++---- .../kbn-dev-utils/src/plugin_list/generate_plugin_list.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/developer/architecture/code-exploration.asciidoc b/docs/developer/architecture/code-exploration.asciidoc index bed54277c82b4..2f67ae002c916 100644 --- a/docs/developer/architecture/code-exploration.asciidoc +++ b/docs/developer/architecture/code-exploration.asciidoc @@ -11,7 +11,7 @@ NOTE: //// [[code-exploration]] -=== Exploring Kibana code +== Exploring Kibana code The goals of our folder heirarchy are: @@ -28,10 +28,10 @@ To that aim, we strive to: [discrete] [[kibana-services-applications]] -==== Services and Applications +=== Services and Applications [discrete] -===== src/plugins +==== src/plugins - {kib-repo}blob/{branch}/src/plugins/advanced_settings[advancedSettings] @@ -283,7 +283,7 @@ WARNING: Missing README. [discrete] -===== x-pack/plugins +==== x-pack/plugins - {kib-repo}blob/{branch}/x-pack/plugins/actions/README.md[actions] diff --git a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts index f3f8817299bb1..f0f799862e24e 100644 --- a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts +++ b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts @@ -54,7 +54,7 @@ NOTE: //// [[code-exploration]] -=== Exploring Kibana code +== Exploring Kibana code The goals of our folder heirarchy are: @@ -71,14 +71,14 @@ To that aim, we strive to: [discrete] [[kibana-services-applications]] -==== Services and Applications +=== Services and Applications [discrete] -===== src/plugins +==== src/plugins ${Array.from(printPlugins(ossPlugins)).join('\n')} [discrete] -===== x-pack/plugins +==== x-pack/plugins ${Array.from(printPlugins(xpackPlugins)).join('\n')} `; } From 1adaa3b76c16e4f02bd9ee98ff181eaea9c24566 Mon Sep 17 00:00:00 2001 From: Yara Tercero Date: Fri, 17 Jul 2020 12:39:51 -0400 Subject: [PATCH 20/24] [Security Solution][Exceptions] - Remove initial add exception item button in builder (#72215) ## Summary This PR addresses two issues in the builder: - **Existing behavior:** if you add a bunch of entries then delete all but one, the indent that shows for when multiple entries exists does not go away - **Updated behavior:** if you add a bunch of entries and delete all but one, the indent that shows for when multiple entries exist goes away - **Existing behavior:** on render of add exception modal, if no exception items exist (or no exception items with entries exist) an `Add Exception` button appears - **Updated behavior:** if only one entry exists, the delete button is disabled for that entry; on initial render of the add exception modal, if no entries exist, an empty entry is shown --- .../builder_button_options.stories.tsx | 17 -- .../builder/builder_button_options.test.tsx | 44 --- .../builder/builder_button_options.tsx | 76 ++--- .../builder/builder_exception_item.test.tsx | 282 ++++++++++++++++++ .../builder/builder_exception_item.tsx | 161 ++++++++++ .../exceptions/builder/exception_item.tsx | 140 --------- .../components/exceptions/builder/index.tsx | 48 ++- .../components/exceptions/translations.ts | 7 - 8 files changed, 493 insertions(+), 282 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx create mode 100644 x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.stories.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.stories.tsx index 7e4cbe34f9a64..9486008e708ea 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.stories.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.stories.tsx @@ -16,26 +16,12 @@ addDecorator((storyFn) => ( )); storiesOf('Components|Exceptions|BuilderButtonOptions', module) - .add('init button', () => { - return ( - - ); - }) .add('and/or buttons', () => { return ( { isAndDisabled={false} isOrDisabled={false} showNestedButton={false} - displayInitButton={false} onOrClicked={jest.fn()} onAndClicked={jest.fn()} onNestedClicked={jest.fn()} @@ -31,44 +30,6 @@ describe('BuilderButtonOptions', () => { expect(wrapper.find('[data-test-subj="exceptionsNestedButton"] button')).toHaveLength(0); }); - test('it renders "add exception" button if "displayInitButton" is true', () => { - const wrapper = mount( - - ); - - expect(wrapper.find('[data-test-subj="exceptionsAddNewExceptionButton"] button')).toHaveLength( - 1 - ); - }); - - test('it invokes "onAddExceptionClicked" when "add exception" button is clicked', () => { - const onOrClicked = jest.fn(); - - const wrapper = mount( - - ); - - wrapper.find('[data-test-subj="exceptionsAddNewExceptionButton"] button').simulate('click'); - - expect(onOrClicked).toHaveBeenCalledTimes(1); - }); - test('it invokes "onOrClicked" when "or" button is clicked', () => { const onOrClicked = jest.fn(); @@ -77,7 +38,6 @@ describe('BuilderButtonOptions', () => { isAndDisabled={false} isOrDisabled={false} showNestedButton={false} - displayInitButton={false} onOrClicked={onOrClicked} onAndClicked={jest.fn()} onNestedClicked={jest.fn()} @@ -97,7 +57,6 @@ describe('BuilderButtonOptions', () => { isAndDisabled={false} isOrDisabled={false} showNestedButton={false} - displayInitButton={false} onOrClicked={jest.fn()} onAndClicked={onAndClicked} onNestedClicked={jest.fn()} @@ -113,7 +72,6 @@ describe('BuilderButtonOptions', () => { const wrapper = mount( { const wrapper = mount( { isAndDisabled={false} isOrDisabled={false} showNestedButton - displayInitButton={false} onOrClicked={jest.fn()} onAndClicked={jest.fn()} onNestedClicked={onNestedClicked} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.tsx index ff1556bcc4d25..eb224b82d756f 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_button_options.tsx @@ -16,7 +16,6 @@ const MyEuiButton = styled(EuiButton)` interface BuilderButtonOptionsProps { isOrDisabled: boolean; isAndDisabled: boolean; - displayInitButton: boolean; showNestedButton: boolean; onAndClicked: () => void; onOrClicked: () => void; @@ -26,64 +25,47 @@ interface BuilderButtonOptionsProps { export const BuilderButtonOptions: React.FC = ({ isOrDisabled = false, isAndDisabled = false, - displayInitButton, showNestedButton = false, onAndClicked, onOrClicked, onNestedClicked, }) => ( - {displayInitButton ? ( + + + {i18n.AND} + + + + + {i18n.OR} + + + {showNestedButton && ( - {i18n.ADD_EXCEPTION_TITLE} + {i18n.ADD_NESTED_DESCRIPTION} - ) : ( - <> - - - {i18n.AND} - - - - - {i18n.OR} - - - {showNestedButton && ( - - - {i18n.ADD_NESTED_DESCRIPTION} - - - )} - )} ); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx new file mode 100644 index 0000000000000..9ca7a371ce81b --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.test.tsx @@ -0,0 +1,282 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { ThemeProvider } from 'styled-components'; +import { mount } from 'enzyme'; +import euiLightVars from '@elastic/eui/dist/eui_theme_light.json'; + +import { ExceptionListItemComponent } from './builder_exception_item'; +import { fields } from '../../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks.ts'; +import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; +import { + getEntryMatchMock, + getEntryMatchAnyMock, +} from '../../../../../../lists/common/schemas/types/entries.mock'; + +describe('ExceptionListItemComponent', () => { + describe('and badge logic', () => { + test('it renders "and" badge with extra top padding for the first exception item when "andLogicIncluded" is "true"', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock(), getEntryMatchMock()]; + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryFirstRowAndBadge"]').exists() + ).toBeTruthy(); + }); + + test('it renders "and" badge when more than one exception item entry exists and it is not the first exception item', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock(), getEntryMatchMock()]; + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect(wrapper.find('[data-test-subj="exceptionItemEntryAndBadge"]').exists()).toBeTruthy(); + }); + + test('it renders indented "and" badge when "andLogicIncluded" is "true" and only one entry exists', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock()]; + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryInvisibleAndBadge"]').exists() + ).toBeTruthy(); + }); + + test('it renders no "and" badge when "andLogicIncluded" is "false"', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock()]; + const wrapper = mount( + ({ eui: euiLightVars, darkMode: false })}> + + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryInvisibleAndBadge"]').exists() + ).toBeFalsy(); + expect(wrapper.find('[data-test-subj="exceptionItemEntryAndBadge"]').exists()).toBeFalsy(); + expect( + wrapper.find('[data-test-subj="exceptionItemEntryFirstRowAndBadge"]').exists() + ).toBeFalsy(); + }); + }); + + describe('delete button logic', () => { + test('it renders delete button disabled when it is only entry left in builder', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock()]; + const wrapper = mount( + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryDeleteButton"] button').props().disabled + ).toBeTruthy(); + }); + + test('it does not render delete button disabled when it is not the only entry left in builder', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock()]; + + const wrapper = mount( + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryDeleteButton"] button').props().disabled + ).toBeFalsy(); + }); + + test('it does not render delete button disabled when "exceptionItemIndex" is not "0"', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock()]; + const wrapper = mount( + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryDeleteButton"] button').props().disabled + ).toBeFalsy(); + }); + + test('it does not render delete button disabled when more than one entry exists', () => { + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock(), getEntryMatchMock()]; + const wrapper = mount( + + ); + + expect( + wrapper.find('[data-test-subj="exceptionItemEntryDeleteButton"] button').at(0).props() + .disabled + ).toBeFalsy(); + }); + + test('it invokes "onChangeExceptionItem" when delete button clicked', () => { + const mockOnDeleteExceptionItem = jest.fn(); + const exceptionItem = getExceptionListItemSchemaMock(); + exceptionItem.entries = [getEntryMatchMock(), getEntryMatchAnyMock()]; + const wrapper = mount( + + ); + + wrapper + .find('[data-test-subj="exceptionItemEntryDeleteButton"] button') + .at(0) + .simulate('click'); + + expect(mockOnDeleteExceptionItem).toHaveBeenCalledWith( + { + ...exceptionItem, + entries: [getEntryMatchAnyMock()], + }, + 0 + ); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.tsx new file mode 100644 index 0000000000000..8e57e83d0e7e4 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_exception_item.tsx @@ -0,0 +1,161 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useMemo, useCallback } from 'react'; +import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import styled from 'styled-components'; + +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { AndOrBadge } from '../../and_or_badge'; +import { EntryItemComponent } from './entry_item'; +import { getFormattedBuilderEntries } from '../helpers'; +import { FormattedBuilderEntry, ExceptionsBuilderExceptionItem, BuilderEntry } from '../types'; + +const MyInvisibleAndBadge = styled(EuiFlexItem)` + visibility: hidden; +`; + +const MyFirstRowContainer = styled(EuiFlexItem)` + padding-top: 20px; +`; + +interface ExceptionListItemProps { + exceptionItem: ExceptionsBuilderExceptionItem; + exceptionId: string; + exceptionItemIndex: number; + isLoading: boolean; + indexPattern: IIndexPattern; + andLogicIncluded: boolean; + isOnlyItem: boolean; + onDeleteExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; + onChangeExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; +} + +export const ExceptionListItemComponent = React.memo( + ({ + exceptionItem, + exceptionId, + exceptionItemIndex, + indexPattern, + isLoading, + isOnlyItem, + andLogicIncluded, + onDeleteExceptionItem, + onChangeExceptionItem, + }) => { + const handleEntryChange = useCallback( + (entry: BuilderEntry, entryIndex: number): void => { + const updatedEntries: BuilderEntry[] = [ + ...exceptionItem.entries.slice(0, entryIndex), + { ...entry }, + ...exceptionItem.entries.slice(entryIndex + 1), + ]; + const updatedExceptionItem: ExceptionsBuilderExceptionItem = { + ...exceptionItem, + entries: updatedEntries, + }; + onChangeExceptionItem(updatedExceptionItem, exceptionItemIndex); + }, + [onChangeExceptionItem, exceptionItem, exceptionItemIndex] + ); + + const handleDeleteEntry = useCallback( + (entryIndex: number): void => { + const updatedEntries: BuilderEntry[] = [ + ...exceptionItem.entries.slice(0, entryIndex), + ...exceptionItem.entries.slice(entryIndex + 1), + ]; + const updatedExceptionItem: ExceptionsBuilderExceptionItem = { + ...exceptionItem, + entries: updatedEntries, + }; + + onDeleteExceptionItem(updatedExceptionItem, exceptionItemIndex); + }, + [exceptionItem, onDeleteExceptionItem, exceptionItemIndex] + ); + + const entries = useMemo( + (): FormattedBuilderEntry[] => + indexPattern != null ? getFormattedBuilderEntries(indexPattern, exceptionItem.entries) : [], + [indexPattern, exceptionItem] + ); + + const andBadge = useMemo((): JSX.Element => { + const badge = ; + if (entries.length > 1 && exceptionItemIndex === 0) { + return ( + + {badge} + + ); + } else if (entries.length > 1) { + return ( + + {badge} + + ); + } else { + return ( + + {badge} + + ); + } + }, [entries.length, exceptionItemIndex]); + + const getDeleteButton = useCallback( + (index: number): JSX.Element => { + const button = ( + handleDeleteEntry(index)} + isDisabled={isOnlyItem && entries.length === 1 && exceptionItemIndex === 0} + aria-label="entryDeleteButton" + className="exceptionItemEntryDeleteButton" + data-test-subj="exceptionItemEntryDeleteButton" + /> + ); + if (index === 0 && exceptionItemIndex === 0) { + return {button}; + } else { + return {button}; + } + }, + [entries.length, exceptionItemIndex, handleDeleteEntry, isOnlyItem] + ); + + return ( + + {andLogicIncluded && andBadge} + + + {entries.map((item, index) => ( + + + + + + {getDeleteButton(index)} + + + ))} + + + + ); + } +); + +ExceptionListItemComponent.displayName = 'ExceptionListItem'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx deleted file mode 100644 index 5e53ce3ba6578..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/exception_item.tsx +++ /dev/null @@ -1,140 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import React, { useMemo } from 'react'; -import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import styled from 'styled-components'; - -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; -import { AndOrBadge } from '../../and_or_badge'; -import { EntryItemComponent } from './entry_item'; -import { getFormattedBuilderEntries } from '../helpers'; -import { FormattedBuilderEntry, ExceptionsBuilderExceptionItem, BuilderEntry } from '../types'; - -const MyInvisibleAndBadge = styled(EuiFlexItem)` - visibility: hidden; -`; - -const MyFirstRowContainer = styled(EuiFlexItem)` - padding-top: 20px; -`; - -interface ExceptionListItemProps { - exceptionItem: ExceptionsBuilderExceptionItem; - exceptionId: string; - exceptionItemIndex: number; - isLoading: boolean; - indexPattern: IIndexPattern; - andLogicIncluded: boolean; - onCheckAndLogic: (item: ExceptionsBuilderExceptionItem[]) => void; - onDeleteExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; - onExceptionItemChange: (item: ExceptionsBuilderExceptionItem, index: number) => void; -} - -export const ExceptionListItemComponent = React.memo( - ({ - exceptionItem, - exceptionId, - exceptionItemIndex, - indexPattern, - isLoading, - andLogicIncluded, - onCheckAndLogic, - onDeleteExceptionItem, - onExceptionItemChange, - }) => { - const handleEntryChange = (entry: BuilderEntry, entryIndex: number): void => { - const updatedEntries: BuilderEntry[] = [ - ...exceptionItem.entries.slice(0, entryIndex), - { ...entry }, - ...exceptionItem.entries.slice(entryIndex + 1), - ]; - const updatedExceptionItem: ExceptionsBuilderExceptionItem = { - ...exceptionItem, - entries: updatedEntries, - }; - onExceptionItemChange(updatedExceptionItem, exceptionItemIndex); - }; - - const handleDeleteEntry = (entryIndex: number): void => { - const updatedEntries: BuilderEntry[] = [ - ...exceptionItem.entries.slice(0, entryIndex), - ...exceptionItem.entries.slice(entryIndex + 1), - ]; - const updatedExceptionItem: ExceptionsBuilderExceptionItem = { - ...exceptionItem, - entries: updatedEntries, - }; - - onDeleteExceptionItem(updatedExceptionItem, exceptionItemIndex); - }; - - const entries = useMemo((): FormattedBuilderEntry[] => { - onCheckAndLogic([exceptionItem]); - return indexPattern != null - ? getFormattedBuilderEntries(indexPattern, exceptionItem.entries) - : []; - }, [indexPattern, exceptionItem, onCheckAndLogic]); - - const andBadge = useMemo((): JSX.Element => { - const badge = ; - if (entries.length > 1 && exceptionItemIndex === 0) { - return {badge}; - } else if (entries.length > 1) { - return {badge}; - } else { - return {badge}; - } - }, [entries.length, exceptionItemIndex]); - - const getDeleteButton = (index: number): JSX.Element => { - const button = ( - handleDeleteEntry(index)} - aria-label="entryDeleteButton" - className="exceptionItemEntryDeleteButton" - data-test-subj="exceptionItemEntryDeleteButton" - /> - ); - if (index === 0 && exceptionItemIndex === 0) { - return {button}; - } else { - return {button}; - } - }; - - return ( - - {andLogicIncluded && andBadge} - - - {entries.map((item, index) => ( - - - - - - {getDeleteButton(index)} - - - ))} - - - - ); - } -); - -ExceptionListItemComponent.displayName = 'ExceptionListItem'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx index 6bff33afaf70c..08e5b49073ecf 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx @@ -3,11 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { useMemo, useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import styled from 'styled-components'; -import { ExceptionListItemComponent } from './exception_item'; +import { ExceptionListItemComponent } from './builder_exception_item'; import { useFetchIndexPatterns } from '../../../../detections/containers/detection_engine/rules/fetch_index_patterns'; import { ExceptionListItemSchema, @@ -80,20 +80,9 @@ export const ExceptionBuilder = ({ ); const handleCheckAndLogic = (items: ExceptionsBuilderExceptionItem[]): void => { - setAndLogicIncluded((includesAnd: boolean): boolean => { - if (includesAnd) { - return true; - } else { - return items.filter(({ entries }) => entries.length > 1).length > 0; - } - }); + setAndLogicIncluded(items.filter(({ entries }) => entries.length > 1).length > 0); }; - // Bubble up changes to parent - useEffect(() => { - onChange({ exceptionItems: filterExceptionItems(exceptions), exceptionsToDelete }); - }, [onChange, exceptionsToDelete, exceptions]); - const handleDeleteExceptionItem = ( item: ExceptionsBuilderExceptionItem, itemIndex: number @@ -164,16 +153,6 @@ export const ExceptionBuilder = ({ setExceptions((existingExceptions) => [...existingExceptions, { ...newException }]); }, [setExceptions, listType, listId, listNamespaceType, ruleName]); - // An exception item can have an empty array for `entries` - const displayInitialAddExceptionButton = useMemo((): boolean => { - return ( - exceptions.length === 0 || - (exceptions.length === 1 && - exceptions[0].entries != null && - exceptions[0].entries.length === 0) - ); - }, [exceptions]); - // Filters index pattern fields by exceptionable fields if list type is endpoint const filterIndexPatterns = useCallback(() => { if (listType === 'endpoint') { @@ -199,6 +178,22 @@ export const ExceptionBuilder = ({ } }; + // Bubble up changes to parent + useEffect(() => { + onChange({ exceptionItems: filterExceptionItems(exceptions), exceptionsToDelete }); + }, [onChange, exceptionsToDelete, exceptions]); + + useEffect(() => { + if ( + exceptions.length === 0 || + (exceptions.length === 1 && + exceptions[0].entries != null && + exceptions[0].entries.length === 0) + ) { + handleAddNewExceptionItem(); + } + }, [exceptions, handleAddNewExceptionItem]); + return ( {(isLoading || indexPatternLoading) && ( @@ -233,9 +228,9 @@ export const ExceptionBuilder = ({ isLoading={indexPatternLoading} exceptionItemIndex={index} andLogicIncluded={andLogicIncluded} - onCheckAndLogic={handleCheckAndLogic} + isOnlyItem={exceptions.length === 1} onDeleteExceptionItem={handleDeleteExceptionItem} - onExceptionItemChange={handleExceptionItemChange} + onChangeExceptionItem={handleExceptionItemChange} />
@@ -253,7 +248,6 @@ export const ExceptionBuilder = ({ Date: Fri, 17 Jul 2020 10:06:54 -0700 Subject: [PATCH 21/24] =?UTF-8?q?docs:=20=E2=9C=8F=EF=B8=8F=20add=20"Explo?= =?UTF-8?q?re=20underlying=20data"=20user=20docs=20(#70807)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: ✏️ add "Explore underlying data" user docs * docs: ✏️ improve docs * docs: ✏️ change the way Discover is referred * docs: ✏️ improve texts in line with review comments * Update docs/drilldowns/explore-underlying-data.asciidoc Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> * Update docs/drilldowns/explore-underlying-data.asciidoc Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com> --- .../explore-underlying-data.asciidoc | 41 ++++++++++++++++++ .../images/explore_data_context_menu.png | Bin 0 -> 103214 bytes .../images/explore_data_in_chart.png | Bin 0 -> 99870 bytes docs/user/dashboard.asciidoc | 1 + 4 files changed, 42 insertions(+) create mode 100644 docs/drilldowns/explore-underlying-data.asciidoc create mode 100644 docs/drilldowns/images/explore_data_context_menu.png create mode 100644 docs/drilldowns/images/explore_data_in_chart.png diff --git a/docs/drilldowns/explore-underlying-data.asciidoc b/docs/drilldowns/explore-underlying-data.asciidoc new file mode 100644 index 0000000000000..e0f940f73e96e --- /dev/null +++ b/docs/drilldowns/explore-underlying-data.asciidoc @@ -0,0 +1,41 @@ +[[explore-underlying-data]] +== Explore the underlying data for a visualization + +++++ +Explore the underlying data +++++ + +Dashboard panels have an *Explore underlying data* action that navigates you to *Discover*, +where you can narrow your documents to the ones you'll most likely use in a visualization. +This action is available for visualizations backed by a single index pattern. + +You can access *Explore underlying data* in two ways: from the panel context +menu or from the menu that appears when you interact with the chart. + +[float] +[[explore-data-from-panel-context-menu]] +=== Explore data from panel context menu + +The *Explore underlying data* action in the panel menu navigates you to Discover, +carrying over the index pattern, filters, query, and time range for the visualization. + +[role="screenshot"] +image::images/explore_data_context_menu.png[Explore underlying data from panel context menu] + +[float] +[[explore-data-from-chart]] +=== Explore data from chart action + +Initiating *Explore underlying data* from the chart also navigates to Discover, +carrying over the current context for the visualization. In addition, this action +applies the filters and time range created by the events that triggered the action. + +[role="screenshot"] +image::images/explore_data_in_chart.png[Explore underlying data from chart] + +You can disable this action by adding the following line to your `kibana.yml` config. + +["source","yml"] +----------- +xpack.discoverEnhanced.actions.exploreDataInChart.enabled: false +----------- diff --git a/docs/drilldowns/images/explore_data_context_menu.png b/docs/drilldowns/images/explore_data_context_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..5742991030c892151dad9d156b7fb3b0ad3f5cdc GIT binary patch literal 103214 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

1NzFg> z)cTcP#W`rS*IVCcXurE=oZ!{Ex1it{ zI$PauA8oq*fMKPXqCB+{E3E*J^U(U)K2kL%CHQXQFD;(6n)mZPHQ2;1ZhWv9R(*kf z^Zv-D%#IC*fq-qED95&g;V$QnaWJU)6XdG4k$Q3RYxTSofVS>$e0pJU4Q5M3}4P`iWTowBct*#+iJvmTY1SXobjoOK?}a6o{d2bxd|ft0FgF-ph0a#Me=fvi z7@NfJB)P@slN=t*UV%>&en>CY$YSsJ(e42bs9}Lzxsb^ZZaD-+i&Llf7xrT=8}~!q z)?|Reni05A%fdt{?sdfGs~2MPM-ql>HI0=)9h|=y--InM2GB@{-L>_sudNu&?>_LS zCmD`tDaFDz#QKCPg`L*)azO?gPJj70Q4xy_umg^&KUb+yf8x_{E3I;ql5i2&swULF zCo9yemA)tLfA0Ly6p1~;>JEfL&OjJ#k)=_Yw<$O82#Np9Y`UVC*PiCeI|A=XDC-Q) z$4FgC#}^Hzf0K6(r9`l$>}Zqr>X(01FTmqvWM}wT4Pift9NtkacCDwKmZJl;c=sb7 z>iXea89$iH9V@z0i}_}B-2OtM4KlSqrcmOE;N(yzW5L#yXI8iSaTcoHz36etqp?}5 z%=QhPtp`8x$*Z^bmmePUu}l*ywN2D`@2Jz_b3bcuN7ZQKaDP32uj-eF47>4LNt*g2 zN)v^ocRV|rv_%C0v(p z5S^_oHW~-9P13vz3X{0Z*`9JEH=%vi{1II&p*{l#qu#?c4y9*1Rs!ix*qwTr9k~ao zwAMDUHV4$0C6nuK{{g=dHM9ygo%U)5mtJk$Fxo*=KPi10DOA$w#(9iY3rCj%j|*rx zt_x)>Vys=JXYhiO$&hY>2$sNQW3!d~>odhX(2tip&6q;byP3ibd$G#?t_QZZBYmdW z9sI~HvhhGLp;2uL`eG1Wxa?b=XwY2MX?VkBi$G;=J}RWFzxc5q4)miv*_+Z*p0Wf{ z7T_bJc%-pO*b1xXfz1MPxWUba=iW#|@l)p!C@&gY zHQi6`lIn!u>r6C0DepyU98e#YyH5%_TmOVZFBYn)U%qARJ^H2#Lklf*!W^p(k{CWE z`r5jfVq?X54juM&T)JSPH~7q(Uzs(aT@c4MXR-UVny25Q*;FSeg7Td9N61PNbw6AN zi_A<-!t`2{t*WpzktdDUgIy|S0XWOttx@s_H-=|bOrhze1Rq^g@CkRZ_DWO*z{m%< z6vRke+&7%TW*(*g$tLAgx7JOZ;J&TusowLRYNS9-LkrDG_DLmsrOe6B9Atu~?wU=F zsQ+OU|18=5d;VamhjZSH_$Ff?zbz)0p@j-*u4)O39&gx=ACmT7+N9Rm5O;Lz2`?{^ z`UJlmw{hybG->C=CT;qj;JcoK>xRaLz$?Hh0@Xitb(v<>6{3R~_IcM-gc&a6Y~-X< zo81@VWO+{aV3)uqRlY#@<3%fCglWBG)EO?7Uz)s%UfUGl4kQV++Ytvbe(ak`n%*&Z z?9+;45xNH^ymSa291tOVTf%R1eYoRyd@41f^;-0>qG=^OG)?UbYp{+#q$k^dtxtKz zkYPpNj0SZj4U6=to11OqV1js8WJOv)=(WYf49WGNQ0ar~;S+0A=l7%rN*QR`tn2W3#ZYkQS=X97Eam+giLhX zuP;^)1^oUzPTU|@{r0t02$lfURha8!#meCHr9v6=Cw-UJvP)X2A{^_k^Df9Eb<-ya-%i?www!G9>c@WwLk*ub4yZjF}OmMdb4XOu1pAOYZalVHD!MD(;$tW`d(j6 zH^)M6VAe=hMmhxKSkqPgO_b9;xHB@9ViHNnYNnn~t5IDIg>494&x$XBlb-8*EWVrn z+RTNeCRWS7WP8Y|_zP9Qsfmp?SFy&((>WqPS-V$NZ$9C?1etAT*1GK~NiAU9cTlY! z&x6_L-1U3V&!apXNKZX2%fDQWY^5OqHIw)=%V8x2yQDH=jgt*!m)x%@fE=uyB^^{* z%pJ}+8_pok7)`wsGx7yNGFNhgt%ds`gAt zkoYF6nnFFnIa6mH=O#Wko<=y>W{S@34j05_)innPqfnbCl_^EA(o5q?5O}Mq_4rJ-Y(ab^x5KM>`A%%HkzL zV>!`qzc4$k%1LUOG3F{~mWEiYGBG2d%m732uafkUo#^1Z7|j@6S}Yu3EYPYh5;Dk*Jz+B9)Pq`K*n_`asjpdF{EifbyYAhM%dE;_wgMTaA zKA+#(_l%z;E(z(*zDP7Xt-QB;}zSYn7xvuBmy;$~~IWza%GiPSb z_Gljar_c07ha~}1_)7!4wV!wT7mau;Cv`kN28BeHzEakD2x`r~LCK+lA2gq|ntDOt ztKap)6dX=rqBPxy*R4jH^XOOOa44zVr^e)j^L+rOt$TomI_xgQ0cF{;4!iDD4-*x) z#D(};qPhbzh=Xa_c9YQFGKf@>W;(M6oui`tT4Ejtuj8BuAvc2kb$}CTUKEs{4kem5wcm}W?(8z!N@V~ET-lCr!9%L zjVBU=j)o!x_XM4l8cVhnhE%=vQTD1E*IJdC0zbn=nj;0mvUO=?qGXgYZMHPOa@s?N zz9f-;XOm)w>8Z2+pl?6b#!2_O00;l9aqCCf{#Nw6q$eZl+1q2Dn1|-mS)SgBOy* zn^aDw33~p_)rq;NPML%nV~M*CZqlQaNVdD-OpKi<2O`EmmqnT#HaA_+X!&~ zMQ~iKD7o{S{e;ZCaX-mm6DP=AA}#tpNHQ*HkLMc#C=~DM8m7bouhrb?>t&53)@QN^k8=^c|)TzK)YDgDYb z{7?Ee#|q|rI}81?mtCv1Uyq-nvH+doRDQpWGWfF0($q>Y`OY71(MYMmru$zNfvIsp zUh&Uvwnv*1=1Q@6=q|Q+q&M=>2uq^q9M$0Q+*A8|$m-uD-oA)6ubEqTr(xR}K_(ZZ zz5RMMKE8XOjbpo+pnm&zz$(j#$FH* zJKr1ET?o)abYh+Noh8v1@%qS7&#ifmPVvOUHSz2r;E~h&WZiADEdOh>Y<8Mh7~4St z0;z{3@mH?Tf_NAMLK|vOO(_y?$GCg%`?hPgj_|gN>0RiLyid3_XPolTpbQS+$za{k z-CbHlD$kno@Vr&}sCMyi#mb*%eOAmSLE0cwmNdcbeyxETFq z+;b}p`BM@CZE@bbl1HGtU5l3;HJ>rwLBeekuc*4>*LlpyY^Rg zc1Cv3{L5UDtWK^gs>@$%)4N@eS@E`$%y@1Nk4jaBknsOR0rE~{Z7~X7FBP6!<;~yR zy;%*W@Ki}j)Ga6&B}6OjjV3Cx`H;+sRilRkFND*hbL56J$ajktXA~_}+A!?7R2y*n zx+!Js%Nw-)~!JBdZ_3yNW&i!PlShM7a z))Pkhu2$~0%05(BZ&)pmjNn0JEX!JOp1uwO!mlUwnXNne4-MPVbV_1l^da-BIkFg_ zugmrOlr4AN){RnR%_$s`TxzV!cW>Qm;R?yDsjX4917DI*AlcAUcyqwHBsod%9(`aa zkZ($+Hzo!&J0V<~aC1=Wjp1TmukmqLWD5cVFxXS7uz)ocw}Yn8{-$4}K$&aQzf^O4 zXuYpeXM#k3Ee<)#^lYg4*A51Bqd(Q)QmR}gsY((PL8wOH)da=)jweG$`kL#c?9h42 z!AavK2#pN)fhR}j`1dv&{3Ttb7S+ME6^h1rd>CRk!F}<0c$X>ab z?j(DcmE4jdZh4+|jy>|u#5rP;BgDrh2Bg*V*&K>-`bfKCsX<-t-47RsLw&eb+Okd( zPB9-01ciEzhx2lo-7+zu7)%8!<*w{ZR)C4+Y2PL>Wl6n)dv8&DxIP&GU38j4cKrG~(~cqVIE&qCL2S%~>6_7PrJ2Z(cn1lRy^j=L*wO)_Q?-T0 z1Fc5NE3K<=0)a5{GV<2szbn7t;P<=qU=j+ zfmk8~loSQ6b^l9CLo+k#2{x#cjrNh#9`xY4kW=NOb54_ z(T@);6a2WBJ#B~A7q3~fC|7fyh+wjYPQWi)%y4)`QJHzs-x*~=?I%h>xVA%T91>Of(4v~3AdP@qo zN8P)f(cEsWTq_Buj?_1@SFP>SVS_2po7eR*s8lO6L> z985Sh`|p`e8DmhOT;lFPss6yJOZE%W#@*>>_4{7`93Uq>5?{IueJC+VcsqAD`Zdhp z49H;6lc{Qy430*DbSQv)yanaagE|qObz^9ZLn1$E#nb8`CcoSG2mjw_$MsZQS#XM( z$>UN*JZ(t6Iqd~I2lEiTqq$nUo;aKNb}pC`blk)QX>4;AKKMbU#wQ`+7H~_m&ehy*2%Cc%DO0 zCdWsm15XUJV;4W1h}5Hc?RK#N(?_2VViyfuV-^OEwdLWTMZ9zXJfE_}IAzbZF%*|i zoz!JBnbp3PT57{fT6CXn!B}BNvM_rRGP3y?r$GqX!`(euEm2@!ZTHuJ1S_^sKI0+v z)XYz`K^(f8N(-D;XEcy*ynPW3S{4(sF*rC3J*vu6=PE1yi0u_yT7AatEa&~LaE{n! zC>5w>?HYi$!T+c+@8iSOT82GgAu$zJsnpG`z@K?@lYheqp~G4bC~H~w$f20bVDmv0 zJW^~th=7dGTWG9EFS#E3TLg5*;AkTmJ7cPCFErk=2GwFwe?u37e-um{YNUYV&EYeVcVE~1vGwDnI z4T@Bc0PY~h4eNgtVKqa@p!SgWq6LZ?cW}zX7jYjg;E%@QkE}Q5N(-XU0*2AyQ<@>m zWmgC)hODndl&g@X_3ddX~Dq3P7H=h@xqBU|uL zJXhdzbOL>Cxg_p|F7D?->CLa6PN-M_g+wp5$R2n?3jp1B&R1S}$!NRazUn}L;r{sW zrNVgsxr!*M7XgRjo?>ht%}_#%KgpGu=j`x?5vlOh?O~u7OYo!IW&|=i7|DM6%<3Ak_}L>|DycQ9B7j0UArfsa%5GCwkQ9 ziOyEvX=H?XoF1qgy&j0B#R_iLO@3$8?jKGcKruC(g<7el9=W&Ayx}H>G zgURz18tGe8PGnkb>FJH=vbFlw+O)P^MRFc4E zM5&HzHQO|%?sczGvLol@BJ$;mxA}5`NBBxs5JOs}h_R8)4GwRCN`O&EmWlo`thIhJ zFY-(0VfV7G*-!P_0B*+}{b(g^9gMW~(>4RhZFqCoF_C`|wf*DOigP zF3)$)2h;$<{W+(wC-A1gnNDqY4#r{ zm|^Y)ZpidZ&yz4>SZHhB7WkRG4xAcUm%^MAC>9N6jrJF%YIc|}rMBNj%yqH>J9|3T!oP7LfDl2Pt`@#fHq z6;=D-_awMA8a2DX+7nsrdSf1EfF;kq^$AEUDz`t&usghPC$`&D_{!%tm8Gmx zX!j*MuI7g0?@B7Ck52xW6{g|(SvRHJj(0!a$1v$m?8HjBNW~RrfxvFFZ&8<*;*P2E zmA8MTFE+iZVg6>=Ei3;_Um-h0d*i7vBR-b_hKClzi4zio!t?Wshw8K@ya~tf8Kr$S z493~Yd;Z|;u=?FRfuBHz@T|B#WTj4_om=@d=_h1|`C4hIO%PVSlLEY_vo2;zN}L); z(I)ILva)%KJNii9+lf_r~yaWO(% zLS9#|+QC5-zEmRVw2ftX#*U&~zL^i5GkY>+dRW1%;X!X@jB913T7RrDe){h4`&HFp z+0nl2+y2aDoiz*h)C=s{omP_L;2=@>OQoXy^0x6I0-g@1c91=WCC1M;o_ANIh6-(z zB2;@_+aa6q8JOB5!-3@{&)`(zF?gA)w`km-gHWROqI;s;RNl05^nb>)DpmE-WLb1f zx&3%Kn1j}gGx3=#gC|B^mu&Z?6sTkj`+@IcDsO%&PVs3wDteH**5hcq7JBCROSOw+ z81dLM@M-Z+$XhxLhZ}UesmQCsjC+1;+K|#f4WYx63`IZA0P3(lT|SP=f?Y>p_twh& zPiF^wpX#98o{@-@d}pRr=N*TtfbSkpGOlAACZ4%z)xIf^EMZK#yruM|{!02qa{h7Y z%iUR6Nn)$|UUo)jF9EKivHmX|k~K0;=b#+9$FNvNu)f9%pQh#lRev3i@ryp@zBXCb zk;xXHc8j74d4x8hFRqo@g{hz;3-#)LJ`*v)>GfbM7`wG~92)#t zi&}l(VfW;j(ZEfE%#jlSWjn11mJ>y_?{2FX!_MXRmysAscXYiziu(7Zj2|Wd0Lvpi z+)S!RHhHmfxtyA+_i^gyqkMu9ZUoq4P(h=5$=A8YYQUf|>CI+I>|BLQ;j5{`pv7A~ zeWb|k;_4HL>PAc|3TaV*si#1}mxwYL$2InNigWFp=0WPF@0+g^jr;Fptn|Fy8GKN$ zou9j&?U|@Qp_HRme=E%C#aP6#{15_MD7D>>n@^18jjUSE5f;O(P|++68G4q!nk*SR z;8;`!8ppXuHr{$=Xq1(4$8cPUS0IZS0TfYPvJ+ZZ}r*XZGywJ2W_Ca02!fKPd ztF{)fN?}aLF z`lPNZLjFv*Q&OVJ8^Q8maidZtN}`m{!iRKQdCAt~~$mMSLCgk79X&G^bCwO2qZ0dBv&`YM_S1X~i+|~Na*x)JsktqA^MbxvQntl7#4hOjc zJCgqsGcysA0;Jkk-iHK7pV}KwT@K3t0jRWxm{mU;W}y0GXs`jk}xr;urD)YkJI6)hH&gJJ@`im-}*^&pZQ#W9@gx$FiuGgNvJz3ZPZ-|J-7@ z5nP|>WsF|bL>r6|z3#|QdhZ66k#{byH|LS44pIQb*7?TsAo=gA zyba;-n7}`7FUh7}NhWhf&V`N9u&uzgu03v*1z4pt={qEy!g<4-N(e>>0_dJatJ#yP z7~5;v*LnBCvfUpO6hznYvbyBR7eNHGv|KBX7Pm(D9yti;pd3si;W;l!z%bAZBVtRo z-FPvVlHJ~x8cZT;g5fA(AKM!Z60+3f;Lv`X60>jcs0;LE?I1;QVN?OdbA zZAVUFO2`GxN77X8ALwj4C1(#bPK=Dv%AIGplj;HA3ReGyfms8$2L$VXWc>s?s1o*h zrBolbA)GXD1U^&3OFdD{r5<3f*Lc_aJb`*cT;Nl8IVN|=)p+JkqSN9woM0#@0t z-7#zaTMiL!4csNgdL+w#ClBbeFd%k><&5KR2{3$@CVz*_>wfhOq}?D4(Nf<2=|i;L z(}Va*puaK&M}?2Six>bU$|;~O&JLa8vL9v?Bt0+Ht)Ot?L-{56D>AUmcKjU^fAZ#Id<1& zXYr=Pg)s0tzpR8!XQYxI%w-sOs4t=HA;ySz|69N>0C;ddp?0+!{gLS~4dn0ytf}Zm z$`|w)Puk^S@$4C;8Y_kE@-I3F%%7FA1KU3M&`b5_5T4Rt_yO`kX%k(gVEbbfpRsBj zZfJ@>Hw?$$HC{z**=WzE;H;u>bbe|BM=C90NW@cOE?Z|rFMBN>%6Aw;JaP`Rh@41A zi|Zq{9@@L@4}Gp~e>s9J>7DN>S#y$3bJ{zVs9q%3RKzH~ox$=y?tYUW44@@3N8Eo$ z_n&%b)3m_F_2t!&{}BSSPdpW5|42o1%+@se>72~bx73c(c@35(jN0!dzi|9xIM}dq zWrc@6$xuJi$VMp#tJMX?FdG>Jr@i*9sBiE%jC|F6u;3+KeZZGhu67XI?9}$C)AS+E zY9Ydr>~$xtT9Up`pNgV(_+Pz#f_=mUobO#L~ek6 z;oMwK;mkO#5Q3YGhGzOMYHfJ+achWAm+N6>_vetMfgq0|=a*gczmJkJI2*TL-%mfH z(`L6>2O`_-Lj8ZmTz!O-JbDcb1@_bY;YWw1*j1gH`QngYoM6#YwyP(2;DxMCjc9!Y zINO8v=ZKHe8P=Ug&Gh5waQBw1P*H zzXt*O71;USByi1PCvH@Nh2cIa;mttdw(xhK#Ix41$?V}uT_hbu3g`JMljUr)rC+!} z7|d_-pT@(s0~ZK@gikpxFV??b{oWGUiMV~pGRvEB%xQ%`j~%PM5v>fL5<%-b6sYMN zqxxJwJBD9QOfru4Su0v()LWliOf5<)0Z3%k*XCJt?F@4#vMF3vsQMDC{Lz0-{XfZJ z$ir+UZ+)rtuNd>N|6-L|1v78(rQbn!IT|zRrYW%`J!9=ku%U%qzHL^H{ZEthGixLT zDdJV?Pk1uo=1_Q$%ErN$?h21)jQW>4StP=Hb&qRb>!`ySA*Re%(f?CRByt!^4I3QE z{{@^1Wa1kSvU?u=Ts3muzZO1*D+2u_yw=82mCb3hDj!QZ-MMHH{ZK4jYU#?K5}~m) z%2V&Y+ElWIf>-ZIQp;#n+LC>`Z1+!A(&P{rh;W*>QtAHz5eyoL%aEw%qJFj-@?6Mc z5NY>#v9*Lcq%#|U0G6t(*QVbUV>2+S%9MJGhB{(RuN_Fk;XxkcxuAud=9fBHs$e|R zw4iC~sNs5xb;S_x^EL!5uh8!WK}ByodC@XC3osqzqS?EsdCk)@Ubv#5GI^i;LT$z^ z7QivEQpZ2fdx#}gO`T)vqk8;5gb;?E@sIKeUZp?lMv{lS{5hZ5`F``}lRXl5#L}s2 zFp~)MwGhZQ+mi*24_zOyig?}&B*z=>>)knw@7g=e+FyNtRo)zqRfyKG(p%Cu)aA(M zU#KrBzP|eP7f-#Buf74l!|&H8^9K!|U_<;{+I||3wa+R%Yp++FjA3>1`-NkSRg2}< znb{G6U8BgC-pdCSW`UfWHSP85o5LsZ!l;&itA}28IGgiqnAD|9WcjJ+DTG1sgAzrY4Gux zEg{znQo+5$>_@UhU{ATif8QSMvK(YcHvnC`^10Gkr883=@p%p+Q_Ow7V)!@<)>bf z@sX-@*f=3E9jP?#Ca81JRY$k|=8^`b;28YhNnw<>bjm&b>oA@QU~@LFGFt95O$;># zI9+mDIk#M2>HE+TuQOhjy{i76B|}K%E?lZaEm_O%)QzjXQ3V1wix-N7LXCi{2QBmt z*+7Y2B~^B6&m&Oqvi8+qxB^6o@fOBwQOVSRc;r76SR(Zy>V}RKY)H)&zJkkUYq%$F zJligeeh3StV4iJB%+QFo<>kHvlJou-a^Mc69a3+CE zHH81R;DpRub1bN71?F+@oG&P?axZ()lijHrKFZWJ!}a{8{rB|Ke7U1*9m^2t^Nt6Qhj=zg!Yhi-N+Ty z6_Y6EY(A?FHn;~Manv?@Njlmf)BX7&c6B8f0rb=d``@x?mJk2|xICrgX#Feu76PAU zuLUvjSYmrs#@7cXt{iNQ$}D)<11bEkH;A^P&Z=9oZ*C7eR4D98a+@QxGdP!1BO(t% z;1cP@DYfU6)Ln#LprWEL`TuA36nkmGSHMF%zcX*Nu$%z9N91-SCHuc$H-h~-!5fZ$ zoTo*4Y54B`?2w74f11K6<*xSCSs8#uz)d$7!po;0By3G3mL;PV#I*x9{nXe`DyzQX zrIJ;G%$OEjlQ*pSB_|JgKlw0I@Z$b=!ni(#h@dgD6t%I{TTGr` zwJJOpuL3%8A81@@6!sF7856$7yfN}JQxGlKLeZAN(-@K6Vf6RT3akii(_p%)gB(Cs6vOK zRbrksJZL?m#%0JQvHJK;N{u~F+m6%=;ArAh15p3RVjTeC_}^f+oc{HOX_!+S_qsRM zT~=w8WLs#tUQ|?#8ca;tSGv7|WM&c(OyA(4%$SC|H~WZZyTQ*YuA5JnciZ69Bm~lU zUH;iD6lTQ#AA00X1P|Kd7ALBQ+GL9D(I?^0cm)sS4&F2H^$w_Zi z3|xP@Je7P@%~9v=o8qVx#H|s$z4A|bXS(h=AV#6Nc*6-N@3-Z6Tv zTq&RA%DwrRm{sbYQ|jf~N(14;(XWBd)rl*qlBAO$f`SoN@U=@H>DCGUX+K03X!hC+ zt%3jdBZ2Th5c`p+1Ns%B@WMYDF!$**9LaKl*+o z;1gI)Iy^Jcw|&8dxyK!w+kc&wd$*6;eWDStac1zP<$UXyDzVH~AjX9@N?Qa7(@!-v zH2#HQuz;^(GR%skmNo>Y6oplJD z=WYbgi2y7T8cKHiXLT*`4RWx4J+^h+KXykBkF9=gzO6Uo$e=GVa{vPqARyRILOF=o@T` zaLomQUtxYCy4sFp+=aqk{cE%)L3fKOeyp`S5I7kIhu|ZMUA^wzAvjt^$E0 zHO`)9==U7CjS5D*AP?9#Jj{F9{^zQKVJqlV+2s1)3LXf`Q(iLhFF7{qA ziWReil_IQ2<}E0kLsqAY!IwNU<(mRrUmY!*b0u*EkQb1Te*pr5Bmu70ifR?*kLWQZ z;U9=gB4w?4F$;5u1wOjdS!KJt2Nxyc$#t>8MAL;pL9$j^zib&1jT**ZmaOwOQ#v&MS2>WY*W$k8T#UNy>?3 zypd67Lukg|?wz^6T=Xo^DEz_l$f%K;yJ+km;vq(p2BXl0z}eyy#>LV8C2@ciIXoKG z+8Nl-Aa&GPa}0_D^#4W2kK=d)Z|{edt%h5OLQ5VM$RVNS*Ce5^jRj z3dX&B1*H^$u+!+H6;km#WH&6D87xte1#Fv#wPS3T!;w|-v#k-sI+xw>qBPpeJ~5sq zUeoy;s^Z0xuM3{LXgi~|;8#z3RVF{Ut&^w2N}nAMZUTc}J$OGqJKQecmQG<0@g!#N zExsrO3YZhwEhUh#UqcFYq+d08JwC+&5z_tQ3JJl*HartclS!)nQLI(nlf!D_DT~5; zywZ6pHpVj1r9105>?EVv^KiO3B-I{pQBB;}=ysVeUE6Dac>s24zN0nDGYn*pHR6hb zB|>4@%&A%^FT-EQ0q2uK^_XGE@Y3Z+c8lpsr<~3YUWWzbM0LUPkG#$ zV2`s>`^6*yYu8scs4w=B)r_0Mdxh2tKEP8*BO~PpB!j2MQ=(ej}jN+fMM#VklQ4+wBmf*3HL6@(WN_%}*xqJr%H zM$;TOK=$WDIR(>tT5+`}CFJQ%8dTA6c#=MI!gB`D<-}cv7+EQ`ny@m5>DGr_zEO-X zQwixARUmpsGM62`%T13FMY{dr^iT;_TcfK(b2fLS`Bo>~0k1MV)ce_?|I=D3h|3Qi zD_=mASX!9s@w$?IAkO>6(k@E6uS{Ss&?Ft+M-XLLa%;Q+<5_vq@!& zV)Cc;P;S~mv`P=6aJ)LgoF?fgri<$4LL-lGCE;<%RiVUalAL?=^h z^MhJOFTeHKUCtDLC7|OTOr%x~KC`I0+T(LM@muMRI4pS@?e?0n3~nChm7UN@l~h(U zJgA0?R$|HdEpsy>I;nhy$Vj>R84g3}5ItaqQsL9%Lm?a+d0oq4RV}Eyt8b+gyiU~^ zueRI(i@i=|x%}@UMh{L%48|HqU3UQx7h<=)Z6BD-!MH#C!gzstl=6)lz~D`(pMJDM zT9BVP)vIFq)wP-qghXHPxwDvXoCVTs_P5riO0myG#}maOt-xO2KsNM-+hsBDJZ>yp zuGjI>6sF6l$BW;HH(E@WWpDK{(Tmf4c~N7YvDf5*xV1R%wmnn18~x5yu{ZWDY7FQc z6R1jv{Z8}IK*_1&7t7hC?(BAH(6l3`@UIU(Krz6`o69bupGrUrEB@pSvQEJybe4SX zA$GL&L!ePwO~jLp!-o6k9uFF#^%GWaa);1jtq@Sw@YJr3Wp*$H?(P*$4mK0t$0 zxT~`9blqF$Vj3Q954}t$_FO8gABDK>Hj4WD5>63%@K|PaT-K@kT%n)XEq?nR%+-FV z?f|70SpFWHgqn>HS*F$teF+>Bc-)H}aKg1Ywr#>N{ffjf3!QiEbMr^>5Cl3VKHxu+ z5mgV1mA1lhW?B}F1d`!q#Ob1Vi5*$5o!}Ij9yIuu@e+FD-|a9kDTNWL7`@=1&Wj>z z`s5ECpIZ%%H^0BJry?%R+$b|Dd{J${D-g6EM<25v2i9Zr=(5-jXwa>pEQBXD>W$7) zqz+Nq`8`x%k(Bw+zf8cSe&lhSaQ(%2Adw*rmACIId879nrS<%J3}xL= zyB+OMuru9Fn+-khHd*pGcFETP*I1hLV;Bui?T_o6y!Uduw{7x*d0*XyIikOg`l-)- z`Q_*Wofl%O1enMG%A}jCR=8nP%p8Zp1#=)xYpoy%MINt#8O6HWAsAE2+*^xz#%W8e zkgBMLUadgTa`qj^jvV&NgnTI#l_J_P>kW9-wTticD}&MFogGi5-Cxx&U6k}$zn*G2eJsCE;q^4?FxH^3qH;h?IZhqdy&F^d5#*2x5`f2D8S~_pL=4Wn^efz zNXp>|zwUDXKFJnoYoS(3uC~W_0BsCG1bTCB_ElZIN5&~x7x%5|;IeBb0&_8q2q;Fg z!a{Be?Nv{|#G(=AUQ>alKcUBEV*%khr)94*olZC*UpS3)GU0ktZ=P0e&a1xPmDgM7 zs#{8Fw{ld^$CiFjS&D$8TTMQV_)Z68&!q4;&PIr?wU+yN9;Z`2Y+yB} zF^$vanqz1(OY-{I_jYjBdK74@m8j2X6`96K8OFYr9tH211X-f+8|L`OzM8Ia-T@Hf`?df(lkd03TLuxdr7@H%wm zpd&FI`>&%pZi@JlM*?;6EU8iK>)!;d4=Uc^n!9=#AEcsaN706{6eTdz)Fh8vPbHJ% zZzCHD%R4c!d-#h+)+754;9#B(^h@aSlq1A}PJp8R(Ofy&NrhtTi@oWsoAceS&8LQ< z1n@hL4x{h12`7AmJ~$n(P$%SiO5Zqyh8ZRFUg9yFq1m=bQ)4oyhfYlAtr!gLJZumY>*u4mC0%N^4YM!Z?h=Kfv-!c+QC zNxd9h6tG6^_~G&{$0?~y|qyJY`yOi+Ap^EGl6Y$_y{vn^(_Vx`KzsuheQ1&Y3G2q+v&_q zZbwsg;;Y1>^dw~ys%y&c1uA!fdt>Q@G|G)5;mG`AfaaMfXh?x{bJP5Gdxrn-Y%Oso zV1NQ;1eK2z+LO~SOQ#kE%JBTaRKP6ge5NMwER}zDs%`O?82lSWWT;c4n}b4J*GO8? zS#9Cd3afExe)FCvTI_>VC%W(;lH57xI7SV9w#f_w4^3n>Fp?WRFf0h&gQ*BPM*X=t zm%8cpN3RWK{yBl>e1(CaNT-z!x*f{74-P(NGs^lDxwYRipe|#mNX8`G73}b;?(Ef8 z^I{}^MmdC0J7bbdC$wJgU-EY`0v2TuD{%Rj0X-Gdlj$?E-#?0ZLKI`t?gCnT+`1Xb zbW9No=tNGggdLQ6PWX;Z1StsBu=_;rm7|A6=7zu|$)yr0^WnT?agx<@T z7C_T&b|%&lKU664G8>12sojY2K$?<#t`~8gWhO&nY`L>_sW(Y6K+9ykIpAo2zsn%T zRI)gUCK#>T8Q?e_4qATpc2YczmN9>0pwwaVcN&-dC{U3?XO+Oy;CfD|f(0s*j4vxA zw45&Z67;o7L$!0$bSBz{9n@VQWA{REEeQbx&?UoF!+uy0Z+vZc_%{|3gqMX1h|N9^ zd^ErjY(H^+BkCHLUh#9f4$FBCUo8|?mT=;3>OsM)5!MA5ll(2mBKx;_A@>$g(1P@h z)K5Mi!Sl^LMn(bt$BY1adL3x)SH0bYP;&>k$gRPY*-=s1^=)yWlO6o#jdF>15Z>=G z=#>d++O(NO8j;S_WRWJmsC+ADu5`-B_JD}k4*>{3x5aY}>Ur=Oy<_}B8r#9f1ty2- z!5jiBkzop}3*)^U5}~W2Fy%=J#Zx~{H{^bSLdAK=W)hbNrO{C8xQG}w>ajQ?En@-CpW;nkW8Jn!;8@fv9MU1@4N7J;B$}o&msPAqg2C!4Htx6zF zm6AXUPC81Or|BGP{iod_;)k~*hVBG0l(HCc=_BO2=4{E7oNCm}=VU zUDHyoKuZyjMHyIJ;N)6thKY>H`XKC2gbWwo0!x*5dJQ5TA%V$eLed(9U3MB)T@gS8 zW&cTcdmmYjUbnJH2Wfsl?OcU#JiIqz5VIa*0@KP_LRFPu#FWSZ@H8gEz=(p9?>Fi4 z$cCJvC|-gjA`Q%^Ac)vg9$F}h_J-|Xk=`))lJx%b$cj;!iFoS;i{qZ2NsN6Vi+J0} zqCsGb>v>Wyjb6%^o&ORfr!2scD&Ns2~jpT z%Nga8nj`;~bqR}isNBZOl4zI*<=3dM)Z!}i=UJ&Ph*<9jfDusI8bpRmva%TMP={Gr zvHSrdwcs#}6{5)-Hbf!k;TDNq@l5%So=fM1#g>otyt!dpS$`bdFlHY0aP0%34-+*~@ahrXXa?Xm^ z1xD1;wMjpB3SA3GV#rcf^ObV*Pd3NHXd0&33CDF^GpQgy-hyAZzQ21p9&)XuqiV-%d103K(r>qA zRl|eq<}zV*n=(y>*5iEJMA(39$q6N3?8}$#kW%!;cN~R(<`l&Q#4);*%nd3)ee*>s z&To}8nPiytm5&1BKBy_WHW`8DqSFX69-(fzUMMA z{!@>SAc1T}*Rk=u)3$$vZn!FuHkUo@hUHqbFiuOHsU@|VRAUV9UXQlLfK0S2Mzh(G zj{4(w&a$!3skQWb=|m<**7J3uZ?&8%zA9v+qgyFV?L${`(}Dyyhjyz&?bHxJU_sk) z2fMzB<~(5FV%bliec6zOD=CRkPa0VpD1pm>HI9kAKtj#*Bs4Jmk=cdBF?@$WiGUDu zxKsK!wujnOi-9PC0CEX(-|729p`I^&nDd03l*=>YQG`O4)W?yuYJpN zdX<^VM+u(SF2)aqQARsgEo2d6R8Y)MP1Vc)!<>Us@GS_|q%s{^D3pKB9|zL<$V0Wl(s+N7G#V^9 z@1!y%be+~MoqpWxhx&1lQBeK?2%ak3hIDQ=)A($=-6ZpSeHA(8tV{jtz@2qiEw-H*3@~K;By}1S|;`V9l{hxhsd- zHeR6cJvR48vs)6@QnamhN8}5({^E27`~fb~(|VJ`r?#Af1};CoaXn82Mu;{wUuVk6 zvHL8ssxIU zSnh`x9>T3|LaG?x;#l--;QF8ryASCU22SkM_6df!=?#T&lVL<0`6Br!VtBxyiY$w1 z;={Y#!wpp!ix?@+R1lCyfC@a$$;u>FvUh3xJg8RAbzHNG=|UUp!Bc6@20ADDwD;13 z;tiW*Tj>Fajp2ctY!5`w*IQQX8hvjeFTQ7{K5iR0v^!}n-!qytauhx+mI__j9Q+$g@DaWTOL3%$n$9TJBm=1Ne+iql>(aE*gq7M)b)q8RbU2@xK^FVI?!Q15 zDE17-rVWoYIsDZ7JK>$h)#ufV3c6K5^@+RAci!*j-=l-qD^-~7Rfg{}EajH!7~%AC zB_flts3o%sW{Be$!9w8rbC#2Sre&b1wl7EJ6_XBcW`k!&Gd_ozdZ3vnHi5kkQ=nai z)_I|3K$7yU<6BY2l3!ECK5rl?*sbk_DEdnW^Yyme*QcA=Kfc^*1`};uza)MaYCMoi zTMkQdYF55j92wD;1ygmYm3{iSU#7ZFOyc0PJMXlZlP2bO*k+>A9r^2v_x5}9_tE2b zn4cCFi--s2`^|<@AM;dGy2LJkK_C0UA2GhoR_t0tzxS%r_UIb%&cxStCe?Sy{(fDa zbux~b=Hz|=a~TgCKf7B0fAMMna`L=uaMc;I)5zClK*qO|O|D;b^1t(FT0+)`VYL#Q zy9W%*JwTLt!FG5l`a9P;OV3+y$#T~HaQN*IBTa(S%Z{tdeI7wr-(oz<+{IE;E-kMc zM9!};8R$kvWg4>Ed>iePMS@Jff#+CmzWfCdJx@Mzw15cH-0b_j_gS-Sq8ODIp?P!) zujz}%yU~!YNReNu4_zCg3U z^$*!MXh{U30~x+RC%GO+Tfw+lPZ4Y~=FWI?Rx*=FaJs98_~vZYepZ)E+uJAl)8#UGRHWD-z;OI^b`LX}EH3Z1kwS^IK z#p`&y-^t;E6bFP__X*M-@i8rlmJ8<-v6X8K#dQf8 z(c73TXXN5yOkV2*^8mR2f)FFOwy0jUw+xfQPNym!Dsq*XCyh28R)&l3Ek$Rm58oyB z#q8n~fD5@j+D@c<}z>45;5U+sr141_EvbEDwv=mG@|z$e($1FI7||?SnA~wd-mA5 zA%aZw+IfOkGGlV$lo8D^_G0_a37f{{+UA-*K#NH`Xj!r-S3H7LX%pIr1nqY{$!_t# zas}Q=9IMal3fsYQyp*Qm_bTC^E76bA7tO zhMEhIr}Oo$OabCpjR%W)_b=BOA0_{DS5p7EtA*5~tP_`=_(72tY1b=fwtRYxtT)G+@>q72su2l!U%YTtQAoxKdbG#2P8rCmG=Q6 zws)plU@w})zN7;@aph)P-Hc5uH&UcwXL)dmDXe+CB5HX8`GHv8{oavRI*I0el&6^t%sJVTy9lgW%lBk)dVT+*Hi94;|9+%uoLx zV{ZXe)%OLA0)mtXk`mILf*>6dBAwDDNOyNhH%fPRcZY-^-5}lF-Mn+T=Tzj8N+e)+3eFaf6A6l;WnK7D=CoKnm1*hP^PNOB^2X`; zEcVSA0dRNN*^}nm<#+rhZ=q#tM1kuNWA2ucqogyp zHyM2j?L6hz?&q3fw#V)yHB?{@?8j2vq^dT0hUeqeP(2^MaI*r(&`c*3ssfHa;8Ce$ zre@LPQg3X(8suAO_A;g2Agp|eJH224)$olvrk=>_8s)vDw8(<(piH=9?O-&OqVi`F z;pm9%ihwrU3A&7qfT9+YV^|ttYgTd{4#&&QS4hCQ6_@!KVPyd&6}!tc42+x7w@nW} zg+EH1=nJ_Q<8iMT@F6p4J~focP(Oj6O$P;w9`@%2^nKXgFqm;UDJz*TA0(JJ($k3< zyT}a!hfM75elBpiHHTt@Jp32-`%z$K){bq>Xb8)6UiR9#&~YFg-f6xJFOQ@a{>rzq zS@o+*;5$Ir_%;77r4b~+$52{ zyt}!eI;$8IjcL_S7TL1&GdS2DHy(jOSPrLYV2S5!AkpUZ{GHVsLnU;)I>LgY9oGPV z!bzna=)(;kVd_zm0sZC0ktc9WLQv!fY4(e)(Ow7Hqm?duc{Do}Ie9S!C#YFKJg;YIhbMo{uR2z{C38bm00HJ`_~8 zswK8N76UnyP%f+PL99N}gDU#haXggz8i)Jmfp&O z$mynt)!;NYEg3o5_^~|Wn+F7RUkGlE(y!rBKX+v%6i{Pc66399c3Cb~rb|*%P!jt` z??A+pVmI|-9sPaQ^$kbRGgOF5ZocmWH!QwOAE-jNLobo?_3G(xX*oKt$RYFulFAg(TMOV>t?!P3kIxbkd4!N&pA(qq z{MI$!lt^GsHTqmoYMjo^M-)22Lzd&*w8b7Y2}~9e;&j#qeC0;bl4S=nf5d!s07|uu*unI1J`d zPzh)?Av02L6oyTkxmkH@NbW4`5iB#q`7Qe^q6WHK17kd#2*2 z$tw|~O;o&vEZ*~Yi^%yy)=6Wxtk4{>jg#jGkSwqf6{I}Xtyww#Lu5K{c_^+s- zDP7GG*E?>1lpY}be6F8&IaL0E-45So5fm}CnDiC?^;9F~0bdI$+nZFj6akM0X9ZlFuJ$ud2H z@^;!}ZS;YOu^y}-yhy~)V*YyAl30KaPAXS0d<+w`onx#L5I?E@VST0;a8r}aW)f^i6k%^ zbPYa3Rs#`ufBLZdKLSsJ0O6paf2!90Ag(2rf@EX2lb4$KVLN7Y#P3cFW^KxG$P=`U zZ`CBhf2ySdVGDG&d;r@L9t?#)40QCQCST3q0zyw*qsp3X&)MhXR6I^(jzbV^m&P3= z{}uHmg7g$S3H?)1_Xo+vt%$ers)kNO1L;$(Bd5DThTrUNxei-FkZF}5hy8b0$|3}q zw%Br6_9?*L@mSGGgTwHm2b)wRBC_XRmXWe+!0Y8p5VTz!N0eY{0>Td21<=T<&+p(- zU&iJ8cegVMIvy|!uQg3;9l2iH%5p; zLBpXC@};V@wtn7QVSogFekB|-jB|u1^G;|E`%5KT6jR~ z+P;uei#wvd#GsbB(Jq6}4kn&hYb(Z1(-y0ol`bJUY z)97o!=vKJyAdm^4d4_eF8JQ>fHGb7|COVTs_Wpl){NYXQJp=^A!vlV8dc)tYrMpS6 zF6fG<{GTkOq?0^m$ z&hs?+p^@FLV)94B>b{lp1upNZoqkT^)c}0VLes@B3MzJ%ByrLDLPq(VAlzmtF|mxu zG3I(yJK^eLxuReZhS_fra2~+N;{;A^+9~;baCWT`K9TMCo%OWL{g0oLiI4(b5CMb6 zdIVccKbJ{T@?1NL(tZsI6-@?fU5a;G$6l<}+Z-tmZ`>0a8e&&dPHypR9iL=|86=SN z$cb7Dspr>9N{B=a{*e1Y#m?@Np02ajceXt-q~sxn0s#sBm=jv8PEpnMK@ojGM_H7D zyoX%f*%5QQcU#@qpy4^a^mjfA;J;n+U&%orN<@*Nsm^D11DlBK*o z;?dbfR*a(UMAF<_C3k4r0NDw}FZ8m&B|nmgQhX55;E$Rx1XRq9k`DRf%${n5DAflz zWU~P|mz4$)70BuJG-uB}_&2Xw6D*g?XeUh@7GDe2XJT>pyM4fXX21xv5+o!d3prn?6%#svkxk>eM@Qe3auhl~hp>zfe9veXO8&dBf(<3q+WmKF z*G$_94edu?9vtYmMBnCu%cgHS$x3ASEKZT-e6Zy8`7J_FG*P&Oa80=ZEA@xgVQ4}N_IS!)&z=|#r5g!Ayp5_h@2} zPo!fY2mT0RB@lxJ{UJqh*y)LALqjiO-@7Zr8`G!A$+K_-pp-%4>o0{1K7*(g}x%B2=1`I-8s+<9)E zt;!C5bA&RmSm~)_=FC3(2u$2)Ia#Lngx5nZ;14cysWM{lA0HNtY@l47FMsSSMZV|} zaK(`y10kmcgdF<=E%v`t@;wKTgAMo%f008k+&MZ+5@TDFjsSB!+;GNktIzskf&qBy zdX7`+<>O-j8pA(8Kq)>4T;NA+IiPs%Fv2t6gx_=3=3~L9(^vI64oPZJ?MnhkZ8$*L z{U?2;J|HDSnTGVZ0FQmR*A~Rn=vp)%|fv&U@GY_@VE5r2zu?MZQ#NIRYFgTBn5cJfdniW4z!+z zHv^+h9be~)%*S-be=kf5+uOBkxq@uhpsUw77}>!0FJLb0lUA@1@_>C6dvyR4=r1)g z7x=fkatDMEDF7kmE#?pSY=S52cYHa6iCLSQvAf8bTiB?m;^PIMv+NgKgK$_} zq)(t@{*4{?3ZN|Z8!j+64zYNa0H?tZrv&GU(k8tya>Xq){%Qin^K;YvMi^#Af7Jon z1NiSdP4)|R>*%j>pJ3zi1#lGhN0b)&@sHNXR#rcT;i^sOQKOm`_X0`wd=<9ty*+Qw zWI#@0?ryr1RhyiUQx_KraoAFkfe2^h)Jc!b+D1sr$i}I{>hrs+xnx>+Pcm-74q%jCI20a?Vl^SH`QcuhEse&4Z0jkm5(Nf{Gck0F zDTmi^&`czNyYh}BI;Cl$fcFiXLo9F?p>Tf!Yt<~JUlpwtP)-zw^FCKAvlirlkh;hhRizSLA9`#NGmj%wz<(@a{5F|7)#9lyUWnlOI8#39h+sJWk% z9R0E9;Ly-;%SdXCV~!$eq&DP|fsREYm@MAEUfwb({s(mmSq`b3l@)@JP*=}A;4(^g zS^g5*dC$4<9=yZR~&Np0;A%CmRrlQq|3jde4S z-eibeIlW4SwcQ(G@6yqR0HN^^6QnqGbIK$ifAK>l(9dQjO%mJI9IvkhjYMDsZh`qL zT99goh7l{TQD)Hz=&Kg+=~eAiMo`eQVbrKId+g;GjxgDSTtzswP~xpxOTfhlCHn{n z;~@`dc=N$B?Z@G9pn&85-B~pwx$+;J@{FjO;*gweML`^ayJ4~=9{RrGeNJI zk9UpW*_+1phUqmly`NSGA;7d6peJL@xT29jT6dn$qaBT1T*f?0Z&=GILqYlf9E{pC zs2#nIjmfjgu8JL_mW_67a4^ipwaU$98oRt%QbGcQD4$3B#X=#j{xC5WRRGkpXB7rf zXFAmZh$VD6of-**7Hg4g*MJUmcn2`qeB+H0CrC*+uzAu9A2Dwn>dqCF1M;zbrUmm? zMgX?fqqfkEvJTSMDl@uS;53-gd>Gmq)u*D}^-ZjmX@|{oI?F$utuS3HxSROeBCG&4 zd3Azicp5vn3N6KT#MX4NuWAF_r=rs6z`i%*?mGT&R#MG5odDjn8Bf5?M1MiF~B~%3;1%LGzE#Oxb9aWJSj&}=ygm9A)UqF zNqEvnveePi6Qf#fZ!blhfDW{V$17p1Y4``t66Utf3)`ql;c-`2qy=(8~x#xHECcd_&h8cE+&Xv2}H+FdJ{`vz&6UqX6^;61 z?BW6yg2$44Ki%BE8&~~Js5qIsUVmGn#`r>Gd-8$Al(oVbvmsk5fsZ9$Q7%Qj)*^tz z&P}zc#;#23-b9=66%1G>G69SfU6+ap{v`kxe7O-xuh@pKw)@)$3Tgo4%(=B?Ln-Q! z1Ow{GZT_;rM7Br;V|#Y%v(bEE9(82t#xUfO{-5I%O7dS82&6%3gS;0udhHymaokW? zi0^*?{+)0CDo7abrNepQQ4E|~i_4bF@x=ve`FDY{`o{4Hpq-+Dyk?D=DK!czzn`~0 zCZd)o_Wf@yql;zho+6iV1U1@PDs3#@uQ!2ko*~?Ql|Di>SwSrs=|VvU1#7n2+Qet* zu+XL9IdroWf>SnE#~7w8RYre;$>9eX#dLco_Lz59Wc0$6!s}f*znLKn(wbf^^!+|H zi15?J;Kk)I$z&sA9`AN@urLf*!U18S9Dtd|_@e>jqZgH`1GW3JGg-}vW-mWF(@zv* zB;ik~q90)Y{ZceAU{HJaG-}b-_Q!Ke`O;Inl1t%;(W!E!&GtD`bszpEgDG_)n}^^uwOE~lChQR55h>v? z0M{r(wCRBKCj_J`+9IA>Vvv}*PbVE_oitzT9}s$^rsNly`hRwklrI7eo-8a-T;CaI z_g_`552*54Z`=`bHv-MrvYnj%nCnh(?_vO#QyGeD_VuCUMPgra12<@Ea=5I<7CNnO zy=T@trRdSQ;;lBcbscd#d2!Vx6jycY1dZXV67LEs>bA>#T|Nhmf`X_8w$(0 z&XvQ(zZ3dwRIs@igGQmix)e)sJU?pu=I}7#l)oW#n>#3smS2Usk)V-5P03-V)Xhi6 ztmLTd&d<0?=c(VE>tyL~t7YY%H)-P$Q6A=B@ESo7!v01L)O`q-%l;_U{4UQa2 z`5F)uOeSV>Q&M)P8|YG7n9i2|2*hH@J|EX8rNG)il;bC6&%xR_mql=Plt{SGYINNl z7B*N97U?0WP{iLEf2l5iP(Tnvmns_d0@m|T4jssaWlE;QA_ybNowzN%M(K;LnYg0|YZuHtll`nJoLc1FL(vk7W)KS|a5a8<{$ zJ_w6J#!u3`S069E#VRjvePUEla2x9!Lyrp6yPMor~Y4LciWG*pDGY!9z%Dyo1rN1;!H_8T4` z&um>>`q?8716xd`S?%v)VK4#fXSK%H71+Sioui{#vmCVk5GN`nBsH}uaaroo(>p^K zi$+n8g!MMp=+O(!H;I|1xGB3f+g~W0#WNIZG)V4gI=1H)oBUxq&FoGaPyN8{#7CO2 z(Xk(gQPetq(SEVj&&tIAg6?dlLZ8=lYH*S2*Yc=&!bEQWG|x$S{M(chA7un8dEB6& zxrU3pZ?W%LCm338B{RAtBPA-1p+`gY_W-oAFy(?=ea}Krj3EA%3fN`ejD_%{u!>E` zM?~%4v79{Be+Nx}bJ6!Gd1rc)7n`SB70k{PFO0?xKip8Da7U`C{eicvwB>h(rZ*ND zj;bq1t*xCaX}J?25tfjyk8R>Pl@?EVik;)7_4TqnOK@V zC_nA?F6GEwfly@*d05rR`>LJmPORitbuGR3n5Y}$%g0U|lez9K^T!+wyo46IF?iRHJJDCb zHPwhpUpQGOm|c_OV|(gZPk5X6ZD3`CRD_S1xDqNI(bSjpKTuAPR$?%rb?WKgWPy`FCSX3yN~YAsRioCH}4c z?vh(}EP%3^DH;t~0x276q1JM83#zM%i6Z5Xz&WIHcc@{VzA2H)qnHH)z6a!7>zo%1 znI=ejSrG*S=tZ$a1?*+_-w2|I;;XQe)x|LTGmOUbbLT3d6k#o)mKHy_j_XI$E0kzR zCE_KEWr_Y`@8Gc8&rUAwrl2gJRI=+iZ?PX)Bx=`H#9VVzDSOM=p6g0zkwt$uKc{C3wL%5#iFV)kH8R4DYsZIw8p4892SI0&I$i2t(NN!i26&h^cuDVR1XSCh} zbUJKGdUv{%q+od=xm{IjRAM4AYJ;#W;MUQ_M@L7KTj|-RC$O6T-nhFyPiNIQNUa9E zgx&9Fy@NCXnsgX$nisf--^E`J4r&@Mg!14_YnpPHUSm~iXAx~R(rGKp%QM5kti`Z5 zj(zA5`kMKvm;rTyX03oBXSh8Cm#Rju1gQN99|(9WLI1fxA=?*eyVrQlPhoNU?4EOM zZ;v%f_{mr7{swICX(5&v!Tfv=Z^DKp>D<1*ZAAnSrq^^dY8XTqdO6QtW>_qW*bTuG zwQ>^ayT&6$98RX*3n(9y;6CKyc?=gk{4w3&I!ZA>=w=CAkT z=g_Nj$c$4*jgtd652WASAa~zfpKXt@R_MpWf4L23FSW>v6hZ5fE{N`rRK3c_qia2`Tw0HUQ`OZ0W+FKMuEE4GGXSRx>ub%z&<`>6KqBXa0to zJ=N$a7ti6Cm_?4cqXhlMl9q$xr zJ2#ulZboIrS_`5rQ+=HL*SNUCO->g%5jg|7uE4<(qsWS&rgA6Ox6-ZyI|+n8hWxy} zb8Y*y4#TAk2j}m~L%9d&eWioN3d=p4 z*cv;+0AdJX5@?pSD=n}ue-E*oLtE)tMzwYtUph^wU4L1UwPmNB=Q`hPKV9@X%RH>o z=`#ClviuRa)*>@2Xan1k-w=j=p8yN1OCoDy-0O@WJYYd8nM*>o+AQX*Ck(jFH@n`} zn5JfXCreCmvno`5+__oHc^giu`1a~#*z=j+nuY?=M-qde+UkbEscFuIrFVk1h!&eZ^B^n&cUGieK z>JU~YPg4B#5*|Jq;Bt6|RIMAN$}&G182W)07MBjC>FT`$+9Dm~+_DV60tyW3H622!Yne4Bfm~<%h|?Dv)JZ_RIa2PoRRQO%f4TJEi!GuO3C^{fW(YC7g`ZLL-e9~betdky*URZ6%SVzXgZAw?`?M3_psJRj z*8MPz%~JBxj9UgQN3Ee;85;|Yq9AN^n;2hCJt@jPfkGz?Ie|aF0onmI--pO}Vu(%MqxME{qbjQ4r z1aiDkCIs{TZ5MT6cLVXC>rvmYJG<&tfa_CHO>1R(=@@~M9X$%{vHO!1G3F&rlTAd- zZTCzto4Z4*peBJfx>+^j9U`M!7rfQ6A>;i1DhDGCxOmC9A&<+mcEZNwB5{gb}x@zpZ>tU;D~ z?k8{5n_YzR(!oAIla)grGFYb*5(1t_8!k9o(MkhnQg0Dqrx7%^rqb)Tnt^{NU~9-3 zZ08QhLwSwx^w-56IKT>}cOq`Y!^_gDSUR6?E)RXoI)rzMZbMP0vZAW4J!YY!OKLNp zkIW$}-;k4*M){ooTGa7)_4n8dInSM=u7vLMqa%2m+YXWCh?hZFG}OmBQA96aRo0M_ zQOHf5;f_>a);drtG`@~Pr{DpaPfV*`l6K=Rv2ICryrHJBG60U>{Y>9bR9N{aEIexa zJ*LQ`d*d@u%T08vj5Sq`gE$B>r>&y^SjVSteqDpr9;s(WO}as6-rKp6*T)tZ)F`pv z36*OQJ(tXY%%tLZjW>7Q`hYqpm>Jdfc}teeu#D|&D4rE-umfLxHd*Y%gl%2hw$Qg+u|2E$$~PYySOGV8zlk@S z7|V~($=I`Xt%x(s7UZ;hn1c3Yzu=3WJROhLA83=CUj>8d6_+WFi(fd`Qm>s|jAz}w zopuF~VztmDLn|jp->gZ@PuK)F(#I1?UG4C1gN=!ng(>@i7d3K!Oq#%P)74 zG`iO&&_NaGg`-H$OMr(~G9zIl&`xAgx0KyV3VspzZUA5`$HnG&@}%Qh6=4}<9Zb^A zVh;88%H=aYm74AOE$xF6(l>kXwBRT{$d63{pt*@lg9Y3DQ21LH`oweZx$!*&oEUmR z1_i1-)tfK1H$WVF&CMAq2n;9iy$i~Ixan>Fi!3+|wqtB=h!HU7eiAxyf{KirsR(*oMvN*F?Xd6U#IYK1l$9Jyah~|D_;+>>V)w7c8x3 z;I)dugAy#k?hMl6vVme7wyR&$fOM7f8UGu0(qG52z{8C;D`h56(*g++AUkFvQ1%o` zpMfjnc=OTE?Bkz_DGAjkjRM+nYMkBdiJ!C}`N)b%`j!OdKj8a+lLm)MP{L+H!##3e z>NN<0RB5e1iv=M9p8FIW=L5)SfdyKuE``<;9mU`~vNC%{(N{VPk`eu=tZIo7;J(HH znA!ay!22I&K>5xjyJyw^FcT;@xwTnj5Hql~`I~K+iy~1N(sLJ-Cs()H1ZOjWoXnym zAbNG9X04dukz!EUUb}@Uq|_~qu)pC}22wPxL#f0Vzi}5g(-@OuK=Mz98>0KS_QMbG z#nzT^gV(@$GbIWXI!T$tvIi)#oGfMYOfQNe{ves&p>&Q?bnwpfI!oX`5Ilt*)U!svm-Q5x zX&Pf7WltJMjTha$<+2Bn^v!-OIGqOqvoD)8JIreh!CV<-SbpHBebcp_*zU<7ae;Nus?akV`po)Z(F$huR>5I|hb zxY+hFDgfNWI1qKI@VUUX2>>e%!2?L*_(K^B4-PG;LAk3n3eA+vTkez6kC%db1*0Rp|H79L}R{b*$ywWat`O?)!bI*jTBuSjF`#Ra$^OltbSIw zbueB4rk@f7Xe$vr1P8WZs&IXrR&n$~oz5Lr1hg_98hIMiBop6+*usGIZj^Nb%Kiz` zVj$bqYg@>O243$=xLu?MG28*4omSZyahEhv5vN)kq8XfwC`AChYf&?yLQlzFk1mi- zv{Vg*0WV_J8z4@+_q!aTESlJjh0oV}VV~hP|2?me?{qK*`lvY3)*{mu= z-o2Tt6~Y4Pc25N$m+z2)Ip9c~8?m-tJ?>4aI`mbJSkjaQLV|GO2ys zE9Pa7z#KlM)Ya{s8aKI@*U+}o>$ka}B^^qsAE%S*Jb~RF zuzS7h01~u8bdvw-a*_d%C*O4igNegITza?t=6YqB?v1iZLS9wi^UiL ztFUW5%F2ZO}oYe=YoC%}&QASH>5g5`Wpw?kC|SNR#6X#DcReAQe>y zT1E`RN3hX6M1hLQST@}M-iu$3bE4a*$PmeoxcbiB1Lyym18{ZzcNG@Uo|*#-nd*}y zZx|z0Lm6`|b*UpMTIo!^WClQz=4ism^p7oe08MH2#<&mqk!GpZP#36jf^An~=uwgB zCs9i8TlnzZac-qCj*rT2@v4$RRW|zjGz#FY5s=mV2>emA$2I}hm*FH(oFzgdK={|1 z*_YFvp5RBA(-^X?KH8TAFOUSim45Nh@P*TWSPj8W94tYp`cR2MLDp7|MtO3y-W=n! zD|x-`_2R(tm>|EYf;AHGtq!PwtX@;EVK7hBi7a030shCalUe-YX&nKLYHV_zeB0KE z*0))J6f_qX5SU<9ZT%G_gNlghAKJ9PTpo=?6{k>0OsOY%o)~p+>+F-@dQx)@L?A9VRz*D z|Erj>Kmd42@@L?OC&BYo+v9l4(PZlhxIDHSWoA#19@2u8 zu`zGilRJxr>MtUhRR>flBzb?$8H`WAE2V-1x| zY~e$2?|a*8AKf5RVuqA-fbd^2NGagB&^rgDaX+zu!C!4_Y=q|?7mXric;qXG>w2Er#=-K-5aPFv;~sak4Zj&;-`GTEckZt@1JJjhCE-?mZBGqJY6MSs>2Zb>cpR6 z5r5pv&{zXy-Q_ISP(AX&F;}3UNuE}7e3u~Q_Q2NdzM zJN>I;!a$O^QjLxXcE7vn{#G(rGXw2d6UE8RIsC&)7_I`LPk7wivcs(Qng#EA(IqirsIKxT*X2cU-fk?IljCac^4%no$&)k zqW@QuB;2ORVqjf$gxQ-*HShgjGWq`VKCM|1tk`{j6(1Hzok4ZSK3NH8xYF8AVyqzb z>gdxkbSks&SuU!?lb9Q`Ru{)gf7(vPvrzZV$agFF_!yuR$Ko*1j~0-LZ4_zSVhAmi zr^Mu+oC*(CkbB$T5LN}YM{GV2Apbj^j!ZofisHmH?mgzb%5kOO1H>qWnX_hp1EN|0@xnyX!@8Wy6nz?Gkf04drNvW0&D3_n`qf5qHsl>|YBX%Mk|nShpR;ifpE739M`ZVdZ2<+EN13; z2ABzEllZ>!m%sSDs#rnH|4L3Lor;@feD_sKI3<8j?qNltf+6iOrpnyr;B#5yIhjRK zv49MJofE3-HYZd+(m=uEE&lmqHBXv~nt338DN{24EHkz}J(NVu4h9rq9Id9qePbAi zhX@tZ{#~07q|Oeh0WNGbYA90zD>p?{EoA!h)sbkMR~qfhm;sto5<%wogvb3W>`Sh@ zot^V)yW>8~&Cs(Fi-9e+;lxsXIo|$qsPQ$3YA-$3d91YLRS>};z<@3`M?IoQbg=iYUL%{$*>S*dSA`jh9f`9 z#>#S|T4D-fCpUa;L@S1)QCwe5XC^w*Yp57w=;C;m{NXl&_0{bJbSTB*<*rrGh^fv1 zP&O?-N`P|(@~=427Dv%rc%9+~{N}O&Me$C~RS?w?v*r_N)WzztU>$LX`|;I{<1v#h zaHRrD?GGLL(K)mQnbYwkY5{Zf+Vl*a+(}qsJek|1w?I}d%7=!lwo!Re6wO^KCoufT z!z0o4cQ}x~@+5|ImlU(HVP1PR-{?vFmAhb>a>fx~54hc7)w9oVsYUTeoF9^L_mjtUxee zSzau7xU8M#bVvZHFw_SY#0ZOU03+aic%}2?XL!Is0kKJROA1*8RbjJ_!=XFA(n9AG z%Yw%|FE6tf+A7U7KQ|copRQA5{g~V{J$wGlT5M6&pH19;urRZ>R6YM$1{c{8kBvEM zZRN5;mC@(T1m$-jl5jTmo?>NTHS`6eNbihy5CHXX5QO#cNz?7lH2cAs)o=tEz7%%=o*}SrkI;T zR;RKk8rmRaKUkc)XL90<&%yG6v?rhmzx3%RnE!B>nw@iobQ}oOC+AM@BL}eG(EW~F%IEJs#*>oG3Z`& zJM9}arDS9C*Vb9-z#`&_d~kbxGw=E!n}Q5WBe4~b9VSy#vk*??eSd#1tEAfUB_h_o zemYyn@0{6S(QmuS>S!iAsM9LU>OrXgVP`%LYUbXF@@Z2TS)%IaSg(Glui zLj%gcSk#{(s;0PbeexBd)=+7%JIET=A9?hZhzjssw(YHLq$auOtf)30>WPJnG|lOc1m_I-+9wT!+)GgFIad{j8d!J zem=szR25~hkUIQ34>1 zZ06630Z^tFGLbg>0x0TvG3N|a++@OjE>dBM6h7@rQ8m2G(HXxfX-@oz%xac7PlE;O z(Hb+|QtYIMwD|yOyMLO094p>QRPAG0uAs3u^!coC`S7=)9EFm&K?`vDe|t_pm7{N@ zb3x{R>X+`Efoj5orkiM|lBQVB1K4;@bI(HUFGlUx7$2?Ui@)qAG6bCX#zk{GpO5<8 z`R0z(xT{fiR32}0(}Q-qt)Q42dm!mAaERp42&$~?$VQm-^?M9NHWACCW#Si7)<5Ls zWfA&$oqULw`=vgg>iI*qsV)Ur2??QIL&;N04M-86=tZ9w&Yf~6IBIU$MIG^A)%fBF zFpQS{&?%8w-C9F;b@MVvJ#FIkYCMxfrng6_alopCn!Hp0eeB~Cy70b;(I^MY6X^A; zX>hAAmj$F9UB`QbFwuU~;MWEUN86PJUUu3}@V|~aSFO3Di}-osdUuUHbi>_16BZ0z z9HZ%!%!B{_ldGPS<@PD|_DGdqp&pUd=&#R_3@K*}&v>wTeD7x)C8{?p9bK{tmFnWN zB_3qw%RN}Ff03?z|3hQ#P$hs>?|2gJa=uayBcCS=QHk+fWFapjwD1I_b+Vf|m4f6%{g-v^`u zZGm+*v)=3!qg3xF-F=r`A^AO|vgPdl+;PVhIH2LL+K33)<)Z*kZb64MSvJ-QRdr3p zh+3Mn2@T~#!--|Xv!fBRHcrvR`q-p&48M<|m;TA_^g3#zN9*n_{>@i*&4q6Jf2x^{ zR^N`2f4oTCyc>PB@^x+}Ni*aA&Z%I~`3#>AsMRMusECijHMEXC3JC4*-1;FpTvv$!c1RrpZoEo;r`Bkx@RJNN{EcskIdCOX1bhj=r9{ z2FuDtrF9Am-HCR`d*SR*QFS&vf1fH1DtZ4-@Q)W z7U>9Dw5@T?$6zrUjalbf(CPMwe7iOq z3#iv68Yt<^vfGQ-t1A_s(QI-GnSeKEp~oAz?Chg5il`oJEL?9lTDTWtd5E2EUDdwW zcg-i9*zm$1s}j?%^07n8UXGdGy!UzkfoB89d2c*MJYf+ZwDGkP2l70juYd~p?)cV5 zm|m)7NmA~STF5GgwrkkfLgDhJ&dy%Nt*#U{(vC)GSQwe89*otL9*kbqQ+mdOwKx{E zY!{))_O`8%P=;Y037j~() zQ!i23$yGa4jP}Y`i|2`}B=Cx&#o(DBmCn0}cm-N(XJoamX zrW*|c<<32zj7j=ts@S-QEi$Tgyyih#JB^A{2v;_q+=}nLW8r5z-|wy(E=$ zE!@UHh)TO1IMC^V1`2u+tGz&iLh$@TLM~GYr|Gm@_G@gb3M*yWhK>B0^+D7H50oAyCh(Sr_`7p9ybnkH5`FQBeq_CfDOwJMa60$b7PM z#l*aHB0|#F?4x_6eSG={JtbVr@;*m}_rqSYd(ZN_QBh1UOnUVqg$u_Ay8O=>`A#Y0 zLO%{s;yJ8C(N}1z=;U)D&bF?iFUcp4SqEKkMk^osvl42|diUF(Ut}Nais2&JuFnd^ zUya*;v~_7u-!P}^c?&B;b@*T z_Y*DX)>p`Zui7xPa&%YMN8&g5JZZSqy_w6icg2=lpIaIk<|AhX)T18-IS1C#1Hq@n zI*mCT6-2AM={KEpzRMv{SS2^}O_bM`ozyB-PEA0ivbBu_R=_NcVsW?n*QFtzmq#nI zRYn*p^$y960|Us;9Yik+Ru6l2(a)u4s&zAVdtlR;UE8V$>7v)2@+D|+c+I@8yOUXf zlVN2`KwzUa0Aw3q(fdA!^znEHU3@Rlh0-u>zdsZj&vPBl6m^}CQ9I4^N6mXt*CC>m zVsPu-##SIoWNm3KvrX%b(ZX!)<@Jn@&Fw07{sW)s_Aqz*-CSI?c+yqTsXVaFd4A?} zA(4@%y|Qe0xk>edF$jZ!>xT3*D#d-N^pzi6OM}HQio!1<2dQckqp`_T-_EQho$Q{n zNd0r*S_$G8`zH+RqR349ni)p%~e@NrJ_vKUvyg@0I<2pj_EhY|z(I=1Uu!{$=htBv#GMvC?KV+-wUGZ#e{i@=r)z6yDdY5Fp zrm&hux4|-eY0D*A77&BPRai+RFOFE-(EQsA0Jz;IU1wA0)yJ+*S%>8o*szgXADY#Z zC4n31xDm3os$;JcyE0(g?Kfi2d;1CY<(mi%Zdy^RGT}w-;ebvGdRo2m+&ns!gHl$` z7V$8iS!vhXrBoR`BAeTxAFWx9Qhzc^KH3V5s0n>~!&t}=MXjtBdQ*VX``-UTGMUS> zdB{GZ7m69 zTIuCMv##VE+8-Z~_gpY5pa;@+>fUjWt+P2F4WzwjEVc!jy@9Xv7`ksTHuO*bzUqbD105593>h8Y4jT+uAMB_vlA#K!C~?{-M02(m4@nR+b*jKZho?(PQ-(| zf+<+!-t}_Y?)s$uKoc;3f4q5C?oMEDldhD~s9o&vt!LyBlffljmmm&>6g$G&i=%5{ zTF!9=sWdGfL+UOER=H8?k@DjN4Zgb;eG0bTF#3XgqPK{^VN@F1)!`#I+AeGef!O3_ z-zm`&bpeQ457P$!k+puQGZz`I`BRp#M!jl|VHUc>?b{L*u#mxP8rpICDEUGoc|0|` zr6M<4wG!t~?#>MUI-*k060}8Q2NR= z$~{_~)d~Dw?nV%BMcggcu9FU*SgDG)Jj@sv!+nca3I~7b9`!~Q-J*k%iueLy`G4K^ z);qjpwc6he9Y0AijkW7bF1!T>%b)*hHC#2>2aQ#Gmp&q?L`s<9Xf3s6Bb0yEwP}AG zixZWwNyc{3)Wd{iA)r!`OOISFgKzX+l|(u&Xc=5yIHuwqq*%X(963?QBbL1gM=y|) zn7OMqP3c$KpYvDQMLN=)h3la$w}M?~S&oyW0)ZT(oHOyVZ{msRCl{0i@*0v85M8%K za{snEIb$;7@Fg>x@;sT}E zsGBdRmS7fL+v)4mYAoJHDu)f6&7O2%uL2umndKx@iwN(jDqce)nPmi3lE*;_0zHs@j5cHvN^Zt!(tWW&v`3+_ferl)XP8g$J#x2gqPwFM3@}g zy*edwg9l+tu0PYbEvzM;DmQ9b2b-J{H^{eY*9knT9UY6>57C9OfxYPwoz(3!4;LO{ zb%|>U_+!3_j42C<0r?KjJ3Q#;dqlY{H#6*+f9h1H>y&|TYl0X8@zO8R7-9ItVDi1l z7;8O{Ll`xN3RC41L@<(kF=Ju1P*6Ad_RMP}YyEV6YN-z$L}&HBqM7#^((?!~mq=8! z^b&6g+CrtIy5enf0>p2-z;lICUzuK@8zq4{g~xJ`6(4YKpeRbJ8MxTx&$ziiUN=^_ ztv!p6;@!uz{RLQ)9*d!VKkH;=7KF7Qb}`h5dK}`O?M^7|l>_!VPu^_Z%sSi#62(-5 z18(aiAy^79I^wNHp}Hny`p*HxAqf2wWsyLWj9!3-kvfW6oiX)bd znyCZ0r2w8CXQ`>jbnwq9} z`gKdVD+uk>+pJqai#xkbrn;Z*er|6ci)vwTm#!m8es4hE_&YSS$xhy&44`=5Qv)3Z zi8U_Im|`hD0GklA{uf<|U-flbUvyy_N}!WT;@V1iEIBD(1048n2r$$+- zBTIIPXesv^xdhxRBBCpZFc#mF&@z_4t^DLTI~|YD1PbGo4I{N=A%C3T2PokFU)7(S z`nv-xHo+36wwk)!^0Q64%gF4Tlu-Vg_v3erO3*(yU)43`;d8&9p4}4 z07`Y5l9@txxJJgR`K-5zH<4cmdj=3ewPZjuYQOTyk1k_8Kx!HTm2NyFlt{5!JSB;3 zn>mU94M+NmW1kwaAJs=a>5XGL;nIK9oK7Co;@ZNg2%me_exU8W(vIvvA2b@C_FuU~ zj;D0opAofEZaL30vJjbxgWI5CLS^5&5EX~lR$fadoKSC0Q8y%Ic^cW&`Obpg15Icf zD>yv;I^Yy*7{NbejQ|BNn^+dl+Z}IKAbx8p*Iq=>3uw=Fon05Rz^KZEQSVppwHM}z zX_@Q990?Ot!qeT$ZAxu3^l}ko_v-e}emEpOU+0`rIMPR&9L*dptNJr5a)_T*D21YA z%H(EvnrkRtCIB*eAFVGw7`fe2RgcnpxL_LTK4%B2iF*Z>gZpMLzPDAFKQwsjsE6@#)i4Y=0Jf;T`Kq8RqQ^hg3IoK3sD%w2%b?H6hSINW#hR`)z5eA;iEk&WTD%_F=dK-x{OkCN$)jV#@;{XJ;PZI zM}3i;Pg7FcKh{*LcUWOu>LaDrO{4S5^BcJDg(xt? zy6zSLZqNJlMXbA}>}q;6!VcQOQM31UU;Iono;4b#UT#A$2U!EvX!AcpE3Wd#ly~^= z6yZVBLz5UK)8#u*F(tYTTm4(cq2P>Zz|gv?$qmPW1sZ{fcGvu z%quXP)abobZ-!a|~Y%QlpAIvj094FvUPNAQ0a5^XAyXEvykVApCyyRibX9Io=DxlC#q z>1MMTTR3Hkgrd}uL=(@teYhn-#Z6ju>4+>`vt2{;!LdPAao9Fvz=tQawAM=THdX8P zy&_DJl4N=sCDN?FYJzy`tX`HT=K@Ks#O{O4U}RP8d(DF_W`QGa=0%Y=U(bh>M;FFo z9CnBi!JS9QQZCU4K*(@e<51Q(x;uv0y2P}08QWf+5h00RTO$C&ApcE6Y5v|A)lDGK z`!JfL08y+28Bnzo70>jY*&M{k7$cM|^J!VL(+_9((2@kR3_VsC$H035-%NKNZRTXOp-p>hamtxqYXk zh;0>s%Y1zHM;3HPD)bhP4)G5r2S?oH48v7ZC5qP<{NORbv?E6!mS9pAmVJjC^$VFI zC)@K>$!%>K?+Vp`P^~SCNe`ae6?gD&HmKwsBNnsk4!D~x>b^fZ++r8`b*|2?ya)1# zhNd&V+=SU7EbY0P*Z7Yn8e|Xa-SXC$g{;u-RfkVLkO#0a$21PYg;gU^M4V>Ac%ZMD z)-v*t5S6C7vHq=1n(=;8X(>G|1q|VD$zlCt!_c&_6%m@<==7K~sN#6#es&PibM(i; z%8Jt~^u}K0{-*d^cBy%2#W+*9D^S)KR^efd-aJn)l+%{S8GLysvVUeC~uDmgShYF#7l7rYUq;I+HC)338P_mIEqqC z1xt>-{gOh8&EcxBotr%Mjd1t3P){N^yS71B8-)4O6BZ}GGR@gF+p27(C{9xYuKHas zOt~TYGtnU@Hjcl)TdsWTc$dr{#}LPW{L2sMu)PhT0A+(9HOT_Te)$T?nx{W^XuDcy z?-^?Utpxbq+T)tinI_h1!+wnzt3PY`HEPQFXWF2d-n6gTdHcz5g3pM>Y=T& zCtSDCX`(tGQX}a2#Vlk)0p#mvF-#2<-E-3kGARQr0{_24w)WExGRvcBCEc0kfPsC{ z@x@u+pCmOB0o3od$x~K$24+G|`wt)!G?0|%DP%#;Iu$EISI+(7$FoVcUy-*d@WD`d zC6YB7J+3b)WDMac@UJJr2^3?UyTBPA{5vPKLqgKxl9$(Dsv~S$?Zt|Yv670Dc*O{ zyoC_7$WNeH$)ygGZ1BnS3i z4F&&uNnT};?fB@I;ED5}VNYC6CT+I@y7Jj%K@q9~DnsrSM&u`jnLW-@nJC{)=B9147#D9HNGe2N8qPHO* ziX-z2*+kmgUcUa6eUnOBCpOgE$X#WviC|&088Pr5KC%pf3SR>VPYCQTw=evMcK792 z8azip>_i=3HEQSN6&EiDqxq8lLZ0+lAJkU;6u>Vm)mA*;-8E1R{b=gsEDHW=hObn@ zI-cLwSa3?Ygcr?2tq9+;`G?m(N9iSH!wHENUJ_imP`nYY;kdX zrb_d*Bh?5A5fBeh|MZY!JGQt_= z$a}1cguEs^s(%`lq?j!74m=#*$}Ad8zsu};HGkLh7}*RbDrD@B1||17$RYI1O7Y`M zvc%AYG7MII7ZH5cvJZ&t#`D^4k2hK057`s3pZLC2vCc=B&ZU!;pwghuAphgt6H0Jw zl#+K5NHNs=&6jr~pa#?zvKR5Cz5GSv`hGie2XS8E6A)dkP_(P7aAfTfOIzfE@t9)dZ8s9I7})y#AYO#SoUkNgjVv2uYw?TipQ& z_e&q29^>`!l!$PN>f!Pm-HfWOaT+{X$YsIrk{(}x+X?28aga0gR%brMiP=_Qv*Tl8 zmwaD8Bb-&1=_B0_>>ylbkx%fTl7YUmaN8xrY7^VL_y$}bGl6^aKOf=vk06}*hzru> zmL7`qo;6Ao7+DdZr0P^~H6#6E(CH_>38~Ff}bCjm^>GF#^ z-1^NN(6NsE4{gL$yt#S_f)Nz3)*q|{@i8&v+d?LxjdZ*jxg+cW<-8&EK(e8j27YJo zz@CLW`ll~b)2Eo1s9%O7{gaK7oSGQs#UzB$jBKenZF$D)k4kY4@zsaDT~nxA|7R!qG9{2t+pOa7-F498xZYrc)m6wF50u-N;2caOVB zVVBdSgYE;p%uFuhZiT42l#3;p9O7T8Q5;?7e**89>>C!^|t2!kfs|=&x^mlQO{kbG7W8YLk1l z(PoT=FkVf&U~H&(?PVb_OvCfQjC;)zz4Fo-=Y( zZlyGhu16?tqoZB}vY$PC#>;YUcXOxU7RYrxa0;~O=qsF09 zO>G#jybfmk(hlr-6JfXSOXa{EY~2~XZUt7T0LmV7@61QZwx2TPF}(Giu_^85JL?6c zWA^;i9q3y&lZS`H~9%RzT6=gM{iP$5)7wbYiY=$U*(y3HabTtgA zdMq5iP@5oQsi0PpX-(5;7`Vf&_#13;VZKf5ZDcsZOGU@XMd*9p5wYz&hL5`U-zNDLmVz#+Y3`ZTS}2UBpL534sG&nu45JfJMH1^ygBTmf_O;ttnYk6$C*Ct zQe=zPIR7NB#f>ywHxJjy-px0W&ZjohCJC4qDnWBg?@g#dl@+sBqs+4j$a_&Dd|pl| zHl$)?D^vuepj!=+H9v z#n9^2QRjfIj^2_{_2p^Kw){_ABY2plPM{{{-UOGEf1W+l|OS-sJMo+<@%&9jJ#ueH>w&fqwHdC!5?m!!MBj`#b+WfHF-wokD z?~iJT{%pn1zbIAf+7jpQ_O&qw3Jydn_{p6rk=-OY98|g()V!1$(X_JopABc(8>bo{ z8hG2m+sC_W6F(*E_jPI;0T9aE0J%zs5aW_XzIKJ8kO;+{dfO{vx2RJ z;c$3D^mMKZQj$0jVon8Iw@0>lN??Jbs$A(A=HtH!k<#Eq4~HY? z7vvFu2GQ_Ojq;z52_SmZGIKcu;L89zz=6#O3Qg$|(s<3XcOEPy>KLhe0J3IPf9dE| zN`ED9!etA<1?;*^*ZNPq*a+_sGrp<`d_csF_@0|P8ZZHhh3GZw{>tXndAC6aogdNn z3z@@Dm5V!dNk=d0-!lY6>3;aW|3(AQV+0IpT9cu_{xvNS;?VG-H>=@nN+0Nu9gmcu zO3V624=@~WON?u>^~CFfhP4HSd75rM+;xr3mr-%C>^RwOqT>M=t&US4`2PJmA3w4K z2VKrvhks0Of8o$ce3*;Ho%PX$tWw?Zy|wg|?T4 z=yeP@J0QLucJb3AJ1A6DeezyM>p00_*!jiwscru876Ov}=YQPuF}VBx`bJtiaOX*o6r1ZW**m#oQb;_? zWM!!^HFfYWZqO+y5<64N(2cfBi?o^v6dP^H&h3(=?+j3a?QE zz(j*+z7sm2mtBHiwkQHC2=D>q8_LlZ`cUe9Ud^-$rW2a4c~m!8_F!p-;J_y&CBG%} zaa9KXis1ZL9DC@56WprtoGIZNAbhuqe%*cO|#EytkH90&PG1NHJ|ZU65J_D})OS!6Y6@!xGfLlj47m9&dJq~^E0NzuN| zu@&f|gm^6qlw*7N|P*aURCFQGHC->;*fAc+oH%R#NUm;LHM(z0X z7oCXNHwRaG)O!tA+bv6W7efWkGyPJ^ItGUqoFb(cG3=7mwiLD6_l$YC0jsf3OWS{D zGY5)Wb9YKy7`%?|6P*!A9m^m~`{aXHZbxM%i5DIE=;|g3SBr!JX%6`HRDPUeWwng^ zf5QiWPD4Vg&PrDmV9l&|;2G-T+p(`7ZS%}O|NKb3Lyhd&*68rwIIKzkF}P*MSS&CtL9(+avop1jYU%J*P_yBrOAw&waZ_n+3z;!Q)A@^tF)gu4zL2KgZ`f)z} zWv~I%(IG$Spn#d=4CD7VxB@_&;`ssm*MMJ--jwy`>z5m$<8`v%KX1}$D4Kn7w5U^$ zGI#&;BkXfJ;NdCY>W+f*Els%{9KRSHKI>^iOr10QYpDGr`uHKYOlnYn$)*oI1n>o3 z|HBuYGZK@eGd0x_`Y$>2bj)`q{Y2o8glNbXOm^zu1hu>SWG(KTG3EjREZV^nB3AL; zKAt2zv>-IDe82fVrKlO+L%CobDv?@%*zutmtp$T6Yl}0-T!RT60dw3UcEf2n4;4oQAHa_jtWjVOSNe}MGN|tc zfR#LD1vA&alh;$yKHK!oP;~X=je04<{YMJ^_XoSQ=qatE3iSl{RUQPQ!hgEoUI=4) z^^74T@|^@}lr-TtGyZI8E}) zbV-4M)xQ>#d0{ssREd!X>##HZrfpwSU%WHkuZhQRm}|$FHjAZ0mP&u043ko!TrrqwyFuxD96v86W}6Be>9Dbx|NaiK(29 zpA39bJyGvvKH#343X4v5-DqffEcje_`ECj3KG94)RMKwn(!4>ZB6#b&p}IFfrYHXR z*PW-&b?|6JoW{k_^DL0&57VF|xGtcR*x);iZ9?$CqJ9*C#9S|KOjbd`(Pwj?P5>(0 zpG8+nFDEVp&3A~R0Nbx)xjiLU!Ya7TSHm}{8wFmionr4n*H12Fu#maXVi@A6)M z=%B;XL(i{@5>+mXz0fPs1}`P61@-_P+Bgy3kqhjc}Pe&JN1pS_MQ?!eRg;F%x7C|)^M(p-b1}! z5#aItS*J7$aYfBq9c+oj9jnt1O*gew*h$~WeTF)p(}m8|L%^Q>X?#p>o|*kdJt`i> z%fa*7v|XKg)+0EpQKCq;S;^EP|63JVH_7D6wxjcK&iCrlFi|4M&iU3Ctl3MKR*~38hs-Ax#Hh22)*S;iIVv}yLr0N)mz?VKj`E> zQ$BVw=6ShtvrlMuW$62g>Vb;3)gH7DC*J763`eCht5ag&`rWclzSBeyZ@R!!$kOT9 zd#77yItL;+Wz$7!@r~3#jpRV)Emy@;BH-r9L{8=r+K|6X|?9U@|79)gG4<|hO&X1 z+*8m=2r|wRs#$Frd|Pt=qHJ~F|Epd%C`3+T3PoF5+k|F0sGRBfCieG#e*K|hpEmMYhJmTeS$iSQICMMR7q`%`q$W?0g<1ZtQ3J3s{=`qGgs zb@ygeGrrBVN{T+9CWmoI8wetionjU{J$s^zF=s$7!hCpR9n zZ(B9Bd7|-goPxbN)S{(_V5}?5$LgYt26OBj^0{~D#jb>H=u!2nj5Y0-Y?tv?IU8-a ziNug}FeH`G7#8W<|4#fDsece1wh7<yDj@Ip|E^e7O+&g6IYnv0nrCm>*2$oAX(d zJU9az-4NZJ4mW!brbG89OPeyd-BwR{>Kov`Ej2g28u9g7r7d|wxs!(jftw4%2R^@& zOJOHF^MKhqwc&a-zGda!Zt~H?(uTg`ro-#`l6HI^J2&yVO?`XVQkeaT{VfGr!nwIO zEmvXiqa5p{)0Z_@jaduhJRl+J{;3v>nEP@ogZozDR2?S|T!9+d|HQzfcL8I6etB%* zef-SzOe3&I+m*iVQd-D(Ba}nveDGj?oseE+TaycdwDUGUvj6Qvbp2E8==5HV#|X|j z_PkLng4VKVL}ls(-{30n>q5tVlvc58OU(hEsrB_tF+FOA+Onx+m7X46piVzmcheTM zu&M;M9!vIG0MR$hC^-X4z+8Fpqsa3*9X|7oiS5-8gUg(jpIXo>j&!kl!&Q8{l}}>} zgF;Pw=TGu81pJ#}n-L4mx9`uVh*ZpXgI&hnGc;qDGbQ&?_P)dMOO74M^NEF;nm@%X zQw{_cXNO)H2f!LGIkFKW)v#gx^PP9t<-(=wtHOnWwG?CdM(mip{KXn8`0-#Yn*RF2 z+zya<*)2ATpqh@;WYg0z$Xhjrt2u$vTNY2(imh z*mB!D*`?%&>wT5;o&)+5ar>*f!UgPB;S$OktXF&W>O4mXss|Bck4W|@U1PPW*{pqp z{aTiHicsd;)t{~IrsvV)A69yzUNl_GYu!^>&K?l;;}m0MfK~W1WW%B@Q&FyD5Z5|k zF5Y1cpkI-33UZZB2Bj1UT9SZaoL+0`9rVLuO+SQO3=aNpXSaxMy#*n-?$x`$K-NH5 zyJ=&1b<_+>1~mJFrkiUWG_UICY_EK+TU^%OkbTbxYM!h)l#3)fB8oqYyh4;#ZvDs| z9t7{$`f?zPm`m}DqQqRR9%R{%7#XDiprF2us0f1N@$t9f8Y-G(we7mlZiVIYtzeWK z^4nLu+n=ii<0mdrT#Af37L1{C>CK8n17#_@e8%-B>&tr~C>4tCcA3ulE1y?2S4sJ{ zbxXc=-sAp3i7essW=ILnITo@&--|H=k13&9o~0dbsNMrnhr@5^E1`qa_Mo?!J4;3q zR@FW`4dM=fZ_<%3N5NgF<$xB2e?G5mN(FznP*aTkh9@_x4?8p67oaRXGsUzwjQC#a zTUs|kPi8qALB79defR0@&x0&O3DSk$DB$dx#zS{Y3P|FZQhvvK*^(-53~=X2_M;la zUv1EN34bA&YFekR*=Te&LA7|-h{nx@bz^VeUob7zIVh<|k}fG;l^q38I+yM7!BJ(E z1%{XX2Iz26n}Ilx-Y(NGfmvVM%|nPNrEN{p7ZGbs;xGG6H&gpZxoNI)fSma?3H#eRgL>NY`S zCOPQN?nQg?zAmMD?8N2N!O~u}9ek#H{_4dOc-XY_QmOB%)NCC~j%-ZKGU}&wiPH|Z zuG;pytPy*<%WT+XZ0df_lcoI)9h6MH*hTVE-O|kw9#1=_D;J!kDFEs|C<~d=Th_ms z<=pX37dkrbKEEEFb1hy(mpr-VxpWQx`ev-D6_3=dXI~j;*%6hXl8u$Jy4bS`C=e7>X2UvCASBVc$XzeG-@W%1%tTZqt zZm-?XC&x%}X&@l3_)HMSnMDyUUh|WcthVSDee}b(4Zoy`BR{=7g|*Y7<@jdw;+r~ z4A1A9tiQgqkDln*AL&jzZb|Sy^f|D?l~PlzoD3G!JGZ~-CtBEFfZ5i|MBJEO%sUS` z@#QEvCo2rp9{2^>k|1w4?@J!Q<4wl~hUa2ynIo;I%Ws`&VO=TpmN({}2*oa(UXUrF zUFWk-cCej*(!Ka3NW2*xuQ;POTOw4p1w{vF<5M3jRt&!l5npqqzZpxG&6=TILPx^; zr;2p=<{OqAQquqvcRXNZ?*+tQ6Wxe912UG) zi`9`(sl*TWZ45X1xq(-$`FON(LEB?!Xphw`d=|SsMjx>eh^FN^;D3XB*Ng?(dlfhQ z{^aBafc=+Bx~7^PbA{MB_f^SeDlx~+LEanV$S!=S*WNqoLZTsXny*_nIuTFZF?zYq z*Oq~colg$axu@Izqv3}%)Du-lIlmx|KVwbG#!SA2-ut!Ev5z$nL#FW=^4Zn+AU9t6 z$t|fZT@RgShb-O9*wUlyT@=FDgAj5Qi5bUU?z5IB*XQ#gETao2A!wg_+n%VVv+A9t zgg`;i5^&x&m@9Cl@&SOO^=Io`J;ifwwW0@C`4RD7uJ_%cJHy2VZ}8lYzs|K_m+jD= zv-?C-#d@~$L+9;)OG0#h_yG2c_T^*$W%uSikp5cK>I(?jkz5UYF1gV<%kPx*%}~LphmNZeJzipF?n%;nXmQ6Nz|nOyQaOQ}dC7&< z@}YhE)opP;KLsn}(K(<7@4->2+)MVra!zQCdU4#k5N)zDqD8~f7R2*O$0Z$4Yq9HX zi5`s5tIT@uuKC4I-rWu6kNILe7F&L=O-~*gLi z723iPJBflklp*b777ki1ecuj=^4u~uK0W>}55km_y?md`&H0lNrt4Iq`kl44tRCA(_RyH2fcTX|gU5k)}B&1LamWhCD>#L%$yn_R^_v`i*?Q zkn2ZYW-EZKP0`82^GOY~Vr~QGmbB$(lhn3C3m2L-eY{>)LYQ`%uEg1TIr+Z;!v8}s z-+I!No}t>+r^ng5$))fenEvCC7rLubOK?YsEly01FJdk`LVV9RQo$e;6_JQr{lV8m zbSKpv)7ey6*YjL5i7N0O5-9}Uf8W$#*EuDH_pqzPO{a!hb_j>v z_Rj4Cp9V<1i6ehlZG1xEku`b^L|-o7s^d98*>VLU%hK&nh&yDz#b%d;y`UwFV#W&2 z#^}@v_GZYpL@;?~}eFht-CXa~-$*CLqp5`;cn)rrQHf7T$p` z(&XoH#VokeZ$`z@>Be7S^>jzxH{;#{K7tF#7Oi^4J{JNBne7)xgtQ@TVeG=s%LZmUKU-xE zai~+kGvd^7z?kT>$NuR41 zZn;@q1%+KN!BJ|=;tF->t>JwT-dm>xYqgd|qp^(9svoj`ZW+5Nl!CTp2HpmhuF~#+`wJnIA3+^K9(Z$Wb%LCTDzgt zr^YprR-V9g2N;{Q8zw*xKd=(A&8XNml&2~h6w&RF$HJXcDf1#4!SJ-SZk_oqa*;FYeIk|71 z!;Plg%=2Y8bI%&~uYG$yT@9qe2PQ)}%Tux{$}jjAH0Kl!d<#W4cQwiiDyN1~p9Pus zBbUUJ;NowC9`(mx?a=T&%5I9q=!rLWml`0p{B;eu?T+SG9V?o07WETNgnG4bzD=6J z49CoP?)0&geW)wWb=$J$9;$d?I>iDnmdO#A;-}T5a^1?QS&*ffh*8FrNhHrgs+;TbV$2pzm5(3IMJXe8 zwlQ2E(41)RxT%*A6EGK(xXqa%sD$pWH32Gpc;i73?+d9B?H~VD@EoG>Y(!nSC>yFF zbx-DCT0HJrTtqq)+c&XG*Fx^gUFj~yY^+U6=+wf&L4TT%-|0=$okfKUDW-A7rUp$I zsg2jg@3U7w;2TB0BoO4BHuwPW?`J+#hG1vAxwysVrAG>4x|rc)b&YwlV z0vp{$_jTdBuz|j=Z=VbV@6o4R=F|KnEBZR~L|v<3cwToVw%(fguXNH|3TM&p5tc#D zw$!VZz4f}x-4ui_4{xS!E*sCicU?IGL({2l_*gi{RX zt?Ua^9`$Xs+vd>1ex5?^XiOhJe!dEg8Er_!-+`&aEI z&1_T4SD5Z_>+*~De#$?4aHA;un>0i^*>@;r1YrX)m2q|254*CM;%>XHH9Y}U@900D)wr)Oln zM!?}`2<-*Qn!S1Z?xA8mW1#G(J{|GtU<}>ghK`>*TQPCC-08UgU!5oSOY6P<4X>kC zk{Zh!lJoZFA0H3$e_xU9Xx8CVQ0Tl*K4_kxT{^!8{uXndY2Kn)gB9s-N?5O`lAqt+ zO4lzuyU4NXqNBYJIXb0@XgX!8xb#oG7h|ezYJ8FvcT>fOtMS5EZZ@_;eAucWVMua} zd?J`4``ljTbTF_v7DP5Tj1FHd57stk@Ku93;$z*Ia)UvorFn${kD4D+_v0i@O;-0g za^8v2IlkSmUO(+$Sm2tSwsabWo}@JtLkwSEc8iks>rxSc$T*t`bM(k5m{ z?Q<_qdzfjdLHbU+vlaz1Zup+sW@hT_*4O4ocS;0Ho|pXZ62$J;AsD7&G!??)Cf0KB zW6pc|cS3c#AZkW#*s*_;TumjdWfjDdLB6y1y*WBFC0L|tlh1Zvmd9!km8i>Nbr#q% z0Lx^7VT*kTxZkE^RecjdthPfi(tiDr>}3=E<{=`kFM46+wc`>V4OvDp#gBL^PD65k zuA~=N_&kn3`)<7C_A+gprJ?%yk^mvX~yHet5JT0d796n*x|2dzS{}Bd014bopr9Ickbg`O_xe7-b=6>$^G8k z^plpDo3mW|vUmb=_+ydS_c3}1uJ4I)DjrurUAV7=)yF{heBarib|HPU1-+vbHz|^w z$72a{To55a@gYZ@@(rzGMV%i zfKSuQD^7zrw1C&|NRP1H+n~o}(9A@EkD{OgHDSbA=6v(6&Red*NiM$ya`st~6{-H{#)s8hCYb z*)ooh5B6?#$>h3SwW-xiv?1@Q#A%tid<&wAHzpuu`5EK~<>L0#oOD7?9)+w9R42vA zhaz6=^r{F1`7W0TiK^l^1)=iquV4J&${fJgy7U}SwvkGZ{Ky;l)sw{ z)1XK~Px7Z!Dccs?(5>R$A*2T*D|3dyuN}#l0=__KiBXLA6V}!Rnf#rn6pw zH8q~5K-;BZDtxr4G(<=z<9Wc zUh+?mY1`*z)~kz>``=8x!^|KrVfE;_{-Ht1`w@GN$@>NRDZ;?h3$Q#Hav4(+dSl%d zU>EpRmyfcg6T#lNh0+?}x;G`}>zZn#O<6o2)b)kZUA{zX=YWg7eOT zxmAlg5@kOTGDL953ZR!GH4+4gMs4byDy2VO^!L8Ee>F zem69g^jE!xF5gz-!{LU7YB!a6vuWf?;gI&eop-luTmYX?(u`zAcwh04h=1XnL5S#FMG5JhMT@TcR#p{t44&C;4yUi$HPm|GPaa{OENrAN3aU=~ z=M7g>P(V#|ba&t(nS0dLYE zfm<>vc|ZFzYI3dED1EYx~rU;iWN=VdT#Zw8*0p>=Qcq#V$0Ryhv~=_|5+vRJsY6~-g2{~1c43| z-$tpWFxILK(I@uhc^zDM;BMCA$fk+0-jk09ljeW_!tB^88jHHr13XNqj)?o;Z>=Q)|W6!=T5sJLu-&Yys z{rSGXf5G?T2agx`wcLB|InT4)d(Lev6Mg@~vENj}-}#9C)7^YLJ<~F(qO^oPl+|a^ z>c(qkEA)x(gzW&aVfGDfs$YH+P*jK;nxLRm9_{6vaMbeq2o;5+i z5(@@VtSH55`ES{anmpC{*CNY0ZY2!YIo9-@c!@1aYI2T9?Spzjq{>%%SlQrNN4WMi ztByEGP4IXvf=_V-KauIZIMlFw3hR5o++wxAfLnk;ZVY){Xswpn}oL*kY zu(`G2;yk>S-r&;)B6+Bq{N2Uv6s#i3RI1b9UQ}xO)QZK#9n7V4$23sC&t^jwru2=O zH$@oM*g$VfWf<~2se8CDJFK->oU7F3R@kah0}B>1Z}mjU%4tl@PqYmp=3aMuxq>p( zhDB%W)1@D_$Y%RbMnpsMva60O$iQw*aN=``Tz>9wiB};WBG#I}I4ywC9!5LUKDAk$ zU`egnK_{5N{(73LSesH8XjBtoqJi)j@EVjryr~Uhd1|j=+qHedtCO+qRExwVb&tEp zFnFZizBq9AJPdCsZJOHAS*?)cIc>f%Y$jm--I3Zd?V)o5oNjnQ1Gbc-!+PV>vrLVZ z!Rd|8&JO0~s2iX1@7X9xTAAo=j&uA_J0c}9@PiNCu-Th+EeSib3-xK#Ear902(I^e ztI+wwpUdY2mtP>Nacx`w_QXZbKUng8MjDQgXC0cYB(@*k1>JLiA;5 z1|B=ASZrA>siSw_NB`@)Lp-KAX0BRWqp9)GJON8W^~o|6_1Vt@bFJmrIn1hx4R>NV z)VnWDoGl|ut_z8u0rFnRj1I{B8AN|n>gseV@HA~ zWBk0N5|yV`?~N%}Gg-8`G_N~Q!DwYWHdoZ2`N|NQb_dcN$l+x{D{XE>1?Ob>&AQ5V zYmBbefxXRnN_-kK!W{hzios!Y72N*LDi)br*rV^tw&Lej3Nr?hH_NS}G#-f#@Eba> z^lyKknr0XtnKbYmu1PuT9o=JjR^q&|cax}B`%7oF!eegD<|OZv<+xwFMDRp@dWyUU z)Ga4n`t^IgufnXuu0PYIq^FQbdke=L!*J$P%uMZ?UZ=Lc82N@!C*Cf9dhvF_MvW6k zRcZHd6(EG-(xq~MSt;V3BvTumi*p9@atvJd6&0{roT|K}sulk{k^20ggdnk?q0Iu$ zoE{5j#Jo>x)ACV~tua2m&YLp0*1#DpN23I0QB*wEJ|^_?FVT!!CY`0TBU(Y_*|%&3 zdWbd4={3rS_pG)aCGy!ZLj=R2Td=A`AHMXtFPia=9OMt*Ve+Oj}`8` z*7*DK#vfro8HH%Lqw+>iD4z)MfQUhr6&G>;2gv^LLZGr0$8dO}{p%cK|j*ndmA z@Q{gj-RtvySEk&ROj7#W%OqjFU<}F+=>Vz9d9~Rze2My7#c0AVBbcWsq$f|vd#thj zY4qr}Ty@8-3e==2tC4G0LhGjmDmb+mav$}S?J5{uMe3jEDqIko{cAANwfc?H`t}GT zO)YCuheK_tQs1m|sIU0Yvaot_af6}aYys|q>52YX7O(Qm`ipFdoZ*p5A^b_f)`QFm z?_^`O@VlEe_vr7;^{xVDYmGYcYTd24Q}r=F^178(>eF%FS{r_ z)S}`Z*~a(+6}7zJgMyt?iLH0ZY=Oniq$Dq^_u?+1pn}F00eyq)#vJcR3vIB-oSH zW7r`d{4|ZmLq)Xoj7}pF(}Ci~a#0jljaG@}`wtHmI6VKXbV~>W$sm5uiHhDXj<0Hb zO{^-BJu7S`n@BVyM?&u_A#~Q=Y9~~y2&(L7?Q)XMUZ68>i)7^7oL$oyN5&E6BA$#c zg*r?TW-G2QOOBK_kCirI`NX7Oy_Lpkji&j~*HoOXu;#dA1Su+|HT|u=Bp0Zv1be`4 z0tuZ@(k+_=N=vh$oTeMo77sdh11g;jg%hys#ux{E4>c+p!>17gVj3$KzmJ^#Y{-aPF1csZL5RRo zrrg?HQFwXn-j17jLV#rFxaBJsSQZww>N1&JdJXBIk#_3$w5Lx0oOYT=?d{I@qOjq8 z1=fRV*5^gM^h)Nxn{x7pZki3|q{s${R$A)2UJ8NkPUlz@Yi+`GCY~A3wO*$vy-?Pw zD)oT*h%XsKSrMD+=<5%$ysl9B`60h2KwZDvuO#bRN>s-Q%xN_O5!Fc>fL%-I>3?s2 z8=2E89H~u{!qW01Sa9w!9p9-VY;bC>1Gpf~poflTN=PU~S~%_j-Ho-`Th;ojZ;SXRL5*4Oxrkn#BD zEAXYAN@tD8b3Kn9^DWI=M4SjTpULhSVB`Qp{faSVGJB#&yl1D=vDQTX z5A@>FHKeoVhRv!o`Zw9%?!>(|_sk`#U#DMMjF668)b@*V{9qXN^6F^ezMP%}MU4~3 z9=;o7mZJ_8YGwc$qoOI1J>O`wcJ2RvAI_!G#ry@1A$nWfM_n_VMq}D@~ z-tYfXJ8xWYA8#_A1O81a0VPB)wTudg;3xwt&|)QoiCke0n%VRZ^@`+wBzkthD#pQu z;OIf9bx*>kZMP=BZk#s;D(;xS8FTc5?6AgFy8_380Bn{gfH0mv&jyxO>ZG+S=hznJ zYHgIu5|kgXf|S&mj;|R(8XO-rp{(ljpq3ITueKJ?**e{BxB0xnl4d5nB&{^3e;nHT z06$ay<&RyMcO2-On95qGqYOoX78TI9hs;5+7oN2ZlK1Ad9*K5?M2}9doDK`M8Z4PV z^M$sxBKHA$sF=2y4C<+PaL$z{ZknBGL@Q&q-P~O1nyiO-XRFj4z$ltjU2koWi?Ngv zsVdp=l<>8vuD%nOQ`=G_L{Qvh*)rG=dC)!gEw-tyH+n7x`M|TO^r!CN6GkC}4+z2` z5EBAF56)QiO>bv@hYqeV4*67T>)u6xS@*_xMvZdBiTLOpPh>XA7L}4;XgBMVHC?R1 zq_NMvxY#e7pa&8nZ~v`R=cZ8!0_nS5==N|t8GI#vhw0>NcKEdt^ZD)V2s}Ta>*Cnp zDm_Tvq))k)QOY}qKV9ew`nzuMm^tSrG4Y0VdV9&>fe(Oo6HAkglu8%SlfE zM61fi{t{j0v@LskJM8Xki406C$L;_cFe7?n<)YRS+pp#28UfI#Ka<%jx3;xh!utBPViToOc9h$-Q^jcL*_APBMVRc=;4K@ml zBn;U7*=)rW2c%&*ODAE?k2wu6;v6Ycz!F~02+=qsP1=^worg^(vrPlArp%O^dJ- zsy@EUnE2$;>}}_O+r~svjXp6gG%RS-cLX_r`lKOvbLL1l4N9ud)SvuW)_Y(LJ{yxv z4Oc-bz4D7LzDZz=jk8zOnbA9rpk(Rl`Z|;zuz!<926xsc0c2+GWRt}gKfKihfo1=W zdmRE9rQqkI(x1yFP0D;JRE=B<*KUM%#BDD!BSUC0zOfrn6KDfP;vG!2!+o#$D-?T# zvO_Y)M3~BC3qx@sl{G?}z)CMZnHql4N}GA7`H8Si-QSBgaAsWeE~M3Ew^f@VtYaLh ze!vkB)_N{uFL*^W_+)Iw6Nt7`z{khfb3!Du8pE~1>zx!ulzp&!P?S)JiLw2@7aszW z`hd=43cJ;O_A_Vy_+p7|qz4XIC%%KCVY92tX91C(1H!jNdMf3xWiaxX4@8Q=`Tj8; z6Q3z-O1duv(ta26$(1zWxA@*4@KGQPdQme{?l0hMp56g0UsF+@)twkBQy9hG*4+Cy zK)DR1=(oZhM%fywM&*^M&I)0#gT$$C0QsgI`J5$tmDVF9M;D`EFs5L z{^SuO$eZwU8v>EY=;z? zvWpA_&`LDbG>BB8K3-u}bGLw71JJh42#=0yz6&-O*sSdkbN{&eY2Q8?D?c$OUl`*- zK^E-MKkXi?&2uqnsIv>^Ra^eprxqP({FzkHN^knvXLFY4Vwp4s+tahZUj#v|#SJZ= z6qaR7bZGc^4N;57UZ4V;?Jxn)BpIB;ra3+Cht~Qa*Ha{HHiH@--L$ zx-+?+UaitV=|9w3ahlDk9Udp|2kntP zi^mIO5@9T=&K|2?(lS)HN>?NJjMl?9GmRSF(9i${nYk*1%y_P&JbX>A`O2LP;9vxq zHEXMpc@WsYoth3vzzF084RtobNe&8)P%^1 z2LiH)0#>>6u_8@{XCsTmd<%O4kSL!KM#fWM(6`^)&!}NRATzCK>ECz|uI%Q8?wt@S zQmsvWlA7pX%~E^E`l_Q^m`)`pdbrRhcc|3aV@J)k){TP)7^KvmnPnKB?Vny3RG3Kx_->!6ptI=uqTV@PQsI1bed z^!aJFdsUmw*o9p`Vl3ZwQHp9PrQ$Hsjo;gdi$1R9LU2cO!cYSp~&Dr*6ql+HHP#oliaGaW& zS`x_2`g1JL3Kwun+T5PG^2>>Oj#Lg%DG&jwozN#}c`>_inFp8;nhQ6+&kb_C=7p6W z>Tiz_+?%fFieSdpg3d#RQiX&PYeZ2}jZm_NsX~tx>xZ3H$+#{vYsepK?+^%~d<~=z zZJo5QB3`%ORFS)9LKkdR7$0rpXy%9BIr;L@2S&0?I)R*fU7h|W=0XwL9{z48-5v$I zS$yYRzZxa}F&#MP?E=N`UBm$5ursoT8sv-FCJmi2!^#Fp9j_Uj}6*1{c=87=C4ZuEz#AFPosZD6=teK` z73w16qs`q)Ju2VR^6hhJCgVdqKM#6T4i_z!DGC6iT}MNeR}B|Z8fVE+J&9w$@ltR8 zme)g|tJF^~loyEE_H7tpyhV$OHt#MDVS>h4$z};6nTm+iGhu^U3KXr1j^&)2PApZW zO#al}tTqFig(d>0%H#@P^Dv>KM-(Ax$ZYx3i9tkzbst17D^u~3 zplR8D2!dNspUR}R(AX6=j+Fm&i%#N0Nj=^^&|jCnsZPR?lh zX(c{~f&}#-XtQ#W9rTU3cU>jNUhzF6dAgIP2lW_J- ztD0GvXdIfNz#y6ek&{R<4E7Yr%;V|mA7G|0;Pzc>$@(S<4;(5h4Kd>);^DIAnzZQN z-HFIN+8p(3O#Re>A_~|sqq!`DafN_ZRT7D`6cQTRP@VLw*_YQh*vn%;&z86=ZX5ZA z7XI>w9l;24nUf1d>bSr9NBz*VBJiD1+eH*QZ@2H|T&|B{(vJRq^K&`S!gQ06ZxY~r zy7(jB_?Jwj!@mQr$_Wt37e;CJg}K#KBNE?7!++}lQ)ry-F%D#xsx!Ig9*cJS*vFG} zs(QkbErEe-8d^}la4;P`Z|RJ}JInV2iAi7Y-j`@)2BlQgxXa*>HA4LxA6mlkecSOEQidi{~#)Zhw!9Wp1}S@mV}{l4{S`nLm!m1DPnQx%cQpaBppD3qp_% z$xSG14GlsRFhM@%6ii6M$}{64&g^q1U|(wT^i<$vXB%oHz2>l3vm&xuvPzstJhsN3e0V(=aZg5-a71@vpQP`#1 z@6Md!cmDO-R07zNpDui8docFJVNGhh&k zvoN_DXf*yfyq$O5#Efh@{L(jg&7Y58OeMLav8vQuzdkcBfOtfK*1b%kLx^_ksEsdv zrD6PI1#?S^fD-lQ*`bsXE2xzov1Pk{<}kIJA&@BQbkH9v1%LD}1pSwe5z zi3-jaYbhK8#yp|iqtq|9MfhDkldl9z7u3i z_2&~kUZ5EGXd~z=d9($BJ+XLa?Ut9>**x-+=ca+Ij$!!+c$0U)QM$jm9Dn+Bc#j?3T(!1Ond+9d8#bp zyRo%ZJ2qx>%`!P`@ZQIeALT%59)jxkj@h5H#R@&#Qfgq&2ORG9v%C72pVMPhO@K!? zHh6ve81~)Oy}?V+D<4||1=j5?wP6?wpd~|W$3SL^Rja>1V^37V@nG)ob7v1rFsl8$ zQBo5CeZ!y#FrtVlq-8&)lb-%E+TZPfM(SM z^M7x}Fe#5OZu8q6B6IA2+?7cWG~eYc|MymFK>z?ZwDE`b34E|$hrkLvKr^+H!*4U{ zAH%EDJ%lJ)N(n!_PvHIG?%frr3N-(Bq7RVlzZ3mW4*AJ9|CQ)}iX31>{#T;^7smcS zh3-^+5NUk;VW{7*_npQiQt|S1eeA!hK433_Z9*Qv#O8W(7573QW~R@`RARWlP34*e%A_b_@87K2Y8pNj?=i z629_I(IXZpXPxdocz^&0F7t#CeC@ip_%n@@GBt0_tMOn7XJ5D768IQ_G>MD>YE4iw zbtv>@rc=QikA5swh(EP55`aIY;6Ea6BS{jsx|LpfFj#P4dhFa82g(Cp4cE>+&yew` zv#R&a`mk-qM+|0Du0 zP_x3=rot5y3zwx)T0AbY-Z*DM!tdG)V;P~ad?Cg40 zMu5z-^C7RVKI@+|EivyfZuRy0_OC=XiVkln=^noRa!QbLv^ed<$mI6`>pORBJH{%+ zFt;KcjO*MxUVMNk_GJQf$ce8iYNB;k**Q1@1wF^LloX{Tr|;!0AoII3W?XbX>&*gH z&eGNX!xq|OaRl{M#E}omPihF*CAA=Es6OrNo6?WW zX`i=fyS7~EFsY5s!Eid@nB(etFZ*V|zo6e;bQ#cTOq0n2%BI9x*^IxRT(d`fzd00NQR5JH zKF;IoFFC0@Mo3Z+kA)|9%Gt5O)2q*=mh_^;&IIqoO!7U*AiGZoc<1LOUY*xY*j%e) z%{DC@CC~4!;PA@XS2&>PRVjT9jX{y$rs;)U*|;L6Q8#sj_No3G$>QgH(%?2D?{B;I zOx|#l}XNK~Jrm zLd*12S6FbTd15WU;{QSXySxvDZB?e;=f|3DMyMy&cz(GV=H{OBwtyZB1X?!VRxynh ziX*g}k!+UP9R6iLCf6EynW`&@Vz1s1Rx%mK{xOxmDKZrizF?^`PS{j1oK2QTr$QMY zc~nhtmV6=t=ZhWA%k1MM#aRl$a~ld;_VZ;9T2zQnOfg!f5S(lducPSw(#@M+b2;Nb z$%-IEk4ps>@TnJf-2K+odEwxV31-a z@BlRazQh~z`4YewSuant%IvKJzDPO~>$?wJ?D0?MhBchZ$O=wZ2_Xf=Au}%cm|WOM zdCd9ye!LSuz0K7zI)?jm!=2kot-*W2UMIeuM|i0Bw-}4Wm5hjW#GlDX!FPsvFukjp k+9JqE??H*O4CrsJKzn|w`$ErE4*@@#FkN+ws$InY0G%JLy#N3J literal 0 HcmV?d00001 diff --git a/docs/drilldowns/images/explore_data_in_chart.png b/docs/drilldowns/images/explore_data_in_chart.png new file mode 100644 index 0000000000000000000000000000000000000000..05d4f5fac9b2fafe808e72ff0ab2c5e0028f33fc GIT binary patch literal 99870 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

@1p8Xrj8Q!w#bssBL9{8 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 VWGX&|iQ!=%RYeVWsl0j6{{Z*TLa+b; literal 0 HcmV?d00001 diff --git a/docs/user/dashboard.asciidoc b/docs/user/dashboard.asciidoc index a812d4e3bdd2d..b812af7e981bf 100644 --- a/docs/user/dashboard.asciidoc +++ b/docs/user/dashboard.asciidoc @@ -160,6 +160,7 @@ When you're finished adding and arranging the panels, save the dashboard. . Enter the dashboard *Title* and optional *Description*, then *Save* the dashboard. include::{kib-repo-dir}/drilldowns/drilldowns.asciidoc[] +include::{kib-repo-dir}/drilldowns/explore-underlying-data.asciidoc[] [[sharing-dashboards]] == Share the dashboard From 679209b308d70bcdecdad2eadf3dc21e81eae8a3 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 17 Jul 2020 11:38:45 -0600 Subject: [PATCH 22/24] [Maps] 7.9 documenation updates (#71893) * [Maps] 7.9 documenation updates * more cleanup * add vector tiles card to tile layers page --- docs/maps/heatmap-layer.asciidoc | 4 +-- docs/maps/maps-aggregations.asciidoc | 4 +-- docs/maps/maps-getting-started.asciidoc | 35 +++++-------------------- docs/maps/tile-layer.asciidoc | 4 ++- docs/maps/vector-layer.asciidoc | 11 ++++---- 5 files changed, 18 insertions(+), 40 deletions(-) diff --git a/docs/maps/heatmap-layer.asciidoc b/docs/maps/heatmap-layer.asciidoc index 7149bc5623169..9dc2781db44a3 100644 --- a/docs/maps/heatmap-layer.asciidoc +++ b/docs/maps/heatmap-layer.asciidoc @@ -7,8 +7,8 @@ Heat map layers cluster point data to show locations with higher densities. [role="screenshot"] image::maps/images/heatmap_layer.png[] -To add a heat map layer to your map, click *Add layer*, then select the *Heat map* layer. -The index must contain at least one field mapped as {ref}/geo-point.html[geo_point]. +To add a heat map layer to your map, click *Add layer*, then select *Heat map*. +The index must contain at least one field mapped as {ref}/geo-point.html[geo_point] or {ref}/geo-shape.html[geo_shape]. NOTE: Only count, sum, unique count metric aggregations are available with the grid aggregation source and heat map layers. Average, min, and max are turned off because the heat map will blend nearby values. diff --git a/docs/maps/maps-aggregations.asciidoc b/docs/maps/maps-aggregations.asciidoc index 872ed1cdedb7e..6b2dc8077bc30 100644 --- a/docs/maps/maps-aggregations.asciidoc +++ b/docs/maps/maps-aggregations.asciidoc @@ -47,7 +47,7 @@ Grid aggregation layers use {ref}/search-aggregations-bucket-geotilegrid-aggrega Symbolize grid aggregation metrics as: *Clusters*:: Creates a <> with a cluster symbol for each gridded cell. -The cluster location is the weighted centroid for all geo-points in the gridded cell. +The cluster location is the weighted centroid for all documents in the gridded cell. *Grid rectangles*:: Creates a <> with a bounding box polygon for each gridded cell. @@ -60,7 +60,7 @@ To enable a grid aggregation layer: To enable a blended layer that dynamically shows clusters or documents: . Click *Add layer*, then select the *Documents* layer. -. Configure *Index pattern* and the *Geospatial field*. To enable clustering, the *Geospatial field* must be set to a field mapped as {ref}/geo-point.html[geo_point]. +. Configure *Index pattern* and the *Geospatial field*. . In *Scaling*, select *Show clusters when results exceed 10000*. diff --git a/docs/maps/maps-getting-started.asciidoc b/docs/maps/maps-getting-started.asciidoc index 09a4dc61cae28..e0d43a571a331 100644 --- a/docs/maps/maps-getting-started.asciidoc +++ b/docs/maps/maps-getting-started.asciidoc @@ -68,40 +68,17 @@ The first layer you'll add is a choropleth layer to shade world countries by web log traffic. Darker shades symbolize countries with more web log traffic, and lighter shades symbolize countries with less traffic. -==== Add a vector layer to display world country boundaries - . Click *Add layer*. -. Select the *EMS Boundaries* layer. +. Select *Choropleth*. . From the *Layer* dropdown menu, select *World Countries*. +. Under *Statistics source*, set *Index pattern* to *kibana_sample_data_logs*. +. Set *Join field* to *geo.src*. . Click the *Add layer* button. . Set *Name* to `Total Requests by Country`. . Set *Opacity* to 50%. . Click *Add* under *Tooltip fields*. . In the popover, select *ISO 3166-1 alpha-2 code* and *name* and click *Add*. - -===== Join the vector layer with the sample web log index - -You now have a vector layer containing the world countries. -To symbolize countries by web traffic, you'll need to augment the world country features with the count of Elasticsearch weblog documents originating from each country. -To do this, you'll create a <> to link the vector source *World Countries* to -the {es} index `kibana_sample_data_logs` on the shared key iso2 = geo.src. - -. Click plus image:maps/images/gs_plus_icon.png[] next to the *Term Joins* label. -. Click *Join --select--* -. Set *Left field* to *ISO 3166-1 alpha-2 code*. -. Set *Right source* to *kibana_sample_data_logs*. -. Set *Right field* to *geo.src*. -. Click *and use metric count*. -. Set *Custom label* to *web logs count*. - -===== Set the layer style - -All of the world countries are still a single color because the layer is using <>. -To shade the world countries based on which country is sending the most requests, you'll need to use <>. - -. Under *Fill color*, change the selected value from *Solid* to *By value*. -. In the field select input, select *web logs count*. -. Select the grey color ramp. +. Under *Fill color*, select the grey color ramp. . Under *Border color*, change the selected color to *white*. . Click *Save & close*. + @@ -127,7 +104,7 @@ This layer displays web log documents as points. The layer is only visible when users zoom in the map past zoom level 9. . Click *Add layer*. -. Click the *Documents* layer. +. Select *Documents*. . Set *Index pattern* to *kibana_sample_data_logs*. . Click the *Add layer* button. . Set *Name* to `Actual Requests`. @@ -161,7 +138,7 @@ image::maps/images/grid_metrics_both.png[] ===== Add the layer . Click *Add layer*. -. Click the *Clusters and grids* layer. +. Select *Clusters and grids*. . Set *Index pattern* to *kibana_sample_data_logs*. . Click the *Add layer* button. . Set *Name* to `Total Requests and Bytes`. diff --git a/docs/maps/tile-layer.asciidoc b/docs/maps/tile-layer.asciidoc index 6da8dbad0a66d..2a60504c3c790 100644 --- a/docs/maps/tile-layer.asciidoc +++ b/docs/maps/tile-layer.asciidoc @@ -7,7 +7,7 @@ Tile layers display image tiles served from a tile server. [role="screenshot"] image::maps/images/tile_layer.png[] -To add a tile layer to your map, click *Add layer*, then select one of the following layers: +To add a tile layer to your map, click *Add layer*, then select one of the following: *Configured Tile Map Service*:: Tile map service configured in kibana.yml. See map.tilemap.url in <> for details. @@ -16,4 +16,6 @@ See map.tilemap.url in <> for details. *Tile Map Service*:: Tile map service configured in interface. +*Vector tiles*:: Data service implementing the Mapbox vector tile specification. + *Web Map Service*:: Maps from OGC Standard WMS. diff --git a/docs/maps/vector-layer.asciidoc b/docs/maps/vector-layer.asciidoc index d6a5931659a40..494bd915b7f56 100644 --- a/docs/maps/vector-layer.asciidoc +++ b/docs/maps/vector-layer.asciidoc @@ -7,15 +7,14 @@ Vector layers display points, lines, and polygons. [role="screenshot"] image::maps/images/vector_layer.png[] -To add a vector layer to your map, click *Add layer*, then select one of the following layers: +To add a vector layer to your map, click *Add layer*, then select one of the following: -*Clusters and grids*:: Geospatial data grouped in grids with metrics for each gridded cell. -The index must contain at least one field mapped as {ref}/geo-point.html[geo_point]. +*Choropleth*:: Shaded areas to compare statistics across boundaries. -*Configured GeoJSON*:: Vector data from hosted GeoJSON configured in kibana.yml. -See map.regionmap.* in <> for details. +*Clusters and grids*:: Geospatial data grouped in grids with metrics for each gridded cell. +The index must contain at least one field mapped as {ref}/geo-point.html[geo_point] or {ref}/geo-shape.html[geo_shape]. -*Documents*:: Vector data from a Kibana index pattern. +*Documents*:: Points, lines, and polyons from Elasticsearch. The index must contain at least one field mapped as {ref}/geo-point.html[geo_point] or {ref}/geo-shape.html[geo_shape]. NOTE: Document results are limited to the `index.max_result_window` index setting, which defaults to 10000. From 35ff37a434e61d2475428ff474fce50ee9bb68b1 Mon Sep 17 00:00:00 2001 From: Wylie Conlon Date: Fri, 17 Jul 2020 14:02:52 -0400 Subject: [PATCH 23/24] [Lens] Fix switching with layers (#71982) * [Lens] Fix chart switching with multiple layers * Unskip Lens smokescreen test * Fix types * Revert

change --- .../config_panel/config_panel.tsx | 2 +- .../config_panel/layer_panel.test.tsx | 6 +- .../editor_frame/config_panel/layer_panel.tsx | 2 +- .../workspace_panel/chart_switch.test.tsx | 53 +++++++++++ .../workspace_panel/chart_switch.tsx | 7 +- .../xy_visualization/xy_suggestions.test.ts | 92 +++++++++++++++++-- .../public/xy_visualization/xy_suggestions.ts | 16 +++- .../test/functional/apps/lens/smokescreen.ts | 26 ++++++ .../test/functional/page_objects/lens_page.ts | 28 ++++++ 9 files changed, 214 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 7f4a48fa2fda2..73126b814f256 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -129,7 +129,7 @@ function LayerPanels( className="lnsConfigPanel__addLayerBtn" fullWidth size="s" - data-test-subj="lnsXY_layer_add" + data-test-subj="lnsLayerAddButton" aria-label={i18n.translate('xpack.lens.xyChart.addLayerButton', { defaultMessage: 'Add layer', })} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index 1f987f86d3950..9545bd3c840da 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -93,14 +93,14 @@ describe('LayerPanel', () => { describe('layer reset and remove', () => { it('should show the reset button when single layer', () => { const component = mountWithIntl(); - expect(component.find('[data-test-subj="lns_layer_remove"]').first().text()).toContain( + expect(component.find('[data-test-subj="lnsLayerRemove"]').first().text()).toContain( 'Reset layer' ); }); it('should show the delete button when multiple layers', () => { const component = mountWithIntl(); - expect(component.find('[data-test-subj="lns_layer_remove"]').first().text()).toContain( + expect(component.find('[data-test-subj="lnsLayerRemove"]').first().text()).toContain( 'Delete layer' ); }); @@ -109,7 +109,7 @@ describe('LayerPanel', () => { const cb = jest.fn(); const component = mountWithIntl(); act(() => { - component.find('[data-test-subj="lns_layer_remove"]').first().simulate('click'); + component.find('[data-test-subj="lnsLayerRemove"]').first().simulate('click'); }); expect(cb).toHaveBeenCalled(); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index e51a155a19935..f72b1429967d2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -429,7 +429,7 @@ export function LayerPanel( size="xs" iconType="trash" color="danger" - data-test-subj="lns_layer_remove" + data-test-subj="lnsLayerRemove" onClick={() => { // If we don't blur the remove / clear button, it remains focused // which is a strange UX in this case. e.target.blur doesn't work diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx index 648bb5c03cb39..ceced2a7a353c 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx @@ -46,6 +46,16 @@ describe('chart_switch', () => { }; } + /** + * There are three visualizations. Each one has the same suggestion behavior: + * + * visA: suggests an empty state + * visB: suggests an empty state + * visC: + * - Never switches to subvisC2 + * - Allows a switch to subvisC3 + * - Allows a switch to subvisC1 + */ function mockVisualizations() { return { visA: generateVisualization('visA'), @@ -292,6 +302,49 @@ describe('chart_switch', () => { expect(getMenuItem('visB', component).prop('betaBadgeIconType')).toEqual('alert'); }); + it('should support multi-layer suggestions without data loss', () => { + const dispatch = jest.fn(); + const visualizations = mockVisualizations(); + const frame = mockFrame(['a', 'b']); + + const datasourceMap = mockDatasourceMap(); + datasourceMap.testDatasource.getDatasourceSuggestionsFromCurrentState.mockReturnValue([ + { + state: {}, + table: { + columns: [ + { + columnId: 'a', + operation: { + label: '', + dataType: 'string', + isBucketed: true, + }, + }, + ], + isMultiRow: true, + layerId: 'a', + changeType: 'unchanged', + }, + keptLayerIds: ['a', 'b'], + }, + ]); + + const component = mount( + + ); + + expect(getMenuItem('visB', component).prop('betaBadgeIconType')).toBeUndefined(); + }); + it('should indicate data loss if no data will be used', () => { const dispatch = jest.fn(); const visualizations = mockVisualizations(); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx index fa87d80e5cf40..51b4a347af6f1 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx @@ -139,7 +139,7 @@ export function ChartSwitch(props: Props) { dataLoss = 'nothing'; } else if (!topSuggestion) { dataLoss = 'everything'; - } else if (layers.length > 1) { + } else if (layers.length > 1 && layers.length !== topSuggestion.keptLayerIds.length) { dataLoss = 'layers'; } else if (topSuggestion.columns !== layers[0][1].getTableSpec().length) { dataLoss = 'columns'; @@ -258,14 +258,15 @@ function getTopSuggestion( newVisualization: Visualization, subVisualizationId?: string ): Suggestion | undefined { - const suggestions = getSuggestions({ + const unfilteredSuggestions = getSuggestions({ datasourceMap: props.datasourceMap, datasourceStates: props.datasourceStates, visualizationMap: { [visualizationId]: newVisualization }, activeVisualizationId: props.visualizationId, visualizationState: props.visualizationState, subVisualizationId, - }).filter((suggestion) => { + }); + const suggestions = unfilteredSuggestions.filter((suggestion) => { // don't use extended versions of current data table on switching between visualizations // to avoid confusing the user. return ( diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index f301206355060..f5828dbaeccc3 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -13,6 +13,7 @@ import { } from '../types'; import { State, XYState, visualizationTypes } from './types'; import { generateId } from '../id_generator'; +import { xyVisualization } from './xy_visualization'; jest.mock('../id_generator'); @@ -119,7 +120,33 @@ describe('xy_suggestions', () => { }); expect(suggestions).toHaveLength(visualizationTypes.length); - expect(suggestions.map(({ state }) => state.preferredSeriesType)).toEqual([ + expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ + 'bar_stacked', + 'area_stacked', + 'area', + 'line', + 'bar_horizontal_stacked', + 'bar_horizontal', + 'bar', + ]); + }); + + // This limitation is acceptable for now, but is now tested + test('is unable to generate layers when switching from a non-XY chart with multiple layers', () => { + (generateId as jest.Mock).mockReturnValueOnce('aaa'); + const suggestions = getSuggestions({ + table: { + isMultiRow: true, + columns: [numCol('bytes'), dateCol('date')], + layerId: 'first', + changeType: 'unchanged', + }, + keptLayerIds: ['first', 'second'], + }); + + expect(suggestions).toHaveLength(visualizationTypes.length); + expect(suggestions.map(({ state }) => state.layers.length)).toEqual([1, 1, 1, 1, 1, 1, 1]); + expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'bar_stacked', 'area_stacked', 'area', @@ -156,7 +183,51 @@ describe('xy_suggestions', () => { }); expect(suggestions).toHaveLength(visualizationTypes.length); - expect(suggestions.map(({ state }) => state.preferredSeriesType)).toEqual([ + expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ + 'line', + 'bar', + 'bar_horizontal', + 'bar_stacked', + 'bar_horizontal_stacked', + 'area', + 'area_stacked', + ]); + }); + + test('suggests all basic x y charts when switching from another x y chart with multiple layers', () => { + (generateId as jest.Mock).mockReturnValueOnce('aaa'); + const suggestions = getSuggestions({ + table: { + isMultiRow: true, + columns: [numCol('bytes'), dateCol('date')], + layerId: 'first', + changeType: 'unchanged', + }, + keptLayerIds: ['first', 'second'], + state: { + legend: { isVisible: true, position: 'bottom' }, + preferredSeriesType: 'bar', + layers: [ + { + layerId: 'first', + seriesType: 'bar', + xAccessor: 'date', + accessors: ['bytes'], + splitAccessor: undefined, + }, + { + layerId: 'second', + seriesType: 'bar', + xAccessor: undefined, + accessors: [], + splitAccessor: undefined, + }, + ], + }, + }); + + expect(suggestions).toHaveLength(visualizationTypes.length); + expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'line', 'bar', 'bar_horizontal', @@ -165,6 +236,15 @@ describe('xy_suggestions', () => { 'area', 'area_stacked', ]); + expect(suggestions.map(({ state }) => state.layers.map((l) => l.layerId))).toEqual([ + ['first', 'second'], + ['first', 'second'], + ['first', 'second'], + ['first', 'second'], + ['first', 'second'], + ['first', 'second'], + ['first', 'second'], + ]); }); test('suggests all basic x y chart with date on x', () => { @@ -388,7 +468,7 @@ describe('xy_suggestions', () => { changeType: 'unchanged', }, state: currentState, - keptLayerIds: [], + keptLayerIds: ['first'], }); expect(rest).toHaveLength(visualizationTypes.length - 2); @@ -497,7 +577,7 @@ describe('xy_suggestions', () => { changeType: 'extended', }, state: currentState, - keptLayerIds: [], + keptLayerIds: ['first'], }); expect(rest).toHaveLength(0); @@ -536,7 +616,7 @@ describe('xy_suggestions', () => { changeType: 'reorder', }, state: currentState, - keptLayerIds: [], + keptLayerIds: ['first'], }); expect(rest).toHaveLength(0); @@ -576,7 +656,7 @@ describe('xy_suggestions', () => { changeType: 'extended', }, state: currentState, - keptLayerIds: [], + keptLayerIds: ['first'], }); expect(rest).toHaveLength(0); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts index e0bfbd266f8f1..d7348f00bf8b8 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.ts @@ -394,17 +394,25 @@ function buildSuggestion({ : undefined, }; + // Maintain consistent order for any layers that were saved const keptLayers = currentState - ? currentState.layers.filter( - (layer) => layer.layerId !== layerId && keptLayerIds.includes(layer.layerId) - ) + ? currentState.layers + // Remove layers that aren't being suggested + .filter((layer) => keptLayerIds.includes(layer.layerId)) + // Update in place + .map((layer) => (layer.layerId === layerId ? newLayer : layer)) + // Replace the seriesType on all previous layers + .map((layer) => ({ + ...layer, + seriesType, + })) : []; const state: State = { legend: currentState ? currentState.legend : { isVisible: true, position: Position.Right }, fittingFunction: currentState?.fittingFunction || 'None', preferredSeriesType: seriesType, - layers: [...keptLayers, newLayer], + layers: Object.keys(existingLayer).length ? keptLayers : [...keptLayers, newLayer], }; return { diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index 8bb5faf2469d7..23d4cc972675b 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -165,5 +165,31 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // legend item(s), so we're using a class selector here. expect(await find.allByCssSelector('.echLegendItem')).to.have.length(3); }); + + it('should switch from a multi-layer stacked bar to a multi-layer line chart', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await PageObjects.lens.goToTimeRange(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'avg', + field: 'bytes', + }); + + await PageObjects.lens.createLayer(); + + expect(await PageObjects.lens.hasChartSwitchWarning('line')).to.eql(false); + + await PageObjects.lens.switchToVisualization('line'); + + expect(await PageObjects.lens.getLayerCount()).to.eql(2); + }); }); } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 4252c400ff1cd..d101c9754d562 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -167,5 +167,33 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await testSubjects.existOrFail('visTypeTitle'); }); }, + + /** + * Checks a specific subvisualization in the chart switcher for a "data loss" indicator + * + * @param subVisualizationId - the ID of the sub-visualization to switch to, such as + * lnsDatatable or bar_stacked + */ + async hasChartSwitchWarning(subVisualizationId: string) { + await this.openChartSwitchPopover(); + + const element = await testSubjects.find(`lnsChartSwitchPopover_${subVisualizationId}`); + return await testSubjects.descendantExists('euiKeyPadMenuItem__betaBadgeWrapper', element); + }, + + /** + * Returns the number of layers visible in the chart configuration + */ + async getLayerCount() { + const elements = await testSubjects.findAll('lnsLayerRemove'); + return elements.length; + }, + + /** + * Adds a new layer to the chart, fails if the chart does not support new layers + */ + async createLayer() { + await testSubjects.click('lnsLayerAddButton'); + }, }); } From 3cef292bbd52edb94d87ec73401553e8450a8736 Mon Sep 17 00:00:00 2001 From: Quynh Nguyen <43350163+qn895@users.noreply.github.com> Date: Fri, 17 Jul 2020 13:35:25 -0500 Subject: [PATCH 24/24] [ML] Fix annotations pagination & change labels from letters to numbers (#72204) --- .../__snapshots__/annotations_table.test.js.snap | 1 + .../annotations_table/annotations_table.js | 13 ++++++++----- .../public/application/explorer/explorer_utils.js | 2 +- .../timeseriesexplorer_utils/get_focus_data.ts | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/__snapshots__/annotations_table.test.js.snap b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/__snapshots__/annotations_table.test.js.snap index 63ec1744b62d0..9eb44c71aa799 100644 --- a/x-pack/plugins/ml/public/application/components/annotations/annotations_table/__snapshots__/annotations_table.test.js.snap +++ b/x-pack/plugins/ml/public/application/components/annotations/annotations_table/__snapshots__/annotations_table.test.js.snap @@ -77,6 +77,7 @@ exports[`AnnotationsTable Initialization with annotations prop. 1`] = ` "dataType": "boolean", "field": "current_series", "name": "current_series", + "render": [Function], "width": "0px", }, ] 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 cf4d25f159a1a..86398a57c3a45 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 @@ -13,7 +13,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import rison from 'rison-node'; import React, { Component, Fragment } from 'react'; - +import memoizeOne from 'memoize-one'; import { EuiBadge, EuiButtonIcon, @@ -130,7 +130,7 @@ export class AnnotationsTable extends Component { } } - getAnnotationsWithExtraInfo(annotations) { + getAnnotationsWithExtraInfo = memoizeOne((annotations) => { // if there is a specific view/chart entities that the annotations can be scoped to // add a new column called 'current_series' if (Array.isArray(this.props.chartDetails?.entityData?.entities)) { @@ -147,7 +147,7 @@ export class AnnotationsTable extends Component { // if not make it return the original annotations return annotations; } - } + }); getJob(jobId) { // check if the job was supplied via props and matches the supplied jobId @@ -438,7 +438,7 @@ export class AnnotationsTable extends Component { name: i18n.translate('xpack.ml.annotationsTable.labelColumnName', { defaultMessage: 'Label', }), - sortable: true, + sortable: (key) => +key, width: '60px', render: (key) => { return {key}; @@ -644,15 +644,18 @@ export class AnnotationsTable extends Component { name: CURRENT_SERIES, dataType: 'boolean', width: '0px', + render: () => '', } ); + + const items = this.getAnnotationsWithExtraInfo(annotations); return ( { - d.key = String.fromCharCode(65 + i); + d.key = (i + 1).toString(); return d; }), aggregations: resp.aggregations, diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts index 8bac9a51af174..d213d371f1d90 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer_utils/get_focus_data.ts @@ -156,8 +156,8 @@ export function getFocusData( .sort((a, b) => { return a.timestamp - b.timestamp; }) - .map((d, i) => { - d.key = String.fromCharCode(65 + i); + .map((d, i: number) => { + d.key = (i + 1).toString(); return d; });