From c584b0c7f2371e497c4b8a5123d4bc294bf493c6 Mon Sep 17 00:00:00 2001 From: ppisljar Date: Mon, 24 Feb 2020 07:58:34 -0500 Subject: [PATCH 01/73] removing references to visTypes uiExports --- src/legacy/core_plugins/kibana/public/kibana.js | 2 -- .../plugins/kbn_tp_run_pipeline/public/legacy.ts | 2 -- x-pack/legacy/plugins/canvas/public/legacy_start.ts | 3 --- .../legacy/plugins/dashboard_mode/public/dashboard_viewer.js | 4 +--- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index d77fc780f4cc26..f63759675a6b49 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -26,8 +26,6 @@ import { npSetup } from 'ui/new_platform'; // import the uiExports that we want to "use" import 'uiExports/home'; -import 'uiExports/visTypes'; - import 'uiExports/visualize'; import 'uiExports/savedObjectTypes'; import 'uiExports/fieldFormatEditors'; diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts index 39ce2b3077c961..a7cd313038d69c 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/public/legacy.ts @@ -28,8 +28,6 @@ import 'ui/autoload/all'; // Used to run esaggs queries import 'uiExports/fieldFormats'; import 'uiExports/search'; -import 'uiExports/visRequestHandlers'; -import 'uiExports/visResponseHandlers'; // Used for kibana_context function import 'uiExports/savedObjectTypes'; diff --git a/x-pack/legacy/plugins/canvas/public/legacy_start.ts b/x-pack/legacy/plugins/canvas/public/legacy_start.ts index 21bf5aaa6d8184..d7d1a940d3b43a 100644 --- a/x-pack/legacy/plugins/canvas/public/legacy_start.ts +++ b/x-pack/legacy/plugins/canvas/public/legacy_start.ts @@ -8,9 +8,6 @@ // Import the uiExports that the application uses // These will go away as these plugins are converted to NP import 'ui/autoload/all'; -import 'uiExports/visTypes'; -import 'uiExports/visResponseHandlers'; -import 'uiExports/visRequestHandlers'; import 'uiExports/savedObjectTypes'; import 'uiExports/spyModes'; import 'uiExports/embeddableFactories'; diff --git a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js index 8ca023aa90cf12..c974b30932421d 100644 --- a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js +++ b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js @@ -15,9 +15,7 @@ import { uiModules } from 'ui/modules'; // import the uiExports that we want to "use" import 'uiExports/contextMenuActions'; -import 'uiExports/visTypes'; -import 'uiExports/visResponseHandlers'; -import 'uiExports/visRequestHandlers'; + import 'uiExports/inspectorViews'; import 'uiExports/interpreter'; import 'uiExports/savedObjectTypes'; From 581f1bd6e9329b66db5bc3cb3348475595db5aa2 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Mon, 24 Feb 2020 16:26:34 +0100 Subject: [PATCH 02/73] Expressions debug mode (#57841) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 add ability to execute expression in debug mode * feat: 🎸 store resolved arguments in debug information * feat: 🎸 track function execution time and set "success" flag * feat: 🎸 store debug information for functions that throw * feat: 🎸 use performance.now, safe "fn" reference, fix typo --- src/plugins/expressions/common/ast/types.ts | 53 ++++ .../common/execution/execution.test.ts | 253 +++++++++++++++++- .../expressions/common/execution/execution.ts | 67 ++++- .../expressions/common/executor/executor.ts | 26 +- 4 files changed, 379 insertions(+), 20 deletions(-) diff --git a/src/plugins/expressions/common/ast/types.ts b/src/plugins/expressions/common/ast/types.ts index 82a7578dd4b892..0b505f117a5807 100644 --- a/src/plugins/expressions/common/ast/types.ts +++ b/src/plugins/expressions/common/ast/types.ts @@ -17,6 +17,9 @@ * under the License. */ +import { ExpressionValue, ExpressionValueError } from '../expression_types'; +import { ExpressionFunction } from '../../public'; + export type ExpressionAstNode = | ExpressionAstExpression | ExpressionAstFunction @@ -31,6 +34,56 @@ export interface ExpressionAstFunction { type: 'function'; function: string; arguments: Record; + + /** + * Debug information added to each function when expression is executed in *debug mode*. + */ + debug?: ExpressionAstFunctionDebug; +} + +export interface ExpressionAstFunctionDebug { + /** + * True if function successfully returned output, false if function threw. + */ + success: boolean; + + /** + * Reference to the expression function this AST node represents. + */ + fn: ExpressionFunction; + + /** + * Input that expression function received as its first argument. + */ + input: ExpressionValue; + + /** + * Map of resolved arguments expression function received as its second argument. + */ + args: Record; + + /** + * Result returned by the expression function. Including an error result + * if it was returned by the function (not thrown). + */ + output?: ExpressionValue; + + /** + * Error that function threw normalized to `ExpressionValueError`. + */ + error?: ExpressionValueError; + + /** + * Raw error that was thrown by the function, if any. + */ + rawError?: any | Error; + + /** + * Time in milliseconds it took to execute the function. Duration can be + * `undefined` if error happened during argument resolution, because function + * timing starts after the arguments have been resolved. + */ + duration: number | undefined; } export type ExpressionAstArgument = string | boolean | number | ExpressionAstExpression; diff --git a/src/plugins/expressions/common/execution/execution.test.ts b/src/plugins/expressions/common/execution/execution.test.ts index b6c1721e33eefc..f6ff9efca848b9 100644 --- a/src/plugins/expressions/common/execution/execution.test.ts +++ b/src/plugins/expressions/common/execution/execution.test.ts @@ -18,20 +18,28 @@ */ import { Execution } from './execution'; -import { parseExpression } from '../ast'; +import { parseExpression, ExpressionAstExpression } from '../ast'; import { createUnitTestExecutor } from '../test_helpers'; import { ExpressionFunctionDefinition } from '../../public'; import { ExecutionContract } from './execution_contract'; +beforeAll(() => { + if (typeof performance === 'undefined') { + (global as any).performance = { now: Date.now }; + } +}); + const createExecution = ( expression: string = 'foo bar=123', - context: Record = {} + context: Record = {}, + debug: boolean = false ) => { const executor = createUnitTestExecutor(); const execution = new Execution({ executor, ast: parseExpression(expression), context, + debug, }); return execution; }; @@ -406,4 +414,245 @@ describe('Execution', () => { }); }); }); + + describe('debug mode', () => { + test('can execute expression in debug mode', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + const result = await execution.result; + + expect(result).toEqual({ + type: 'num', + value: 5, + }); + }); + + test('can execute expression with sub-expression in debug mode', async () => { + const execution = createExecution( + 'add val={var_set name=foo value=5 | var name=foo} | add val=10', + {}, + true + ); + execution.start(0); + const result = await execution.result; + + expect(result).toEqual({ + type: 'num', + value: 15, + }); + }); + + describe('when functions succeed', () => { + test('sets "success" flag on all functions to true', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + for (const node of execution.state.get().ast.chain) { + expect(node.debug?.success).toBe(true); + } + }); + + test('stores "fn" reference to the function', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + for (const node of execution.state.get().ast.chain) { + expect(node.debug?.fn.name).toBe('add'); + } + }); + + test('saves duration it took to execute each function', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + for (const node of execution.state.get().ast.chain) { + expect(typeof node.debug?.duration).toBe('number'); + expect(node.debug?.duration).toBeLessThan(100); + expect(node.debug?.duration).toBeGreaterThanOrEqual(0); + } + }); + + test('sets duration to 10 milliseconds when function executes 10 milliseconds', async () => { + const execution = createExecution('sleep 10', {}, true); + execution.start(-1); + await execution.result; + + const node = execution.state.get().ast.chain[0]; + expect(typeof node.debug?.duration).toBe('number'); + expect(node.debug?.duration).toBeLessThan(50); + expect(node.debug?.duration).toBeGreaterThanOrEqual(5); + }); + + test('adds .debug field in expression AST on each executed function', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + for (const node of execution.state.get().ast.chain) { + expect(typeof node.debug).toBe('object'); + expect(!!node.debug).toBe(true); + } + }); + + test('stores input of each function', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + const { chain } = execution.state.get().ast; + + expect(chain[0].debug!.input).toBe(-1); + expect(chain[1].debug!.input).toEqual({ + type: 'num', + value: 0, + }); + expect(chain[2].debug!.input).toEqual({ + type: 'num', + value: 2, + }); + }); + + test('stores output of each function', async () => { + const execution = createExecution('add val=1 | add val=2 | add val=3', {}, true); + execution.start(-1); + await execution.result; + + const { chain } = execution.state.get().ast; + + expect(chain[0].debug!.output).toEqual({ + type: 'num', + value: 0, + }); + expect(chain[1].debug!.output).toEqual({ + type: 'num', + value: 2, + }); + expect(chain[2].debug!.output).toEqual({ + type: 'num', + value: 5, + }); + }); + + test('stores resolved arguments of a function', async () => { + const execution = createExecution( + 'add val={var_set name=foo value=5 | var name=foo} | add val=10', + {}, + true + ); + execution.start(-1); + await execution.result; + + const { chain } = execution.state.get().ast; + + expect(chain[0].debug!.args).toEqual({ + val: 5, + }); + + expect((chain[0].arguments.val[0] as ExpressionAstExpression).chain[0].debug!.args).toEqual( + { + name: 'foo', + value: 5, + } + ); + }); + + test('store debug information about sub-expressions', async () => { + const execution = createExecution( + 'add val={var_set name=foo value=5 | var name=foo} | add val=10', + {}, + true + ); + execution.start(0); + await execution.result; + + const { chain } = execution.state.get().ast.chain[0].arguments + .val[0] as ExpressionAstExpression; + + expect(typeof chain[0].debug).toBe('object'); + expect(typeof chain[1].debug).toBe('object'); + expect(!!chain[0].debug).toBe(true); + expect(!!chain[1].debug).toBe(true); + + expect(chain[0].debug!.input).toBe(0); + expect(chain[0].debug!.output).toBe(0); + expect(chain[1].debug!.input).toBe(0); + expect(chain[1].debug!.output).toBe(5); + }); + }); + + describe('when expression throws', () => { + const executor = createUnitTestExecutor(); + executor.registerFunction({ + name: 'throws', + args: {}, + help: '', + fn: () => { + throw new Error('foo'); + }, + }); + + test('stores debug information up until the function that throws', async () => { + const execution = new Execution({ + executor, + ast: parseExpression('add val=1 | throws | add val=3'), + debug: true, + }); + execution.start(0); + await execution.result; + + const node1 = execution.state.get().ast.chain[0]; + const node2 = execution.state.get().ast.chain[1]; + const node3 = execution.state.get().ast.chain[2]; + + expect(typeof node1.debug).toBe('object'); + expect(typeof node2.debug).toBe('object'); + expect(typeof node3.debug).toBe('undefined'); + }); + + test('stores error thrown in debug information', async () => { + const execution = new Execution({ + executor, + ast: parseExpression('add val=1 | throws | add val=3'), + debug: true, + }); + execution.start(0); + await execution.result; + + const node2 = execution.state.get().ast.chain[1]; + + expect(node2.debug?.error).toMatchObject({ + type: 'error', + error: { + message: '[throws] > foo', + }, + }); + expect(node2.debug?.rawError).toBeInstanceOf(Error); + }); + + test('sets .debug object to expected shape', async () => { + const execution = new Execution({ + executor, + ast: parseExpression('add val=1 | throws | add val=3'), + debug: true, + }); + execution.start(0); + await execution.result; + + const node2 = execution.state.get().ast.chain[1]; + + expect(node2.debug).toMatchObject({ + success: false, + fn: expect.any(Object), + input: expect.any(Object), + args: expect.any(Object), + error: expect.any(Object), + rawError: expect.any(Error), + duration: expect.any(Number), + }); + }); + }); + }); }); diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 2a272e187cffcf..7e7df822724aea 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -23,7 +23,7 @@ import { createExecutionContainer, ExecutionContainer } from './container'; import { createError } from '../util'; import { Defer } from '../../../kibana_utils/common'; import { RequestAdapter, DataAdapter } from '../../../inspector/common'; -import { isExpressionValueError } from '../expression_types/specs/error'; +import { isExpressionValueError, ExpressionValueError } from '../expression_types/specs/error'; import { ExpressionAstExpression, ExpressionAstFunction, @@ -32,7 +32,7 @@ import { parseExpression, } from '../ast'; import { ExecutionContext, DefaultInspectorAdapters } from './types'; -import { getType } from '../expression_types'; +import { getType, ExpressionValue } from '../expression_types'; import { ArgumentType, ExpressionFunction } from '../expression_functions'; import { getByAlias } from '../util/get_by_alias'; import { ExecutionContract } from './execution_contract'; @@ -44,6 +44,13 @@ export interface ExecutionParams< ast?: ExpressionAstExpression; expression?: string; context?: ExtraContext; + + /** + * Whether to execute expression in *debug mode*. In *debug mode* inputs and + * outputs as well as all resolved arguments and time it took to execute each + * function are saved and are available for introspection. + */ + debug?: boolean; } const createDefaultInspectorAdapters = (): DefaultInspectorAdapters => ({ @@ -190,23 +197,55 @@ export class Execution< } const { function: fnName, arguments: fnArgs } = link; - const fnDef = getByAlias(this.state.get().functions, fnName); + const fn = getByAlias(this.state.get().functions, fnName); - if (!fnDef) { + if (!fn) { return createError({ message: `Function ${fnName} could not be found.` }); } + let args: Record = {}; + let timeStart: number | undefined; + try { - // Resolve arguments before passing to function - // resolveArgs returns an object because the arguments themselves might - // actually have a 'then' function which would be treated as a promise - const { resolvedArgs } = await this.resolveArgs(fnDef, input, fnArgs); - const output = await this.invokeFunction(fnDef, input, resolvedArgs); + // `resolveArgs` returns an object because the arguments themselves might + // actually have a `then` function which would be treated as a `Promise`. + const { resolvedArgs } = await this.resolveArgs(fn, input, fnArgs); + args = resolvedArgs; + timeStart = this.params.debug ? performance.now() : 0; + const output = await this.invokeFunction(fn, input, resolvedArgs); + + if (this.params.debug) { + const timeEnd: number = performance.now(); + (link as ExpressionAstFunction).debug = { + success: true, + fn, + input, + args: resolvedArgs, + output, + duration: timeEnd - timeStart, + }; + } + if (getType(output) === 'error') return output; input = output; - } catch (e) { - e.message = `[${fnName}] > ${e.message}`; - return createError(e); + } catch (rawError) { + const timeEnd: number = this.params.debug ? performance.now() : 0; + rawError.message = `[${fnName}] > ${rawError.message}`; + const error = createError(rawError) as ExpressionValueError; + + if (this.params.debug) { + (link as ExpressionAstFunction).debug = { + success: false, + fn, + input, + args, + error, + rawError, + duration: timeStart ? timeEnd - timeStart : undefined, + }; + } + + return error; } } @@ -327,7 +366,9 @@ export class Execution< const resolveArgFns = mapValues(argAstsWithDefaults, (asts, argName) => { return asts.map((item: ExpressionAstExpression) => { return async (subInput = input) => { - const output = await this.params.executor.interpret(item, subInput); + const output = await this.params.executor.interpret(item, subInput, { + debug: this.params.debug, + }); if (isExpressionValueError(output)) throw output.error; const casted = this.cast(output, argDefs[argName as any].types); return casted; diff --git a/src/plugins/expressions/common/executor/executor.ts b/src/plugins/expressions/common/executor/executor.ts index af3662d13de4ef..2ecbc5f75a9e87 100644 --- a/src/plugins/expressions/common/executor/executor.ts +++ b/src/plugins/expressions/common/executor/executor.ts @@ -31,6 +31,15 @@ import { ExpressionAstExpression, ExpressionAstNode } from '../ast'; import { typeSpecs } from '../expression_types/specs'; import { functionSpecs } from '../expression_functions/specs'; +export interface ExpressionExecOptions { + /** + * Whether to execute expression in *debug mode*. In *debug mode* inputs and + * outputs as well as all resolved arguments and time it took to execute each + * function are saved and are available for introspection. + */ + debug?: boolean; +} + export class TypesRegistry implements IRegistry { constructor(private readonly executor: Executor) {} @@ -145,10 +154,14 @@ export class Executor = Record(ast: ExpressionAstNode, input: T): Promise { + public async interpret( + ast: ExpressionAstNode, + input: T, + options?: ExpressionExecOptions + ): Promise { switch (getType(ast)) { case 'expression': - return await this.interpretExpression(ast as ExpressionAstExpression, input); + return await this.interpretExpression(ast as ExpressionAstExpression, input, options); case 'string': case 'number': case 'null': @@ -161,9 +174,10 @@ export class Executor = Record( ast: string | ExpressionAstExpression, - input: T + input: T, + options?: ExpressionExecOptions ): Promise { - const execution = this.createExecution(ast); + const execution = this.createExecution(ast, undefined, options); execution.start(input); return await execution.result; } @@ -192,7 +206,8 @@ export class Executor = Record( ast: string | ExpressionAstExpression, - context: ExtraContext = {} as ExtraContext + context: ExtraContext = {} as ExtraContext, + { debug }: ExpressionExecOptions = {} as ExpressionExecOptions ): Execution { const params: ExecutionParams = { executor: this, @@ -200,6 +215,7 @@ export class Executor = Record Date: Mon, 24 Feb 2020 16:40:20 +0100 Subject: [PATCH 03/73] no sparse array by default. (#58212) Co-authored-by: Elastic Machine --- .../src/types/array_type.test.ts | 37 ++++++++++++++++--- .../kbn-config-schema/src/types/array_type.ts | 4 +- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/packages/kbn-config-schema/src/types/array_type.test.ts b/packages/kbn-config-schema/src/types/array_type.test.ts index 73661ef849cf4f..66b72096a593da 100644 --- a/packages/kbn-config-schema/src/types/array_type.test.ts +++ b/packages/kbn-config-schema/src/types/array_type.test.ts @@ -85,14 +85,29 @@ test('fails if mixed types of content in array', () => { ); }); -test('returns empty array if input is empty but type has default value', () => { - const type = schema.arrayOf(schema.string({ defaultValue: 'test' })); +test('fails if sparse content in array', () => { + const type = schema.arrayOf(schema.string()); expect(type.validate([])).toEqual([]); + expect(() => type.validate([undefined])).toThrowErrorMatchingInlineSnapshot( + `"[0]: sparse array are not allowed"` + ); }); -test('returns empty array if input is empty even if type is required', () => { - const type = schema.arrayOf(schema.string()); +test('fails if sparse content in array if optional', () => { + const type = schema.arrayOf(schema.maybe(schema.string())); + expect(type.validate([])).toEqual([]); + expect(() => type.validate([undefined])).toThrowErrorMatchingInlineSnapshot( + `"[0]: sparse array are not allowed"` + ); +}); + +test('fails if sparse content in array if nullable', () => { + const type = schema.arrayOf(schema.nullable(schema.string())); expect(type.validate([])).toEqual([]); + expect(type.validate([null])).toEqual([null]); + expect(() => type.validate([undefined])).toThrowErrorMatchingInlineSnapshot( + `"[0]: sparse array are not allowed"` + ); }); test('fails for null values if optional', () => { @@ -102,9 +117,19 @@ test('fails for null values if optional', () => { ); }); +test('returns empty array if input is empty but type has default value', () => { + const type = schema.arrayOf(schema.string({ defaultValue: 'test' })); + expect(type.validate([])).toEqual([]); +}); + +test('returns empty array if input is empty even if type is required', () => { + const type = schema.arrayOf(schema.string()); + expect(type.validate([])).toEqual([]); +}); + test('handles default values for undefined values', () => { - const type = schema.arrayOf(schema.string({ defaultValue: 'foo' })); - expect(type.validate([undefined])).toEqual(['foo']); + const type = schema.arrayOf(schema.string(), { defaultValue: ['foo'] }); + expect(type.validate(undefined)).toEqual(['foo']); }); test('array within array', () => { diff --git a/packages/kbn-config-schema/src/types/array_type.ts b/packages/kbn-config-schema/src/types/array_type.ts index ad74f375588ad7..a0353e8348ddd6 100644 --- a/packages/kbn-config-schema/src/types/array_type.ts +++ b/packages/kbn-config-schema/src/types/array_type.ts @@ -31,7 +31,7 @@ export class ArrayType extends Type { let schema = internals .array() .items(type.getSchema().optional()) - .sparse(); + .sparse(false); if (options.minSize !== undefined) { schema = schema.min(options.minSize); @@ -49,6 +49,8 @@ export class ArrayType extends Type { case 'any.required': case 'array.base': return `expected value of type [array] but got [${typeDetect(value)}]`; + case 'array.sparse': + return `sparse array are not allowed`; case 'array.parse': return `could not parse array value from [${value}]`; case 'array.min': From 6b735c9ca016a65cc0c2e29fb144a1046020f1d3 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 24 Feb 2020 11:17:29 -0500 Subject: [PATCH 04/73] [ML] New Platform server shim: update usage collector to use core savedObjects (#58058) * use NP savedObjects and createInternalRepository for usage collection * fix route doc typo * update MlTelemetrySavedObject type * remove fileDataVisualizer routes dependency on legacy es plugin * update mlTelemetry tests * remove deprecated use of getSavedObjectsClient --- x-pack/legacy/plugins/ml/index.ts | 3 +- .../ml/server/lib/ml_telemetry/index.ts | 1 - .../ml_telemetry/make_ml_usage_collector.ts | 15 ++- .../lib/ml_telemetry/ml_telemetry.test.ts | 102 +++++------------- .../server/lib/ml_telemetry/ml_telemetry.ts | 39 +++---- .../plugins/ml/server/new_platform/plugin.ts | 21 ++-- .../ml/server/routes/file_data_visualizer.ts | 2 +- .../ml/server/routes/job_audit_messages.ts | 2 +- 8 files changed, 55 insertions(+), 130 deletions(-) diff --git a/x-pack/legacy/plugins/ml/index.ts b/x-pack/legacy/plugins/ml/index.ts index 0ef5e14e44f718..09f1b9ccedce4f 100755 --- a/x-pack/legacy/plugins/ml/index.ts +++ b/x-pack/legacy/plugins/ml/index.ts @@ -81,7 +81,8 @@ export const ml = (kibana: any) => { injectUiAppVars: server.injectUiAppVars, http: mlHttpService, savedObjects: server.savedObjects, - elasticsearch: kbnServer.newPlatform.setup.core.elasticsearch, // NP + coreSavedObjects: kbnServer.newPlatform.start.core.savedObjects, + elasticsearch: kbnServer.newPlatform.setup.core.elasticsearch, }; const { usageCollection, cloud, home } = kbnServer.newPlatform.setup.plugins; const plugins = { diff --git a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/index.ts b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/index.ts index 5da4f6b62bcec9..dffd95f50e0d95 100644 --- a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/index.ts +++ b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/index.ts @@ -6,7 +6,6 @@ export { createMlTelemetry, - getSavedObjectsClient, incrementFileDataVisualizerIndexCreationCount, storeMlTelemetry, MlTelemetry, diff --git a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts index 293480b2aa5dc8..a120450bbb2b0a 100644 --- a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts +++ b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts @@ -5,19 +5,17 @@ */ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { SavedObjectsServiceStart } from 'src/core/server'; import { createMlTelemetry, - getSavedObjectsClient, ML_TELEMETRY_DOC_ID, MlTelemetry, MlTelemetrySavedObject, } from './ml_telemetry'; -import { UsageInitialization } from '../../new_platform/plugin'; - export function makeMlUsageCollector( usageCollection: UsageCollectionSetup | undefined, - { elasticsearchPlugin, savedObjects }: UsageInitialization + savedObjects: SavedObjectsServiceStart ): void { if (!usageCollection) { return; @@ -28,11 +26,10 @@ export function makeMlUsageCollector( isReady: () => true, fetch: async (): Promise => { try { - const savedObjectsClient = getSavedObjectsClient(elasticsearchPlugin, savedObjects); - const mlTelemetrySavedObject = (await savedObjectsClient.get( - 'ml-telemetry', - ML_TELEMETRY_DOC_ID - )) as MlTelemetrySavedObject; + const mlTelemetrySavedObject: MlTelemetrySavedObject = await savedObjects + .createInternalRepository() + .get('ml-telemetry', ML_TELEMETRY_DOC_ID); + return mlTelemetrySavedObject.attributes; } catch (err) { return createMlTelemetry(); diff --git a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts index fcf3763626b6f6..9d14ffb31be631 100644 --- a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts +++ b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts @@ -6,7 +6,6 @@ import { createMlTelemetry, - getSavedObjectsClient, incrementFileDataVisualizerIndexCreationCount, ML_TELEMETRY_DOC_ID, MlTelemetry, @@ -26,22 +25,11 @@ describe('ml_telemetry', () => { }); describe('storeMlTelemetry', () => { - let elasticsearchPlugin: any; - let savedObjects: any; let mlTelemetry: MlTelemetry; - let savedObjectsClientInstance: any; + let internalRepository: any; beforeEach(() => { - savedObjectsClientInstance = { create: jest.fn() }; - const callWithInternalUser = jest.fn(); - const internalRepository = jest.fn(); - elasticsearchPlugin = { - getCluster: jest.fn(() => ({ callWithInternalUser })), - }; - savedObjects = { - SavedObjectsClient: jest.fn(() => savedObjectsClientInstance), - getSavedObjectsRepository: jest.fn(() => internalRepository), - }; + internalRepository = { create: jest.fn(), get: jest.fn() }; mlTelemetry = { file_data_visualizer: { index_creation_count: 1, @@ -49,59 +37,28 @@ describe('ml_telemetry', () => { }; }); - it('should call savedObjectsClient create with the given MlTelemetry object', () => { - storeMlTelemetry(elasticsearchPlugin, savedObjects, mlTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][1]).toBe(mlTelemetry); + it('should call internalRepository create with the given MlTelemetry object', () => { + storeMlTelemetry(internalRepository, mlTelemetry); + expect(internalRepository.create.mock.calls[0][1]).toBe(mlTelemetry); }); - it('should call savedObjectsClient create with the ml-telemetry document type and ID', () => { - storeMlTelemetry(elasticsearchPlugin, savedObjects, mlTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe('ml-telemetry'); - expect(savedObjectsClientInstance.create.mock.calls[0][2].id).toBe(ML_TELEMETRY_DOC_ID); + it('should call internalRepository create with the ml-telemetry document type and ID', () => { + storeMlTelemetry(internalRepository, mlTelemetry); + expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry'); + expect(internalRepository.create.mock.calls[0][2].id).toBe(ML_TELEMETRY_DOC_ID); }); - it('should call savedObjectsClient create with overwrite: true', () => { - storeMlTelemetry(elasticsearchPlugin, savedObjects, mlTelemetry); - expect(savedObjectsClientInstance.create.mock.calls[0][2].overwrite).toBe(true); - }); - }); - - describe('getSavedObjectsClient', () => { - let elasticsearchPlugin: any; - let savedObjects: any; - let savedObjectsClientInstance: any; - let callWithInternalUser: any; - let internalRepository: any; - - beforeEach(() => { - savedObjectsClientInstance = { create: jest.fn() }; - callWithInternalUser = jest.fn(); - internalRepository = jest.fn(); - elasticsearchPlugin = { - getCluster: jest.fn(() => ({ callWithInternalUser })), - }; - savedObjects = { - SavedObjectsClient: jest.fn(() => savedObjectsClientInstance), - getSavedObjectsRepository: jest.fn(() => internalRepository), - }; - }); - - it('should return a SavedObjectsClient initialized with the saved objects internal repository', () => { - const result = getSavedObjectsClient(elasticsearchPlugin, savedObjects); - - expect(result).toBe(savedObjectsClientInstance); - expect(savedObjects.SavedObjectsClient).toHaveBeenCalledWith(internalRepository); + it('should call internalRepository create with overwrite: true', () => { + storeMlTelemetry(internalRepository, mlTelemetry); + expect(internalRepository.create.mock.calls[0][2].overwrite).toBe(true); }); }); describe('incrementFileDataVisualizerIndexCreationCount', () => { - let elasticsearchPlugin: any; let savedObjects: any; - let savedObjectsClientInstance: any; - let callWithInternalUser: any; let internalRepository: any; - function createSavedObjectsClientInstance( + function createInternalRepositoryInstance( telemetryEnabled?: boolean, indexCreationCount?: number ) { @@ -136,51 +93,42 @@ describe('ml_telemetry', () => { } function mockInit(telemetryEnabled?: boolean, indexCreationCount?: number): void { - savedObjectsClientInstance = createSavedObjectsClientInstance( - telemetryEnabled, - indexCreationCount - ); - callWithInternalUser = jest.fn(); - internalRepository = jest.fn(); + internalRepository = createInternalRepositoryInstance(telemetryEnabled, indexCreationCount); savedObjects = { - SavedObjectsClient: jest.fn(() => savedObjectsClientInstance), - getSavedObjectsRepository: jest.fn(() => internalRepository), - }; - elasticsearchPlugin = { - getCluster: jest.fn(() => ({ callWithInternalUser })), + createInternalRepository: jest.fn(() => internalRepository), }; } it('should not increment if telemetry status cannot be determined', async () => { mockInit(); - await incrementFileDataVisualizerIndexCreationCount(elasticsearchPlugin, savedObjects); + await incrementFileDataVisualizerIndexCreationCount(savedObjects); - expect(savedObjectsClientInstance.create.mock.calls).toHaveLength(0); + expect(internalRepository.create.mock.calls).toHaveLength(0); }); it('should not increment if telemetry status is disabled', async () => { mockInit(false); - await incrementFileDataVisualizerIndexCreationCount(elasticsearchPlugin, savedObjects); + await incrementFileDataVisualizerIndexCreationCount(savedObjects); - expect(savedObjectsClientInstance.create.mock.calls).toHaveLength(0); + expect(internalRepository.create.mock.calls).toHaveLength(0); }); it('should initialize index_creation_count with 1', async () => { mockInit(true); - await incrementFileDataVisualizerIndexCreationCount(elasticsearchPlugin, savedObjects); + await incrementFileDataVisualizerIndexCreationCount(savedObjects); - expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe('ml-telemetry'); - expect(savedObjectsClientInstance.create.mock.calls[0][1]).toEqual({ + expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry'); + expect(internalRepository.create.mock.calls[0][1]).toEqual({ file_data_visualizer: { index_creation_count: 1 }, }); }); it('should increment index_creation_count to 2', async () => { mockInit(true, 1); - await incrementFileDataVisualizerIndexCreationCount(elasticsearchPlugin, savedObjects); + await incrementFileDataVisualizerIndexCreationCount(savedObjects); - expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe('ml-telemetry'); - expect(savedObjectsClientInstance.create.mock.calls[0][1]).toEqual({ + expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry'); + expect(internalRepository.create.mock.calls[0][1]).toEqual({ file_data_visualizer: { index_creation_count: 2 }, }); }); diff --git a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts index 1bac3f17806449..d76b1ee94e21e9 100644 --- a/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts +++ b/x-pack/legacy/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch'; -import { SavedObjectsLegacyService } from 'src/legacy/server/kbn_server'; -import { callWithInternalUserFactory } from '../../client/call_with_internal_user_factory'; +import { + SavedObjectAttributes, + SavedObjectsServiceStart, + ISavedObjectsRepository, +} from 'src/core/server'; -export interface MlTelemetry { +export interface MlTelemetry extends SavedObjectAttributes { file_data_visualizer: { index_creation_count: number; }; @@ -29,35 +31,22 @@ export function createMlTelemetry(count: number = 0): MlTelemetry { } // savedObjects export function storeMlTelemetry( - elasticsearchPlugin: ElasticsearchPlugin, - savedObjects: SavedObjectsLegacyService, + internalRepository: ISavedObjectsRepository, mlTelemetry: MlTelemetry ): void { - const savedObjectsClient = getSavedObjectsClient(elasticsearchPlugin, savedObjects); - savedObjectsClient.create('ml-telemetry', mlTelemetry, { + internalRepository.create('ml-telemetry', mlTelemetry, { id: ML_TELEMETRY_DOC_ID, overwrite: true, }); } -// needs savedObjects and elasticsearchPlugin -export function getSavedObjectsClient( - elasticsearchPlugin: ElasticsearchPlugin, - savedObjects: SavedObjectsLegacyService -): any { - const { SavedObjectsClient, getSavedObjectsRepository } = savedObjects; - const callWithInternalUser = callWithInternalUserFactory(elasticsearchPlugin); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - return new SavedObjectsClient(internalRepository); -} export async function incrementFileDataVisualizerIndexCreationCount( - elasticsearchPlugin: ElasticsearchPlugin, - savedObjects: SavedObjectsLegacyService + savedObjects: SavedObjectsServiceStart ): Promise { - const savedObjectsClient = getSavedObjectsClient(elasticsearchPlugin, savedObjects); - + const internalRepository = await savedObjects.createInternalRepository(); try { - const { attributes } = await savedObjectsClient.get('telemetry', 'telemetry'); + const { attributes } = await internalRepository.get('telemetry', 'telemetry'); + if (attributes.enabled === false) { return; } @@ -70,7 +59,7 @@ export async function incrementFileDataVisualizerIndexCreationCount( let indicesCount = 1; try { - const { attributes } = (await savedObjectsClient.get( + const { attributes } = (await internalRepository.get( 'ml-telemetry', ML_TELEMETRY_DOC_ID )) as MlTelemetrySavedObject; @@ -80,5 +69,5 @@ export async function incrementFileDataVisualizerIndexCreationCount( } const mlTelemetry = createMlTelemetry(indicesCount); - storeMlTelemetry(elasticsearchPlugin, savedObjects, mlTelemetry); + storeMlTelemetry(internalRepository, mlTelemetry); } diff --git a/x-pack/legacy/plugins/ml/server/new_platform/plugin.ts b/x-pack/legacy/plugins/ml/server/new_platform/plugin.ts index 10961182be841a..43c276ac63a13d 100644 --- a/x-pack/legacy/plugins/ml/server/new_platform/plugin.ts +++ b/x-pack/legacy/plugins/ml/server/new_platform/plugin.ts @@ -14,6 +14,7 @@ import { CoreSetup, IRouter, IScopedClusterClient, + SavedObjectsServiceStart, } from 'src/core/server'; import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; @@ -28,12 +29,10 @@ import { LICENSE_TYPE } from '../../common/constants/license'; import { annotationRoutes } from '../routes/annotations'; import { jobRoutes } from '../routes/anomaly_detectors'; import { dataFeedRoutes } from '../routes/datafeeds'; -// @ts-ignore: could not find declaration file for module import { indicesRoutes } from '../routes/indices'; import { jobValidationRoutes } from '../routes/job_validation'; import { makeMlUsageCollector } from '../lib/ml_telemetry'; import { notificationRoutes } from '../routes/notification_settings'; -// @ts-ignore: could not find declaration file for module import { systemRoutes } from '../routes/system'; import { dataFrameAnalyticsRoutes } from '../routes/data_frame_analytics'; import { dataRecognizer } from '../routes/modules'; @@ -45,7 +44,6 @@ import { filtersRoutes } from '../routes/filters'; import { resultsServiceRoutes } from '../routes/results_service'; import { jobServiceRoutes } from '../routes/job_service'; import { jobAuditMessagesRoutes } from '../routes/job_audit_messages'; -// @ts-ignore: could not find declaration file for module import { fileDataVisualizerRoutes } from '../routes/file_data_visualizer'; import { initMlServerLog, LogInitialization } from '../client/log'; import { HomeServerPluginSetup } from '../../../../../../src/plugins/home/server'; @@ -67,6 +65,7 @@ export interface MlCoreSetup { injectUiAppVars: (id: string, callback: () => {}) => any; http: MlHttpServiceSetup; savedObjects: SavedObjectsLegacyService; + coreSavedObjects: SavedObjectsServiceStart; elasticsearch: ElasticsearchServiceSetup; } export interface MlInitializerContext extends PluginInitializerContext { @@ -93,15 +92,11 @@ export interface RouteInitialization { route(route: ServerRoute | ServerRoute[]): void; router: IRouter; xpackMainPlugin: MlXpackMainPlugin; - savedObjects?: SavedObjectsLegacyService; + savedObjects?: SavedObjectsServiceStart; spacesPlugin: any; securityPlugin: any; cloud?: CloudSetup; } -export interface UsageInitialization { - elasticsearchPlugin: ElasticsearchPlugin; - savedObjects: SavedObjectsLegacyService; -} declare module 'kibana/server' { interface RequestHandlerContext { @@ -123,7 +118,7 @@ export class Plugin { public setup(core: MlCoreSetup, plugins: PluginsSetup) { const xpackMainPlugin: MlXpackMainPlugin = plugins.xpackMain; - const { http } = core; + const { http, coreSavedObjects } = core; const pluginId = this.pluginId; mirrorPluginStatus(xpackMainPlugin, plugins.ml); @@ -208,14 +203,10 @@ export class Plugin { const extendedRouteInitializationDeps: RouteInitialization = { ...routeInitializationDeps, config: this.config, - savedObjects: core.savedObjects, + savedObjects: coreSavedObjects, spacesPlugin: plugins.spaces, cloud: plugins.cloud, }; - const usageInitializationDeps: UsageInitialization = { - elasticsearchPlugin: plugins.elasticsearch, - savedObjects: core.savedObjects, - }; const logInitializationDeps: LogInitialization = { log: this.log, @@ -240,7 +231,7 @@ export class Plugin { fileDataVisualizerRoutes(extendedRouteInitializationDeps); initMlServerLog(logInitializationDeps); - makeMlUsageCollector(plugins.usageCollection, usageInitializationDeps); + makeMlUsageCollector(plugins.usageCollection, coreSavedObjects); } public stop() {} diff --git a/x-pack/legacy/plugins/ml/server/routes/file_data_visualizer.ts b/x-pack/legacy/plugins/ml/server/routes/file_data_visualizer.ts index 95f2a9fe7298f0..d5a992c9332930 100644 --- a/x-pack/legacy/plugins/ml/server/routes/file_data_visualizer.ts +++ b/x-pack/legacy/plugins/ml/server/routes/file_data_visualizer.ts @@ -138,7 +138,7 @@ export function fileDataVisualizerRoutes({ // follow-up import calls to just add additional data will include the `id` of the created // index, we'll ignore those and don't increment the counter. if (id === undefined) { - await incrementFileDataVisualizerIndexCreationCount(elasticsearchPlugin, savedObjects!); + await incrementFileDataVisualizerIndexCreationCount(savedObjects!); } const result = await importData( diff --git a/x-pack/legacy/plugins/ml/server/routes/job_audit_messages.ts b/x-pack/legacy/plugins/ml/server/routes/job_audit_messages.ts index 72983129900052..76986b935b993a 100644 --- a/x-pack/legacy/plugins/ml/server/routes/job_audit_messages.ts +++ b/x-pack/legacy/plugins/ml/server/routes/job_audit_messages.ts @@ -50,7 +50,7 @@ export function jobAuditMessagesRoutes({ xpackMainPlugin, router }: RouteInitial /** * @apiGroup JobAuditMessages * - * @api {get} /api/ml/results/anomalies_table_data Get all audit messages + * @api {get} /api/ml/job_audit_messages/messages Get all audit messages * @apiName GetAllJobAuditMessages * @apiDescription Returns all audit messages */ From c6f5fdd061d93ad0d67335a658449be92e24640c Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Mon, 24 Feb 2020 17:42:34 +0100 Subject: [PATCH 05/73] Advanced settings UI change to centralize save state (#53693) --- .../advanced_settings/public/_index.scss | 2 +- .../public/management_app/_index.scss | 3 + .../management_app/advanced_settings.scss | 40 +- .../management_app/advanced_settings.tsx | 16 +- .../management_app/components/_index.scss | 1 + .../field/__snapshots__/field.test.tsx.snap | 7069 ++++++++--------- .../components/field/field.test.tsx | 267 +- .../management_app/components/field/field.tsx | 545 +- .../management_app/components/field/index.ts | 2 +- .../form/__snapshots__/form.test.tsx.snap | 1228 ++- .../management_app/components/form/_form.scss | 13 + .../components/form/_index.scss | 1 + .../components/form/form.test.tsx | 114 +- .../management_app/components/form/form.tsx | 280 +- .../public/management_app/types.ts | 13 + .../telemetry_management_section.tsx | 54 +- test/functional/page_objects/settings_page.ts | 6 +- .../translations/translations/ja-JP.json | 11 - .../translations/translations/zh-CN.json | 10 - 19 files changed, 5086 insertions(+), 4589 deletions(-) create mode 100644 src/plugins/advanced_settings/public/management_app/_index.scss create mode 100644 src/plugins/advanced_settings/public/management_app/components/_index.scss create mode 100644 src/plugins/advanced_settings/public/management_app/components/form/_form.scss create mode 100644 src/plugins/advanced_settings/public/management_app/components/form/_index.scss diff --git a/src/plugins/advanced_settings/public/_index.scss b/src/plugins/advanced_settings/public/_index.scss index f3fe78bf6a9c01..d13c37bff32d00 100644 --- a/src/plugins/advanced_settings/public/_index.scss +++ b/src/plugins/advanced_settings/public/_index.scss @@ -17,4 +17,4 @@ * under the License. */ - @import './management_app/advanced_settings'; +@import './management_app/index'; diff --git a/src/plugins/advanced_settings/public/management_app/_index.scss b/src/plugins/advanced_settings/public/management_app/_index.scss new file mode 100644 index 00000000000000..aa1980692f7b7a --- /dev/null +++ b/src/plugins/advanced_settings/public/management_app/_index.scss @@ -0,0 +1,3 @@ +@import './advanced_settings'; + +@import './components/index'; diff --git a/src/plugins/advanced_settings/public/management_app/advanced_settings.scss b/src/plugins/advanced_settings/public/management_app/advanced_settings.scss index 79b6feccb6b7d6..016edb2817da82 100644 --- a/src/plugins/advanced_settings/public/management_app/advanced_settings.scss +++ b/src/plugins/advanced_settings/public/management_app/advanced_settings.scss @@ -17,21 +17,27 @@ * under the License. */ -.mgtAdvancedSettings__field { + .mgtAdvancedSettings__field { + * { margin-top: $euiSize; } - &Wrapper { - width: 640px; - @include internetExplorerOnly() { - min-height: 1px; - } + padding-left: $euiSizeS; + margin-left: -$euiSizeS; + &--unsaved { + // Simulates a left side border without shifting content + box-shadow: -$euiSizeXS 0px $euiColorSecondary; } - - &Actions { - padding-top: $euiSizeM; + &--invalid { + // Simulates a left side border without shifting content + box-shadow: -$euiSizeXS 0px $euiColorDanger; + } + @include internetExplorerOnly() { + min-height: 1px; + } + &Row { + padding-left: $euiSizeS; } @include internetExplorerOnly { @@ -40,3 +46,19 @@ } } } + +.mgtAdvancedSettingsForm__unsavedCount { + @include euiBreakpoint('xs', 's') { + display: none; + } +} + +.mgtAdvancedSettingsForm__unsavedCountMessage{ + // Simulates a left side border without shifting content + box-shadow: -$euiSizeXS 0px $euiColorSecondary; + padding-left: $euiSizeS; +} + +.mgtAdvancedSettingsForm__button { + width: 100%; +} diff --git a/src/plugins/advanced_settings/public/management_app/advanced_settings.tsx b/src/plugins/advanced_settings/public/management_app/advanced_settings.tsx index 5057d072e3e415..39312c9340ff9e 100644 --- a/src/plugins/advanced_settings/public/management_app/advanced_settings.tsx +++ b/src/plugins/advanced_settings/public/management_app/advanced_settings.tsx @@ -38,7 +38,7 @@ import { ComponentRegistry } from '../'; import { getAriaName, toEditableConfig, DEFAULT_CATEGORY } from './lib'; -import { FieldSetting, IQuery } from './types'; +import { FieldSetting, IQuery, SettingsChanges } from './types'; interface AdvancedSettingsProps { enableSaving: boolean; @@ -177,6 +177,13 @@ export class AdvancedSettingsComponent extends Component< }); }; + saveConfig = async (changes: SettingsChanges) => { + const arr = Object.entries(changes).map(([key, value]) => + this.props.uiSettings.set(key, value) + ); + return Promise.all(arr); + }; + render() { const { filteredSettings, query, footerQueryMatched } = this.state; const componentRegistry = this.props.componentRegistry; @@ -205,18 +212,19 @@ export class AdvancedSettingsComponent extends Component<
+
+ + } + fullWidth={true} + title={ +

+ Array test setting + +

+ } > - - -
- - } - title={ -

- Array test setting - -

- } - > - - - - - - - + + + `; exports[`Field for array setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - default_value - , - } - } - /> - - - - - } - title={ -

- Array test setting - -

- } - > - + default_value + , + } + } /> - - } - isInvalid={false} - label="array:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ Array test setting + +

+ } +> + - - - - - - + + } + label="array:test:setting" + labelType="label" + > + +
+ `; exports[`Field for array setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Array test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Array test setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + `; exports[`Field for array setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Array test setting + +

+ } > - - -
- - } - title={ -

- Array test setting - -

- } - > - + + +`; + +exports[`Field for array setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Array test setting + + } + type="asterisk" + /> +

+ } +> + + + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for array setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + default_value + , + } + } /> - - - - default_value - , - } - } - /> - - - - } - title={ -

- Array test setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="array:test:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ Array test setting + +

+ } +> + + + + + +     + + + } + label="array:test:setting" + labelType="label" + > + + + `; exports[`Field for boolean setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Boolean test setting + +

+ } > - - -
- - } - title={ -

- Boolean test setting - -

- } - > - - - } - onChange={[Function]} - onKeyDown={[Function]} + - - - - - + } + onChange={[Function]} + /> + + `; exports[`Field for boolean setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - true - , - } - } - /> - - - - - } - title={ -

- Boolean test setting - -

- } - > - + true + , + } + } /> - - } - isInvalid={false} - label="boolean:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ Boolean test setting + +

+ } +> + - - } - onChange={[Function]} - onKeyDown={[Function]} + + + } + label="boolean:test:setting" + labelType="label" + > + - - - - - + } + onChange={[Function]} + /> +
+ `; exports[`Field for boolean setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Boolean test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Boolean test setting - - } - type="asterisk" - /> -

- } - > - - - } - onChange={[Function]} - onKeyDown={[Function]} + - - - - - + } + onChange={[Function]} + /> + + `; exports[`Field for boolean setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Boolean test setting + +

+ } > - - -
- - } - title={ -

- Boolean test setting - -

+ } - > - - + onChange={[Function]} + /> + + +`; + +exports[`Field for boolean setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Boolean test setting + + } + type="asterisk" + /> +

+ } +> + + - - - - - + } + onChange={[Function]} + /> + +

+ Setting is currently not saved. +

+
+ + `; exports[`Field for boolean setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + true + , + } + } /> - - - - true - , - } - } - /> - - - - } - title={ -

- Boolean test setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="boolean:test:setting" - labelType="label" - > - + + + } + fullWidth={true} + title={ +

+ Boolean test setting + +

+ } +> + + + - } - onChange={[Function]} - onKeyDown={[Function]} + +     + + + } + label="boolean:test:setting" + labelType="label" + > + - - - - - + } + onChange={[Function]} + /> +
+ `; exports[`Field for image setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Image test setting + +

+ } > - - -
- - } - title={ -

- Image test setting - -

- } - > - - - - - - - + + + `; exports[`Field for image setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - null - , - } - } - /> - - - - - } - title={ -

- Image test setting - -

- } - > - + null + , + } + } /> - - } - isInvalid={false} - label="image:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ Image test setting + +

+ } +> + - - - - - - + + } + label="image:test:setting" + labelType="label" + > + +
+ `; exports[`Field for image setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Image test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Image test setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + `; exports[`Field for image setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Image test setting + +

+ } > - - -
- - } - title={ -

- Image test setting - -

- } - > - + + +`; + +exports[`Field for image setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Image test setting + + } + type="asterisk" + /> +

+ } +> + + + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for image setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + null + , + } + } /> - - - - null - , - } - } - /> - - - - } - title={ -

- Image test setting - -

- } - > - - - - - -     - - - - - - - - } - isInvalid={false} - label="image:test:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ Image test setting + +

+ } +> + + + + + +     + + + + + + + + } + label="image:test:setting" + labelType="label" + > + + + `; exports[`Field for json setting should render as read only if saving is disabled 1`] = ` - - - -
+ description={ + +
+ + + - + {} + , + } + } /> - - - - {} - , - } - } - /> - - - - } - title={ -

- Json test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Json test setting + +

+ } +> + +
- -
- -
-
- - - - + +
+
+ `; exports[`Field for json setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - + {} + , + } + } /> - - - - {} - , - } - } - /> - - - - } - title={ -

- Json test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Json test setting + +

+ } +> + + + + } + label="json:test:setting" + labelType="label" + > +
- - - + -
- -
-
- - - - + fullWidth={true} + height="auto" + isReadOnly={true} + maxLines={30} + minLines={6} + mode="json" + onChange={[Function]} + setOptions={ + Object { + "showLineNumbers": false, + "tabSize": 2, + } + } + showGutter={false} + theme="textmate" + value="{\\"hello\\": \\"world\\"}" + width="100%" + /> +
+
+ `; exports[`Field for json setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Json test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Json test setting - - } - type="asterisk" - /> -

- } +
- -
- -
-
- - - - + +
+ + `; exports[`Field for json setting should render default value if there is no user value set 1`] = ` - - - -
+ description={ + +
+ + + - + {} + , + } + } /> - - - - {} - , - } - } - /> - - - - } - title={ -

- Json test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Json test setting + +

+ } +> + + + + + +     + + + } + label="json:test:setting" + labelType="label" + > +
- - - - - -     - - - } - isInvalid={false} - label="json:test:setting" - labelType="label" + +
+
+ +`; + +exports[`Field for json setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Json test setting + + } + type="asterisk" + /> +

+ } +> + +
+ +
+ +

-

- -
-
- - - - + Setting is currently not saved. +

+ + + `; exports[`Field for json setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + {} + , + } + } /> - - - - {} - , - } - } - /> - - - - } - title={ -

- Json test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Json test setting + +

+ } +> + + + + + +     + + + } + label="json:test:setting" + labelType="label" + > +
- - - - - -     - - - } - isInvalid={false} - label="json:test:setting" - labelType="label" - > -
- -
-
- - - - + +
+
+ `; exports[`Field for markdown setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Markdown test setting + +

+ } > - - -
- - } - title={ -

- Markdown test setting - -

- } +
- -
- -
-
- - - - + +
+ + `; exports[`Field for markdown setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - + null + , + } + } /> - - - - null - , - } - } - /> - - - - } - title={ -

- Markdown test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Markdown test setting + +

+ } +> + + + + } + label="markdown:test:setting" + labelType="label" + > +
- - - + -
- -
-
- - - - + fullWidth={true} + height="auto" + isReadOnly={true} + maxLines={30} + minLines={6} + mode="markdown" + onChange={[Function]} + setOptions={ + Object { + "showLineNumbers": false, + "tabSize": 2, + } + } + showGutter={false} + theme="textmate" + value="**bold**" + width="100%" + /> +
+
+ `; exports[`Field for markdown setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Markdown test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Markdown test setting - - } - type="asterisk" - /> -

- } +
- -
- -
-
- - - - + +
+ + `; exports[`Field for markdown setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Markdown test setting + +

+ } > - - -
- - } - title={ -

- Markdown test setting - -

- } +
+ +
+ + +`; + +exports[`Field for markdown setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Markdown test setting + + } + type="asterisk" + /> +

+ } +> + +
- +
+ +

-

- -
-
- - - - + Setting is currently not saved. +

+ + + `; exports[`Field for markdown setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + null + , + } + } /> - - - - null - , - } - } - /> - - - - } - title={ -

- Markdown test setting - -

- } + + + + } + fullWidth={true} + title={ +

+ Markdown test setting + +

+ } +> + + + + + +     + + + } + label="markdown:test:setting" + labelType="label" + > +
- - - - - -     - - - } - isInvalid={false} - label="markdown:test:setting" - labelType="label" - > -
- -
-
- - - - + +
+
+ `; exports[`Field for number setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Number test setting + +

+ } > - - -
- - } - title={ -

- Number test setting - -

- } - > - - - - - - - + + + `; exports[`Field for number setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - 5 - , - } - } - /> - - - - - } - title={ -

- Number test setting - -

- } - > - + 5 + , + } + } /> - - } - isInvalid={false} - label="number:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ Number test setting + +

+ } +> + - - - - - - + + } + label="number:test:setting" + labelType="label" + > + +
+ `; exports[`Field for number setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Number test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Number test setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + +`; + +exports[`Field for number setting should render default value if there is no user value set 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Number test setting + +

+ } +> + + + + `; -exports[`Field for number setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Number test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Number test setting - -

- } - > - + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for number setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + 5 + , + } + } /> - - - - 5 - , - } - } - /> - - - - } - title={ -

- Number test setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="number:test:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ Number test setting + +

+ } +> + + + + + +     + + + } + label="number:test:setting" + labelType="label" + > + + + `; exports[`Field for select setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Select test setting + +

+ } > - - -
- - } - title={ -

- Select test setting - -

- } - > - - - - - - - + + + `; exports[`Field for select setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - Orange - , - } - } - /> - - - - - } - title={ -

- Select test setting - -

- } - > - + Orange + , + } + } /> - - } - isInvalid={false} - label="select:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ Select test setting + +

+ } +> + - - - - - - + + } + label="select:test:setting" + labelType="label" + > + +
+ `; exports[`Field for select setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Select test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- Select test setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + `; exports[`Field for select setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ Select test setting + +

+ } > - - -
- - } - title={ -

- Select test setting - -

- } - > - + + +`; + +exports[`Field for select setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ Select test setting + + } + type="asterisk" + /> +

+ } +> + + + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for select setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + Orange + , + } + } /> - - - - Orange - , - } - } - /> - - - - } - title={ -

- Select test setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="select:test:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ Select test setting + +

+ } +> + + + + + +     + + + } + label="select:test:setting" + labelType="label" + > + + + `; exports[`Field for string setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test setting + +

+ } > - - -
- - } - title={ -

- String test setting - -

- } - > - - - - - - - + + + `; exports[`Field for string setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - null - , - } - } - /> - - - - - } - title={ -

- String test setting - -

- } - > - + null + , + } + } /> - - } - isInvalid={false} - label="string:test:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ String test setting + +

+ } +> + - - - - - - + + } + label="string:test:setting" + labelType="label" + > + +
+ `; exports[`Field for string setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- String test setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + `; exports[`Field for string setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test setting + +

+ } > - - -
- - } - title={ -

- String test setting - -

- } - > - + + +`; + +exports[`Field for string setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ String test setting + + } + type="asterisk" + /> +

+ } +> + + + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for string setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + null + , + } + } /> - - - - null - , - } - } - /> - - - - } - title={ -

- String test setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="string:test:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ String test setting + +

+ } +> + + + + + +     + + + } + label="string:test:setting" + labelType="label" + > + + + `; exports[`Field for stringWithValidation setting should render as read only if saving is disabled 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test validation setting + +

+ } > - - -
- - } - title={ -

- String test validation setting - -

- } - > - - - - - - - + + + `; exports[`Field for stringWithValidation setting should render as read only with help text if overridden 1`] = ` - - - -
+ description={ + +
+ + + - - - - - foo-default - , - } - } - /> - - - - - } - title={ -

- String test validation setting - -

- } - > - + foo-default + , + } + } /> - - } - isInvalid={false} - label="string:test-validation:setting" - labelType="label" + + + + + } + fullWidth={true} + title={ +

+ String test validation setting + +

+ } +> + - - - - - - + + } + label="string:test-validation:setting" + labelType="label" + > + +
+ `; exports[`Field for stringWithValidation setting should render custom setting icon if it is custom 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test validation setting + + } + type="asterisk" + /> +

+ } > - - -
- - } - title={ -

- String test validation setting - - } - type="asterisk" - /> -

- } - > - - - - - - - + + + `; exports[`Field for stringWithValidation setting should render default value if there is no user value set 1`] = ` - +
+ + } + fullWidth={true} + title={ +

+ String test validation setting + +

+ } > - - -
- - } - title={ -

- String test validation setting - -

- } - > - + + +`; + +exports[`Field for stringWithValidation setting should render unsaved value if there are unsaved changes 1`] = ` + +
+ + } + fullWidth={true} + title={ +

+ String test validation setting + + } + type="asterisk" + /> +

+ } +> + + + +

- - - - - - + Setting is currently not saved. +

+
+
+ `; exports[`Field for stringWithValidation setting should render user value if there is user value is set 1`] = ` - - - -
+ description={ + +
+ + + - + foo-default + , + } + } /> - - - - foo-default - , - } - } - /> - - - - } - title={ -

- String test validation setting - -

- } - > - - - - - -     - - - } - isInvalid={false} - label="string:test-validation:setting" - labelType="label" - > - - - - - - + + + + } + fullWidth={true} + title={ +

+ String test validation setting + +

+ } +> + + + + + +     + + + } + label="string:test-validation:setting" + labelType="label" + > + + + `; diff --git a/src/plugins/advanced_settings/public/management_app/components/field/field.test.tsx b/src/plugins/advanced_settings/public/management_app/components/field/field.test.tsx index 81df22ccf6e43d..8e41fed6858986 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/field.test.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/field/field.test.tsx @@ -20,21 +20,14 @@ import React from 'react'; import { I18nProvider } from '@kbn/i18n/react'; import { shallowWithI18nProvider, mountWithI18nProvider } from 'test_utils/enzyme_helpers'; -import { mount } from 'enzyme'; +import { mount, ReactWrapper } from 'enzyme'; import { FieldSetting } from '../../types'; import { UiSettingsType, StringValidation } from '../../../../../../core/public'; import { notificationServiceMock, docLinksServiceMock } from '../../../../../../core/public/mocks'; // @ts-ignore import { findTestSubject } from '@elastic/eui/lib/test'; -import { Field } from './field'; - -jest.mock('ui/notify', () => ({ - toastNotifications: { - addDanger: () => {}, - add: jest.fn(), - }, -})); +import { Field, getEditableValue } from './field'; jest.mock('brace/theme/textmate', () => 'brace/theme/textmate'); jest.mock('brace/mode/markdown', () => 'brace/mode/markdown'); @@ -45,6 +38,18 @@ const defaults = { category: ['category'], }; +const exampleValues = { + array: ['example_value'], + boolean: false, + image: 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=', + json: { foo: 'bar2' }, + markdown: 'Hello World', + number: 1, + select: 'banana', + string: 'hello world', + stringWithValidation: 'foo', +}; + const settings: Record = { array: { name: 'array:test:setting', @@ -161,7 +166,7 @@ const settings: Record = { description: 'Description for String test validation setting', type: 'string', validation: { - regex: new RegExp('/^foo'), + regex: new RegExp('^foo'), message: 'must start with "foo"', }, value: undefined, @@ -182,11 +187,22 @@ const userValues = { string: 'foo', stringWithValidation: 'fooUserValue', }; + const invalidUserValues = { stringWithValidation: 'invalidUserValue', }; -const save = jest.fn(() => Promise.resolve(true)); -const clear = jest.fn(() => Promise.resolve(true)); + +const handleChange = jest.fn(); +const clearChange = jest.fn(); + +const getFieldSettingValue = (wrapper: ReactWrapper, name: string, type: string) => { + const field = findTestSubject(wrapper, `advancedSetting-editField-${name}`); + if (type === 'boolean') { + return field.props()['aria-checked']; + } else { + return field.props().value; + } +}; describe('Field', () => { Object.keys(settings).forEach(type => { @@ -197,8 +213,7 @@ describe('Field', () => { const component = shallowWithI18nProvider( { value: userValues[type], isOverridden: true, }} - save={save} - clear={clear} + handleChange={handleChange} enableSaving={true} toasts={notificationServiceMock.createStartContract().toasts} dockLinks={docLinksServiceMock.createStartContract().links} @@ -232,14 +246,12 @@ describe('Field', () => { const component = shallowWithI18nProvider( ); - expect(component).toMatchSnapshot(); }); @@ -251,8 +263,7 @@ describe('Field', () => { // @ts-ignore value: userValues[type], }} - save={save} - clear={clear} + handleChange={handleChange} enableSaving={true} toasts={notificationServiceMock.createStartContract().toasts} dockLinks={docLinksServiceMock.createStartContract().links} @@ -269,48 +280,44 @@ describe('Field', () => { ...setting, isCustom: true, }} - save={save} - clear={clear} + handleChange={handleChange} enableSaving={true} toasts={notificationServiceMock.createStartContract().toasts} dockLinks={docLinksServiceMock.createStartContract().links} /> ); - expect(component).toMatchSnapshot(); }); - }); - - if (type === 'select') { - it('should use options for rendering values', () => { - const component = mountWithI18nProvider( + it('should render unsaved value if there are unsaved changes', async () => { + const component = shallowWithI18nProvider( ); - const select = findTestSubject(component, `advancedSetting-editField-${setting.name}`); - // @ts-ignore - const labels = select.find('option').map(option => option.prop('value')); - expect(labels).toEqual(['apple', 'orange', 'banana']); + expect(component).toMatchSnapshot(); }); + }); - it('should use optionLabels for rendering labels', () => { + if (type === 'select') { + it('should use options for rendering values and optionsLabels for rendering labels', () => { const component = mountWithI18nProvider( { ); const select = findTestSubject(component, `advancedSetting-editField-${setting.name}`); // @ts-ignore + const values = select.find('option').map(option => option.prop('value')); + expect(values).toEqual(['apple', 'orange', 'banana']); + // @ts-ignore const labels = select.find('option').map(option => option.text()); expect(labels).toEqual(['Apple', 'Orange', 'banana']); }); @@ -328,8 +338,8 @@ describe('Field', () => { { const userValue = userValues[type]; (component.instance() as Field).getImageAsBase64 = ({}: Blob) => Promise.resolve(''); - it('should be able to change value from no value and cancel', async () => { - await (component.instance() as Field).onImageChange([userValue]); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-cancelEditField-${setting.name}`).simulate( - 'click' - ); - expect( - (component.instance() as Field).state.unsavedValue === - (component.instance() as Field).state.savedValue - ).toBe(true); - }); - - it('should be able to change value and save', async () => { - await (component.instance() as Field).onImageChange([userValue]); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-saveEditField-${setting.name}`).simulate( - 'click' - ); - expect(save).toBeCalled(); - component.setState({ savedValue: userValue }); + it('should be able to change value and cancel', async () => { + (component.instance() as Field).onImageChange([userValue]); + expect(handleChange).toBeCalled(); await wrapper.setProps({ + unsavedChanges: { + value: userValue, + changeImage: true, + }, setting: { ...(component.instance() as Field).props.setting, value: userValue, }, }); - await (component.instance() as Field).cancelChangeImage(); + expect(clearChange).toBeCalledWith(setting.name); wrapper.update(); }); - it('should be able to change value from existing value and save', async () => { + it('should be able to change value from existing value', async () => { + await wrapper.setProps({ + unsavedChanges: {}, + }); const updated = wrapper.update(); findTestSubject(updated, `advancedSetting-changeImage-${setting.name}`).simulate('click'); - const newUserValue = `${userValue}=`; await (component.instance() as Field).onImageChange([newUserValue]); - const updated2 = wrapper.update(); - findTestSubject(updated2, `advancedSetting-saveEditField-${setting.name}`).simulate( - 'click' - ); - expect(save).toBeCalled(); - component.setState({ savedValue: newUserValue }); - await wrapper.setProps({ - setting: { - ...(component.instance() as Field).props.setting, - value: newUserValue, - }, - }); - wrapper.update(); + expect(handleChange).toBeCalled(); }); it('should be able to reset to default value', async () => { const updated = wrapper.update(); findTestSubject(updated, `advancedSetting-resetField-${setting.name}`).simulate('click'); - expect(clear).toBeCalled(); + expect(handleChange).toBeCalledWith(setting.name, { + value: getEditableValue(setting.type, setting.defVal), + changeImage: true, + }); }); }); } else if (type === 'markdown' || type === 'json') { describe(`for changing ${type} setting`, () => { const { wrapper, component } = setup(); const userValue = userValues[type]; - const fieldUserValue = userValue; - - it('should be able to change value and cancel', async () => { - (component.instance() as Field).onCodeEditorChange(fieldUserValue as UiSettingsType); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-cancelEditField-${setting.name}`).simulate( - 'click' - ); - expect( - (component.instance() as Field).state.unsavedValue === - (component.instance() as Field).state.savedValue - ).toBe(true); - }); - it('should be able to change value and save', async () => { - (component.instance() as Field).onCodeEditorChange(fieldUserValue as UiSettingsType); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-saveEditField-${setting.name}`).simulate( - 'click' - ); - expect(save).toBeCalled(); - component.setState({ savedValue: fieldUserValue }); + it('should be able to change value', async () => { + (component.instance() as Field).onCodeEditorChange(userValue as UiSettingsType); + expect(handleChange).toBeCalledWith(setting.name, { value: userValue }); await wrapper.setProps({ setting: { ...(component.instance() as Field).props.setting, @@ -445,19 +417,21 @@ describe('Field', () => { wrapper.update(); }); + it('should be able to reset to default value', async () => { + const updated = wrapper.update(); + findTestSubject(updated, `advancedSetting-resetField-${setting.name}`).simulate('click'); + expect(handleChange).toBeCalledWith(setting.name, { + value: getEditableValue(setting.type, setting.defVal), + }); + }); + if (type === 'json') { it('should be able to clear value and have empty object populate', async () => { - (component.instance() as Field).onCodeEditorChange('' as UiSettingsType); + await (component.instance() as Field).onCodeEditorChange('' as UiSettingsType); wrapper.update(); - expect((component.instance() as Field).state.unsavedValue).toEqual('{}'); + expect(handleChange).toBeCalledWith(setting.name, { value: setting.defVal }); }); } - - it('should be able to reset to default value', async () => { - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-resetField-${setting.name}`).simulate('click'); - expect(clear).toBeCalled(); - }); }); } else { describe(`for changing ${type} setting`, () => { @@ -470,76 +444,45 @@ describe('Field', () => { // @ts-ignore const invalidUserValue = invalidUserValues[type]; it('should display an error when validation fails', async () => { - (component.instance() as Field).onFieldChange(invalidUserValue); + await (component.instance() as Field).onFieldChange(invalidUserValue); + const expectedUnsavedChanges = { + value: invalidUserValue, + error: (setting.validation as StringValidation).message, + isInvalid: true, + }; + expect(handleChange).toBeCalledWith(setting.name, expectedUnsavedChanges); + wrapper.setProps({ unsavedChanges: expectedUnsavedChanges }); const updated = wrapper.update(); const errorMessage = updated.find('.euiFormErrorText').text(); - expect(errorMessage).toEqual((setting.validation as StringValidation).message); + expect(errorMessage).toEqual(expectedUnsavedChanges.error); }); } - it('should be able to change value and cancel', async () => { - (component.instance() as Field).onFieldChange(fieldUserValue); + it('should be able to change value', async () => { + await (component.instance() as Field).onFieldChange(fieldUserValue); const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-cancelEditField-${setting.name}`).simulate( - 'click' - ); - expect( - (component.instance() as Field).state.unsavedValue === - (component.instance() as Field).state.savedValue - ).toBe(true); + expect(handleChange).toBeCalledWith(setting.name, { value: fieldUserValue }); + updated.setProps({ unsavedChanges: { value: fieldUserValue } }); + const currentValue = getFieldSettingValue(updated, setting.name, type); + expect(currentValue).toEqual(fieldUserValue); }); - it('should be able to change value and save', async () => { - (component.instance() as Field).onFieldChange(fieldUserValue); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-saveEditField-${setting.name}`).simulate( - 'click' - ); - expect(save).toBeCalled(); - component.setState({ savedValue: fieldUserValue }); + it('should be able to reset to default value', async () => { await wrapper.setProps({ - setting: { - ...(component.instance() as Field).props.setting, - value: userValue, - }, + unsavedChanges: {}, + setting: { ...setting, value: fieldUserValue }, }); - wrapper.update(); - }); - - it('should be able to reset to default value', async () => { const updated = wrapper.update(); findTestSubject(updated, `advancedSetting-resetField-${setting.name}`).simulate('click'); - expect(clear).toBeCalled(); + const expectedEditableValue = getEditableValue(setting.type, setting.defVal); + expect(handleChange).toBeCalledWith(setting.name, { + value: expectedEditableValue, + }); + updated.setProps({ unsavedChanges: { value: expectedEditableValue } }); + const currentValue = getFieldSettingValue(updated, setting.name, type); + expect(currentValue).toEqual(expectedEditableValue); }); }); } }); - - it('should show a reload toast when saving setting requiring a page reload', async () => { - const setting = { - ...settings.string, - requiresPageReload: true, - }; - const toasts = notificationServiceMock.createStartContract().toasts; - const wrapper = mountWithI18nProvider( - - ); - (wrapper.instance() as Field).onFieldChange({ target: { value: 'a new value' } }); - const updated = wrapper.update(); - findTestSubject(updated, `advancedSetting-saveEditField-${setting.name}`).simulate('click'); - expect(save).toHaveBeenCalled(); - await save(); - expect(toasts.add).toHaveBeenCalledWith( - expect.objectContaining({ - title: expect.stringContaining('Please reload the page'), - }) - ); - }); }); diff --git a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx index 7158e3d5e7b3e6..d9c3752d1c0a50 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx @@ -18,17 +18,16 @@ */ import React, { PureComponent, Fragment } from 'react'; -import ReactDOM from 'react-dom'; +import classNames from 'classnames'; import 'brace/theme/textmate'; import 'brace/mode/markdown'; import { EuiBadge, - EuiButton, - EuiButtonEmpty, EuiCode, EuiCodeBlock, + EuiScreenReaderOnly, // @ts-ignore EuiCodeEditor, EuiDescribedFormGroup, @@ -36,23 +35,20 @@ import { EuiFieldText, // @ts-ignore EuiFilePicker, - EuiFlexGroup, - EuiFlexItem, EuiFormRow, EuiIconTip, EuiImage, EuiLink, EuiSpacer, - EuiToolTip, EuiText, EuiSelect, EuiSwitch, EuiSwitchEvent, - keyCodes, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { FieldSetting } from '../../types'; +import { FieldSetting, FieldState } from '../../types'; import { isDefaultValue } from '../../lib'; import { UiSettingsType, @@ -64,71 +60,37 @@ import { interface FieldProps { setting: FieldSetting; - save: (name: string, value: string) => Promise; - clear: (name: string) => Promise; + handleChange: (name: string, value: FieldState) => void; enableSaving: boolean; dockLinks: DocLinksStart['links']; toasts: ToastsStart; + clearChange?: (name: string) => void; + unsavedChanges?: FieldState; + loading?: boolean; } -interface FieldState { - unsavedValue: any; - savedValue: any; - loading: boolean; - isInvalid: boolean; - error: string | null; - changeImage: boolean; - isJsonArray: boolean; -} - -export class Field extends PureComponent { - private changeImageForm: EuiFilePicker | undefined; - constructor(props: FieldProps) { - super(props); - const { type, value, defVal } = this.props.setting; - const editableValue = this.getEditableValue(type, value, defVal); - - this.state = { - isInvalid: false, - error: null, - loading: false, - changeImage: false, - savedValue: editableValue, - unsavedValue: editableValue, - isJsonArray: type === 'json' ? Array.isArray(JSON.parse(String(defVal) || '{}')) : false, - }; - } - - UNSAFE_componentWillReceiveProps(nextProps: FieldProps) { - const { unsavedValue } = this.state; - const { type, value, defVal } = nextProps.setting; - const editableValue = this.getEditableValue(type, value, defVal); - - this.setState({ - savedValue: editableValue, - unsavedValue: value === null || value === undefined ? editableValue : unsavedValue, - }); +export const getEditableValue = ( + type: UiSettingsType, + value: FieldSetting['value'], + defVal?: FieldSetting['defVal'] +) => { + const val = value === null || value === undefined ? defVal : value; + switch (type) { + case 'array': + return (val as string[]).join(', '); + case 'boolean': + return !!val; + case 'number': + return Number(val); + case 'image': + return val; + default: + return val || ''; } +}; - getEditableValue( - type: UiSettingsType, - value: FieldSetting['value'], - defVal: FieldSetting['defVal'] - ) { - const val = value === null || value === undefined ? defVal : value; - switch (type) { - case 'array': - return (val as string[]).join(', '); - case 'boolean': - return !!val; - case 'number': - return Number(val); - case 'image': - return val; - default: - return val || ''; - } - } +export class Field extends PureComponent { + private changeImageForm: EuiFilePicker | undefined = React.createRef(); getDisplayedDefaultValue( type: UiSettingsType, @@ -150,47 +112,60 @@ export class Field extends PureComponent { } } - setLoading(loading: boolean) { - this.setState({ - loading, - }); - } + handleChange = (unsavedChanges: FieldState) => { + this.props.handleChange(this.props.setting.name, unsavedChanges); + }; - clearError() { - this.setState({ - isInvalid: false, - error: null, - }); + resetField = () => { + const { type, defVal } = this.props.setting; + if (type === 'image') { + this.cancelChangeImage(); + return this.handleChange({ + value: getEditableValue(type, defVal), + changeImage: true, + }); + } + return this.handleChange({ value: getEditableValue(type, defVal) }); + }; + + componentDidUpdate(prevProps: FieldProps) { + if ( + prevProps.setting.type === 'image' && + prevProps.unsavedChanges?.value && + !this.props.unsavedChanges?.value + ) { + this.cancelChangeImage(); + } } onCodeEditorChange = (value: UiSettingsType) => { - const { type } = this.props.setting; - const { isJsonArray } = this.state; + const { defVal, type } = this.props.setting; let newUnsavedValue; - let isInvalid = false; - let error = null; + let errorParams = {}; switch (type) { case 'json': + const isJsonArray = Array.isArray(JSON.parse((defVal as string) || '{}')); newUnsavedValue = value.trim() || (isJsonArray ? '[]' : '{}'); try { JSON.parse(newUnsavedValue); } catch (e) { - isInvalid = true; - error = i18n.translate('advancedSettings.field.codeEditorSyntaxErrorMessage', { - defaultMessage: 'Invalid JSON syntax', - }); + errorParams = { + error: i18n.translate('advancedSettings.field.codeEditorSyntaxErrorMessage', { + defaultMessage: 'Invalid JSON syntax', + }), + isInvalid: true, + }; } break; default: newUnsavedValue = value; } - this.setState({ - error, - isInvalid, - unsavedValue: newUnsavedValue, + this.handleChange({ + value: newUnsavedValue, + ...errorParams, }); }; @@ -201,58 +176,44 @@ export class Field extends PureComponent { onFieldChangeEvent = (e: React.ChangeEvent) => this.onFieldChange(e.target.value); - onFieldChange = (value: any) => { - const { type, validation } = this.props.setting; - const { unsavedValue } = this.state; - + onFieldChange = (targetValue: any) => { + const { type, validation, value, defVal } = this.props.setting; let newUnsavedValue; switch (type) { case 'boolean': - newUnsavedValue = !unsavedValue; + const { unsavedChanges } = this.props; + const currentValue = unsavedChanges + ? unsavedChanges.value + : getEditableValue(type, value, defVal); + newUnsavedValue = !currentValue; break; case 'number': - newUnsavedValue = Number(value); + newUnsavedValue = Number(targetValue); break; default: - newUnsavedValue = value; + newUnsavedValue = targetValue; } - let isInvalid = false; - let error = null; + let errorParams = {}; - if (validation && (validation as StringValidationRegex).regex) { + if ((validation as StringValidationRegex)?.regex) { if (!(validation as StringValidationRegex).regex!.test(newUnsavedValue.toString())) { - error = (validation as StringValidationRegex).message; - isInvalid = true; + errorParams = { + error: (validation as StringValidationRegex).message, + isInvalid: true, + }; } } - this.setState({ - unsavedValue: newUnsavedValue, - isInvalid, - error, + this.handleChange({ + value: newUnsavedValue, + ...errorParams, }); }; - onFieldKeyDown = ({ keyCode }: { keyCode: number }) => { - if (keyCode === keyCodes.ENTER) { - this.saveEdit(); - } - if (keyCode === keyCodes.ESCAPE) { - this.cancelEdit(); - } - }; - - onFieldEscape = ({ keyCode }: { keyCode: number }) => { - if (keyCode === keyCodes.ESCAPE) { - this.cancelEdit(); - } - }; - onImageChange = async (files: any[]) => { if (!files.length) { - this.clearError(); this.setState({ unsavedValue: null, }); @@ -266,19 +227,24 @@ export class Field extends PureComponent { if (file instanceof File) { base64Image = (await this.getImageAsBase64(file)) as string; } - const isInvalid = !!(maxSize && maxSize.length && base64Image.length > maxSize.length); - this.setState({ - isInvalid, - error: isInvalid - ? i18n.translate('advancedSettings.field.imageTooLargeErrorMessage', { - defaultMessage: 'Image is too large, maximum size is {maxSizeDescription}', - values: { - maxSizeDescription: maxSize.description, - }, - }) - : null, + + let errorParams = {}; + const isInvalid = !!(maxSize?.length && base64Image.length > maxSize.length); + if (isInvalid) { + errorParams = { + isInvalid, + error: i18n.translate('advancedSettings.field.imageTooLargeErrorMessage', { + defaultMessage: 'Image is too large, maximum size is {maxSizeDescription}', + values: { + maxSizeDescription: maxSize.description, + }, + }), + }; + } + this.handleChange({ changeImage: true, - unsavedValue: base64Image, + value: base64Image, + ...errorParams, }); } catch (err) { this.props.toasts.addDanger( @@ -305,152 +271,62 @@ export class Field extends PureComponent { } changeImage = () => { - this.setState({ + this.handleChange({ + value: null, changeImage: true, }); }; cancelChangeImage = () => { - const { savedValue } = this.state; - - if (this.changeImageForm) { - this.changeImageForm.fileInput.value = null; - this.changeImageForm.handleChange(); - } - - this.setState({ - changeImage: false, - unsavedValue: savedValue, - }); - }; - - cancelEdit = () => { - const { savedValue } = this.state; - this.clearError(); - this.setState({ - unsavedValue: savedValue, - }); - }; - - showPageReloadToast = () => { - if (this.props.setting.requiresPageReload) { - this.props.toasts.add({ - title: i18n.translate('advancedSettings.field.requiresPageReloadToastDescription', { - defaultMessage: 'Please reload the page for the "{settingName}" setting to take effect.', - values: { - settingName: this.props.setting.displayName || this.props.setting.name, - }, - }), - text: element => { - const content = ( - <> - - - window.location.reload()}> - {i18n.translate('advancedSettings.field.requiresPageReloadToastButtonLabel', { - defaultMessage: 'Reload page', - })} - - - - - ); - ReactDOM.render(content, element); - return () => ReactDOM.unmountComponentAtNode(element); - }, - color: 'success', - }); - } - }; - - saveEdit = async () => { - const { name, defVal, type } = this.props.setting; - const { changeImage, savedValue, unsavedValue, isJsonArray } = this.state; - - if (savedValue === unsavedValue) { - return; - } - - let valueToSave = unsavedValue; - let isSameValue = false; - - switch (type) { - case 'array': - valueToSave = valueToSave.split(',').map((val: string) => val.trim()); - isSameValue = valueToSave.join(',') === (defVal as string[]).join(','); - break; - case 'json': - valueToSave = valueToSave.trim(); - valueToSave = valueToSave || (isJsonArray ? '[]' : '{}'); - default: - isSameValue = valueToSave === defVal; - } - - this.setLoading(true); - try { - if (isSameValue) { - await this.props.clear(name); - } else { - await this.props.save(name, valueToSave); - } - - this.showPageReloadToast(); - - if (changeImage) { - this.cancelChangeImage(); - } - } catch (e) { - this.props.toasts.addDanger( - i18n.translate('advancedSettings.field.saveFieldErrorMessage', { - defaultMessage: 'Unable to save {name}', - values: { name }, - }) - ); + if (this.changeImageForm.current) { + this.changeImageForm.current.fileInput.value = null; + this.changeImageForm.current.handleChange({}); } - this.setLoading(false); - }; - - resetField = async () => { - const { name } = this.props.setting; - this.setLoading(true); - try { - await this.props.clear(name); - this.showPageReloadToast(); - this.cancelChangeImage(); - this.clearError(); - } catch (e) { - this.props.toasts.addDanger( - i18n.translate('advancedSettings.field.resetFieldErrorMessage', { - defaultMessage: 'Unable to reset {name}', - values: { name }, - }) - ); + if (this.props.clearChange) { + this.props.clearChange(this.props.setting.name); } - this.setLoading(false); }; - renderField(setting: FieldSetting) { - const { enableSaving } = this.props; - const { loading, changeImage, unsavedValue } = this.state; - const { name, value, type, options, optionLabels = {}, isOverridden, ariaName } = setting; + renderField(id: string, setting: FieldSetting) { + const { enableSaving, unsavedChanges, loading } = this.props; + const { + name, + value, + type, + options, + optionLabels = {}, + isOverridden, + defVal, + ariaName, + } = setting; + const a11yProps: { [key: string]: string } = unsavedChanges + ? { + 'aria-label': ariaName, + 'aria-describedby': id, + } + : { + 'aria-label': ariaName, + }; + const currentValue = unsavedChanges + ? unsavedChanges.value + : getEditableValue(type, value, defVal); switch (type) { case 'boolean': return ( ) : ( ) } - checked={!!unsavedValue} + checked={!!currentValue} onChange={this.onFieldChangeSwitch} disabled={loading || isOverridden || !enableSaving} - onKeyDown={this.onFieldKeyDown} data-test-subj={`advancedSetting-editField-${name}`} - aria-label={ariaName} + {...a11yProps} /> ); case 'markdown': @@ -458,10 +334,10 @@ export class Field extends PureComponent { return (
{ $blockScrolling: Infinity, }} showGutter={false} + fullWidth />
); case 'image': + const changeImage = unsavedChanges?.changeImage; if (!isDefaultValue(setting) && !changeImage) { - return ( - - ); + return ; } else { return ( { - this.changeImageForm = input; - }} - onKeyDown={this.onFieldEscape} + ref={this.changeImageForm} + fullWidth data-test-subj={`advancedSetting-editField-${name}`} /> ); @@ -501,8 +375,8 @@ export class Field extends PureComponent { case 'select': return ( { return { text: optionLabels.hasOwnProperty(option) ? optionLabels[option] : option, @@ -512,31 +386,31 @@ export class Field extends PureComponent { onChange={this.onFieldChangeEvent} isLoading={loading} disabled={loading || isOverridden || !enableSaving} - onKeyDown={this.onFieldKeyDown} + fullWidth data-test-subj={`advancedSetting-editField-${name}`} /> ); case 'number': return ( ); default: return ( ); @@ -699,8 +573,12 @@ export class Field extends PureComponent { } renderResetToDefaultLink(setting: FieldSetting) { - const { ariaName, name } = setting; - if (isDefaultValue(setting)) { + const { defVal, ariaName, name } = setting; + if ( + defVal === this.props.unsavedChanges?.value || + isDefaultValue(setting) || + this.props.loading + ) { return; } return ( @@ -726,7 +604,7 @@ export class Field extends PureComponent { } renderChangeImageLink(setting: FieldSetting) { - const { changeImage } = this.state; + const changeImage = this.props.unsavedChanges?.changeImage; const { type, value, ariaName, name } = setting; if (type !== 'image' || !value || changeImage) { return; @@ -752,84 +630,49 @@ export class Field extends PureComponent { ); } - renderActions(setting: FieldSetting) { - const { ariaName, name } = setting; - const { loading, isInvalid, changeImage, savedValue, unsavedValue } = this.state; - const isDisabled = loading || setting.isOverridden; - - if (savedValue === unsavedValue && !changeImage) { - return; - } - - return ( - - - - - - - - - (changeImage ? this.cancelChangeImage() : this.cancelEdit())} - disabled={isDisabled} - data-test-subj={`advancedSetting-cancelEditField-${name}`} - > - - - - - - ); - } - render() { - const { setting } = this.props; - const { error, isInvalid } = this.state; + const { setting, unsavedChanges } = this.props; + const error = unsavedChanges?.error; + const isInvalid = unsavedChanges?.isInvalid; + + const className = classNames('mgtAdvancedSettings__field', { + 'mgtAdvancedSettings__field--unsaved': unsavedChanges, + 'mgtAdvancedSettings__field--invalid': isInvalid, + }); + const id = setting.name; return ( - - - - - {this.renderField(setting)} - - - - {this.renderActions(setting)} - + + + <> + {this.renderField(id, setting)} + {unsavedChanges && ( + +

+ {unsavedChanges.error + ? unsavedChanges.error + : i18n.translate('advancedSettings.field.settingIsUnsaved', { + defaultMessage: 'Setting is currently not saved.', + })} +

+
+ )} + +
+
); } } diff --git a/src/plugins/advanced_settings/public/management_app/components/field/index.ts b/src/plugins/advanced_settings/public/management_app/components/field/index.ts index 5c86519116fe9f..d1b9b34515532e 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/index.ts +++ b/src/plugins/advanced_settings/public/management_app/components/field/index.ts @@ -17,4 +17,4 @@ * under the License. */ -export { Field } from './field'; +export { Field, getEditableValue } from './field'; diff --git a/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap b/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap index 8c471f5f5be9cf..bce9cb67537dbc 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap +++ b/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap @@ -1,449 +1,849 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Form should not render no settings message when instructed not to 1`] = ``; +exports[`Form should not render no settings message when instructed not to 1`] = ` + +
+ + + + + +

+ General +

+
+
+
+ + + +
+
+ + + + + + +

+ Dashboard +

+
+
+
+ + +
+
+ + + + + + +

+ X-pack +

+
+ + + + + + + , + "settingsCount": 9, + } + } + /> + + +
+
+ + +
+
+ +
+
+`; exports[`Form should render no settings message when there are no settings 1`] = ` - - + + + + - - , - } - } + +

+ General +

+
+
+
+ + + +
+
+ -
+ + + + + +

+ Dashboard +

+
+
+
+ + +
+
+ + + + + + +

+ X-pack +

+
+ + + + + + + , + "settingsCount": 9, + } + } + /> + + +
+
+ + +
+
+ +
`; exports[`Form should render normally 1`] = ` - - - - - + + + + -

- General -

-
-
-
- - +

+ General +

+ + + + + - + -
-
- - - - - - + + + + + + + -

- Dashboard -

- -
-
- - +

+ Dashboard +

+ + + + + -
-
- - - - - - -

- X-pack -

-
- +
+
+ + + + + - - - - - - , - "settingsCount": 9, + +

+ X-pack +

+
+ + + + + + + , + "settingsCount": 9, + } } - } - /> - - -
-
- - + + + + + + -
-
- + toasts={Object {}} + /> + + + +
`; exports[`Form should render read-only when saving is disabled 1`] = ` - - - - - + + + + -

- General -

-
-
-
- - +

+ General +

+
+
+ + + - + - - - - - - - - + + + + + + + -

- Dashboard -

- -
-
- - +

+ Dashboard +

+ + + + + -
-
- - - - - - -

- X-pack -

-
- +
+
+ + + + + - - - - - - , - "settingsCount": 9, + +

+ X-pack +

+
+ + + + + + + , + "settingsCount": 9, + } } - } - /> - - -
-
- - + + + + + + -
-
- + toasts={Object {}} + /> + + + +
`; diff --git a/src/plugins/advanced_settings/public/management_app/components/form/_form.scss b/src/plugins/advanced_settings/public/management_app/components/form/_form.scss new file mode 100644 index 00000000000000..02ebb90221d90f --- /dev/null +++ b/src/plugins/advanced_settings/public/management_app/components/form/_form.scss @@ -0,0 +1,13 @@ +@import '@elastic/eui/src/components/header/variables'; +@import '@elastic/eui/src/components/nav_drawer/variables'; + +.mgtAdvancedSettingsForm__bottomBar { + margin-left: $euiNavDrawerWidthCollapsed; + z-index: 9; // Puts it inuder the nav drawer when expanded + &--pushForNav { + margin-left: $euiNavDrawerWidthExpanded; + } + @include euiBreakpoint('xs', 's') { + margin-left: 0; + } +} diff --git a/src/plugins/advanced_settings/public/management_app/components/form/_index.scss b/src/plugins/advanced_settings/public/management_app/components/form/_index.scss new file mode 100644 index 00000000000000..2ef4ef1d20ce99 --- /dev/null +++ b/src/plugins/advanced_settings/public/management_app/components/form/_index.scss @@ -0,0 +1 @@ +@import './form'; diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx index 468cfbfc708205..0e942665b23a9e 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/form/form.test.tsx @@ -18,9 +18,14 @@ */ import React from 'react'; -import { shallowWithI18nProvider } from 'test_utils/enzyme_helpers'; +import { shallowWithI18nProvider, mountWithI18nProvider } from 'test_utils/enzyme_helpers'; import { UiSettingsType } from '../../../../../../core/public'; +// @ts-ignore +import { findTestSubject } from '@elastic/eui/lib/test'; + +import { notificationServiceMock } from '../../../../../../core/public/mocks'; +import { SettingsChanges } from '../../types'; import { Form } from './form'; jest.mock('../field', () => ({ @@ -29,6 +34,25 @@ jest.mock('../field', () => ({ }, })); +beforeAll(() => { + const localStorage: Record = { + 'core.chrome.isLocked': true, + }; + + Object.defineProperty(window, 'localStorage', { + value: { + getItem: (key: string) => { + return localStorage[key] || null; + }, + }, + writable: true, + }); +}); + +afterAll(() => { + delete (window as any).localStorage; +}); + const defaults = { requiresPageReload: false, readOnly: false, @@ -43,50 +67,52 @@ const defaults = { const settings = { dashboard: [ { + ...defaults, name: 'dashboard:test:setting', ariaName: 'dashboard test setting', displayName: 'Dashboard test setting', category: ['dashboard'], - ...defaults, + requiresPageReload: true, }, ], general: [ { + ...defaults, name: 'general:test:date', ariaName: 'general test date', displayName: 'Test date', description: 'bar', category: ['general'], - ...defaults, }, { + ...defaults, name: 'setting:test', ariaName: 'setting test', displayName: 'Test setting', description: 'foo', category: ['general'], - ...defaults, }, ], 'x-pack': [ { + ...defaults, name: 'xpack:test:setting', ariaName: 'xpack test setting', displayName: 'X-Pack test setting', category: ['x-pack'], description: 'bar', - ...defaults, }, ], }; + const categories = ['general', 'dashboard', 'hiddenCategory', 'x-pack']; const categoryCounts = { general: 2, dashboard: 1, 'x-pack': 10, }; -const save = (key: string, value: any) => Promise.resolve(true); -const clear = (key: string) => Promise.resolve(true); +const save = jest.fn((changes: SettingsChanges) => Promise.resolve([true])); + const clearQuery = () => {}; describe('Form', () => { @@ -94,10 +120,10 @@ describe('Form', () => { const component = shallowWithI18nProvider( { const component = shallowWithI18nProvider( { const component = shallowWithI18nProvider( { const component = shallowWithI18nProvider( { expect(component).toMatchSnapshot(); }); + + it('should hide bottom bar when clicking on the cancel changes button', async () => { + const wrapper = mountWithI18nProvider( + + ); + (wrapper.instance() as Form).setState({ + unsavedChanges: { + 'dashboard:test:setting': { + value: 'changedValue', + }, + }, + }); + const updated = wrapper.update(); + expect(updated.exists('[data-test-subj="advancedSetting-bottomBar"]')).toEqual(true); + await findTestSubject(updated, `advancedSetting-cancelButton`).simulate('click'); + updated.update(); + expect(updated.exists('[data-test-subj="advancedSetting-bottomBar"]')).toEqual(false); + }); + + it('should show a reload toast when saving setting requiring a page reload', async () => { + const toasts = notificationServiceMock.createStartContract().toasts; + const wrapper = mountWithI18nProvider( + + ); + (wrapper.instance() as Form).setState({ + unsavedChanges: { + 'dashboard:test:setting': { + value: 'changedValue', + }, + }, + }); + const updated = wrapper.update(); + + findTestSubject(updated, `advancedSetting-saveButton`).simulate('click'); + expect(save).toHaveBeenCalled(); + await save({ 'dashboard:test:setting': 'changedValue' }); + expect(toasts.add).toHaveBeenCalledWith( + expect.objectContaining({ + title: expect.stringContaining( + 'One or more settings require you to reload the page to take effect.' + ), + }) + ); + }); }); diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx index 91d587866836ee..ef433dd990d33a 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx @@ -18,7 +18,7 @@ */ import React, { PureComponent, Fragment } from 'react'; - +import classNames from 'classnames'; import { EuiFlexGroup, EuiFlexItem, @@ -27,30 +27,188 @@ import { EuiPanel, EuiSpacer, EuiText, + EuiTextColor, + EuiBottomBar, + EuiButton, + EuiToolTip, + EuiButtonEmpty, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; +import { isEmpty } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { toMountPoint } from '../../../../../kibana_react/public'; import { DocLinksStart, ToastsStart } from '../../../../../../core/public'; import { getCategoryName } from '../../lib'; -import { Field } from '../field'; -import { FieldSetting } from '../../types'; +import { Field, getEditableValue } from '../field'; +import { FieldSetting, SettingsChanges, FieldState } from '../../types'; type Category = string; +const NAV_IS_LOCKED_KEY = 'core.chrome.isLocked'; interface FormProps { settings: Record; + visibleSettings: Record; categories: Category[]; categoryCounts: Record; clearQuery: () => void; - save: (key: string, value: any) => Promise; - clear: (key: string) => Promise; + save: (changes: SettingsChanges) => Promise; showNoResultsMessage: boolean; enableSaving: boolean; dockLinks: DocLinksStart['links']; toasts: ToastsStart; } +interface FormState { + unsavedChanges: { + [key: string]: FieldState; + }; + loading: boolean; +} + export class Form extends PureComponent { + state: FormState = { + unsavedChanges: {}, + loading: false, + }; + + setLoading(loading: boolean) { + this.setState({ + loading, + }); + } + + getSettingByKey = (key: string): FieldSetting | undefined => { + return Object.values(this.props.settings) + .flat() + .find(el => el.name === key); + }; + + getCountOfUnsavedChanges = (): number => { + return Object.keys(this.state.unsavedChanges).length; + }; + + getCountOfHiddenUnsavedChanges = (): number => { + const shownSettings = Object.values(this.props.visibleSettings) + .flat() + .map(setting => setting.name); + return Object.keys(this.state.unsavedChanges).filter(key => !shownSettings.includes(key)) + .length; + }; + + areChangesInvalid = (): boolean => { + const { unsavedChanges } = this.state; + return Object.values(unsavedChanges).some(({ isInvalid }) => isInvalid); + }; + + handleChange = (key: string, change: FieldState) => { + const setting = this.getSettingByKey(key); + if (!setting) { + return; + } + const { type, defVal, value } = setting; + const savedValue = getEditableValue(type, value, defVal); + if (change.value === savedValue) { + return this.clearChange(key); + } + this.setState({ + unsavedChanges: { + ...this.state.unsavedChanges, + [key]: change, + }, + }); + }; + + clearChange = (key: string) => { + if (!this.state.unsavedChanges[key]) { + return; + } + const unsavedChanges = { ...this.state.unsavedChanges }; + delete unsavedChanges[key]; + + this.setState({ + unsavedChanges, + }); + }; + + clearAllUnsaved = () => { + this.setState({ unsavedChanges: {} }); + }; + + saveAll = async () => { + this.setLoading(true); + const { unsavedChanges } = this.state; + + if (isEmpty(unsavedChanges)) { + return; + } + const configToSave: SettingsChanges = {}; + let requiresReload = false; + + Object.entries(unsavedChanges).forEach(([name, { value }]) => { + const setting = this.getSettingByKey(name); + if (!setting) { + return; + } + const { defVal, type, requiresPageReload } = setting; + let valueToSave = value; + let equalsToDefault = false; + switch (type) { + case 'array': + valueToSave = valueToSave.split(',').map((val: string) => val.trim()); + equalsToDefault = valueToSave.join(',') === (defVal as string[]).join(','); + break; + case 'json': + const isArray = Array.isArray(JSON.parse((defVal as string) || '{}')); + valueToSave = valueToSave.trim(); + valueToSave = valueToSave || (isArray ? '[]' : '{}'); + default: + equalsToDefault = valueToSave === defVal; + } + if (requiresPageReload) { + requiresReload = true; + } + configToSave[name] = equalsToDefault ? null : valueToSave; + }); + + try { + await this.props.save(configToSave); + this.clearAllUnsaved(); + if (requiresReload) { + this.renderPageReloadToast(); + } + } catch (e) { + this.props.toasts.addDanger( + i18n.translate('advancedSettings.form.saveErrorMessage', { + defaultMessage: 'Unable to save', + }) + ); + } + this.setLoading(false); + }; + + renderPageReloadToast = () => { + this.props.toasts.add({ + title: i18n.translate('advancedSettings.form.requiresPageReloadToastDescription', { + defaultMessage: 'One or more settings require you to reload the page to take effect.', + }), + text: toMountPoint( + <> + + + window.location.reload()}> + {i18n.translate('advancedSettings.form.requiresPageReloadToastButtonLabel', { + defaultMessage: 'Reload page', + })} + + + + + ), + color: 'success', + }); + }; + renderClearQueryLink(totalSettings: number, currentSettings: number) { const { clearQuery } = this.props; @@ -102,8 +260,9 @@ export class Form extends PureComponent { { return null; } + renderCountOfUnsaved = () => { + const unsavedCount = this.getCountOfUnsavedChanges(); + const hiddenUnsavedCount = this.getCountOfHiddenUnsavedChanges(); + return ( + + + + ); + }; + + renderBottomBar = () => { + const areChangesInvalid = this.areChangesInvalid(); + const bottomBarClasses = classNames('mgtAdvancedSettingsForm__bottomBar', { + 'mgtAdvancedSettingsForm__bottomBar--pushForNav': + localStorage.getItem(NAV_IS_LOCKED_KEY) === 'true', + }); + return ( + + + +

{this.renderCountOfUnsaved()}

+
+ + + + + {i18n.translate('advancedSettings.form.cancelButtonLabel', { + defaultMessage: 'Cancel changes', + })} + + + + + + {i18n.translate('advancedSettings.form.saveButtonLabel', { + defaultMessage: 'Save changes', + })} + + + + + +
+
+ ); + }; + render() { - const { settings, categories, categoryCounts, clearQuery } = this.props; + const { unsavedChanges } = this.state; + const { visibleSettings, categories, categoryCounts, clearQuery } = this.props; const currentCategories: Category[] = []; categories.forEach(category => { - if (settings[category] && settings[category].length) { + if (visibleSettings[category] && visibleSettings[category].length) { currentCategories.push(category); } }); return ( - {currentCategories.length - ? currentCategories.map(category => { - return this.renderCategory(category, settings[category], categoryCounts[category]); - }) - : this.maybeRenderNoSettings(clearQuery)} +
+ {currentCategories.length + ? currentCategories.map(category => { + return this.renderCategory( + category, + visibleSettings[category], + categoryCounts[category] + ); + }) + : this.maybeRenderNoSettings(clearQuery)} +
+ {!isEmpty(unsavedChanges) && this.renderBottomBar()}
); } diff --git a/src/plugins/advanced_settings/public/management_app/types.ts b/src/plugins/advanced_settings/public/management_app/types.ts index 05bb5e754563dc..d44a05ce36f5d2 100644 --- a/src/plugins/advanced_settings/public/management_app/types.ts +++ b/src/plugins/advanced_settings/public/management_app/types.ts @@ -47,6 +47,19 @@ export interface FieldSetting { } // until eui searchbar and query are typed + +export interface SettingsChanges { + [key: string]: any; +} + +export interface FieldState { + value?: any; + changeImage?: boolean; + loading?: boolean; + isInvalid?: boolean; + error?: string | null; +} + export interface IQuery { ast: any; // incomplete text: string; diff --git a/src/plugins/telemetry/public/components/telemetry_management_section.tsx b/src/plugins/telemetry/public/components/telemetry_management_section.tsx index 20c8873b132727..bf14c33a480481 100644 --- a/src/plugins/telemetry/public/components/telemetry_management_section.tsx +++ b/src/plugins/telemetry/public/components/telemetry_management_section.tsx @@ -33,8 +33,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { PRIVACY_STATEMENT_URL } from '../../common/constants'; import { OptInExampleFlyout } from './opt_in_example_flyout'; -// @ts-ignore import { Field } from '../../../advanced_settings/public'; +import { ToastsStart } from '../../../../core/public/'; import { TelemetryService } from '../services/telemetry_service'; const SEARCH_TERMS = ['telemetry', 'usage', 'data', 'usage data']; @@ -44,12 +44,14 @@ interface Props { showAppliesSettingMessage: boolean; enableSaving: boolean; query?: any; + toasts: ToastsStart; } interface State { processing: boolean; showExample: boolean; queryMatches: boolean | null; + enabled: boolean; } export class TelemetryManagementSection extends Component { @@ -57,6 +59,7 @@ export class TelemetryManagementSection extends Component { processing: false, showExample: false, queryMatches: null, + enabled: this.props.telemetryService.getIsOptedIn() || false, }; UNSAFE_componentWillReceiveProps(nextProps: Props) { @@ -79,7 +82,7 @@ export class TelemetryManagementSection extends Component { render() { const { telemetryService } = this.props; - const { showExample, queryMatches } = this.state; + const { showExample, queryMatches, enabled, processing } = this.state; if (!telemetryService.getCanChangeOptInStatus()) { return null; @@ -119,7 +122,7 @@ export class TelemetryManagementSection extends Component { displayName: i18n.translate('telemetry.provideUsageStatisticsTitle', { defaultMessage: 'Provide usage statistics', }), - value: telemetryService.getIsOptedIn(), + value: enabled, description: this.renderDescription(), defVal: true, ariaName: i18n.translate('telemetry.provideUsageStatisticsAriaName', { @@ -127,10 +130,10 @@ export class TelemetryManagementSection extends Component { }), } as any } + loading={processing} dockLinks={null as any} toasts={null as any} - save={this.toggleOptIn} - clear={this.toggleOptIn} + handleChange={this.toggleOptIn} enableSaving={this.props.enableSaving} /> @@ -151,13 +154,13 @@ export class TelemetryManagementSection extends Component {

), @@ -200,20 +203,35 @@ export class TelemetryManagementSection extends Component { ); toggleOptIn = async (): Promise => { - const { telemetryService } = this.props; - const newOptInValue = !telemetryService.getIsOptedIn(); + const { telemetryService, toasts } = this.props; + const newOptInValue = !this.state.enabled; return new Promise((resolve, reject) => { - this.setState({ processing: true }, async () => { - try { - await telemetryService.setOptIn(newOptInValue); - this.setState({ processing: false }); - resolve(true); - } catch (err) { - this.setState({ processing: false }); - reject(err); + this.setState( + { + processing: true, + enabled: newOptInValue, + }, + async () => { + try { + await telemetryService.setOptIn(newOptInValue); + this.setState({ processing: false }); + toasts.addSuccess( + newOptInValue + ? i18n.translate('telemetry.optInSuccessOn', { + defaultMessage: 'Usage data collection turned on.', + }) + : i18n.translate('telemetry.optInSuccessOff', { + defaultMessage: 'Usage data collection turned off.', + }) + ); + resolve(true); + } catch (err) { + this.setState({ processing: false }); + reject(err); + } } - }); + ); }); }; diff --git a/test/functional/page_objects/settings_page.ts b/test/functional/page_objects/settings_page.ts index d7e5064cf72805..ff340c6b0abcde 100644 --- a/test/functional/page_objects/settings_page.ts +++ b/test/functional/page_objects/settings_page.ts @@ -94,7 +94,7 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider `[data-test-subj="advancedSetting-editField-${propertyName}"] option[value="${propertyValue}"]` ); await PageObjects.header.waitUntilLoadingHasFinished(); - await testSubjects.click(`advancedSetting-saveEditField-${propertyName}`); + await testSubjects.click(`advancedSetting-saveButton`); await PageObjects.header.waitUntilLoadingHasFinished(); } @@ -102,14 +102,14 @@ export function SettingsPageProvider({ getService, getPageObjects }: FtrProvider const input = await testSubjects.find(`advancedSetting-editField-${propertyName}`); await input.clearValue(); await input.type(propertyValue); - await testSubjects.click(`advancedSetting-saveEditField-${propertyName}`); + await testSubjects.click(`advancedSetting-saveButton`); await PageObjects.header.waitUntilLoadingHasFinished(); } async toggleAdvancedSettingCheckbox(propertyName: string) { testSubjects.click(`advancedSetting-editField-${propertyName}`); await PageObjects.header.waitUntilLoadingHasFinished(); - await testSubjects.click(`advancedSetting-saveEditField-${propertyName}`); + await testSubjects.click(`advancedSetting-saveButton`); await PageObjects.header.waitUntilLoadingHasFinished(); } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 4b06645cdfe043..78bb39dd22dea1 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1618,8 +1618,6 @@ "advancedSettings.categoryNames.timelionLabel": "Timelion", "advancedSettings.categoryNames.visualizationsLabel": "ビジュアライゼーション", "advancedSettings.categorySearchLabel": "カテゴリー", - "advancedSettings.field.cancelEditingButtonAriaLabel": "{ariaName} の編集をキャンセル", - "advancedSettings.field.cancelEditingButtonLabel": "キャンセル", "advancedSettings.field.changeImageLinkAriaLabel": "{ariaName} を変更", "advancedSettings.field.changeImageLinkText": "画像を変更", "advancedSettings.field.codeEditorSyntaxErrorMessage": "無効な JSON 構文", @@ -1632,17 +1630,10 @@ "advancedSettings.field.imageTooLargeErrorMessage": "画像が大きすぎます。最大サイズは {maxSizeDescription} です", "advancedSettings.field.offLabel": "オフ", "advancedSettings.field.onLabel": "オン", - "advancedSettings.field.requiresPageReloadToastButtonLabel": "ページを再読み込み", - "advancedSettings.field.requiresPageReloadToastDescription": "「{settingName}」設定を有効にするには、ページを再読み込みしてください。", - "advancedSettings.field.resetFieldErrorMessage": "{name} をリセットできませんでした", "advancedSettings.field.resetToDefaultLinkAriaLabel": "{ariaName} をデフォルトにリセット", "advancedSettings.field.resetToDefaultLinkText": "デフォルトにリセット", - "advancedSettings.field.saveButtonAriaLabel": "{ariaName} を保存", - "advancedSettings.field.saveButtonLabel": "保存", - "advancedSettings.field.saveFieldErrorMessage": "{name} を保存できませんでした", "advancedSettings.form.clearNoSearchResultText": "(検索結果を消去)", "advancedSettings.form.clearSearchResultText": "(検索結果を消去)", - "advancedSettings.form.noSearchResultText": "設定が見つかりませんでした {clearSearch}", "advancedSettings.form.searchResultText": "検索用語により {settingsCount} 件の設定が非表示になっています {clearSearch}", "advancedSettings.pageTitle": "設定", "advancedSettings.searchBar.unableToParseQueryErrorMessage": "クエリをパースできません", @@ -2474,8 +2465,6 @@ "statusPage.statusApp.statusTitle": "プラグインステータス", "statusPage.statusTable.columns.idHeader": "ID", "statusPage.statusTable.columns.statusHeader": "ステータス", - "telemetry.callout.appliesSettingTitle": "この設定は {allOfKibanaText} に適用されます", - "telemetry.callout.appliesSettingTitle.allOfKibanaText": "Kibana のすべて", "telemetry.callout.clusterStatisticsDescription": "これは収集される基本的なクラスター統計の例です。インデックス、シャード、ノードの数が含まれます。監視がオンになっているかどうかなどのハイレベルの使用統計も含まれます。", "telemetry.callout.clusterStatisticsTitle": "クラスター統計", "telemetry.callout.errorLoadingClusterStatisticsDescription": "クラスター統計の取得中に予期せぬエラーが発生しました。Elasticsearch、Kibana、またはネットワークのエラーが原因の可能性があります。Kibana を確認し、ページを再読み込みして再試行してください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ecf4dfbb33be65..fc9dacf0e50f7b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1618,8 +1618,6 @@ "advancedSettings.categoryNames.timelionLabel": "Timelion", "advancedSettings.categoryNames.visualizationsLabel": "可视化", "advancedSettings.categorySearchLabel": "类别", - "advancedSettings.field.cancelEditingButtonAriaLabel": "取消编辑 {ariaName}", - "advancedSettings.field.cancelEditingButtonLabel": "取消", "advancedSettings.field.changeImageLinkAriaLabel": "更改 {ariaName}", "advancedSettings.field.changeImageLinkText": "更改图片", "advancedSettings.field.codeEditorSyntaxErrorMessage": "JSON 语法无效", @@ -1632,14 +1630,8 @@ "advancedSettings.field.imageTooLargeErrorMessage": "图像过大,最大大小为 {maxSizeDescription}", "advancedSettings.field.offLabel": "关闭", "advancedSettings.field.onLabel": "开启", - "advancedSettings.field.requiresPageReloadToastButtonLabel": "重新加载页面", - "advancedSettings.field.requiresPageReloadToastDescription": "请重新加载页面,以使“{settingName}”设置生效。", - "advancedSettings.field.resetFieldErrorMessage": "无法重置 {name}", "advancedSettings.field.resetToDefaultLinkAriaLabel": "将 {ariaName} 重置为默认值", "advancedSettings.field.resetToDefaultLinkText": "重置为默认值", - "advancedSettings.field.saveButtonAriaLabel": "保存 {ariaName}", - "advancedSettings.field.saveButtonLabel": "保存", - "advancedSettings.field.saveFieldErrorMessage": "无法保存 {name}", "advancedSettings.form.clearNoSearchResultText": "(清除搜索)", "advancedSettings.form.clearSearchResultText": "(清除搜索)", "advancedSettings.form.noSearchResultText": "未找到设置{clearSearch}", @@ -2474,8 +2466,6 @@ "statusPage.statusApp.statusTitle": "插件状态", "statusPage.statusTable.columns.idHeader": "ID", "statusPage.statusTable.columns.statusHeader": "状态", - "telemetry.callout.appliesSettingTitle": "此设置适用于{allOfKibanaText}", - "telemetry.callout.appliesSettingTitle.allOfKibanaText": "所有 Kibana。", "telemetry.callout.clusterStatisticsDescription": "这是我们将收集的基本集群统计信息的示例。其包括索引、分片和节点的数目。还包括概括性的使用情况统计信息,例如监测是否打开。", "telemetry.callout.clusterStatisticsTitle": "集群统计信息", "telemetry.callout.errorLoadingClusterStatisticsDescription": "尝试提取集群统计信息时发生意外错误。发生此问题的原因可能是 Elasticsearch 出故障、Kibana 出故障或者有网络错误。检查 Kibana,然后重新加载页面并重试。", From 256e4ab67c7fccae9aae38aac22f3788466f8b2f Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Mon, 24 Feb 2020 09:40:37 -0800 Subject: [PATCH 06/73] Adding xpack.encryptedSavedObjects.encryptionKey to docker allow-list (#58291) Co-authored-by: Elastic Machine --- .../os_packages/docker_generator/resources/bin/kibana-docker | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index 34ba25f92beb6a..d4d2e86e1e96bf 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -142,6 +142,7 @@ kibana_vars=( xpack.code.security.enableGitCertCheck xpack.code.security.gitHostWhitelist xpack.code.security.gitProtocolWhitelist + xpack.encryptedSavedObjects.encryptionKey xpack.graph.enabled xpack.graph.canEditDrillDownUrls xpack.graph.savePolicy From b88b99140bc0d63036c0789d1ddc8dc9597e2b5e Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Mon, 24 Feb 2020 18:44:24 +0100 Subject: [PATCH 07/73] [ML] Fix transforms license check. (#58343) Fixes an error where the transforms page would load blank with an expired license. Fixes the issue by adding a type guard. With an expired license, the page now renders again correctly the error message. --- .../lib/authorization/components/common.ts | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/common.ts b/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/common.ts index 5aec2ac041db33..27556e0d673a8e 100644 --- a/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/common.ts +++ b/x-pack/legacy/plugins/transform/public/app/lib/authorization/components/common.ts @@ -21,19 +21,33 @@ export interface Privileges { missingPrivileges: MissingPrivileges; } +function isPrivileges(arg: any): arg is Privileges { + return ( + typeof arg === 'object' && + arg !== null && + arg.hasOwnProperty('hasAllPrivileges') && + typeof arg.hasAllPrivileges === 'boolean' && + arg.hasOwnProperty('missingPrivileges') && + typeof arg.missingPrivileges === 'object' && + arg.missingPrivileges !== null + ); +} + export interface MissingPrivileges { [key: string]: string[] | undefined; } export const toArray = (value: string | string[]): string[] => Array.isArray(value) ? value : [value]; -export const hasPrivilegeFactory = (privileges: Privileges) => (privilege: Privilege) => { +export const hasPrivilegeFactory = (privileges: Privileges | undefined | null) => ( + privilege: Privilege +) => { const [section, requiredPrivilege] = privilege; - if (!privileges.missingPrivileges[section]) { + if (isPrivileges(privileges) && !privileges.missingPrivileges[section]) { // if the section does not exist in our missingPrivileges, everything is OK return true; } - if (privileges.missingPrivileges[section]!.length === 0) { + if (isPrivileges(privileges) && privileges.missingPrivileges[section]!.length === 0) { return true; } if (requiredPrivilege === '*') { @@ -42,7 +56,9 @@ export const hasPrivilegeFactory = (privileges: Privileges) => (privilege: Privi } // If we require _some_ privilege, we make sure that the one // we require is *not* in the missingPrivilege array - return !privileges.missingPrivileges[section]!.includes(requiredPrivilege); + return ( + isPrivileges(privileges) && !privileges.missingPrivileges[section]!.includes(requiredPrivilege) + ); }; // create the text for button's tooltips if the user From 12f35d5788f5250803434b6d8f25d9df82ac0940 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Mon, 24 Feb 2020 10:23:44 -0800 Subject: [PATCH 08/73] Add ingest manager header component (#58300) Co-authored-by: Elastic Machine --- x-pack/legacy/plugins/ingest_manager/index.ts | 2 + .../ingest_manager/components/header.tsx | 62 ++++ .../ingest_manager/components/index.ts | 1 + .../ingest_manager/layouts/default.tsx | 29 +- .../ingest_manager/layouts/index.tsx | 1 + .../ingest_manager/layouts/with_header.tsx | 29 ++ .../sections/agent_config/list_page/index.tsx | 291 +++++++++--------- ...illustration_kibana_getting_started@2x.png | Bin 0 -> 131132 bytes .../ingest_manager/sections/epm/index.tsx | 69 ++++- .../ingest_manager/sections/fleet/index.tsx | 46 ++- .../sections/overview/index.tsx | 32 +- 11 files changed, 397 insertions(+), 165 deletions(-) create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx create mode 100644 x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/assets/illustration_kibana_getting_started@2x.png diff --git a/x-pack/legacy/plugins/ingest_manager/index.ts b/x-pack/legacy/plugins/ingest_manager/index.ts index c20cc7225d780b..7ed5599b234a34 100644 --- a/x-pack/legacy/plugins/ingest_manager/index.ts +++ b/x-pack/legacy/plugins/ingest_manager/index.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { resolve } from 'path'; import { savedObjectMappings, OUTPUT_SAVED_OBJECT_TYPE, @@ -18,6 +19,7 @@ import { export function ingestManager(kibana: any) { return new kibana.Plugin({ id: 'ingestManager', + publicDir: resolve(__dirname, '../../../plugins/ingest_manager/public'), uiExports: { savedObjectSchemas: { [AGENT_CONFIG_SAVED_OBJECT_TYPE]: { diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx new file mode 100644 index 00000000000000..0936b5dcfed109 --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/header.tsx @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import styled from 'styled-components'; +import { EuiFlexGroup, EuiFlexItem, EuiTabs, EuiTab, EuiSpacer } from '@elastic/eui'; +import { Props as EuiTabProps } from '@elastic/eui/src/components/tabs/tab'; + +const Container = styled.div` + border-bottom: ${props => props.theme.eui.euiBorderThin}; + background-color: ${props => props.theme.eui.euiPageBackgroundColor}; +`; + +const Wrapper = styled.div` + max-width: 1200px; + margin-left: auto; + margin-right: auto; + padding-top: ${props => props.theme.eui.paddingSizes.xl}; +`; + +const Tabs = styled(EuiTabs)` + top: 1px; + &:before { + height: 0px; + } +`; + +export interface HeaderProps { + leftColumn?: JSX.Element; + rightColumn?: JSX.Element; + tabs?: EuiTabProps[]; +} + +export const Header: React.FC = ({ leftColumn, rightColumn, tabs }) => ( + + + + {leftColumn ? {leftColumn} : null} + {rightColumn ? {rightColumn} : null} + + + {tabs ? ( + + + {tabs.map(props => ( + + {props.name} + + ))} + + + ) : ( + + + + )} + + + +); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/index.ts index 5133d825884944..b6bb29462c5693 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/components/index.ts @@ -4,3 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ export { Loading } from './loading'; +export { Header, HeaderProps } from './header'; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx index eaf49fed3d9338..f99d1bfe500268 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx @@ -4,17 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { - EuiPage, - EuiPageBody, - EuiTabs, - EuiTab, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, -} from '@elastic/eui'; +import styled from 'styled-components'; +import { EuiTabs, EuiTab, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import euiStyled from '../../../../../../legacy/common/eui_styled_components'; import { Section } from '../sections'; import { useLink, useConfig } from '../hooks'; import { EPM_PATH, FLEET_PATH, AGENT_CONFIG_PATH } from '../constants'; @@ -24,7 +16,12 @@ interface Props { children?: React.ReactNode; } -const Nav = euiStyled.nav` +const Container = styled.div` + min-height: calc(100vh - ${props => props.theme.eui.euiHeaderChildSize}); + background: ${props => props.theme.eui.euiColorEmptyShade}; +`; + +const Nav = styled.nav` background: ${props => props.theme.eui.euiColorEmptyShade}; border-bottom: ${props => props.theme.eui.euiBorderThin}; padding: ${props => @@ -32,13 +29,13 @@ const Nav = euiStyled.nav` .euiTabs { padding-left: 3px; margin-left: -3px; - }; + } `; export const DefaultLayout: React.FunctionComponent = ({ section, children }) => { const { epm, fleet } = useConfig(); return ( -

+ - - {children} - -
+ {children} + ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/index.tsx index 858951bd0d38f4..a9ef7f16562600 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/index.tsx @@ -4,3 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ export { DefaultLayout } from './default'; +export { WithHeaderLayout } from './with_header'; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx new file mode 100644 index 00000000000000..d59c99316c8b8e --- /dev/null +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/with_header.tsx @@ -0,0 +1,29 @@ +/* + * 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, { Fragment } from 'react'; +import styled from 'styled-components'; +import { EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui'; +import { Header, HeaderProps } from '../components'; + +const Page = styled(EuiPage)` + background: ${props => props.theme.eui.euiColorEmptyShade}; +`; + +interface Props extends HeaderProps { + children?: React.ReactNode; +} + +export const WithHeaderLayout: React.FC = ({ children, ...rest }) => ( + +
+ + + + {children} + + + +); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx index ca9fb195166f6b..ef5a38d4869015 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/list_page/index.tsx @@ -5,9 +5,6 @@ */ import React, { useState } from 'react'; import { - EuiPageBody, - EuiPageContent, - EuiTitle, EuiSpacer, EuiText, EuiFlexGroup, @@ -24,11 +21,43 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { AgentConfig } from '../../../types'; import { DEFAULT_AGENT_CONFIG_ID, AGENT_CONFIG_DETAILS_PATH } from '../../../constants'; +import { WithHeaderLayout } from '../../../layouts'; // import { SearchBar } from '../../../components'; import { useGetAgentConfigs, usePagination, useLink } from '../../../hooks'; import { AgentConfigDeleteProvider } from '../components'; import { CreateAgentConfigFlyout } from './components'; +const AgentConfigListPageLayout: React.FunctionComponent = ({ children }) => ( + + + +

+ +

+
+
+ + +

+ +

+
+
+ + } + > + {children} +
+); + export const AgentConfigListPage: React.FunctionComponent<{}> = () => { // Create agent config flyout state const [isCreateAgentConfigFlyoutOpen, setIsCreateAgentConfigFlyoutOpen] = useState( @@ -123,71 +152,46 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => { ); return ( - - - {isCreateAgentConfigFlyoutOpen ? ( - { - setIsCreateAgentConfigFlyoutOpen(false); - sendRequest(); - }} - /> - ) : null} - - -

- -

-
- - - - - - - - - - - - - - {selectedAgentConfigs.length ? ( - - - {deleteAgentConfigsPrompt => ( - { - deleteAgentConfigsPrompt( - selectedAgentConfigs.map(agentConfig => agentConfig.id), - () => { - sendRequest(); - setSelectedAgentConfigs([]); - } - ); + + {isCreateAgentConfigFlyoutOpen ? ( + { + setIsCreateAgentConfigFlyoutOpen(false); + sendRequest(); + }} + /> + ) : null} + + {selectedAgentConfigs.length ? ( + + + {deleteAgentConfigsPrompt => ( + { + deleteAgentConfigsPrompt( + selectedAgentConfigs.map(agentConfig => agentConfig.id), + () => { + sendRequest(); + setSelectedAgentConfigs([]); + } + ); + }} + > + - - - )} - - - ) : null} - - {/* + + )} + + + ) : null} + + {/* { setPagination({ @@ -198,83 +202,82 @@ export const AgentConfigListPage: React.FunctionComponent<{}> = () => { }} fieldPrefix={AGENT_CONFIG_SAVED_OBJECT_TYPE} /> */} - - - sendRequest()}> - - - - - setIsCreateAgentConfigFlyoutOpen(true)} - > - - - - + + + sendRequest()}> + + + + + setIsCreateAgentConfigFlyoutOpen(true)} + > + + + + - - - ) : !search.trim() && agentConfigData?.total === 0 ? ( - emptyPrompt - ) : ( - setSearch('')}> - - - ), - }} - /> - ) - } - items={agentConfigData ? agentConfigData.items : []} - itemId="id" - columns={columns} - isSelectable={true} - selection={{ - selectable: (agentConfig: AgentConfig) => agentConfig.id !== DEFAULT_AGENT_CONFIG_ID, - onSelectionChange: (newSelectedAgentConfigs: AgentConfig[]) => { - setSelectedAgentConfigs(newSelectedAgentConfigs); - }, - }} - pagination={{ - pageIndex: pagination.currentPage - 1, - pageSize: pagination.pageSize, - totalItemCount: agentConfigData ? agentConfigData.total : 0, - }} - onChange={({ page }: { page: { index: number; size: number } }) => { - const newPagination = { - ...pagination, - currentPage: page.index + 1, - pageSize: page.size, - }; - setPagination(newPagination); - sendRequest(); // todo: fix this to send pagination options - }} - /> -
-
+ + + ) : !search.trim() && agentConfigData?.total === 0 ? ( + emptyPrompt + ) : ( + setSearch('')}> + + + ), + }} + /> + ) + } + items={agentConfigData ? agentConfigData.items : []} + itemId="id" + columns={columns} + isSelectable={true} + selection={{ + selectable: (agentConfig: AgentConfig) => agentConfig.id !== DEFAULT_AGENT_CONFIG_ID, + onSelectionChange: (newSelectedAgentConfigs: AgentConfig[]) => { + setSelectedAgentConfigs(newSelectedAgentConfigs); + }, + }} + pagination={{ + pageIndex: pagination.currentPage - 1, + pageSize: pagination.pageSize, + totalItemCount: agentConfigData ? agentConfigData.total : 0, + }} + onChange={({ page }: { page: { index: number; size: number } }) => { + const newPagination = { + ...pagination, + currentPage: page.index + 1, + pageSize: page.size, + }; + setPagination(newPagination); + sendRequest(); // todo: fix this to send pagination options + }} + /> + ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/assets/illustration_kibana_getting_started@2x.png b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/epm/assets/illustration_kibana_getting_started@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..cad64be0b6e36e79012970814c7018776bee5f73 GIT binary patch literal 131132 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ͤum)*z|9JCu4oQ+`+gia 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 { const { epm } = useConfig(); - return epm.enabled ?
hello world - epm app
: null; + const { http } = useCore(); + + if (!epm.enabled) { + return null; + } + + return ( + + + +

+ +

+
+
+ + +

+ +

+
+
+ + } + rightColumn={ + + + + } + tabs={[ + { + id: 'all_packages', + name: 'All packages', + isSelected: true, + }, + { + id: 'installed_packages', + name: 'Installed packages', + }, + ]} + > + hello world - fleet app +
+ ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/index.tsx index 978414769004d2..c4e8c576a1d7db 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/index.tsx @@ -4,9 +4,53 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { WithHeaderLayout } from '../../layouts'; import { useConfig } from '../../hooks'; export const FleetApp: React.FunctionComponent = () => { const { fleet } = useConfig(); - return fleet.enabled ?
hello world - fleet app
: null; + if (!fleet.enabled) { + return null; + } + + return ( + + + +

+ +

+
+
+ + +

+ +

+
+
+ + } + tabs={[ + { + id: 'agents', + name: 'Agents', + isSelected: true, + }, + { + id: 'enrollment_keys', + name: 'Enrollment keys', + }, + ]} + > + hello world - fleet app +
+ ); }; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx index da4a78a39e2fea..ea6b045f504ec1 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/index.tsx @@ -4,7 +4,37 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; +import { EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { WithHeaderLayout } from '../../layouts'; export const IngestManagerOverview: React.FunctionComponent = () => { - return
Ingest manager overview page
; + return ( + + + +

+ +

+
+
+ + +

+ +

+
+
+ + } + /> + ); }; From 63d5e382d888728f6a96eede327c61eaae271989 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Mon, 24 Feb 2020 13:40:33 -0500 Subject: [PATCH 09/73] removes extraHandlers (#58336) --- .../public/embeddable/visualize_embeddable.ts | 4 +--- src/plugins/expressions/public/loader.ts | 6 +++--- src/plugins/expressions/public/render.ts | 4 ++-- src/plugins/expressions/public/types/index.ts | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts index 72a0ef72b56937..32bbae13b79b85 100644 --- a/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -369,9 +369,7 @@ export class VisualizeEmbeddable extends Embeddable { + render = async (data: any, uiState: any = {}) => { if (!data || typeof data !== 'object') { return this.handleRenderError(new Error('invalid data provided to the expression renderer')); } @@ -119,7 +119,7 @@ export class ExpressionRenderHandler { .get(data.as)! .render(this.element, data.value, { ...this.handlers, - ...extraHandlers, + uiState, } as any); } catch (e) { return this.handleRenderError(e); diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts index c77698d3661c24..b5781ef213fd0a 100644 --- a/src/plugins/expressions/public/types/index.ts +++ b/src/plugins/expressions/public/types/index.ts @@ -48,7 +48,7 @@ export interface IExpressionLoaderParams { disableCaching?: boolean; customFunctions?: []; customRenderers?: []; - extraHandlers?: Record; + uiState?: unknown; inspectorAdapters?: Adapters; onRenderError?: RenderErrorHandlerFnType; } From d1df0e5da5a642b889bbe626a5ebaad8bf973f9a Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Mon, 24 Feb 2020 20:47:32 +0200 Subject: [PATCH 10/73] [Telemetry] Server backpressure mechanism (#57556) * finish backpressure mechanism * usage fetch method send OPTIONS before sending POST * add unit test for get_telemetry_failure_details * get currentVersion in constructor * fix type check Co-authored-by: Elastic Machine --- .../core_plugins/telemetry/mappings.json | 7 ++ .../core_plugins/telemetry/server/fetcher.ts | 68 ++++++++++--- .../get_telemetry_failure_details.test.ts | 96 +++++++++++++++++++ .../get_telemetry_failure_details.ts | 45 +++++++++ .../server/telemetry_config/index.ts | 4 + .../server/telemetry_repository/index.ts | 2 + src/plugins/telemetry/public/plugin.ts | 12 +-- 7 files changed, 215 insertions(+), 19 deletions(-) create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.test.ts create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.ts diff --git a/src/legacy/core_plugins/telemetry/mappings.json b/src/legacy/core_plugins/telemetry/mappings.json index a88372a5578e87..fa9cc93d6363a0 100644 --- a/src/legacy/core_plugins/telemetry/mappings.json +++ b/src/legacy/core_plugins/telemetry/mappings.json @@ -17,6 +17,13 @@ }, "userHasSeenNotice": { "type": "boolean" + }, + "reportFailureCount": { + "type": "integer" + }, + "reportFailureVersion": { + "ignore_above": 256, + "type": "keyword" } } } diff --git a/src/legacy/core_plugins/telemetry/server/fetcher.ts b/src/legacy/core_plugins/telemetry/server/fetcher.ts index 6e16328c4abd89..d30ee100668134 100644 --- a/src/legacy/core_plugins/telemetry/server/fetcher.ts +++ b/src/legacy/core_plugins/telemetry/server/fetcher.ts @@ -21,19 +21,26 @@ import moment from 'moment'; // @ts-ignore import fetch from 'node-fetch'; import { telemetryCollectionManager } from './collection_manager'; -import { getTelemetryOptIn, getTelemetrySendUsageFrom } from './telemetry_config'; +import { + getTelemetryOptIn, + getTelemetrySendUsageFrom, + getTelemetryFailureDetails, +} from './telemetry_config'; import { getTelemetrySavedObject, updateTelemetrySavedObject } from './telemetry_repository'; import { REPORT_INTERVAL_MS } from '../common/constants'; export class FetcherTask { - private readonly checkDurationMs = 60 * 1000 * 5; + private readonly initialCheckDelayMs = 60 * 1000 * 5; + private readonly checkIntervalMs = 60 * 1000 * 60 * 12; private intervalId?: NodeJS.Timeout; private lastReported?: number; + private currentVersion: string; private isSending = false; private server: any; constructor(server: any) { this.server = server; + this.currentVersion = this.server.config().get('pkg.version'); } private getInternalRepository = () => { @@ -52,6 +59,9 @@ export class FetcherTask { const allowChangingOptInStatus = config.get('telemetry.allowChangingOptInStatus'); const configTelemetryOptIn = config.get('telemetry.optIn'); const telemetryUrl = config.get('telemetry.url') as string; + const { failureCount, failureVersion } = await getTelemetryFailureDetails({ + telemetrySavedObject, + }); return { telemetryOptIn: getTelemetryOptIn({ @@ -65,6 +75,8 @@ export class FetcherTask { configTelemetrySendUsageFrom, }), telemetryUrl, + failureCount, + failureVersion, }; }; @@ -72,11 +84,31 @@ export class FetcherTask { const internalRepository = this.getInternalRepository(); this.lastReported = Date.now(); updateTelemetrySavedObject(internalRepository, { + reportFailureCount: 0, lastReported: this.lastReported, }); }; - private shouldSendReport = ({ telemetryOptIn, telemetrySendUsageFrom }: any) => { + private updateReportFailure = async ({ failureCount }: { failureCount: number }) => { + const internalRepository = this.getInternalRepository(); + + updateTelemetrySavedObject(internalRepository, { + reportFailureCount: failureCount + 1, + reportFailureVersion: this.currentVersion, + }); + }; + + private shouldSendReport = ({ + telemetryOptIn, + telemetrySendUsageFrom, + reportFailureCount, + currentVersion, + reportFailureVersion, + }: any) => { + if (reportFailureCount > 2 && reportFailureVersion === currentVersion) { + return false; + } + if (telemetryOptIn && telemetrySendUsageFrom === 'server') { if (!this.lastReported || Date.now() - this.lastReported > REPORT_INTERVAL_MS) { return true; @@ -98,6 +130,14 @@ export class FetcherTask { private sendTelemetry = async (url: string, cluster: any): Promise => { this.server.log(['debug', 'telemetry', 'fetcher'], `Sending usage stats.`); + /** + * send OPTIONS before sending usage data. + * OPTIONS is less intrusive as it does not contain any payload and is used here to check if the endpoint is reachable. + */ + await fetch(url, { + method: 'options', + }); + await fetch(url, { method: 'post', body: cluster, @@ -108,21 +148,23 @@ export class FetcherTask { if (this.isSending) { return; } - try { - const telemetryConfig = await this.getCurrentConfigs(); - if (!this.shouldSendReport(telemetryConfig)) { - return; - } + const telemetryConfig = await this.getCurrentConfigs(); + if (!this.shouldSendReport(telemetryConfig)) { + return; + } - // mark that we are working so future requests are ignored until we're done + try { this.isSending = true; const clusters = await this.fetchTelemetry(); + const { telemetryUrl } = telemetryConfig; for (const cluster of clusters) { - await this.sendTelemetry(telemetryConfig.telemetryUrl, cluster); + await this.sendTelemetry(telemetryUrl, cluster); } await this.updateLastReported(); } catch (err) { + await this.updateReportFailure(telemetryConfig); + this.server.log( ['warning', 'telemetry', 'fetcher'], `Error sending telemetry usage data: ${err}` @@ -132,8 +174,12 @@ export class FetcherTask { }; public start = () => { - this.intervalId = setInterval(() => this.sendIfDue(), this.checkDurationMs); + setTimeout(() => { + this.sendIfDue(); + this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); + }, this.initialCheckDelayMs); }; + public stop = () => { if (this.intervalId) { clearInterval(this.intervalId); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.test.ts new file mode 100644 index 00000000000000..c92696838e8e87 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.test.ts @@ -0,0 +1,96 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getTelemetryFailureDetails } from './get_telemetry_failure_details'; + +describe('getTelemetryFailureDetails: get details about server usage fetcher failures', () => { + it('returns `failureCount: 0` and `failureVersion: undefined` when telemetry does not have any custom configs in saved Object', () => { + const telemetrySavedObject = null; + const failureDetails = getTelemetryFailureDetails({ telemetrySavedObject }); + expect(failureDetails).toStrictEqual({ + failureVersion: undefined, + failureCount: 0, + }); + }); + + it('returns telemetryFailureCount and reportFailureVersion from telemetry saved Object', () => { + const telemetrySavedObject = { + reportFailureCount: 12, + reportFailureVersion: '8.0.0', + }; + const failureDetails = getTelemetryFailureDetails({ telemetrySavedObject }); + expect(failureDetails).toStrictEqual({ + failureVersion: '8.0.0', + failureCount: 12, + }); + }); + + it('returns `failureCount: 0` on malformed reportFailureCount telemetry saved Object', () => { + const failureVersion = '8.0.0'; + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { + reportFailureCount: null, + reportFailureVersion: failureVersion, + } as any, + }) + ).toStrictEqual({ failureVersion, failureCount: 0 }); + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { + reportFailureCount: undefined, + reportFailureVersion: failureVersion, + }, + }) + ).toStrictEqual({ failureVersion, failureCount: 0 }); + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { + reportFailureCount: 'not_a_number', + reportFailureVersion: failureVersion, + } as any, + }) + ).toStrictEqual({ failureVersion, failureCount: 0 }); + }); + + it('returns `failureVersion: undefined` on malformed reportFailureCount telemetry saved Object', () => { + const failureCount = 0; + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { + reportFailureVersion: null, + reportFailureCount: failureCount, + } as any, + }) + ).toStrictEqual({ failureCount, failureVersion: undefined }); + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { reportFailureVersion: undefined, reportFailureCount: failureCount }, + }) + ).toStrictEqual({ failureCount, failureVersion: undefined }); + expect( + getTelemetryFailureDetails({ + telemetrySavedObject: { + reportFailureVersion: 123, + reportFailureCount: failureCount, + } as any, + }) + ).toStrictEqual({ failureCount, failureVersion: undefined }); + }); +}); diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.ts new file mode 100644 index 00000000000000..2952fa96a5cf38 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_failure_details.ts @@ -0,0 +1,45 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object'; + +interface GetTelemetryFailureDetailsConfig { + telemetrySavedObject: TelemetrySavedObject; +} + +export interface TelemetryFailureDetails { + failureCount: number; + failureVersion?: string; +} + +export function getTelemetryFailureDetails({ + telemetrySavedObject, +}: GetTelemetryFailureDetailsConfig): TelemetryFailureDetails { + if (!telemetrySavedObject) { + return { + failureVersion: undefined, + failureCount: 0, + }; + } + const { reportFailureCount, reportFailureVersion } = telemetrySavedObject; + + return { + failureCount: typeof reportFailureCount === 'number' ? reportFailureCount : 0, + failureVersion: typeof reportFailureVersion === 'string' ? reportFailureVersion : undefined, + }; +} diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts index ab30dac1c36660..bf9855ce7538e3 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts @@ -21,3 +21,7 @@ export { replaceTelemetryInjectedVars } from './replace_injected_vars'; export { getTelemetryOptIn } from './get_telemetry_opt_in'; export { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from'; export { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status'; +export { + getTelemetryFailureDetails, + TelemetryFailureDetails, +} from './get_telemetry_failure_details'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts index b9ba2ce5573c3c..f1735d1bb28669 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_repository/index.ts @@ -27,4 +27,6 @@ export interface TelemetrySavedObjectAttributes { lastReported?: number; telemetryAllowChangingOptInStatus?: boolean; userHasSeenNotice?: boolean; + reportFailureCount?: number; + reportFailureVersion?: string; } diff --git a/src/plugins/telemetry/public/plugin.ts b/src/plugins/telemetry/public/plugin.ts index 7ba51cacd1949c..9cfb4ca1ec3952 100644 --- a/src/plugins/telemetry/public/plugin.ts +++ b/src/plugins/telemetry/public/plugin.ts @@ -54,9 +54,6 @@ export class TelemetryPlugin implements Plugin Date: Mon, 24 Feb 2020 13:24:46 -0600 Subject: [PATCH 11/73] Show blank lines instead of N/A on service map popovers (#57014) * Show blank lines instead of N/A on service map popovers Because RUM agents never show CPU or memory usage, we don't want to always show the metric with N/A. If a metric is null, just hide the lines. Break up the display and fetching components and update the popover stories to show the list. Update some types. * Fix metric typings --- .../app/ServiceMap/Popover/Contents.tsx | 4 +- .../ServiceMap/Popover/Popover.stories.tsx | 86 +++++++++-------- .../Popover/ServiceMetricFetcher.tsx | 41 +++++++++ .../ServiceMap/Popover/ServiceMetricList.tsx | 92 ++++++------------- x-pack/plugins/apm/common/service_map.ts | 9 ++ .../get_service_map_service_node_info.ts | 31 ++++--- 6 files changed, 147 insertions(+), 116 deletions(-) create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricFetcher.tsx diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx index 378ad9509c2170..f1c53673c87552 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx @@ -14,7 +14,7 @@ import cytoscape from 'cytoscape'; import React from 'react'; import { Buttons } from './Buttons'; import { Info } from './Info'; -import { ServiceMetricList } from './ServiceMetricList'; +import { ServiceMetricFetcher } from './ServiceMetricFetcher'; const popoverMinWidth = 280; @@ -49,7 +49,7 @@ export function Contents({ {isService ? ( - + ) : ( )} diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Popover.stories.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Popover.stories.tsx index b26488c5ef7de9..e5962afd76eb8d 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Popover.stories.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Popover.stories.tsx @@ -6,44 +6,50 @@ import { storiesOf } from '@storybook/react'; import React from 'react'; -import { - ApmPluginContext, - ApmPluginContextValue -} from '../../../../context/ApmPluginContext'; -import { Contents } from './Contents'; +import { ServiceMetricList } from './ServiceMetricList'; -const selectedNodeData = { - id: 'opbeans-node', - label: 'opbeans-node', - href: - '#/services/opbeans-node/service-map?rangeFrom=now-24h&rangeTo=now&refreshPaused=true&refreshInterval=0', - agentName: 'nodejs', - type: 'service' -}; - -storiesOf('app/ServiceMap/Popover/Contents', module).add( - 'example', - () => { - return ( - - {}} - selectedNodeServiceName="opbeans-node" - /> - - ); - }, - { - info: { - propTablesExclude: [ApmPluginContext.Provider], - source: false - } - } -); +storiesOf('app/ServiceMap/Popover/ServiceMetricList', module) + .add('example', () => ( + + )) + .add('loading', () => ( + + )) + .add('some null values', () => ( + + )) + .add('all null values', () => ( + + )); diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricFetcher.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricFetcher.tsx new file mode 100644 index 00000000000000..b0a5e892b5a7e7 --- /dev/null +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricFetcher.tsx @@ -0,0 +1,41 @@ +/* + * 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 { ServiceNodeMetrics } from '../../../../../../../../plugins/apm/common/service_map'; +import { useFetcher } from '../../../../hooks/useFetcher'; +import { useUrlParams } from '../../../../hooks/useUrlParams'; +import { ServiceMetricList } from './ServiceMetricList'; + +interface ServiceMetricFetcherProps { + serviceName: string; +} + +export function ServiceMetricFetcher({ + serviceName +}: ServiceMetricFetcherProps) { + const { + urlParams: { start, end, environment } + } = useUrlParams(); + + const { data = {} as ServiceNodeMetrics, status } = useFetcher( + callApmApi => { + if (serviceName && start && end) { + return callApmApi({ + pathname: '/api/apm/service-map/service/{serviceName}', + params: { path: { serviceName }, query: { start, end, environment } } + }); + } + }, + [serviceName, start, end, environment], + { + preservePreviousData: false + } + ); + const isLoading = status === 'loading'; + + return ; +} diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx index e91eb5e006d823..50ce918ea7037c 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx @@ -5,26 +5,23 @@ */ import { + EuiBadge, EuiFlexGroup, - EuiLoadingSpinner, EuiFlexItem, - EuiBadge + EuiLoadingSpinner } from '@elastic/eui'; import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; import { isNumber } from 'lodash'; import React from 'react'; import styled from 'styled-components'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceNodeMetrics } from '../../../../../../../../plugins/apm/server/lib/service_map/get_service_map_service_node_info'; +import { ServiceNodeMetrics } from '../../../../../../../../plugins/apm/common/service_map'; import { asDuration, asPercent, toMicroseconds, tpmUnit } from '../../../../utils/formatters'; -import { useUrlParams } from '../../../../hooks/useUrlParams'; -import { useFetcher } from '../../../../hooks/useFetcher'; function LoadingSpinner() { return ( @@ -51,53 +48,19 @@ const ItemDescription = styled('td')` text-align: right; `; -const na = i18n.translate('xpack.apm.serviceMap.NotAvailableMetric', { - defaultMessage: 'N/A' -}); - -interface MetricListProps { - serviceName: string; +interface ServiceMetricListProps extends ServiceNodeMetrics { + isLoading: boolean; } -export function ServiceMetricList({ serviceName }: MetricListProps) { - const { - urlParams: { start, end, environment } - } = useUrlParams(); - - const { data = {} as ServiceNodeMetrics, status } = useFetcher( - callApmApi => { - if (serviceName && start && end) { - return callApmApi({ - pathname: '/api/apm/service-map/service/{serviceName}', - params: { - path: { - serviceName - }, - query: { - start, - end, - environment - } - } - }); - } - }, - [serviceName, start, end, environment], - { - preservePreviousData: false - } - ); - - const { - avgTransactionDuration, - avgRequestsPerMinute, - avgErrorsPerMinute, - avgCpuUsage, - avgMemoryUsage, - numInstances - } = data; - const isLoading = status === 'loading'; - +export function ServiceMetricList({ + avgTransactionDuration, + avgRequestsPerMinute, + avgErrorsPerMinute, + avgCpuUsage, + avgMemoryUsage, + numInstances, + isLoading +}: ServiceMetricListProps) { const listItems = [ { title: i18n.translate( @@ -108,7 +71,7 @@ export function ServiceMetricList({ serviceName }: MetricListProps) { ), description: isNumber(avgTransactionDuration) ? asDuration(toMicroseconds(avgTransactionDuration, 'milliseconds')) - : na + : null }, { title: i18n.translate( @@ -119,7 +82,7 @@ export function ServiceMetricList({ serviceName }: MetricListProps) { ), description: isNumber(avgRequestsPerMinute) ? `${avgRequestsPerMinute.toFixed(2)} ${tpmUnit('request')}` - : na + : null }, { title: i18n.translate( @@ -128,13 +91,13 @@ export function ServiceMetricList({ serviceName }: MetricListProps) { defaultMessage: 'Errors per minute (avg.)' } ), - description: avgErrorsPerMinute?.toFixed(2) ?? na + description: avgErrorsPerMinute?.toFixed(2) }, { title: i18n.translate('xpack.apm.serviceMap.avgCpuUsagePopoverMetric', { defaultMessage: 'CPU usage (avg.)' }), - description: isNumber(avgCpuUsage) ? asPercent(avgCpuUsage, 1) : na + description: isNumber(avgCpuUsage) ? asPercent(avgCpuUsage, 1) : null }, { title: i18n.translate( @@ -143,7 +106,9 @@ export function ServiceMetricList({ serviceName }: MetricListProps) { defaultMessage: 'Memory usage (avg.)' } ), - description: isNumber(avgMemoryUsage) ? asPercent(avgMemoryUsage, 1) : na + description: isNumber(avgMemoryUsage) + ? asPercent(avgMemoryUsage, 1) + : null } ]; return isLoading ? ( @@ -165,12 +130,15 @@ export function ServiceMetricList({ serviceName }: MetricListProps) { - {listItems.map(({ title, description }) => ( - - {title} - {description} - - ))} + {listItems.map( + ({ title, description }) => + description && ( + + {title} + {description} + + ) + )}
diff --git a/x-pack/plugins/apm/common/service_map.ts b/x-pack/plugins/apm/common/service_map.ts index fbaa489c450399..528aec2f70ad98 100644 --- a/x-pack/plugins/apm/common/service_map.ts +++ b/x-pack/plugins/apm/common/service_map.ts @@ -21,3 +21,12 @@ export interface Connection { source: ConnectionNode; destination: ConnectionNode; } + +export interface ServiceNodeMetrics { + numInstances: number; + avgMemoryUsage: number | null; + avgCpuUsage: number | null; + avgTransactionDuration: number | null; + avgRequestsPerMinute: number | null; + avgErrorsPerMinute: number | null; +} diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts index 6c4d540103ceca..0fe825e8ace359 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts @@ -18,7 +18,6 @@ import { SERVICE_NODE_NAME } from '../../../common/elasticsearch_fieldnames'; import { percentMemoryUsedScript } from '../metrics/by_agent/shared/memory'; -import { PromiseReturnType } from '../../../typings/common'; interface Options { setup: Setup & SetupTimeRange; @@ -32,10 +31,6 @@ interface TaskParameters { filter: ESFilter[]; } -export type ServiceNodeMetrics = PromiseReturnType< - typeof getServiceMapServiceNodeInfo ->; - export async function getServiceMapServiceNodeInfo({ serviceName, environment, @@ -112,7 +107,10 @@ async function getTransactionMetrics({ setup, filter, minutes -}: TaskParameters) { +}: TaskParameters): Promise<{ + avgTransactionDuration: number | null; + avgRequestsPerMinute: number | null; +}> { const { indices, client } = setup; const response = await client.search({ @@ -140,13 +138,16 @@ async function getTransactionMetrics({ }); return { - avgTransactionDuration: response.aggregations?.duration.value, + avgTransactionDuration: response.aggregations?.duration.value ?? null, avgRequestsPerMinute: response.hits.total.value > 0 ? response.hits.total.value / minutes : null }; } -async function getCpuMetrics({ setup, filter }: TaskParameters) { +async function getCpuMetrics({ + setup, + filter +}: TaskParameters): Promise<{ avgCpuUsage: number | null }> { const { indices, client } = setup; const response = await client.search({ @@ -180,11 +181,14 @@ async function getCpuMetrics({ setup, filter }: TaskParameters) { }); return { - avgCpuUsage: response.aggregations?.avgCpuUsage.value + avgCpuUsage: response.aggregations?.avgCpuUsage.value ?? null }; } -async function getMemoryMetrics({ setup, filter }: TaskParameters) { +async function getMemoryMetrics({ + setup, + filter +}: TaskParameters): Promise<{ avgMemoryUsage: number | null }> { const { client, indices } = setup; const response = await client.search({ index: indices['apm_oss.metricsIndices'], @@ -221,11 +225,14 @@ async function getMemoryMetrics({ setup, filter }: TaskParameters) { }); return { - avgMemoryUsage: response.aggregations?.avgMemoryUsage.value + avgMemoryUsage: response.aggregations?.avgMemoryUsage.value ?? null }; } -async function getNumInstances({ setup, filter }: TaskParameters) { +async function getNumInstances({ + setup, + filter +}: TaskParameters): Promise<{ numInstances: number }> { const { client, indices } = setup; const response = await client.search({ index: indices['apm_oss.transactionIndices'], From 858fe2e9251e748bfbcd85623f22d9c1eac71076 Mon Sep 17 00:00:00 2001 From: Maggie Ghamry <46542915+maggieghamry@users.noreply.github.com> Date: Mon, 24 Feb 2020 14:44:19 -0500 Subject: [PATCH 12/73] [Canvas] Toggles footer editable controls when you turn off edit mode #52786 (#58044) * Bug fix update update to toggle footer edit controls "off" when locking edit controls. * Update to toggle Update to toggle, so that only the "Expression Editor" and tray are hidden when locking controls. * Update to toggle logic Added canUserWrite property, and added a condition to ensure the "page" tray still shows once the Expression editor is locked * Update to property definition Update to consolidate isWriteable and canUserWrite into one variable instead of two. * Adding Test (in progress) code Adding Toolbar test code (so far) - needs to be completed to address nested compononet storybook issue * Adding issue link Adding issue link in TODO comments Co-authored-by: Elastic Machine --- .../toolbar/__examples__/toolbar.stories.tsx | 39 +++++++++++++++++++ .../canvas/public/components/toolbar/index.js | 3 ++ .../public/components/toolbar/toolbar.tsx | 11 +++++- 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 x-pack/legacy/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx diff --git a/x-pack/legacy/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx b/x-pack/legacy/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx new file mode 100644 index 00000000000000..5907c932ddabb1 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/public/components/toolbar/__examples__/toolbar.stories.tsx @@ -0,0 +1,39 @@ +/* + * 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. + */ + +/* + TODO: uncomment and fix this test to address storybook errors as a result of nested component dependencies - https://github.com/elastic/kibana/issues/58289 + */ + +/* +import { action } from '@storybook/addon-actions'; +import { storiesOf } from '@storybook/react'; +import React from 'react'; +import { Toolbar } from '../toolbar'; + +storiesOf('components/Toolbar', module) + .addDecorator(story => ( +
+ {story()} +
+ )) + .add('with null metric', () => ( + + )); +*/ diff --git a/x-pack/legacy/plugins/canvas/public/components/toolbar/index.js b/x-pack/legacy/plugins/canvas/public/components/toolbar/index.js index c834304739a4c0..294a44ba0415a6 100644 --- a/x-pack/legacy/plugins/canvas/public/components/toolbar/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/toolbar/index.js @@ -7,12 +7,14 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import { pure, compose, withState, getContext, withHandlers } from 'recompose'; +import { canUserWrite } from '../../state/selectors/app'; import { getWorkpad, getWorkpadName, getSelectedPageIndex, getSelectedElement, + isWriteable, } from '../../state/selectors/workpad'; import { Toolbar as Component } from './toolbar'; @@ -23,6 +25,7 @@ const mapStateToProps = state => ({ totalPages: getWorkpad(state).pages.length, selectedPageNumber: getSelectedPageIndex(state) + 1, selectedElement: getSelectedElement(state), + isWriteable: isWriteable(state) && canUserWrite(state), }); export const Toolbar = compose( diff --git a/x-pack/legacy/plugins/canvas/public/components/toolbar/toolbar.tsx b/x-pack/legacy/plugins/canvas/public/components/toolbar/toolbar.tsx index 089f021ccdc325..0f8204e6bc261c 100644 --- a/x-pack/legacy/plugins/canvas/public/components/toolbar/toolbar.tsx +++ b/x-pack/legacy/plugins/canvas/public/components/toolbar/toolbar.tsx @@ -39,7 +39,8 @@ enum TrayType { interface Props { workpadName: string; - + isWriteable: boolean; + canUserWrite: boolean; tray: TrayType | null; setTray: (tray: TrayType | null) => void; @@ -66,12 +67,17 @@ export const Toolbar = (props: Props) => { totalPages, showWorkpadManager, setShowWorkpadManager, + isWriteable, } = props; const elementIsSelected = Boolean(selectedElement); const done = () => setTray(null); + if (!isWriteable && tray === TrayType.expression) { + done(); + } + const showHideTray = (exp: TrayType) => { if (tray && tray === exp) { return done(); @@ -135,7 +141,7 @@ export const Toolbar = (props: Props) => { />
- {elementIsSelected && ( + {elementIsSelected && isWriteable && ( Date: Mon, 24 Feb 2020 20:09:38 +0000 Subject: [PATCH 13/73] chore(NA): remove empty filter check from thread loader pool config getter (#58385) --- src/optimize/base_optimizer.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index a833204eaa0e28..a94f251c292f9a 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -152,11 +152,7 @@ export default class BaseOptimizer { getThreadLoaderPoolConfig() { // Calculate the node options from the NODE_OPTIONS env var - const parsedNodeOptions = process.env.NODE_OPTIONS - ? // thread-loader could not receive empty string as options - // or it would break that's why we need to filter here - process.env.NODE_OPTIONS.split(/\s/).filter(opt => !!opt) - : []; + const parsedNodeOptions = process.env.NODE_OPTIONS ? process.env.NODE_OPTIONS.split(/\s/) : []; return { name: 'optimizer-thread-loader-main-pool', From 77fe83e7db27b410cd1eb63084c22ca7bb32d278 Mon Sep 17 00:00:00 2001 From: Brandon Kobel Date: Mon, 24 Feb 2020 13:04:30 -0800 Subject: [PATCH 14/73] Remove restriction that route must start with `/api` to use api authorization (#58351) Co-authored-by: Elastic Machine --- .../authorization/api_authorization.test.ts | 36 +++++-------------- .../server/authorization/api_authorization.ts | 4 +-- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/security/server/authorization/api_authorization.test.ts b/x-pack/plugins/security/server/authorization/api_authorization.test.ts index a5902f251b0829..409f998cfe8d2e 100644 --- a/x-pack/plugins/security/server/authorization/api_authorization.test.ts +++ b/x-pack/plugins/security/server/authorization/api_authorization.test.ts @@ -15,27 +15,7 @@ import { import { authorizationMock } from './index.mock'; describe('initAPIAuthorization', () => { - test(`route that doesn't start with "/api/" continues`, async () => { - const mockHTTPSetup = coreMock.createSetup().http; - initAPIAuthorization( - mockHTTPSetup, - authorizationMock.create(), - loggingServiceMock.create().get() - ); - - const [[postAuthHandler]] = mockHTTPSetup.registerOnPostAuth.mock.calls; - - const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', path: '/app/foo' }); - const mockResponse = httpServerMock.createResponseFactory(); - const mockPostAuthToolkit = httpServiceMock.createOnPostAuthToolkit(); - - await postAuthHandler(mockRequest, mockResponse, mockPostAuthToolkit); - - expect(mockResponse.notFound).not.toHaveBeenCalled(); - expect(mockPostAuthToolkit.next).toHaveBeenCalledTimes(1); - }); - - test(`protected route that starts with "/api/", but "mode.useRbacForRequest()" returns false continues`, async () => { + test(`protected route when "mode.useRbacForRequest()" returns false continues`, async () => { const mockHTTPSetup = coreMock.createSetup().http; const mockAuthz = authorizationMock.create(); initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); @@ -44,7 +24,7 @@ describe('initAPIAuthorization', () => { const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', - path: '/api/foo', + path: '/foo/bar', routeTags: ['access:foo'], }); const mockResponse = httpServerMock.createResponseFactory(); @@ -59,7 +39,7 @@ describe('initAPIAuthorization', () => { expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); }); - test(`unprotected route that starts with "/api/", but "mode.useRbacForRequest()" returns true continues`, async () => { + test(`unprotected route when "mode.useRbacForRequest()" returns true continues`, async () => { const mockHTTPSetup = coreMock.createSetup().http; const mockAuthz = authorizationMock.create(); initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); @@ -68,7 +48,7 @@ describe('initAPIAuthorization', () => { const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', - path: '/api/foo', + path: '/foo/bar', routeTags: ['not-access:foo'], }); const mockResponse = httpServerMock.createResponseFactory(); @@ -83,7 +63,7 @@ describe('initAPIAuthorization', () => { expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); }); - test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { + test(`protected route when "mode.useRbacForRequest()" returns true and user is authorized continues`, async () => { const mockHTTPSetup = coreMock.createSetup().http; const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); @@ -93,7 +73,7 @@ describe('initAPIAuthorization', () => { const headers = { authorization: 'foo' }; const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', - path: '/api/foo', + path: '/foo/bar', headers, routeTags: ['access:foo'], }); @@ -118,7 +98,7 @@ describe('initAPIAuthorization', () => { expect(mockAuthz.mode.useRbacForRequest).toHaveBeenCalledWith(mockRequest); }); - test(`protected route that starts with "/api/", "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { + test(`protected route when "mode.useRbacForRequest()" returns true and user isn't authorized responds with a 404`, async () => { const mockHTTPSetup = coreMock.createSetup().http; const mockAuthz = authorizationMock.create({ version: '1.0.0-zeta1' }); initAPIAuthorization(mockHTTPSetup, mockAuthz, loggingServiceMock.create().get()); @@ -128,7 +108,7 @@ describe('initAPIAuthorization', () => { const headers = { authorization: 'foo' }; const mockRequest = httpServerMock.createKibanaRequest({ method: 'get', - path: '/api/foo', + path: '/foo/bar', headers, routeTags: ['access:foo'], }); diff --git a/x-pack/plugins/security/server/authorization/api_authorization.ts b/x-pack/plugins/security/server/authorization/api_authorization.ts index b280cc74c230f5..cc672fbc69e068 100644 --- a/x-pack/plugins/security/server/authorization/api_authorization.ts +++ b/x-pack/plugins/security/server/authorization/api_authorization.ts @@ -13,8 +13,8 @@ export function initAPIAuthorization( logger: Logger ) { http.registerOnPostAuth(async (request, response, toolkit) => { - // if the api doesn't start with "/api/" or we aren't using RBAC for this request, just continue - if (!request.url.path!.startsWith('/api/') || !mode.useRbacForRequest(request)) { + // if we aren't using RBAC for this request, just continue + if (!mode.useRbacForRequest(request)) { return toolkit.next(); } From 7e087633d26dfebe5cf262bbfde2cd4c29770464 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Mon, 24 Feb 2020 14:44:03 -0700 Subject: [PATCH 15/73] Remove unused indexPattern:fieldMapping:lookBack advanced setting (#58147) * Remove unused indexPattern:fieldMapping:lookBack advanced setting * Remove unused translations Co-authored-by: Elastic Machine --- docs/management/advanced-options.asciidoc | 2 -- src/legacy/core_plugins/kibana/ui_setting_defaults.js | 11 ----------- x-pack/plugins/translations/translations/ja-JP.json | 2 -- x-pack/plugins/translations/translations/zh-CN.json | 2 -- 4 files changed, 17 deletions(-) diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 80c9053dc5ae6f..9d4052bbd0156a 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -62,8 +62,6 @@ mentioned use "\_default_". `histogram:maxBars`:: Date histograms are not generated with more bars than the value of this property, scaling values when necessary. `history:limit`:: In fields that have history, such as query inputs, show this many recent values. -`indexPattern:fieldMapping:lookBack`:: For index patterns containing timestamps in their names, -look for this many recent matching patterns from which to query the field mapping. `indexPattern:placeholder`:: The default placeholder value to use in Management > Index Patterns > Create Index Pattern. `metaFields`:: Fields that exist outside of `_source`. Kibana merges these fields into the document when displaying it. diff --git a/src/legacy/core_plugins/kibana/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/ui_setting_defaults.js index f92694eabe58d1..c0628b72c2ce7a 100644 --- a/src/legacy/core_plugins/kibana/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/ui_setting_defaults.js @@ -690,17 +690,6 @@ export function getUiSettingDefaults() { 'The maximum height that a cell in a table should occupy. Set to 0 to disable truncation', }), }, - 'indexPattern:fieldMapping:lookBack': { - name: i18n.translate('kbn.advancedSettings.indexPattern.recentMatchingTitle', { - defaultMessage: 'Recent matching patterns', - }), - value: 5, - description: i18n.translate('kbn.advancedSettings.indexPattern.recentMatchingText', { - defaultMessage: - 'For index patterns containing timestamps in their names, look for this many recent matching ' + - 'patterns from which to query the field mapping', - }), - }, 'format:defaultTypeMap': { name: i18n.translate('kbn.advancedSettings.format.defaultTypeMapTitle', { defaultMessage: 'Field type format name', diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 78bb39dd22dea1..dc97a96d4fcbab 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -878,8 +878,6 @@ "kbn.advancedSettings.histogram.maxBarsTitle": "最高バー数", "kbn.advancedSettings.historyLimitText": "履歴があるフィールド (例: クエリインプット) に個の数の最近の値が表示されます", "kbn.advancedSettings.historyLimitTitle": "履歴制限数", - "kbn.advancedSettings.indexPattern.recentMatchingText": "名前にタイムスタンプが含まれているインデックスパターンで、フィールドマッチングをクエリする最近の一致したパターンが、この数検索されます", - "kbn.advancedSettings.indexPattern.recentMatchingTitle": "最近一致したパターン", "kbn.advancedSettings.indexPatternPlaceholderText": "「管理 > インデックスパターン > インデックスパターンを作成」で使用される「インデックスパターン名」フィールドのプレースホルダーです。", "kbn.advancedSettings.indexPatternPlaceholderTitle": "インデックスパターンのプレースホルダー", "kbn.advancedSettings.maxBucketsText": "1 つのデータソースが返せるバケットの最大数です", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index fc9dacf0e50f7b..2532cdb0c4d074 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -878,8 +878,6 @@ "kbn.advancedSettings.histogram.maxBarsTitle": "最大条形数", "kbn.advancedSettings.historyLimitText": "在具有历史记录(例如查询输入)的字段中,显示此数目的最近值", "kbn.advancedSettings.historyLimitTitle": "历史记录限制", - "kbn.advancedSettings.indexPattern.recentMatchingText": "对于名称中包含时间戳的索引模式,寻找此数目的最近匹配模式,以从其中查询字段映射", - "kbn.advancedSettings.indexPattern.recentMatchingTitle": "最近匹配模式", "kbn.advancedSettings.indexPatternPlaceholderText": "在“管理 > 索引模式 > 创建索引模式”中“索引模式名称”的占位符。", "kbn.advancedSettings.indexPatternPlaceholderTitle": "索引模式占位符", "kbn.advancedSettings.maxBucketsText": "单个数据源可以返回的最大存储桶数目", From 13eacb51f0fd030f123c05e68c545bdb99f6ac70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 24 Feb 2020 23:43:40 +0100 Subject: [PATCH 16/73] [APM] Stabilize agent configuration API (#57767) --- docs/apm/api.asciidoc | 260 ++++++++++++++++++ docs/apm/index.asciidoc | 2 + .../AddEditFlyout/DeleteButton.tsx | 10 +- .../AddEditFlyout/index.tsx | 2 +- .../AddEditFlyout/saveConfig.ts | 30 +- x-pack/legacy/plugins/apm/readme.md | 22 ++ .../index.test.ts | 41 +++ .../agent_configuration_intake_rt/index.ts | 26 ++ .../apm/server/lib/helpers/es_client.ts | 7 +- .../lib/services/get_service_node_metadata.ts | 4 +- .../__snapshots__/queries.test.ts.snap | 234 ++++++++++------ .../configuration_types.d.ts | 19 +- .../create_or_update_configuration.ts | 22 +- .../find_exact_configuration.ts | 46 ++++ .../get_agent_name_by_service.ts | 6 +- .../agent_configuration/queries.test.ts | 146 ++++++---- .../{search.ts => search_configurations.ts} | 35 ++- .../apm/server/routes/create_apm_api.ts | 6 +- .../routes/settings/agent_configuration.ts | 137 ++++----- .../apis/apm/agent_configuration.ts | 163 ++++++----- .../apis/apm/feature_controls.ts | 42 +-- x-pack/test/api_integration/apis/apm/index.ts | 2 +- x-pack/test/functional/apps/apm/index.ts | 2 +- 23 files changed, 894 insertions(+), 370 deletions(-) create mode 100644 docs/apm/api.asciidoc create mode 100644 x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.test.ts create mode 100644 x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.ts create mode 100644 x-pack/plugins/apm/server/lib/settings/agent_configuration/find_exact_configuration.ts rename x-pack/plugins/apm/server/lib/settings/agent_configuration/{search.ts => search_configurations.ts} (68%) diff --git a/docs/apm/api.asciidoc b/docs/apm/api.asciidoc new file mode 100644 index 00000000000000..b520cc46bef8d3 --- /dev/null +++ b/docs/apm/api.asciidoc @@ -0,0 +1,260 @@ +[role="xpack"] +[[apm-api]] +== API + +Some APM app features are provided via a REST API: + +* <> + +TIP: Kibana provides additional <>, +and general information on <>. + +//// +******************************************************* +//// + +[[agent-config-api]] +=== Agent Configuration API + +The Agent configuration API allows you to fine-tune your APM agent configuration, +without needing to redeploy your application. + +The following Agent configuration APIs are available: + +* <> to create or update an Agent configuration +* <> to delete an Agent configuration. +* <> to list all Agent configurations. +* <> to search for an Agent configuration. + +//// +******************************************************* +//// + +[[apm-update-config]] +==== Create or update configuration + +[[apm-update-config-req]] +===== Request + +`PUT /api/apm/settings/agent-configuration` + +[[apm-update-config-req-body]] +===== Request body + +`service`:: +(required, object) Service identifying the configuration to create or update. + +`name` ::: + (required, string) Name of service + +`environment` ::: + (optional, string) Environment of service + +`settings`:: +(required) Key/value object with settings and their corresponding value. + +`agent_name`:: +(optional) The agent name is used by the UI to determine which settings to display. + + +[[apm-update-config-example]] +===== Example + +[source,console] +-------------------------------------------------- +PUT /api/apm/settings/agent-configuration +{ + "service" : { + "name" : "frontend", + "environment" : "production" + }, + "settings" : { + "transaction_sample_rate" : 0.4, + "capture_body" : "off", + "transaction_max_spans" : 500 + }, + "agent_name": "nodejs" +} +-------------------------------------------------- + +//// +******************************************************* +//// + + +[[apm-delete-config]] +==== Delete configuration + +[[apm-delete-config-req]] +===== Request + +`DELETE /api/apm/settings/agent-configuration` + +[[apm-delete-config-req-body]] +===== Request body +`service`:: +(required, object) Service identifying the configuration to delete + +`name` ::: + (required, string) Name of service + +`environment` ::: + (optional, string) Environment of service + + +[[apm-delete-config-example]] +===== Example + +[source,console] +-------------------------------------------------- +DELETE /api/apm/settings/agent-configuration +{ + "service" : { + "name" : "frontend", + "environment": "production" + } +} +-------------------------------------------------- + +//// +******************************************************* +//// + + +[[apm-list-config]] +==== List configuration + + +[[apm-list-config-req]] +===== Request + +`GET /api/apm/settings/agent-configuration` + +[[apm-list-config-body]] +===== Response body + +[source,js] +-------------------------------------------------- +[ + { + "agent_name": "go", + "service": { + "name": "opbeans-go", + "environment": "production" + }, + "settings": { + "transaction_sample_rate": 1, + "capture_body": "off", + "transaction_max_spans": 200 + }, + "@timestamp": 1581934104843, + "applied_by_agent": false, + "etag": "1e58c178efeebae15c25c539da740d21dee422fc" + }, + { + "agent_name": "go", + "service": { + "name": "opbeans-go" + }, + "settings": { + "transaction_sample_rate": 1, + "capture_body": "off", + "transaction_max_spans": 300 + }, + "@timestamp": 1581934111727, + "applied_by_agent": false, + "etag": "3eed916d3db434d9fb7f039daa681c7a04539a64" + }, + { + "agent_name": "nodejs", + "service": { + "name": "frontend" + }, + "settings": { + "transaction_sample_rate": 1, + }, + "@timestamp": 1582031336265, + "applied_by_agent": false, + "etag": "5080ed25785b7b19f32713681e79f46996801a5b" + } +] +-------------------------------------------------- + +[[apm-list-config-example]] +===== Example + +[source,console] +-------------------------------------------------- +GET /api/apm/settings/agent-configuration +-------------------------------------------------- + +//// +******************************************************* +//// + + +[[apm-search-config]] +==== Search configuration + +[[apm-search-config-req]] +===== Request + +`POST /api/apm/settings/agent-configuration/search` + +[[apm-search-config-req-body]] +===== Request body + +`service`:: +(required, object) Service identifying the configuration. + +`name` ::: + (required, string) Name of service + +`environment` ::: + (optional, string) Environment of service + +`etag`:: +(required) etag is sent by the agent to indicate the etag of the last successfully applied configuration. If the etag matches an existing configuration its `applied_by_agent` property will be set to `true`. Every time a configuration is edited `applied_by_agent` is reset to `false`. + +[[apm-search-config-body]] +===== Response body + +[source,js] +-------------------------------------------------- +{ + "_index": ".apm-agent-configuration", + "_id": "CIaqXXABmQCdPphWj8EJ", + "_score": 2, + "_source": { + "agent_name": "nodejs", + "service": { + "name": "frontend" + }, + "settings": { + "transaction_sample_rate": 1, + }, + "@timestamp": 1582031336265, + "applied_by_agent": false, + "etag": "5080ed25785b7b19f32713681e79f46996801a5b" + } +} +-------------------------------------------------- + +[[apm-search-config-example]] +===== Example + +[source,console] +-------------------------------------------------- +POST /api/apm/settings/agent-configuration/search +{ + "etag" : "1e58c178efeebae15c25c539da740d21dee422fc", + "service" : { + "name" : "frontend", + "environment": "production" + } +} +-------------------------------------------------- + +//// +******************************************************* +//// diff --git a/docs/apm/index.asciidoc b/docs/apm/index.asciidoc index 7eb7278cf03581..d3f0dc5b7f11f2 100644 --- a/docs/apm/index.asciidoc +++ b/docs/apm/index.asciidoc @@ -24,3 +24,5 @@ include::getting-started.asciidoc[] include::bottlenecks.asciidoc[] include::using-the-apm-ui.asciidoc[] + +include::api.asciidoc[] diff --git a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/DeleteButton.tsx b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/DeleteButton.tsx index 496147b02589bc..1564f1ae746a99 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/DeleteButton.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/DeleteButton.tsx @@ -51,12 +51,18 @@ async function deleteConfig( ) { try { await callApmApi({ - pathname: '/api/apm/settings/agent-configuration/{configurationId}', + pathname: '/api/apm/settings/agent-configuration', method: 'DELETE', params: { - path: { configurationId: selectedConfig.id } + body: { + service: { + name: selectedConfig.service.name, + environment: selectedConfig.service.environment + } + } } }); + toasts.addSuccess({ title: i18n.translate( 'xpack.apm.settings.agentConf.flyout.deleteSection.deleteConfigSucceededTitle', diff --git a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/index.tsx index 653dedea733f26..c77617fbb424f0 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/index.tsx @@ -135,8 +135,8 @@ export function AddEditFlyout({ sampleRate, captureBody, transactionMaxSpans, - configurationId: selectedConfig ? selectedConfig.id : undefined, agentName, + isExistingConfig: Boolean(selectedConfig), toasts, trackApmEvent }); diff --git a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/saveConfig.ts b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/saveConfig.ts index 19934cafb4694f..d36120a0547959 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/saveConfig.ts +++ b/x-pack/legacy/plugins/apm/public/components/app/Settings/AgentConfigurations/AddEditFlyout/saveConfig.ts @@ -27,8 +27,8 @@ export async function saveConfig({ sampleRate, captureBody, transactionMaxSpans, - configurationId, agentName, + isExistingConfig, toasts, trackApmEvent }: { @@ -38,8 +38,8 @@ export async function saveConfig({ sampleRate: string; captureBody: string; transactionMaxSpans: string; - configurationId?: string; agentName?: string; + isExistingConfig: boolean; toasts: NotificationsStart['toasts']; trackApmEvent: UiTracker; }) { @@ -64,24 +64,14 @@ export async function saveConfig({ settings }; - if (configurationId) { - await callApmApi({ - pathname: '/api/apm/settings/agent-configuration/{configurationId}', - method: 'PUT', - params: { - path: { configurationId }, - body: configuration - } - }); - } else { - await callApmApi({ - pathname: '/api/apm/settings/agent-configuration/new', - method: 'POST', - params: { - body: configuration - } - }); - } + await callApmApi({ + pathname: '/api/apm/settings/agent-configuration', + method: 'PUT', + params: { + query: { overwrite: isExistingConfig }, + body: configuration + } + }); toasts.addSuccess({ title: i18n.translate( diff --git a/x-pack/legacy/plugins/apm/readme.md b/x-pack/legacy/plugins/apm/readme.md index 2106243d12aeaf..a513249c296db3 100644 --- a/x-pack/legacy/plugins/apm/readme.md +++ b/x-pack/legacy/plugins/apm/readme.md @@ -71,6 +71,28 @@ node scripts/jest.js plugins/apm --watch node scripts/jest.js plugins/apm --updateSnapshot ``` +### Functional tests + +**Start server** +`node scripts/functional_tests_server --config x-pack/test/functional/config.js` + +**Run tests** +`node scripts/functional_test_runner --config x-pack/test/functional/config.js --grep='APM specs'` + +APM tests are located in `x-pack/test/functional/apps/apm`. +For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) + +### API integration tests + +**Start server** +`node scripts/functional_tests_server --config x-pack/test/api_integration/config.js` + +**Run tests** +`node scripts/functional_test_runner --config x-pack/test/api_integration/config.js --grep='APM specs'` + +APM tests are located in `x-pack/test/api_integration/apis/apm`. +For debugging access Elasticsearch on http://localhost:9220` (elastic/changeme) + ### Linting _Note: Run the following commands from `kibana/`._ diff --git a/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.test.ts b/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.test.ts new file mode 100644 index 00000000000000..4c9dc78eb41e9d --- /dev/null +++ b/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.test.ts @@ -0,0 +1,41 @@ +/* + * 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 { agentConfigurationIntakeRt } from './index'; +import { isRight } from 'fp-ts/lib/Either'; + +describe('agentConfigurationIntakeRt', () => { + it('is valid when required parameters are given', () => { + const config = { + service: {}, + settings: {} + }; + + expect(isConfigValid(config)).toBe(true); + }); + + it('is valid when required and optional parameters are given', () => { + const config = { + service: { name: 'my-service', environment: 'my-environment' }, + settings: { + transaction_sample_rate: 0.5, + capture_body: 'foo', + transaction_max_spans: 10 + } + }; + + expect(isConfigValid(config)).toBe(true); + }); + + it('is invalid when required parameters are not given', () => { + const config = {}; + expect(isConfigValid(config)).toBe(false); + }); +}); + +function isConfigValid(config: any) { + return isRight(agentConfigurationIntakeRt.decode(config)); +} diff --git a/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.ts b/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.ts new file mode 100644 index 00000000000000..32a2832b5eaf33 --- /dev/null +++ b/x-pack/plugins/apm/common/runtime_types/agent_configuration_intake_rt/index.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as t from 'io-ts'; +import { transactionSampleRateRt } from '../transaction_sample_rate_rt'; +import { transactionMaxSpansRt } from '../transaction_max_spans_rt'; + +export const serviceRt = t.partial({ + name: t.string, + environment: t.string +}); + +export const agentConfigurationIntakeRt = t.intersection([ + t.partial({ agent_name: t.string }), + t.type({ + service: serviceRt, + settings: t.partial({ + transaction_sample_rate: transactionSampleRateRt, + capture_body: t.string, + transaction_max_spans: transactionMaxSpansRt + }) + }) +]); diff --git a/x-pack/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/plugins/apm/server/lib/helpers/es_client.ts index 8ada02d085631b..86eb1dba507f04 100644 --- a/x-pack/plugins/apm/server/lib/helpers/es_client.ts +++ b/x-pack/plugins/apm/server/lib/helpers/es_client.ts @@ -7,9 +7,10 @@ /* eslint-disable no-console */ import { IndexDocumentParams, - IndicesCreateParams, IndicesDeleteParams, - SearchParams + SearchParams, + IndicesCreateParams, + DeleteDocumentResponse } from 'elasticsearch'; import { cloneDeep, isString, merge, uniqueId } from 'lodash'; import { KibanaRequest } from 'src/core/server'; @@ -188,7 +189,7 @@ export function getESClient( index: (params: APMIndexDocumentParams) => { return withTime(() => callMethod('index', params)); }, - delete: (params: IndicesDeleteParams) => { + delete: (params: IndicesDeleteParams): Promise => { return withTime(() => callMethod('delete', params)); }, indicesCreate: (params: IndicesCreateParams) => { diff --git a/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts b/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts index 7120d3bca6c259..ccd8b123e23e2a 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts @@ -58,8 +58,8 @@ export async function getServiceNodeMetadata({ const response = await client.search(query); return { - host: response.aggregations?.host.buckets[0].key || NOT_AVAILABLE_LABEL, + host: response.aggregations?.host.buckets[0]?.key || NOT_AVAILABLE_LABEL, containerId: - response.aggregations?.containerId.buckets[0].key || NOT_AVAILABLE_LABEL + response.aggregations?.containerId.buckets[0]?.key || NOT_AVAILABLE_LABEL }; } diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap index 542fdd99e26358..db34b4d5d20b5b 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/__snapshots__/queries.test.ts.snap @@ -1,6 +1,90 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`agent configuration queries fetches all environments 1`] = ` +exports[`agent configuration queries findExactConfiguration find configuration by service.environment 1`] = ` +Object { + "body": Object { + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "bool": Object { + "must_not": Array [ + Object { + "exists": Object { + "field": "service.name", + }, + }, + ], + }, + }, + Object { + "term": Object { + "service.environment": "bar", + }, + }, + ], + }, + }, + }, + "index": "myIndex", +} +`; + +exports[`agent configuration queries findExactConfiguration find configuration by service.name 1`] = ` +Object { + "body": Object { + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "term": Object { + "service.name": "foo", + }, + }, + Object { + "bool": Object { + "must_not": Array [ + Object { + "exists": Object { + "field": "service.environment", + }, + }, + ], + }, + }, + ], + }, + }, + }, + "index": "myIndex", +} +`; + +exports[`agent configuration queries findExactConfiguration find configuration by service.name and service.environment 1`] = ` +Object { + "body": Object { + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "term": Object { + "service.name": "foo", + }, + }, + Object { + "term": Object { + "service.environment": "bar", + }, + }, + ], + }, + }, + }, + "index": "myIndex", +} +`; + +exports[`agent configuration queries getAllEnvironments fetches all environments 1`] = ` Object { "body": Object { "aggs": Object { @@ -41,14 +125,79 @@ Object { } `; -exports[`agent configuration queries fetches configurations 1`] = ` +exports[`agent configuration queries getExistingEnvironmentsForService fetches unavailable environments 1`] = ` +Object { + "body": Object { + "aggs": Object { + "environments": Object { + "terms": Object { + "field": "service.environment", + "missing": "ALL_OPTION_VALUE", + "size": 50, + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "term": Object { + "service.name": "foo", + }, + }, + ], + }, + }, + "size": 0, + }, + "index": "myIndex", +} +`; + +exports[`agent configuration queries getServiceNames fetches service names 1`] = ` +Object { + "body": Object { + "aggs": Object { + "services": Object { + "terms": Object { + "field": "service.name", + "size": 50, + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "terms": Object { + "processor.event": Array [ + "transaction", + "error", + "metric", + ], + }, + }, + ], + }, + }, + "size": 0, + }, + "index": Array [ + "myIndex", + "myIndex", + "myIndex", + ], +} +`; + +exports[`agent configuration queries listConfigurations fetches configurations 1`] = ` Object { "index": "myIndex", "size": 200, } `; -exports[`agent configuration queries fetches filtered configurations with an environment 1`] = ` +exports[`agent configuration queries searchConfigurations fetches filtered configurations with an environment 1`] = ` Object { "body": Object { "query": Object { @@ -60,9 +209,7 @@ Object { "boost": 2, "filter": Object { "term": Object { - "service.name": Object { - "value": "foo", - }, + "service.name": "foo", }, }, }, @@ -72,9 +219,7 @@ Object { "boost": 1, "filter": Object { "term": Object { - "service.environment": Object { - "value": "bar", - }, + "service.environment": "bar", }, }, }, @@ -109,7 +254,7 @@ Object { } `; -exports[`agent configuration queries fetches filtered configurations without an environment 1`] = ` +exports[`agent configuration queries searchConfigurations fetches filtered configurations without an environment 1`] = ` Object { "body": Object { "query": Object { @@ -121,9 +266,7 @@ Object { "boost": 2, "filter": Object { "term": Object { - "service.name": Object { - "value": "foo", - }, + "service.name": "foo", }, }, }, @@ -157,68 +300,3 @@ Object { "index": "myIndex", } `; - -exports[`agent configuration queries fetches service names 1`] = ` -Object { - "body": Object { - "aggs": Object { - "services": Object { - "terms": Object { - "field": "service.name", - "size": 50, - }, - }, - }, - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "terms": Object { - "processor.event": Array [ - "transaction", - "error", - "metric", - ], - }, - }, - ], - }, - }, - "size": 0, - }, - "index": Array [ - "myIndex", - "myIndex", - "myIndex", - ], -} -`; - -exports[`agent configuration queries fetches unavailable environments 1`] = ` -Object { - "body": Object { - "aggs": Object { - "environments": Object { - "terms": Object { - "field": "service.environment", - "missing": "ALL_OPTION_VALUE", - "size": 50, - }, - }, - }, - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "term": Object { - "service.name": "foo", - }, - }, - ], - }, - }, - "size": 0, - }, - "index": "myIndex", -} -`; diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/configuration_types.d.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/configuration_types.d.ts index ea8f50c90c1d3a..ddbe6892c54414 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/configuration_types.d.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/configuration_types.d.ts @@ -4,18 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -export interface AgentConfiguration { +import t from 'io-ts'; +import { agentConfigurationIntakeRt } from '../../../../common/runtime_types/agent_configuration_intake_rt'; + +export type AgentConfigurationIntake = t.TypeOf< + typeof agentConfigurationIntakeRt +>; +export type AgentConfiguration = { '@timestamp': number; applied_by_agent?: boolean; etag?: string; agent_name?: string; - service: { - name?: string; - environment?: string; - }; - settings: { - transaction_sample_rate?: number; - capture_body?: string; - transaction_max_spans?: number; - }; -} +} & AgentConfigurationIntake; diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts index 5a67f78de6f652..74fcc61dde863c 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/create_or_update_configuration.ts @@ -6,19 +6,19 @@ import hash from 'object-hash'; import { Setup } from '../../helpers/setup_request'; -import { AgentConfiguration } from './configuration_types'; +import { + AgentConfiguration, + AgentConfigurationIntake +} from './configuration_types'; import { APMIndexDocumentParams } from '../../helpers/es_client'; export async function createOrUpdateConfiguration({ configurationId, - configuration, + configurationIntake, setup }: { configurationId?: string; - configuration: Omit< - AgentConfiguration, - '@timestamp' | 'applied_by_agent' | 'etag' - >; + configurationIntake: AgentConfigurationIntake; setup: Setup; }) { const { internalClient, indices } = setup; @@ -27,15 +27,15 @@ export async function createOrUpdateConfiguration({ refresh: true, index: indices.apmAgentConfigurationIndex, body: { - agent_name: configuration.agent_name, + agent_name: configurationIntake.agent_name, service: { - name: configuration.service.name, - environment: configuration.service.environment + name: configurationIntake.service.name, + environment: configurationIntake.service.environment }, - settings: configuration.settings, + settings: configurationIntake.settings, '@timestamp': Date.now(), applied_by_agent: false, - etag: hash(configuration) + etag: hash(configurationIntake) } }; diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/find_exact_configuration.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/find_exact_configuration.ts new file mode 100644 index 00000000000000..eea409882f8763 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/find_exact_configuration.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + SERVICE_NAME, + SERVICE_ENVIRONMENT +} from '../../../../common/elasticsearch_fieldnames'; +import { Setup } from '../../helpers/setup_request'; +import { AgentConfiguration } from './configuration_types'; +import { ESSearchHit } from '../../../../typings/elasticsearch'; + +export async function findExactConfiguration({ + service, + setup +}: { + service: AgentConfiguration['service']; + setup: Setup; +}) { + const { internalClient, indices } = setup; + + const serviceNameFilter = service.name + ? { term: { [SERVICE_NAME]: service.name } } + : { bool: { must_not: [{ exists: { field: SERVICE_NAME } }] } }; + + const environmentFilter = service.environment + ? { term: { [SERVICE_ENVIRONMENT]: service.environment } } + : { bool: { must_not: [{ exists: { field: SERVICE_ENVIRONMENT } }] } }; + + const params = { + index: indices.apmAgentConfigurationIndex, + body: { + query: { + bool: { filter: [serviceNameFilter, environmentFilter] } + } + } + }; + + const resp = await internalClient.search( + params + ); + + return resp.hits.hits[0] as ESSearchHit | undefined; +} diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_agent_name_by_service.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_agent_name_by_service.ts index dccf8b110d082b..a9af1f6174fd51 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_agent_name_by_service.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_agent_name_by_service.ts @@ -48,8 +48,6 @@ export async function getAgentNameByService({ }; const { aggregations } = await client.search(params); - const agentName = aggregations?.agent_names.buckets[0].key as - | string - | undefined; - return { agentName }; + const agentName = aggregations?.agent_names.buckets[0]?.key; + return agentName as string | undefined; } diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/queries.test.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/queries.test.ts index a82d148781ad88..b951b7f350eed4 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/queries.test.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/queries.test.ts @@ -8,11 +8,12 @@ import { getAllEnvironments } from './get_environments/get_all_environments'; import { getExistingEnvironmentsForService } from './get_environments/get_existing_environments_for_service'; import { getServiceNames } from './get_service_names'; import { listConfigurations } from './list_configurations'; -import { searchConfigurations } from './search'; +import { searchConfigurations } from './search_configurations'; import { SearchParamsMock, inspectSearchParams } from '../../../../../../legacy/plugins/apm/public/utils/testHelpers'; +import { findExactConfiguration } from './find_exact_configuration'; describe('agent configuration queries', () => { let mock: SearchParamsMock; @@ -21,68 +22,117 @@ describe('agent configuration queries', () => { mock.teardown(); }); - it('fetches all environments', async () => { - mock = await inspectSearchParams(setup => - getAllEnvironments({ - serviceName: 'foo', - setup - }) - ); + describe('getAllEnvironments', () => { + it('fetches all environments', async () => { + mock = await inspectSearchParams(setup => + getAllEnvironments({ + serviceName: 'foo', + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); }); - it('fetches unavailable environments', async () => { - mock = await inspectSearchParams(setup => - getExistingEnvironmentsForService({ - serviceName: 'foo', - setup - }) - ); + describe('getExistingEnvironmentsForService', () => { + it('fetches unavailable environments', async () => { + mock = await inspectSearchParams(setup => + getExistingEnvironmentsForService({ + serviceName: 'foo', + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); }); - it('fetches service names', async () => { - mock = await inspectSearchParams(setup => - getServiceNames({ - setup - }) - ); + describe('getServiceNames', () => { + it('fetches service names', async () => { + mock = await inspectSearchParams(setup => + getServiceNames({ + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); }); - it('fetches configurations', async () => { - mock = await inspectSearchParams(setup => - listConfigurations({ - setup - }) - ); + describe('listConfigurations', () => { + it('fetches configurations', async () => { + mock = await inspectSearchParams(setup => + listConfigurations({ + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); }); - it('fetches filtered configurations without an environment', async () => { - mock = await inspectSearchParams(setup => - searchConfigurations({ - serviceName: 'foo', - setup - }) - ); + describe('searchConfigurations', () => { + it('fetches filtered configurations without an environment', async () => { + mock = await inspectSearchParams(setup => + searchConfigurations({ + service: { + name: 'foo' + }, + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); + + it('fetches filtered configurations with an environment', async () => { + mock = await inspectSearchParams(setup => + searchConfigurations({ + service: { + name: 'foo', + environment: 'bar' + }, + setup + }) + ); + + expect(mock.params).toMatchSnapshot(); + }); }); - it('fetches filtered configurations with an environment', async () => { - mock = await inspectSearchParams(setup => - searchConfigurations({ - serviceName: 'foo', - environment: 'bar', - setup - }) - ); + describe('findExactConfiguration', () => { + it('find configuration by service.name', async () => { + mock = await inspectSearchParams(setup => + findExactConfiguration({ + service: { name: 'foo' }, + setup + }) + ); + + expect(mock.params).toMatchSnapshot(); + }); + + it('find configuration by service.environment', async () => { + mock = await inspectSearchParams(setup => + findExactConfiguration({ + service: { environment: 'bar' }, + setup + }) + ); + + expect(mock.params).toMatchSnapshot(); + }); + + it('find configuration by service.name and service.environment', async () => { + mock = await inspectSearchParams(setup => + findExactConfiguration({ + service: { name: 'foo', environment: 'bar' }, + setup + }) + ); - expect(mock.params).toMatchSnapshot(); + expect(mock.params).toMatchSnapshot(); + }); }); }); diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/search.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/search_configurations.ts similarity index 68% rename from x-pack/plugins/apm/server/lib/settings/agent_configuration/search.ts rename to x-pack/plugins/apm/server/lib/settings/agent_configuration/search_configurations.ts index 766baead006b6e..9bbdc96a3a7974 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/search.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/search_configurations.ts @@ -12,29 +12,39 @@ import { Setup } from '../../helpers/setup_request'; import { AgentConfiguration } from './configuration_types'; export async function searchConfigurations({ - serviceName, - environment, + service, setup }: { - serviceName: string; - environment?: string; + service: AgentConfiguration['service']; setup: Setup; }) { const { internalClient, indices } = setup; - const environmentFilter = environment + + // In the following `constant_score` is being used to disable IDF calculation (where frequency of a term influences scoring). + // Additionally a boost has been added to service.name to ensure it scores higher. + // If there is tie between a config with a matching service.name and a config with a matching environment, the config that matches service.name wins + const serviceNameFilter = service.name + ? [ + { + constant_score: { + filter: { term: { [SERVICE_NAME]: service.name } }, + boost: 2 + } + } + ] + : []; + + const environmentFilter = service.environment ? [ { constant_score: { - filter: { term: { [SERVICE_ENVIRONMENT]: { value: environment } } }, + filter: { term: { [SERVICE_ENVIRONMENT]: service.environment } }, boost: 1 } } ] : []; - // In the following `constant_score` is being used to disable IDF calculation (where frequency of a term influences scoring) - // Additionally a boost has been added to service.name to ensure it scores higher - // if there is tie between a config with a matching service.name and a config with a matching environment const params = { index: indices.apmAgentConfigurationIndex, body: { @@ -42,12 +52,7 @@ export async function searchConfigurations({ bool: { minimum_should_match: 2, should: [ - { - constant_score: { - filter: { term: { [SERVICE_NAME]: { value: serviceName } } }, - boost: 2 - } - }, + ...serviceNameFilter, ...environmentFilter, { bool: { must_not: [{ exists: { field: SERVICE_NAME } }] } }, { bool: { must_not: [{ exists: { field: SERVICE_ENVIRONMENT } }] } } diff --git a/x-pack/plugins/apm/server/routes/create_apm_api.ts b/x-pack/plugins/apm/server/routes/create_apm_api.ts index f65e271389938a..21392edbb2c48f 100644 --- a/x-pack/plugins/apm/server/routes/create_apm_api.ts +++ b/x-pack/plugins/apm/server/routes/create_apm_api.ts @@ -23,11 +23,10 @@ import { import { agentConfigurationRoute, agentConfigurationSearchRoute, - createAgentConfigurationRoute, deleteAgentConfigurationRoute, listAgentConfigurationEnvironmentsRoute, listAgentConfigurationServicesRoute, - updateAgentConfigurationRoute, + createOrUpdateAgentConfigurationRoute, agentConfigurationAgentNameRoute } from './settings/agent_configuration'; import { @@ -83,11 +82,10 @@ const createApmApi = () => { .add(agentConfigurationAgentNameRoute) .add(agentConfigurationRoute) .add(agentConfigurationSearchRoute) - .add(createAgentConfigurationRoute) .add(deleteAgentConfigurationRoute) .add(listAgentConfigurationEnvironmentsRoute) .add(listAgentConfigurationServicesRoute) - .add(updateAgentConfigurationRoute) + .add(createOrUpdateAgentConfigurationRoute) // APM indices .add(apmIndexSettingsRoute) diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts index ddd6a270251310..83b845b1fc4365 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts @@ -9,15 +9,19 @@ import Boom from 'boom'; import { setupRequest } from '../../lib/helpers/setup_request'; import { getServiceNames } from '../../lib/settings/agent_configuration/get_service_names'; import { createOrUpdateConfiguration } from '../../lib/settings/agent_configuration/create_or_update_configuration'; -import { searchConfigurations } from '../../lib/settings/agent_configuration/search'; +import { searchConfigurations } from '../../lib/settings/agent_configuration/search_configurations'; +import { findExactConfiguration } from '../../lib/settings/agent_configuration/find_exact_configuration'; import { listConfigurations } from '../../lib/settings/agent_configuration/list_configurations'; import { getEnvironments } from '../../lib/settings/agent_configuration/get_environments'; import { deleteConfiguration } from '../../lib/settings/agent_configuration/delete_configuration'; import { createRoute } from '../create_route'; -import { transactionSampleRateRt } from '../../../common/runtime_types/transaction_sample_rate_rt'; -import { transactionMaxSpansRt } from '../../../common/runtime_types/transaction_max_spans_rt'; import { getAgentNameByService } from '../../lib/settings/agent_configuration/get_agent_name_by_service'; import { markAppliedByAgent } from '../../lib/settings/agent_configuration/mark_applied_by_agent'; +import { + serviceRt, + agentConfigurationIntakeRt +} from '../../../common/runtime_types/agent_configuration_intake_rt'; +import { jsonRt } from '../../../common/runtime_types/json_rt'; // get list of configurations export const agentConfigurationRoute = createRoute(core => ({ @@ -31,20 +35,34 @@ export const agentConfigurationRoute = createRoute(core => ({ // delete configuration export const deleteAgentConfigurationRoute = createRoute(() => ({ method: 'DELETE', - path: '/api/apm/settings/agent-configuration/{configurationId}', + path: '/api/apm/settings/agent-configuration', options: { tags: ['access:apm', 'access:apm_write'] }, params: { - path: t.type({ - configurationId: t.string + body: t.type({ + service: serviceRt }) }, handler: async ({ context, request }) => { const setup = await setupRequest(context, request); - const { configurationId } = context.params.path; + const { service } = context.params.body; + + const config = await findExactConfiguration({ service, setup }); + if (!config) { + context.logger.info( + `Config was not found for ${service.name}/${service.environment}` + ); + + throw Boom.notFound(); + } + + context.logger.info( + `Deleting config ${service.name}/${service.environment} (${config._id})` + ); + return await deleteConfiguration({ - configurationId, + configurationId: config._id, setup }); } @@ -62,23 +80,6 @@ export const listAgentConfigurationServicesRoute = createRoute(() => ({ } })); -const agentPayloadRt = t.intersection([ - t.partial({ agent_name: t.string }), - t.type({ - service: t.intersection([ - t.partial({ name: t.string }), - t.partial({ environment: t.string }) - ]) - }), - t.type({ - settings: t.intersection([ - t.partial({ transaction_sample_rate: transactionSampleRateRt }), - t.partial({ capture_body: t.string }), - t.partial({ transaction_max_spans: transactionMaxSpansRt }) - ]) - }) -]); - // get environments for service export const listAgentConfigurationEnvironmentsRoute = createRoute(() => ({ path: '/api/apm/settings/agent-configuration/environments', @@ -102,55 +103,47 @@ export const agentConfigurationAgentNameRoute = createRoute(() => ({ const setup = await setupRequest(context, request); const { serviceName } = context.params.query; const agentName = await getAgentNameByService({ serviceName, setup }); - return agentName; + return { agentName }; } })); -export const createAgentConfigurationRoute = createRoute(() => ({ - method: 'POST', - path: '/api/apm/settings/agent-configuration/new', - params: { - body: agentPayloadRt - }, +export const createOrUpdateAgentConfigurationRoute = createRoute(() => ({ + method: 'PUT', + path: '/api/apm/settings/agent-configuration', options: { tags: ['access:apm', 'access:apm_write'] }, + params: { + query: t.partial({ overwrite: jsonRt.pipe(t.boolean) }), + body: agentConfigurationIntakeRt + }, handler: async ({ context, request }) => { const setup = await setupRequest(context, request); - const configuration = context.params.body; + const { body, query } = context.params; - // TODO: Remove logger. Only added temporarily to debug flaky test (https://github.com/elastic/kibana/issues/51764) - context.logger.info( - `Hitting: /api/apm/settings/agent-configuration/new with ${configuration.service.name}/${configuration.service.environment}` - ); - const res = await createOrUpdateConfiguration({ - configuration, + // if the config already exists, it is fetched and updated + // this is to avoid creating two configs with identical service params + const config = await findExactConfiguration({ + service: body.service, setup }); - context.logger.info(`Created agent configuration`); - return res; - } -})); + // if the config exists ?overwrite=true is required + if (config && !query.overwrite) { + throw Boom.badRequest( + `A configuration already exists for "${body.service.name}/${body.service.environment}. Use ?overwrite=true to overwrite the existing configuration.` + ); + } + + context.logger.info( + `${config ? 'Updating' : 'Creating'} config ${body.service.name}/${ + body.service.environment + }` + ); -export const updateAgentConfigurationRoute = createRoute(() => ({ - method: 'PUT', - path: '/api/apm/settings/agent-configuration/{configurationId}', - options: { - tags: ['access:apm', 'access:apm_write'] - }, - params: { - path: t.type({ - configurationId: t.string - }), - body: agentPayloadRt - }, - handler: async ({ context, request }) => { - const setup = await setupRequest(context, request); - const { configurationId } = context.params.path; return await createOrUpdateConfiguration({ - configurationId, - configuration: context.params.body, + configurationId: config?._id, + configurationIntake: body, setup }); } @@ -162,41 +155,33 @@ export const agentConfigurationSearchRoute = createRoute(core => ({ path: '/api/apm/settings/agent-configuration/search', params: { body: t.type({ - service: t.intersection([ - t.type({ name: t.string }), - t.partial({ environment: t.string }) - ]), + service: serviceRt, etag: t.string }) }, handler: async ({ context, request }) => { - const { body } = context.params; - - // TODO: Remove logger. Only added temporarily to debug flaky test (https://github.com/elastic/kibana/issues/51764) - context.logger.info( - `Hitting: /api/apm/settings/agent-configuration/search for ${body.service.name}/${body.service.environment}` - ); + const { service, etag } = context.params.body; const setup = await setupRequest(context, request); const config = await searchConfigurations({ - serviceName: body.service.name, - environment: body.service.environment, + service, setup }); if (!config) { context.logger.info( - `Config was not found for ${body.service.name}/${body.service.environment}` + `Config was not found for ${service.name}/${service.environment}` ); - throw new Boom('Not found', { statusCode: 404 }); + throw Boom.notFound(); } context.logger.info( - `Config was found for ${body.service.name}/${body.service.environment}` + `Config was found for ${service.name}/${service.environment}` ); // update `applied_by_agent` field if etags match - if (body.etag === config._source.etag && !config._source.applied_by_agent) { + // this happens in the background and doesn't block the response + if (etag === config._source.etag && !config._source.applied_by_agent) { markAppliedByAgent({ id: config._id, body: config._source, setup }); } diff --git a/x-pack/test/api_integration/apis/apm/agent_configuration.ts b/x-pack/test/api_integration/apis/apm/agent_configuration.ts index 12e08869fa5861..959a0c97acfa3d 100644 --- a/x-pack/test/api_integration/apis/apm/agent_configuration.ts +++ b/x-pack/test/api_integration/apis/apm/agent_configuration.ts @@ -5,6 +5,7 @@ */ import expect from '@kbn/expect'; +import { AgentConfigurationIntake } from '../../../../plugins/apm/server/lib/settings/agent_configuration/configuration_types'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function agentConfigurationTests({ getService }: FtrProviderContext) { @@ -18,108 +19,122 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte .set('kbn-xsrf', 'foo'); } - let createdConfigIds: any[] = []; - async function createConfiguration(configuration: any) { + async function createConfiguration(config: AgentConfigurationIntake) { + log.debug('creating configuration', config.service); const res = await supertest - .post(`/api/apm/settings/agent-configuration/new`) - .send(configuration) + .put(`/api/apm/settings/agent-configuration`) + .send(config) .set('kbn-xsrf', 'foo'); - createdConfigIds.push(res.body._id); + throwOnError(res); return res; } - function deleteCreatedConfigurations() { - const promises = Promise.all(createdConfigIds.map(deleteConfiguration)); - return promises; + async function updateConfiguration(config: AgentConfigurationIntake) { + log.debug('updating configuration', config.service); + const res = await supertest + .put(`/api/apm/settings/agent-configuration?overwrite=true`) + .send(config) + .set('kbn-xsrf', 'foo'); + + throwOnError(res); + + return res; } - function deleteConfiguration(configurationId: string) { - return supertest - .delete(`/api/apm/settings/agent-configuration/${configurationId}`) - .set('kbn-xsrf', 'foo') - .then((response: any) => { - createdConfigIds = createdConfigIds.filter(id => id === configurationId); - return response; - }); + async function deleteConfiguration({ service }: AgentConfigurationIntake) { + log.debug('deleting configuration', service); + const res = await supertest + .delete(`/api/apm/settings/agent-configuration`) + .send({ service }) + .set('kbn-xsrf', 'foo'); + + throwOnError(res); + + return res; + } + + function throwOnError(res: any) { + const { statusCode, req, body } = res; + if (statusCode !== 200) { + throw new Error(` + Endpoint: ${req.method} ${req.path} + Service: ${JSON.stringify(res.request._data.service)} + Status code: ${statusCode} + Response: ${body.message}`); + } } describe('agent configuration', () => { describe('when creating one configuration', () => { - let createdConfigId: string; + const newConfig = { + service: {}, + settings: { transaction_sample_rate: 0.55 }, + }; - const parameters = { + const searchParams = { service: { name: 'myservice', environment: 'development' }, etag: '7312bdcc34999629a3d39df24ed9b2a7553c0c39', }; before(async () => { - log.debug('creating agent configuration'); - - // all / all - const { body } = await createConfiguration({ - service: {}, - settings: { transaction_sample_rate: 0.1 }, - }); - - createdConfigId = body._id; + await createConfiguration(newConfig); }); - it('returns the created configuration', async () => { - const { statusCode, body } = await searchConfigurations(parameters); - + it('can find the created config', async () => { + const { statusCode, body } = await searchConfigurations(searchParams); expect(statusCode).to.equal(200); - expect(body._id).to.equal(createdConfigId); + expect(body._source.service).to.eql({}); + expect(body._source.settings).to.eql({ transaction_sample_rate: 0.55 }); }); - it('succesfully deletes the configuration', async () => { - await deleteConfiguration(createdConfigId); + it('can update the created config', async () => { + await updateConfiguration({ service: {}, settings: { transaction_sample_rate: 0.85 } }); - const { statusCode } = await searchConfigurations(parameters); + const { statusCode, body } = await searchConfigurations(searchParams); + expect(statusCode).to.equal(200); + expect(body._source.service).to.eql({}); + expect(body._source.settings).to.eql({ transaction_sample_rate: 0.85 }); + }); + it('can delete the created config', async () => { + await deleteConfiguration(newConfig); + const { statusCode } = await searchConfigurations(searchParams); expect(statusCode).to.equal(404); }); }); - describe('when creating four configurations', () => { - before(async () => { - log.debug('creating agent configuration'); - - // all / all - await createConfiguration({ + describe('when creating multiple configurations', () => { + const configs = [ + { service: {}, settings: { transaction_sample_rate: 0.1 }, - }); - - // my_service / all - await createConfiguration({ + }, + { service: { name: 'my_service' }, settings: { transaction_sample_rate: 0.2 }, - }); - - // all / production - await createConfiguration({ - service: { environment: 'production' }, + }, + { + service: { name: 'my_service', environment: 'development' }, settings: { transaction_sample_rate: 0.3 }, - }); - - // all / production - await createConfiguration({ - service: { environment: 'development' }, + }, + { + service: { environment: 'production' }, settings: { transaction_sample_rate: 0.4 }, - }); - - // my_service / production - await createConfiguration({ - service: { name: 'my_service', environment: 'development' }, + }, + { + service: { environment: 'development' }, settings: { transaction_sample_rate: 0.5 }, - }); + }, + ]; + + before(async () => { + await Promise.all(configs.map(config => createConfiguration(config))); }); after(async () => { - log.debug('deleting agent configurations'); - await deleteCreatedConfigurations(); + await Promise.all(configs.map(config => deleteConfiguration(config))); }); const agentsRequests = [ @@ -127,20 +142,24 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte service: { name: 'non_existing_service', environment: 'non_existing_env' }, expectedSettings: { transaction_sample_rate: 0.1 }, }, + { + service: { name: 'my_service', environment: 'non_existing_env' }, + expectedSettings: { transaction_sample_rate: 0.2 }, + }, { service: { name: 'my_service', environment: 'production' }, expectedSettings: { transaction_sample_rate: 0.2 }, }, { - service: { name: 'non_existing_service', environment: 'production' }, + service: { name: 'my_service', environment: 'development' }, expectedSettings: { transaction_sample_rate: 0.3 }, }, { - service: { name: 'non_existing_service', environment: 'development' }, + service: { name: 'non_existing_service', environment: 'production' }, expectedSettings: { transaction_sample_rate: 0.4 }, }, { - service: { name: 'my_service', environment: 'development' }, + service: { name: 'non_existing_service', environment: 'development' }, expectedSettings: { transaction_sample_rate: 0.5 }, }, ]; @@ -159,18 +178,18 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte }); describe('when an agent retrieves a configuration', () => { + const config = { + service: { name: 'myservice', environment: 'development' }, + settings: { transaction_sample_rate: 0.9 }, + }; + before(async () => { log.debug('creating agent configuration'); - - await createConfiguration({ - service: { name: 'myservice', environment: 'development' }, - settings: { transaction_sample_rate: 0.9 }, - }); + await createConfiguration(config); }); after(async () => { - log.debug('deleting agent configurations'); - await deleteCreatedConfigurations(); + await deleteConfiguration(config); }); it(`should have 'applied_by_agent=false' on first request`, async () => { diff --git a/x-pack/test/api_integration/apis/apm/feature_controls.ts b/x-pack/test/api_integration/apis/apm/feature_controls.ts index ec2bbca23ddd28..3c5314d0d32613 100644 --- a/x-pack/test/api_integration/apis/apm/feature_controls.ts +++ b/x-pack/test/api_integration/apis/apm/feature_controls.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-console */ - import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -14,8 +12,8 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const supertestWithoutAuth = getService('supertestWithoutAuth'); const security = getService('security'); const spaces = getService('spaces'); - const log = getService('log'); const es = getService('legacyEs'); + const log = getService('log'); const start = encodeURIComponent(new Date(Date.now() - 10000).toISOString()); const end = encodeURIComponent(new Date().toISOString()); @@ -33,7 +31,7 @@ export default function featureControlsTests({ getService }: FtrProviderContext) interface Endpoint { req: { url: string; - method?: 'get' | 'post' | 'delete'; + method?: 'get' | 'post' | 'delete' | 'put'; body?: any; }; expectForbidden: (result: any) => void; @@ -148,7 +146,7 @@ export default function featureControlsTests({ getService }: FtrProviderContext) index: '.apm-agent-configuration', }); - console.warn(JSON.stringify(res, null, 2)); + log.error(JSON.stringify(res, null, 2)); }, }, ]; @@ -196,7 +194,7 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const { statusCode, req } = response; if (statusCode !== 200) { - log.debug(`Endpoint: ${req.method} ${req.path} + throw new Error(`Endpoint: ${req.method} ${req.path} Status code: ${statusCode} Response: ${response.body.message}`); } @@ -216,9 +214,9 @@ export default function featureControlsTests({ getService }: FtrProviderContext) spaceId?: string; }) { for (const endpoint of endpoints) { - console.log(`Requesting: ${endpoint.req.url}. Expecting: ${expectation}`); + log.info(`Requesting: ${endpoint.req.url}. Expecting: ${expectation}`); const result = await executeAsUser(endpoint.req, username, password, spaceId); - console.log(`Responded: ${endpoint.req.url}`); + log.info(`Responded: ${endpoint.req.url}`); try { if (expectation === 'forbidden') { @@ -244,26 +242,28 @@ export default function featureControlsTests({ getService }: FtrProviderContext) } describe('apm feature controls', () => { - let res: any; + const config = { + service: { name: 'test-service' }, + settings: { transaction_sample_rate: 0.5 }, + }; before(async () => { - console.log(`Creating agent configuration`); - res = await executeAsAdmin({ - method: 'post', - url: '/api/apm/settings/agent-configuration/new', - body: { - service: { name: 'test-service' }, - settings: { transaction_sample_rate: 0.5 }, - }, + log.info(`Creating agent configuration`); + await executeAsAdmin({ + method: 'put', + url: '/api/apm/settings/agent-configuration', + body: config, }); - console.log(`Agent configuration created`); + log.info(`Agent configuration created`); }); after(async () => { - console.log('deleting agent configuration'); - const configurationId = res.body._id; + log.info('deleting agent configuration'); await executeAsAdmin({ method: 'delete', - url: `/api/apm/settings/agent-configuration/${configurationId}`, + url: `/api/apm/settings/agent-configuration`, + body: { + service: config.service, + }, }); }); diff --git a/x-pack/test/api_integration/apis/apm/index.ts b/x-pack/test/api_integration/apis/apm/index.ts index c49d5775370485..6f41f4abfecc3a 100644 --- a/x-pack/test/api_integration/apis/apm/index.ts +++ b/x-pack/test/api_integration/apis/apm/index.ts @@ -7,7 +7,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function apmApiIntegrationTests({ loadTestFile }: FtrProviderContext) { - describe('APM', () => { + describe('APM specs', () => { loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./agent_configuration')); }); diff --git a/x-pack/test/functional/apps/apm/index.ts b/x-pack/test/functional/apps/apm/index.ts index 945af09183f03d..bf254f9b9b4193 100644 --- a/x-pack/test/functional/apps/apm/index.ts +++ b/x-pack/test/functional/apps/apm/index.ts @@ -6,7 +6,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function({ loadTestFile }: FtrProviderContext) { - describe('APM', function() { + describe('APM specs', function() { this.tags('ciGroup6'); loadTestFile(require.resolve('./feature_controls')); }); From 5eefdbb84266e2af1998c35d4876f18bc13d1fe0 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Mon, 24 Feb 2020 16:46:58 -0600 Subject: [PATCH 17/73] [Uptime] Use scripted metric for snapshot calculation (#58247) (#58389) Fixes #58079 This is an improved version of #58078 Note, this is a bugfix targeting 7.6.1 . I've decided to open this PR directly against 7.6 in the interest of time. We can forward-port this to 7.x / master later. This patch improves the handling of timespans with snapshot counts. This feature originally worked, but suffered a regression when we increased the default timespan in the query context to 5m. This means that without this patch the counts you get are the maximum total number of monitors that were down over the past 5m, which is not really that useful. We now use a scripted metric to always count precisely the number of up/down monitors. On my box this could process 400k summary docs in ~600ms. This should scale as shards are added. I attempted to keep memory usage relatively slow by using simple maps of strings. --- .../lib/requests/get_snapshot_counts.ts | 194 +++++++++++++----- .../apis/uptime/rest/snapshot.ts | 105 +++++----- 2 files changed, 192 insertions(+), 107 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts b/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts index 62369711460159..8d84c0f4d6769f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts @@ -6,7 +6,7 @@ import { UMElasticsearchQueryFn } from '../adapters'; import { Snapshot } from '../../../common/runtime_types'; -import { QueryContext, MonitorGroupIterator } from './search'; +import { QueryContext } from './search'; import { CONTEXT_DEFAULTS, INDEX_NAMES } from '../../../common/constants'; export interface GetSnapshotCountParams { @@ -16,49 +16,6 @@ export interface GetSnapshotCountParams { statusFilter?: string; } -const fastStatusCount = async (context: QueryContext): Promise => { - const params = { - index: INDEX_NAMES.HEARTBEAT, - body: { - size: 0, - query: { bool: { filter: await context.dateAndCustomFilters() } }, - aggs: { - unique: { - // We set the precision threshold to 40k which is the max precision supported by cardinality - cardinality: { field: 'monitor.id', precision_threshold: 40000 }, - }, - down: { - filter: { range: { 'summary.down': { gt: 0 } } }, - aggs: { - unique: { cardinality: { field: 'monitor.id', precision_threshold: 40000 } }, - }, - }, - }, - }, - }; - - const statistics = await context.search(params); - const total = statistics.aggregations.unique.value; - const down = statistics.aggregations.down.unique.value; - - return { - total, - down, - up: total - down, - }; -}; - -const slowStatusCount = async (context: QueryContext, status: string): Promise => { - const downContext = context.clone(); - downContext.statusFilter = status; - const iterator = new MonitorGroupIterator(downContext); - let count = 0; - while (await iterator.next()) { - count++; - } - return count; -}; - export const getSnapshotCount: UMElasticsearchQueryFn = async ({ callES, dateRangeStart, @@ -81,18 +38,7 @@ export const getSnapshotCount: UMElasticsearchQueryFn = - counts.up > counts.down ? ['down', 'up'] : ['up', 'down']; - counts[leastCommonStatus] = await slowStatusCount(context, leastCommonStatus); - counts[mostCommonStatus] = counts.total - counts[leastCommonStatus]; - } + const counts = await statusCount(context); return { total: statusFilter ? counts[statusFilter] : counts.total, @@ -100,3 +46,139 @@ export const getSnapshotCount: UMElasticsearchQueryFn => { + const res = await context.search({ + index: INDEX_NAMES.HEARTBEAT, + body: statusCountBody(await context.dateAndCustomFilters()), + }); + + return res.aggregations.counts.value; +}; + +const statusCountBody = (filters: any): any => { + return { + size: 0, + query: { + bool: { + filter: [ + { + exists: { + field: 'summary', + }, + }, + filters, + ], + }, + }, + aggs: { + counts: { + scripted_metric: { + init_script: 'state.locStatus = new HashMap(); state.totalDocs = 0;', + map_script: ` + def loc = doc["observer.geo.name"].size() == 0 ? "" : doc["observer.geo.name"][0]; + + // One concern here is memory since we could build pretty gigantic maps. I've opted to + // stick to a simple map to reduce memory overhead. This means we do + // a little string parsing to treat these strings as records that stay lexicographically + // sortable (which is important later). + // We encode the ID and location as $id.len:$id$loc + String id = doc["monitor.id"][0]; + String idLenDelim = Integer.toHexString(id.length()) + ":" + id; + String idLoc = loc == null ? idLenDelim : idLenDelim + loc; + + String status = doc["summary.down"][0] > 0 ? "d" : "u"; + String timeAndStatus = doc["@timestamp"][0].toInstant().toEpochMilli().toString() + status; + state.locStatus[idLoc] = timeAndStatus; + state.totalDocs++; + `, + combine_script: ` + return state; + `, + reduce_script: ` + // Use a treemap since it's traversable in sorted order. + // This is important later. + TreeMap locStatus = new TreeMap(); + long totalDocs = 0; + int uniqueIds = 0; + for (state in states) { + totalDocs += state.totalDocs; + for (entry in state.locStatus.entrySet()) { + // Update the value for the given key if we have a more recent check from this location. + locStatus.merge(entry.getKey(), entry.getValue(), (a,b) -> a.compareTo(b) > 0 ? a : b) + } + } + + HashMap locTotals = new HashMap(); + int total = 0; + int down = 0; + String curId = ""; + boolean curIdDown = false; + // We now iterate through our tree map in order, which means records for a given ID + // always are encountered one after the other. This saves us having to make an intermediate + // map. + for (entry in locStatus.entrySet()) { + String idLoc = entry.getKey(); + String timeStatus = entry.getValue(); + + // Parse the length delimited id/location strings described in the map section + int colonIndex = idLoc.indexOf(":"); + int idEnd = Integer.parseInt(idLoc.substring(0, colonIndex), 16) + colonIndex + 1; + String id = idLoc.substring(colonIndex + 1, idEnd); + String loc = idLoc.substring(idEnd, idLoc.length()); + String status = timeStatus.substring(timeStatus.length() - 1); + + // Here we increment counters for the up/down key per location + // We also create a new hashmap in locTotals if we've never seen this location + // before. + locTotals.compute(loc, (k,v) -> { + HashMap res = v; + if (v == null) { + res = new HashMap(); + res.put('up', 0); + res.put('down', 0); + } + + if (status == 'u') { + res.up++; + } else { + res.down++; + } + + return res; + }); + + + // We've encountered a new ID + if (curId != id) { + total++; + curId = id; + if (status == "d") { + curIdDown = true; + down++; + } else { + curIdDown = false; + } + } else if (!curIdDown) { + if (status == "d") { + curIdDown = true; + down++; + } else { + curIdDown = false; + } + } + } + + Map result = new HashMap(); + result.total = total; + result.location_totals = locTotals; + result.up = total - down; + result.down = down; + result.totalDocs = totalDocs; + return result; + `, + }, + }, + }, + }; +}; diff --git a/x-pack/test/api_integration/apis/uptime/rest/snapshot.ts b/x-pack/test/api_integration/apis/uptime/rest/snapshot.ts index b0d97837c770f9..20fe59d149ae8f 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/snapshot.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/snapshot.ts @@ -34,66 +34,69 @@ export default function({ getService }: FtrProviderContext) { let dateRange: { start: string; end: string }; [true, false].forEach(async (includeTimespan: boolean) => { - describe(`with timespans ${includeTimespan ? 'included' : 'missing'}`, async () => { - before(async () => { - const promises: Array> = []; - - // When includeTimespan is false we have to remove the values there. - let mogrify = (d: any) => d; - if ((includeTimespan = false)) { - mogrify = (d: any): any => { - d.monitor.delete('timespan'); + [true, false].forEach(async (includeObserver: boolean) => { + describe(`with timespans=${includeTimespan} and observer=${includeObserver}`, async () => { + before(async () => { + const promises: Array> = []; + + const mogrify = (d: any) => { + if (!includeTimespan) { + delete d.monitor.timespan; + } + if (!includeObserver) { + delete d.observer; + } return d; }; - } - - const makeMonitorChecks = async (monitorId: string, status: 'up' | 'down') => { - return makeChecksWithStatus( - getService('legacyEs'), - monitorId, - checksPerMonitor, - numIps, - scheduleEvery, - {}, - status, - mogrify - ); - }; - for (let i = 0; i < numUpMonitors; i++) { - promises.push(makeMonitorChecks(`up-${i}`, 'up')); - } - for (let i = 0; i < numDownMonitors; i++) { - promises.push(makeMonitorChecks(`down-${i}`, 'down')); - } + const makeMonitorChecks = async (monitorId: string, status: 'up' | 'down') => { + return makeChecksWithStatus( + getService('legacyEs'), + monitorId, + checksPerMonitor, + numIps, + scheduleEvery, + {}, + status, + mogrify + ); + }; - const allResults = await Promise.all(promises); - dateRange = getChecksDateRange(allResults); - }); + for (let i = 0; i < numUpMonitors; i++) { + promises.push(makeMonitorChecks(`up-${i}`, 'up')); + } + for (let i = 0; i < numDownMonitors; i++) { + promises.push(makeMonitorChecks(`down-${i}`, 'down')); + } - it('will count all statuses correctly', async () => { - const apiResponse = await supertest.get( - `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}` - ); + const allResults = await Promise.all(promises); + dateRange = getChecksDateRange(allResults); + }); - expectFixtureEql(apiResponse.body, 'snapshot'); - }); + it('will count all statuses correctly', async () => { + const apiResponse = await supertest.get( + `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}` + ); - it('will fetch a monitor snapshot filtered by down status', async () => { - const statusFilter = 'down'; - const apiResponse = await supertest.get( - `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}&statusFilter=${statusFilter}` - ); + expectFixtureEql(apiResponse.body, 'snapshot'); + }); - expectFixtureEql(apiResponse.body, 'snapshot_filtered_by_down'); - }); + it('will fetch a monitor snapshot filtered by down status', async () => { + const statusFilter = 'down'; + const apiResponse = await supertest.get( + `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}&statusFilter=${statusFilter}` + ); - it('will fetch a monitor snapshot filtered by up status', async () => { - const statusFilter = 'up'; - const apiResponse = await supertest.get( - `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}&statusFilter=${statusFilter}` - ); - expectFixtureEql(apiResponse.body, 'snapshot_filtered_by_up'); + expectFixtureEql(apiResponse.body, 'snapshot_filtered_by_down'); + }); + + it('will fetch a monitor snapshot filtered by up status', async () => { + const statusFilter = 'up'; + const apiResponse = await supertest.get( + `/api/uptime/snapshot/count?dateRangeStart=${dateRange.start}&dateRangeEnd=${dateRange.end}&statusFilter=${statusFilter}` + ); + expectFixtureEql(apiResponse.body, 'snapshot_filtered_by_up'); + }); }); }); }); From a00ebc6f187ffbd920b0e2bf3f92483239ed0c0f Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Mon, 24 Feb 2020 18:44:52 -0500 Subject: [PATCH 18/73] [Uptime] Delete useless try...catch blocks (#58263) * Delete useless try...catch blocks. * Delete unneeded function. Co-authored-by: Elastic Machine --- .../plugins/uptime/public/hooks/use_telemetry.ts | 10 +++------- .../plugins/uptime/server/lib/helper/index.ts | 1 - .../uptime/server/lib/helper/parse_filter_query.ts | 13 ------------- .../server/lib/requests/get_ping_histogram.ts | 4 ++-- 4 files changed, 5 insertions(+), 23 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/helper/parse_filter_query.ts diff --git a/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts b/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts index 15f276174e2cf1..7eb18404decfde 100644 --- a/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts +++ b/x-pack/legacy/plugins/uptime/public/hooks/use_telemetry.ts @@ -22,13 +22,9 @@ const getApiPath = (page?: UptimePage) => { }; const logPageLoad = async (fetch: HttpHandler, page?: UptimePage) => { - try { - await fetch(getApiPath(page), { - method: 'POST', - }); - } catch (e) { - throw e; - } + await fetch(getApiPath(page), { + method: 'POST', + }); }; export const useUptimeTelemetry = (page?: UptimePage) => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts index 0dcbc0a424b5eb..1607c36f1d1b78 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts @@ -7,6 +7,5 @@ export { getFilterClause } from './get_filter_clause'; export { parseRelativeDate } from './get_histogram_interval'; export { getHistogramIntervalFormatted } from './get_histogram_interval_formatted'; -export { parseFilterQuery } from './parse_filter_query'; export { assertCloseTo } from './assert_close_to'; export { objectValuesToArrays } from './object_to_array'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/parse_filter_query.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/parse_filter_query.ts deleted file mode 100644 index 4c73ec53af9b9b..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/parse_filter_query.ts +++ /dev/null @@ -1,13 +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. - */ - -export const parseFilterQuery = (query?: string | null) => { - try { - return query ? JSON.parse(query) : null; - } catch { - return null; - } -}; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts index 3b448dc31659b7..7b8ca4708255c8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -5,7 +5,7 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { parseFilterQuery, getFilterClause } from '../helper'; +import { getFilterClause } from '../helper'; import { INDEX_NAMES, QUERY } from '../../../common/constants'; import { HistogramQueryResult } from './types'; import { HistogramResult } from '../../../common/types'; @@ -27,7 +27,7 @@ export const getPingHistogram: UMElasticsearchQueryFn< GetPingHistogramParams, HistogramResult > = async ({ callES, from, to, filters, monitorId, statusFilter }) => { - const boolFilters = parseFilterQuery(filters); + const boolFilters = filters ? JSON.parse(filters) : null; const additionalFilters = []; if (monitorId) { additionalFilters.push({ match: { 'monitor.id': monitorId } }); From 33334132eaacde693caa3f7b6a337309abd784bb Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 24 Feb 2020 17:07:36 -0700 Subject: [PATCH 19/73] [kbn/optimizer] disable parallelization in terser plugin (#58396) * [kbn/optimizer] disable parallelization in terer plugin * use more workers when building the dist --- .../kbn-optimizer/src/optimizer/optimizer_config.ts | 11 ++++++++++- packages/kbn-optimizer/src/worker/webpack.config.ts | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts index a258e1010fce38..1c8ae265bf6bb8 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts @@ -25,6 +25,15 @@ import { Bundle, WorkerConfig } from '../common'; import { findKibanaPlatformPlugins, KibanaPlatformPlugin } from './kibana_platform_plugins'; import { getBundles } from './get_bundles'; +function pickMaxWorkerCount(dist: boolean) { + // don't break if cpus() returns nothing, or an empty array + const cpuCount = Math.max(Os.cpus()?.length, 1); + // if we're buiding the dist then we can use more of the system's resources to get things done a little quicker + const maxWorkers = dist ? cpuCount - 1 : Math.ceil(cpuCount / 3); + // ensure we always have at least two workers + return Math.max(maxWorkers, 2); +} + interface Options { /** absolute path to root of the repo/build */ repoRoot: string; @@ -110,7 +119,7 @@ export class OptimizerConfig { const maxWorkerCount = process.env.KBN_OPTIMIZER_MAX_WORKERS ? parseInt(process.env.KBN_OPTIMIZER_MAX_WORKERS, 10) - : options.maxWorkerCount ?? Math.max(Math.ceil(Math.max(Os.cpus()?.length, 1) / 3), 2); + : options.maxWorkerCount ?? pickMaxWorkerCount(dist); if (typeof maxWorkerCount !== 'number' || !Number.isFinite(maxWorkerCount)) { throw new TypeError('worker count must be a number'); } diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 22b927d4638d75..3c6ae78bc4d911 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -252,6 +252,7 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) { cache: false, sourceMap: false, extractComments: false, + parallel: false, terserOptions: { compress: false, mangle: false, From 277b38079ee55a5ae088a3a4c6bacf127f5c8968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Tue, 25 Feb 2020 13:12:27 +0530 Subject: [PATCH 20/73] [Index management] Move to new platform "plugins" folder (#58109) --- x-pack/.i18nrc.json | 2 +- .../cross_cluster_replication/index.js | 7 +- .../components/detail_panel/detail_panel.js | 2 +- .../components/detail_panel/detail_panel.js | 7 +- .../public/extend_index_management/index.js | 9 ++- .../__jest__/extend_index_management.test.js | 6 +- .../index_lifecycle_management/plugin.ts | 8 +- .../public/legacy.ts | 4 +- .../components/policy_table/policy_table.js | 2 +- .../np_ready/extend_index_management/index.js | 3 +- .../legacy/plugins/index_management/index.ts | 29 +------ .../index_management/public/index.html | 3 - .../legacy/plugins/remote_clusters/index.ts | 4 +- x-pack/legacy/plugins/rollup/index.ts | 4 +- x-pack/legacy/plugins/rollup/public/legacy.ts | 2 - x-pack/legacy/plugins/rollup/public/plugin.ts | 20 +++-- x-pack/legacy/plugins/rollup/server/plugin.ts | 10 +-- .../rollup/server/rollup_data_enricher.ts | 7 +- x-pack/legacy/plugins/rollup/server/types.ts | 1 - .../client_integration/helpers/constants.ts | 0 .../helpers/home.helpers.ts | 6 +- .../helpers/http_requests.ts | 0 .../client_integration/helpers/index.ts | 2 +- .../helpers/setup_environment.tsx | 3 +- .../helpers/template_clone.helpers.ts | 4 +- .../helpers/template_create.helpers.ts | 4 +- .../helpers/template_edit.helpers.ts | 4 +- .../helpers/template_form.helpers.ts | 2 +- .../__jest__/client_integration/home.test.ts | 0 .../template_clone.test.tsx | 0 .../template_create.test.tsx | 0 .../client_integration/template_edit.test.tsx | 0 .../__snapshots__/index_table.test.js.snap | 0 .../__jest__/components/index_table.test.js | 4 +- .../__snapshots__/flatten_object.test.js.snap | 0 .../__jest__/lib/flatten_object.test.js | 0 .../plugins/index_management/__mocks__/ace.js | 0 .../__mocks__/ui/documentation_links.js | 0 .../index_management/__mocks__/ui/notify.js | 0 .../common/constants/api_base_path.ts | 0 .../common/constants/base_path.ts | 0 .../common/constants/index.ts | 0 .../common/constants/index_statuses.ts | 0 .../common/constants/invalid_characters.ts | 0 .../common/constants/plugin.ts | 2 +- .../common/constants/ui_metric.ts | 0 .../plugins/index_management/common/index.ts | 0 .../index_management/common/lib/index.ts | 0 .../common/lib/template_serialization.ts | 0 .../index_management/common/types/index.ts | 0 .../common/types/templates.ts | 0 x-pack/plugins/index_management/kibana.json | 15 ++++ .../public/application/app.tsx | 2 +- .../public/application/app_context.tsx | 4 +- .../public/application/components/index.ts | 0 .../client_integration/helpers/index.ts | 2 +- .../helpers/mappings_editor.helpers.ts | 2 +- .../mappings_editor.test.tsx | 0 .../components/mappings_editor/_index.scss | 0 .../mappings_editor/components/_index.scss | 0 .../mappings_editor/components/code_block.tsx | 0 .../configuration_form/configuration_form.tsx | 6 +- .../configuration_form_schema.tsx | 0 .../dynamic_mapping_section.tsx | 0 .../dynamic_mapping_section/index.ts | 0 .../components/configuration_form/index.ts | 0 .../meta_field_section/index.ts | 0 .../meta_field_section/meta_field_section.tsx | 0 .../configuration_form/routing_section.tsx | 0 .../source_field_section/index.ts | 0 .../source_field_section.tsx | 0 .../components/document_fields/_index.scss | 0 .../document_fields/document_fields.tsx | 11 ++- .../document_fields_header.tsx | 0 .../editor_toggle_controls.tsx | 0 .../field_parameters/analyzer_parameter.tsx | 0 .../analyzer_parameter_selects.tsx | 20 +++-- .../field_parameters/analyzers_parameter.tsx | 0 .../field_parameters/boost_parameter.tsx | 0 .../coerce_number_parameter.tsx | 0 .../coerce_shape_parameter.tsx | 0 .../field_parameters/copy_to_parameter.tsx | 0 .../field_parameters/doc_values_parameter.tsx | 0 .../field_parameters/dynamic_parameter.tsx | 0 .../eager_global_ordinals_parameter.tsx | 0 .../field_parameters/enabled_parameter.tsx | 0 .../fielddata_frequency_filter_absolute.tsx | 0 .../fielddata_frequency_filter_percentage.tsx | 0 .../field_parameters/fielddata_parameter.tsx | 0 .../field_parameters/format_parameter.tsx | 0 .../field_parameters/ignore_malformed.tsx | 0 .../ignore_z_value_parameter.tsx | 0 .../document_fields/field_parameters/index.ts | 0 .../field_parameters/index_parameter.tsx | 0 .../field_parameters/locale_parameter.tsx | 0 .../max_shingle_size_parameter.tsx | 0 .../field_parameters/name_parameter.tsx | 0 .../field_parameters/norms_parameter.tsx | 0 .../field_parameters/null_value_parameter.tsx | 0 .../orientation_parameter.tsx | 0 .../field_parameters/path_parameter.tsx | 0 .../field_parameters/relations_parameter.tsx | 0 .../field_parameters/similarity_parameter.tsx | 0 .../split_queries_on_whitespace_parameter.tsx | 0 .../field_parameters/store_parameter.tsx | 0 .../term_vector_parameter.tsx | 0 .../field_parameters/type_parameter.tsx | 0 .../fields/_field_list_item.scss | 0 .../document_fields/fields/_index.scss | 0 .../fields/create_field/create_field.tsx | 80 +++++++++++-------- .../fields/create_field/index.ts | 0 .../required_parameters_forms/alias_type.tsx | 0 .../dense_vector_type.tsx | 0 .../required_parameters_forms/index.ts | 0 .../scaled_float_type.tsx | 0 .../token_count_type.tsx | 0 .../fields/delete_field_provider.tsx | 0 .../edit_field/_edit_field_form_row.scss | 0 .../fields/edit_field/_index.scss | 0 .../advanced_parameters_section.tsx | 0 .../edit_field/basic_parameters_section.tsx | 0 .../fields/edit_field/edit_field.tsx | 0 .../edit_field/edit_field_container.tsx | 4 +- .../fields/edit_field/edit_field_form_row.tsx | 0 .../edit_field/edit_field_header_form.tsx | 0 .../edit_field/field_description_section.tsx | 0 .../fields/edit_field/index.ts | 0 .../edit_field/update_field_provider.tsx | 0 .../fields/field_types/alias_type.tsx | 0 .../fields/field_types/binary_type.tsx | 0 .../fields/field_types/boolean_type.tsx | 0 .../fields/field_types/completion_type.tsx | 0 .../fields/field_types/date_type.tsx | 0 .../fields/field_types/dense_vector_type.tsx | 0 .../fields/field_types/flattened_type.tsx | 0 .../fields/field_types/geo_point_type.tsx | 0 .../fields/field_types/geo_shape_type.tsx | 0 .../fields/field_types/index.ts | 0 .../fields/field_types/ip_type.tsx | 0 .../fields/field_types/join_type.tsx | 0 .../fields/field_types/keyword_type.tsx | 0 .../fields/field_types/nested_type.tsx | 0 .../fields/field_types/numeric_type.tsx | 0 .../fields/field_types/object_type.tsx | 0 .../fields/field_types/range_type.tsx | 0 .../fields/field_types/search_as_you_type.tsx | 0 .../fields/field_types/shape_type.tsx | 0 .../fields/field_types/text_type.tsx | 0 .../fields/field_types/token_count_type.tsx | 0 .../document_fields/fields/fields_list.tsx | 0 .../fields/fields_list_item.tsx | 0 .../fields/fields_list_item_container.tsx | 10 +-- .../document_fields/fields/index.ts | 0 .../modal_confirmation_delete_fields.tsx | 0 .../document_fields/fields_json_editor.tsx | 0 .../document_fields/fields_tree_editor.tsx | 12 +-- .../components/document_fields/index.ts | 0 .../document_fields/search_fields/index.ts | 0 .../search_fields/search_result.tsx | 0 .../search_fields/search_result_item.tsx | 0 .../components/fields_tree.tsx | 0 .../mappings_editor/components/index.ts | 0 .../components/load_mappings/index.ts | 0 .../load_mappings/load_from_json_button.tsx | 0 .../load_mappings_provider.test.tsx | 2 +- .../load_mappings/load_mappings_provider.tsx | 0 .../components/multiple_mappings_warning.tsx | 0 .../components/templates_form/index.ts | 0 .../templates_form/templates_form.tsx | 6 +- .../templates_form/templates_form_schema.ts | 0 .../mappings_editor/components/tree/index.ts | 0 .../mappings_editor/components/tree/tree.tsx | 0 .../components/tree/tree_item.tsx | 0 .../constants/data_types_definition.tsx | 0 .../constants/default_values.ts | 0 .../constants/field_options.tsx | 0 .../constants/field_options_i18n.ts | 0 .../mappings_editor/constants/index.ts | 0 .../constants/mappings_editor.ts | 0 .../constants/parameters_definition.tsx | 0 .../components/mappings_editor/index.ts | 0 .../index_settings_context.tsx | 0 .../mappings_editor/lib/error_reporter.ts | 0 .../lib/extract_mappings_definition.test.ts | 0 .../lib/extract_mappings_definition.ts | 0 .../components/mappings_editor/lib/index.ts | 0 .../lib/mappings_validator.test.ts | 0 .../mappings_editor/lib/mappings_validator.ts | 0 .../mappings_editor/lib/search_fields.test.ts | 0 .../mappings_editor/lib/search_fields.tsx | 0 .../mappings_editor/lib/serializers.ts | 0 .../mappings_editor/lib/utils.test.ts | 0 .../components/mappings_editor/lib/utils.ts | 0 .../mappings_editor/lib/validators.ts | 0 .../mappings_editor/mappings_editor.tsx | 2 +- .../mappings_editor/mappings_state.tsx | 4 +- .../components/mappings_editor/reducer.ts | 0 .../mappings_editor/shared_imports.ts | 8 +- .../components/mappings_editor/types.ts | 0 .../application/components/no_match/index.ts | 0 .../components/no_match/no_match.tsx | 0 .../components/page_error/index.ts | 0 .../page_error/page_error_forbidden.tsx | 0 .../application/components/section_error.tsx | 0 .../components/section_loading.tsx | 0 .../components/template_delete_modal.tsx | 0 .../components/template_form/index.ts | 0 .../components/template_form/steps/index.ts | 0 .../template_form/steps/step_aliases.tsx | 0 .../template_form/steps/step_logistics.tsx | 15 +--- .../template_form/steps/step_mappings.tsx | 0 .../template_form/steps/step_review.tsx | 2 +- .../template_form/steps/step_settings.tsx | 0 .../template_form/steps/use_json_step.ts | 14 ++-- .../template_form/template_form.tsx | 34 ++++---- .../template_form/template_form_schemas.tsx | 5 +- .../template_form/template_steps.tsx | 0 .../components/template_form/types.ts | 0 .../constants/detail_panel_tabs.ts | 0 .../public/application/constants/index.ts | 0 .../constants/refresh_intervals.ts | 0 .../public/application/index.tsx | 2 +- .../public/application/lib/ace.js | 6 +- .../public/application/lib/edit_settings.js | 0 .../public/application/lib/flatten_object.js | 0 .../application/lib/flatten_panel_tree.js | 0 .../application/lib/index_status_labels.js | 0 .../lib/manage_angular_lifecycle.ts | 0 .../public/application/lib/render_badges.js | 0 .../public/application/sections/home/home.tsx | 0 .../public/application/sections/home/index.ts | 0 .../detail_panel/detail_panel.container.js | 0 .../index_list/detail_panel/detail_panel.js | 0 .../edit_settings_json.container.js | 0 .../edit_settings_json/edit_settings_json.js | 0 .../detail_panel/edit_settings_json/index.js | 0 .../home/index_list/detail_panel/index.js | 0 .../detail_panel/show_json/index.js | 0 .../show_json/show_json.container.js | 0 .../detail_panel/show_json/show_json.js | 0 .../index_list/detail_panel/summary/index.js | 0 .../detail_panel/summary/summary.container.js | 0 .../detail_panel/summary/summary.js | 0 .../sections/home/index_list/index.ts | 0 .../index_actions_context_menu/index.js | 0 .../index_actions_context_menu.container.js | 0 .../index_actions_context_menu.js | 0 .../sections/home/index_list/index_list.d.ts | 0 .../sections/home/index_list/index_list.js | 0 .../home/index_list/index_table/index.js | 0 .../index_table/index_table.container.js | 0 .../index_list/index_table/index_table.js | 0 .../sections/home/template_list/index.ts | 0 .../template_list/template_details/index.ts | 0 .../template_details/tabs/index.ts | 0 .../template_details/tabs/tab_aliases.tsx | 0 .../template_details/tabs/tab_mappings.tsx | 0 .../template_details/tabs/tab_settings.tsx | 0 .../template_details/tabs/tab_summary.tsx | 0 .../template_details/template_details.tsx | 4 +- .../home/template_list/template_list.tsx | 6 +- .../template_list/template_table/index.ts | 0 .../template_table/template_table.tsx | 0 .../sections/template_clone/index.ts | 0 .../template_clone/template_clone.tsx | 4 +- .../sections/template_create/index.ts | 0 .../template_create/template_create.tsx | 0 .../sections/template_edit/index.ts | 0 .../sections/template_edit/template_edit.tsx | 4 +- .../public/application/services/api.ts | 4 +- .../application/services/breadcrumbs.ts | 2 +- .../application/services/documentation.ts | 2 +- .../application/services/health_to_color.ts | 0 .../public/application/services/http.ts | 2 +- .../public/application/services/index.ts | 2 +- .../public/application/services/navigation.ts | 0 .../application/services/notification.ts | 2 +- .../public/application/services/routing.ts | 0 .../public/application/services/sort_table.ts | 0 .../public/application/services/ui_metric.ts | 6 +- .../application/services/use_request.ts | 0 .../store/actions/clear_cache_indices.js | 0 .../store/actions/clear_row_status.js | 0 .../store/actions/close_indices.js | 0 .../store/actions/delete_indices.js | 0 .../application/store/actions/detail_panel.js | 0 .../store/actions/edit_index_settings.js | 0 .../store/actions/extension_action.js | 0 .../store/actions/flush_indices.js | 0 .../store/actions/forcemerge_indices.js | 0 .../store/actions/freeze_indices.js | 0 .../public/application/store/actions/index.js | 0 .../store/actions/load_index_data.js | 0 .../application/store/actions/load_indices.js | 0 .../application/store/actions/open_indices.js | 0 .../store/actions/refresh_indices.js | 0 .../store/actions/reload_indices.js | 0 .../application/store/actions/table_state.js | 0 .../store/actions/unfreeze_indices.js | 0 .../store/actions/update_index_settings.js | 0 .../public/application/store/index.ts | 0 .../store/reducers/detail_panel.js | 0 .../application/store/reducers/index.js | 0 .../store/reducers/index_management.js | 0 .../application/store/reducers/indices.js | 0 .../application/store/reducers/row_status.js | 0 .../application/store/reducers/table_state.js | 0 .../application/store/selectors/index.d.ts | 0 .../application/store/selectors/index.js | 0 .../public/application/store/store.d.ts | 0 .../public/application/store/store.js | 0 .../index_management/public/index.scss | 0 .../plugins/index_management/public/index.ts | 11 +-- .../plugins/index_management/public/mocks.ts | 0 .../plugins/index_management/public/plugin.ts | 10 +-- .../services/extensions_service.mock.ts | 0 .../public/services/extensions_service.ts | 0 .../index_management/public/services/index.ts | 0 .../index_management/public/shared_imports.ts | 33 ++++++++ .../plugins/index_management/public/types.ts | 0 .../index_management/server/config.ts} | 14 ++-- .../plugins/index_management/server/index.ts | 10 +++ .../server/lib/fetch_aliases.test.ts | 0 .../server/lib/fetch_aliases.ts | 0 .../server/lib/fetch_indices.ts | 0 .../server/lib/get_managed_templates.ts | 0 .../server/lib/is_es_error.ts | 0 .../plugins/index_management/server/plugin.ts | 4 +- .../server/routes/api/index.ts | 0 .../server/routes/api/indices/index.ts | 0 .../api/indices/register_clear_cache_route.ts | 0 .../api/indices/register_close_route.ts | 0 .../api/indices/register_delete_route.ts | 0 .../api/indices/register_flush_route.ts | 0 .../api/indices/register_forcemerge_route.ts | 0 .../api/indices/register_freeze_route.ts | 0 .../api/indices/register_indices_routes.ts | 0 .../routes/api/indices/register_list_route.ts | 0 .../routes/api/indices/register_open_route.ts | 0 .../api/indices/register_refresh_route.ts | 0 .../api/indices/register_reload_route.ts | 0 .../api/indices/register_unfreeze_route.ts | 0 .../server/routes/api/mapping/index.ts | 0 .../api/mapping/register_mapping_route.ts | 0 .../server/routes/api/settings/index.ts | 0 .../api/settings/register_load_route.ts | 0 .../api/settings/register_settings_routes.ts | 0 .../api/settings/register_update_route.ts | 0 .../server/routes/api/stats/index.ts | 0 .../routes/api/stats/register_stats_route.ts | 0 .../server/routes/api/templates/index.ts | 0 .../api/templates/register_create_route.ts | 0 .../api/templates/register_delete_route.ts | 0 .../api/templates/register_get_routes.ts | 0 .../api/templates/register_template_routes.ts | 0 .../api/templates/register_update_route.ts | 0 .../routes/api/templates/validate_schemas.ts | 0 .../index_management/server/routes/helpers.ts | 0 .../index_management/server/routes/index.ts | 0 .../index_management/server/services/index.ts | 0 .../server/services/index_data_enricher.ts | 0 .../server/services/license.ts | 5 +- .../plugins/index_management/server/types.ts | 2 +- .../index_management/test/fixtures/index.ts | 0 .../test/fixtures/template.ts | 2 +- 365 files changed, 297 insertions(+), 261 deletions(-) delete mode 100644 x-pack/legacy/plugins/index_management/public/index.html rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/constants.ts (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts (96%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/index.ts (95%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx (95%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts (85%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts (84%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts (85%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts (99%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/home.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/template_clone.test.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/template_create.test.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/client_integration/template_edit.test.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/components/__snapshots__/index_table.test.js.snap (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/components/index_table.test.js (98%) rename x-pack/{legacy => }/plugins/index_management/__jest__/lib/__snapshots__/flatten_object.test.js.snap (100%) rename x-pack/{legacy => }/plugins/index_management/__jest__/lib/flatten_object.test.js (100%) rename x-pack/{legacy => }/plugins/index_management/__mocks__/ace.js (100%) rename x-pack/{legacy => }/plugins/index_management/__mocks__/ui/documentation_links.js (100%) rename x-pack/{legacy => }/plugins/index_management/__mocks__/ui/notify.js (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/api_base_path.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/base_path.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/index_statuses.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/invalid_characters.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/constants/plugin.ts (86%) rename x-pack/{legacy => }/plugins/index_management/common/constants/ui_metric.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/lib/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/lib/template_serialization.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/types/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/common/types/templates.ts (100%) create mode 100644 x-pack/plugins/index_management/kibana.json rename x-pack/{legacy => }/plugins/index_management/public/application/app.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/app_context.tsx (90%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts (90%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts (85%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/_index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/_index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/code_block.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form_schema.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/_index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx (91%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields_header.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/editor_toggle_controls.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx (86%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/boost_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_number_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_shape_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/copy_to_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/doc_values_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/eager_global_ordinals_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/enabled_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_absolute.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_percentage.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/format_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_malformed.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_z_value_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/locale_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/max_shingle_size_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/name_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/norms_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/null_value_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/orientation_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/path_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/relations_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/similarity_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/split_queries_on_whitespace_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/store_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/term_vector_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/type_parameter.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_field_list_item.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx (83%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/alias_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/dense_vector_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/scaled_float_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/token_count_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/delete_field_provider.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_edit_field_form_row.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/basic_parameters_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx (97%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_header_form.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/field_description_section.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/update_field_provider.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/alias_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/binary_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/boolean_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/completion_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/date_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/dense_vector_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/flattened_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_point_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_shape_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/ip_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/join_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/keyword_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/nested_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/numeric_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/object_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/range_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/search_as_you_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/shape_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/text_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/token_count_type.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx (92%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/modal_confirmation_delete_fields.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_json_editor.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields_tree_editor.tsx (88%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/fields_tree.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_from_json_button.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/multiple_mappings_warning.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/templates_form/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form_schema.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/tree/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/tree/tree.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/components/tree/tree_item.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/field_options.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/field_options_i18n.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/mappings_editor.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/index_settings_context.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/error_reporter.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/serializers.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/lib/validators.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/reducer.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts (72%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/mappings_editor/types.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/no_match/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/no_match/no_match.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/page_error/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/section_error.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/section_loading.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_delete_modal.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/step_aliases.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx (94%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/step_review.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/step_settings.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts (83%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/template_form.tsx (92%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx (96%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/template_steps.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/components/template_form/types.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/constants/detail_panel_tabs.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/constants/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/constants/refresh_intervals.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/index.tsx (94%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/ace.js (94%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/edit_settings.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/flatten_object.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/flatten_panel_tree.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/index_status_labels.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/manage_angular_lifecycle.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/lib/render_badges.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/home.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_list.d.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_list.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_table/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_aliases.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_mappings.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_settings.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_list.tsx (97%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_table/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_clone/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_clone/template_clone.tsx (96%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_create/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_create/template_create.tsx (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_edit/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/sections/template_edit/template_edit.tsx (96%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/api.ts (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/breadcrumbs.ts (96%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/documentation.ts (98%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/health_to_color.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/http.ts (88%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/index.ts (96%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/navigation.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/notification.ts (93%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/routing.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/sort_table.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/ui_metric.ts (90%) rename x-pack/{legacy => }/plugins/index_management/public/application/services/use_request.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/clear_cache_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/clear_row_status.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/close_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/delete_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/detail_panel.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/edit_index_settings.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/extension_action.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/flush_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/forcemerge_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/freeze_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/load_index_data.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/load_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/open_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/refresh_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/reload_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/table_state.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/unfreeze_indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/actions/update_index_settings.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/detail_panel.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/index_management.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/indices.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/row_status.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/reducers/table_state.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/selectors/index.d.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/selectors/index.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/store.d.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/application/store/store.js (100%) rename x-pack/{legacy => }/plugins/index_management/public/index.scss (100%) rename x-pack/{legacy => }/plugins/index_management/public/index.ts (66%) rename x-pack/{legacy => }/plugins/index_management/public/mocks.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/plugin.ts (90%) rename x-pack/{legacy => }/plugins/index_management/public/services/extensions_service.mock.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/services/extensions_service.ts (100%) rename x-pack/{legacy => }/plugins/index_management/public/services/index.ts (100%) create mode 100644 x-pack/plugins/index_management/public/shared_imports.ts rename x-pack/{legacy => }/plugins/index_management/public/types.ts (100%) rename x-pack/{legacy/plugins/index_management/public/shared_imports.ts => plugins/index_management/server/config.ts} (52%) rename x-pack/{legacy => }/plugins/index_management/server/index.ts (67%) rename x-pack/{legacy => }/plugins/index_management/server/lib/fetch_aliases.test.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/lib/fetch_aliases.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/lib/fetch_indices.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/lib/get_managed_templates.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/lib/is_es_error.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/plugin.ts (94%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_close_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_delete_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_flush_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_freeze_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_indices_routes.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_list_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_open_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_refresh_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_reload_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/indices/register_unfreeze_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/mapping/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/mapping/register_mapping_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/settings/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/settings/register_load_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/settings/register_settings_routes.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/settings/register_update_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/stats/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/stats/register_stats_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/register_create_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/register_delete_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/register_get_routes.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/register_template_routes.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/register_update_route.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/api/templates/validate_schemas.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/helpers.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/routes/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/services/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/services/index_data_enricher.ts (100%) rename x-pack/{legacy => }/plugins/index_management/server/services/license.ts (89%) rename x-pack/{legacy => }/plugins/index_management/server/types.ts (92%) rename x-pack/{legacy => }/plugins/index_management/test/fixtures/index.ts (100%) rename x-pack/{legacy => }/plugins/index_management/test/fixtures/template.ts (88%) diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index f22f7e98d3b8a4..b1cb9075434e87 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -16,7 +16,7 @@ "xpack.fileUpload": "legacy/plugins/file_upload", "xpack.graph": ["legacy/plugins/graph", "plugins/graph"], "xpack.grokDebugger": "legacy/plugins/grokdebugger", - "xpack.idxMgmt": "legacy/plugins/index_management", + "xpack.idxMgmt": "plugins/index_management", "xpack.indexLifecycleMgmt": "legacy/plugins/index_lifecycle_management", "xpack.infra": "plugins/infra", "xpack.ingestManager": "plugins/ingest_manager", diff --git a/x-pack/legacy/plugins/cross_cluster_replication/index.js b/x-pack/legacy/plugins/cross_cluster_replication/index.js index 1b5f42fc5107eb..1b3aafcad5c0f6 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/index.js @@ -49,13 +49,12 @@ export function crossClusterReplication(kibana) { init: function initCcrPlugin(server) { registerLicenseChecker(server); registerRoutes(server); - if ( server.config().get('xpack.ccr.ui.enabled') && - server.plugins.index_management && - server.plugins.index_management.addIndexManagementDataEnricher + server.newPlatform.setup.plugins.indexManagement && + server.newPlatform.setup.plugins.indexManagement.indexDataEnricher ) { - server.plugins.index_management.addIndexManagementDataEnricher(ccrDataEnricher); + server.newPlatform.setup.plugins.indexManagement.indexDataEnricher.add(ccrDataEnricher); } }, }); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js index 16ed0a7d695ad5..7b31ffa5024b76 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js @@ -7,7 +7,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getIndexListUri } from '../../../../../../../../index_management/public/application/services/navigation'; +import { getIndexListUri } from '../../../../../../../../../../plugins/index_management/public'; import { EuiButtonEmpty, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js index e3bda2e67097d2..2ad118d28f38d7 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js @@ -7,8 +7,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getIndexListUri } from '../../../../../../../../index_management/public/application/services/navigation'; - import { EuiButton, EuiButtonEmpty, @@ -31,12 +29,11 @@ import { EuiTextColor, EuiTitle, } from '@elastic/eui'; - import 'brace/theme/textmate'; -import { ContextMenu } from '../context_menu'; - +import { getIndexListUri } from '../../../../../../../../../../plugins/index_management/public'; import { API_STATUS } from '../../../../../constants'; +import { ContextMenu } from '../context_menu'; export class DetailPanel extends Component { static propTypes = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js index 809a7c3e87b75e..c44918c500849b 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js @@ -4,11 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { extensionsService } from '../../../index_management/public'; +import { npSetup } from 'ui/new_platform'; import { get } from 'lodash'; const propertyPath = 'isFollowerIndex'; -export const followerBadgeExtension = { + +const followerBadgeExtension = { matchIndex: index => { return get(index, propertyPath); }, @@ -19,4 +20,6 @@ export const followerBadgeExtension = { filterExpression: 'isFollowerIndex:true', }; -extensionsService.addBadge(followerBadgeExtension); +if (npSetup.plugins.indexManagement) { + npSetup.plugins.indexManagement.extensionsService.addBadge(followerBadgeExtension); +} diff --git a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js index bcbae7e093f465..d2619778617c3e 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/__jest__/extend_index_management.test.js @@ -27,8 +27,10 @@ initHttp(axios.create({ adapter: axiosXhrAdapter }), path => path); initUiMetric(() => () => {}); jest.mock('ui/new_platform'); -jest.mock('../../index_management/public', async () => { - const { indexManagementMock } = await import('../../index_management/public/mocks.ts'); +jest.mock('../../../../plugins/index_management/public', async () => { + const { indexManagementMock } = await import( + '../../../../plugins/index_management/public/mocks.ts' + ); return indexManagementMock.createSetup(); }); diff --git a/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts b/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts index 8d7f937039203f..38d1bea45ce070 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts +++ b/x-pack/legacy/plugins/index_lifecycle_management/plugin.ts @@ -41,14 +41,14 @@ export class Plugin { registerPoliciesRoutes(server); registerTemplatesRoutes(server); - const serverPlugins = server.plugins as any; + const serverPlugins = server.newPlatform.setup.plugins as any; if ( server.config().get('xpack.ilm.ui.enabled') && - serverPlugins.index_management && - serverPlugins.index_management.addIndexManagementDataEnricher + serverPlugins.indexManagement && + serverPlugins.indexManagement.indexDataEnricher ) { - serverPlugins.index_management.addIndexManagementDataEnricher(indexLifecycleDataEnricher); + serverPlugins.indexManagement.indexDataEnricher.add(indexLifecycleDataEnricher); } } } diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts b/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts index 3c21a644c0f783..f7f924add2c514 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/legacy.ts @@ -20,7 +20,9 @@ import { addAllExtensions } from './np_ready/extend_index_management'; if (chrome.getInjected('ilmUiEnabled')) { // We have to initialize this outside of the NP lifecycle, otherwise these extensions won't // be available in Index Management unless the user visits ILM first. - addAllExtensions(); + if ((npSetup.plugins as any).indexManagement) { + addAllExtensions((npSetup.plugins as any).indexManagement.extensionsService); + } // This method handles the cleanup needed when route is scope is destroyed. It also prevents Angular // from destroying scope when route changes and both old route and new route are this same route. diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js index 83d32eae1097d7..903161fe094fc3 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/application/sections/policy_table/components/policy_table/policy_table.js @@ -37,7 +37,7 @@ import { import { RIGHT_ALIGNMENT } from '@elastic/eui/lib/services'; -import { getIndexListUri } from '../../../../../../../../index_management/public/application/services/navigation'; +import { getIndexListUri } from '../../../../../../../../../../plugins/index_management/public'; import { BASE_PATH } from '../../../../../../../common/constants'; import { UIM_EDIT_CLICK } from '../../../../constants'; import { getPolicyPath } from '../../../../services/navigation'; diff --git a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js index 0e662b78b2c180..69658d31695bce 100644 --- a/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js +++ b/x-pack/legacy/plugins/index_lifecycle_management/public/np_ready/extend_index_management/index.js @@ -9,7 +9,6 @@ import { get, every, any } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiSearchBar } from '@elastic/eui'; -import { extensionsService } from '../../../../index_management/public'; import { init as initUiMetric } from '../application/services/ui_metric'; import { init as initNotification } from '../application/services/notification'; import { retryLifecycleForIndex } from '../application/services/api'; @@ -238,7 +237,7 @@ export const ilmFilterExtension = indices => { } }; -export const addAllExtensions = () => { +export const addAllExtensions = extensionsService => { extensionsService.addAction(retryLifecycleActionExtension); extensionsService.addAction(removeLifecyclePolicyActionExtension); extensionsService.addAction(addLifecyclePolicyActionExtension); diff --git a/x-pack/legacy/plugins/index_management/index.ts b/x-pack/legacy/plugins/index_management/index.ts index c92b38c0d94be8..9eba98a526d2bc 100644 --- a/x-pack/legacy/plugins/index_management/index.ts +++ b/x-pack/legacy/plugins/index_management/index.ts @@ -4,36 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resolve } from 'path'; -import { Legacy } from 'kibana'; -import { PLUGIN } from './common/constants'; -import { plugin as initServerPlugin, Dependencies } from './server'; - -export type ServerFacade = Legacy.Server; - export function indexManagement(kibana: any) { return new kibana.Plugin({ - id: PLUGIN.id, + id: 'index_management', configPrefix: 'xpack.index_management', - publicDir: resolve(__dirname, 'public'), - require: ['kibana', 'elasticsearch', 'xpack_main'], - - uiExports: { - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - managementSections: ['plugins/index_management'], - }, - - init(server: ServerFacade) { - const coreSetup = server.newPlatform.setup.core; - const coreInitializerContext = server.newPlatform.coreContext; - const pluginsSetup: Dependencies = { - licensing: server.newPlatform.setup.plugins.licensing as any, - }; - - const serverPlugin = initServerPlugin(coreInitializerContext as any); - const serverPublicApi = serverPlugin.setup(coreSetup, pluginsSetup); - - server.expose('addIndexManagementDataEnricher', serverPublicApi.indexDataEnricher.add); - }, }); } diff --git a/x-pack/legacy/plugins/index_management/public/index.html b/x-pack/legacy/plugins/index_management/public/index.html deleted file mode 100644 index 0e9ac6fa0bc977..00000000000000 --- a/x-pack/legacy/plugins/index_management/public/index.html +++ /dev/null @@ -1,3 +0,0 @@ - -
-
diff --git a/x-pack/legacy/plugins/remote_clusters/index.ts b/x-pack/legacy/plugins/remote_clusters/index.ts index 37b2224f8d7c25..439cb818d8a562 100644 --- a/x-pack/legacy/plugins/remote_clusters/index.ts +++ b/x-pack/legacy/plugins/remote_clusters/index.ts @@ -5,6 +5,8 @@ */ import { resolve } from 'path'; +import { Legacy } from 'kibana'; + import { PLUGIN } from './common'; export function remoteClusters(kibana: any) { @@ -28,7 +30,7 @@ export function remoteClusters(kibana: any) { enabled: Joi.boolean().default(true), }).default(); }, - isEnabled(config: any) { + isEnabled(config: Legacy.KibanaConfig) { return ( config.get('xpack.remote_clusters.enabled') && config.get('xpack.index_management.enabled') ); diff --git a/x-pack/legacy/plugins/rollup/index.ts b/x-pack/legacy/plugins/rollup/index.ts index 7548af23b3aae9..2c8363cc397f45 100644 --- a/x-pack/legacy/plugins/rollup/index.ts +++ b/x-pack/legacy/plugins/rollup/index.ts @@ -40,7 +40,7 @@ export function rollup(kibana: any) { }, init(server: any) { const { core: coreSetup, plugins } = server.newPlatform.setup; - const { usageCollection, metrics } = plugins; + const { usageCollection, metrics, indexManagement } = plugins; const rollupSetup = (plugins.rollup as unknown) as RollupSetup; @@ -54,11 +54,11 @@ export function rollup(kibana: any) { rollupPluginInstance.setup(coreSetup, { usageCollection, metrics, + indexManagement, __LEGACY: { plugins: { xpack_main: server.plugins.xpack_main, rollup: server.plugins[PLUGIN.ID], - index_management: server.plugins.index_management, }, }, }); diff --git a/x-pack/legacy/plugins/rollup/public/legacy.ts b/x-pack/legacy/plugins/rollup/public/legacy.ts index 64eb1f64363892..e3e663ac7b0f44 100644 --- a/x-pack/legacy/plugins/rollup/public/legacy.ts +++ b/x-pack/legacy/plugins/rollup/public/legacy.ts @@ -10,7 +10,6 @@ import { aggTypeFieldFilters } from 'ui/agg_types'; import { addSearchStrategy } from '../../../../../src/plugins/data/public'; import { RollupPlugin } from './plugin'; import { setup as management } from '../../../../../src/legacy/core_plugins/management/public/legacy'; -import { extensionsService } from '../../index_management/public'; const plugin = new RollupPlugin(); @@ -20,7 +19,6 @@ export const setup = plugin.setup(npSetup.core, { aggTypeFilters, aggTypeFieldFilters, addSearchStrategy, - indexManagementExtensions: extensionsService, managementLegacy: management, }, }); diff --git a/x-pack/legacy/plugins/rollup/public/plugin.ts b/x-pack/legacy/plugins/rollup/public/plugin.ts index 90d7e2d9d01919..a01383f4733ef8 100644 --- a/x-pack/legacy/plugins/rollup/public/plugin.ts +++ b/x-pack/legacy/plugins/rollup/public/plugin.ts @@ -27,7 +27,7 @@ import { // @ts-ignore import { CRUD_APP_BASE_PATH } from './crud_app/constants'; import { ManagementSetup } from '../../../../../src/plugins/management/public'; -import { IndexMgmtSetup } from '../../index_management/public'; +import { IndexMgmtSetup } from '../../../../plugins/index_management/public'; // @ts-ignore import { setEsBaseAndXPackBase, setHttp } from './crud_app/services'; import { setNotifications, setFatalErrors } from './kibana_services'; @@ -39,30 +39,28 @@ export interface RollupPluginSetupDependencies { aggTypeFieldFilters: AggTypeFieldFilters; addSearchStrategy: (searchStrategy: SearchStrategyProvider) => void; managementLegacy: ManagementSetupLegacy; - indexManagementExtensions: IndexMgmtSetup['extensionsService']; }; home?: HomePublicPluginSetup; management: ManagementSetup; + indexManagement?: IndexMgmtSetup; } export class RollupPlugin implements Plugin { setup( core: CoreSetup, { - __LEGACY: { - aggTypeFilters, - aggTypeFieldFilters, - addSearchStrategy, - managementLegacy, - indexManagementExtensions, - }, + __LEGACY: { aggTypeFilters, aggTypeFieldFilters, addSearchStrategy, managementLegacy }, home, management, + indexManagement, }: RollupPluginSetupDependencies ) { setFatalErrors(core.fatalErrors); - indexManagementExtensions.addBadge(rollupBadgeExtension); - indexManagementExtensions.addToggle(rollupToggleExtension); + + if (indexManagement) { + indexManagement.extensionsService.addBadge(rollupBadgeExtension); + indexManagement.extensionsService.addToggle(rollupToggleExtension); + } const isRollupIndexPatternsEnabled = core.uiSettings.get(CONFIG_ROLLUPS); diff --git a/x-pack/legacy/plugins/rollup/server/plugin.ts b/x-pack/legacy/plugins/rollup/server/plugin.ts index 52b1e31af4eb22..090cb8a47377a1 100644 --- a/x-pack/legacy/plugins/rollup/server/plugin.ts +++ b/x-pack/legacy/plugins/rollup/server/plugin.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { VisTypeTimeseriesSetup } from 'src/plugins/vis_type_timeseries/server'; +import { IndexMgmtSetup } from '../../../../plugins/index_management/server'; import { registerLicenseChecker } from '../../../server/lib/register_license_checker'; import { PLUGIN } from '../common'; import { ServerShim, RouteDependencies } from './types'; @@ -38,10 +39,12 @@ export class RollupsServerPlugin implements Plugin { __LEGACY: serverShim, usageCollection, metrics, + indexManagement, }: { __LEGACY: ServerShim; usageCollection?: UsageCollectionSetup; metrics?: VisTypeTimeseriesSetup; + indexManagement?: IndexMgmtSetup; } ) { const elasticsearch = await elasticsearchService.adminClient; @@ -76,11 +79,8 @@ export class RollupsServerPlugin implements Plugin { }); } - if ( - serverShim.plugins.index_management && - serverShim.plugins.index_management.addIndexManagementDataEnricher - ) { - serverShim.plugins.index_management.addIndexManagementDataEnricher(rollupDataEnricher); + if (indexManagement && indexManagement.indexDataEnricher) { + indexManagement.indexDataEnricher.add(rollupDataEnricher); } if (metrics) { diff --git a/x-pack/legacy/plugins/rollup/server/rollup_data_enricher.ts b/x-pack/legacy/plugins/rollup/server/rollup_data_enricher.ts index 7c5e160c54a31a..ad621f2d9ba806 100644 --- a/x-pack/legacy/plugins/rollup/server/rollup_data_enricher.ts +++ b/x-pack/legacy/plugins/rollup/server/rollup_data_enricher.ts @@ -4,14 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -interface Index { - name: string; - [key: string]: unknown; -} +import { Index } from '../../../../plugins/index_management/server'; export const rollupDataEnricher = async (indicesList: Index[], callWithRequest: any) => { if (!indicesList || !indicesList.length) { - return indicesList; + return Promise.resolve(indicesList); } const params = { diff --git a/x-pack/legacy/plugins/rollup/server/types.ts b/x-pack/legacy/plugins/rollup/server/types.ts index 62a4841133cffb..bcc6770e9b8ee0 100644 --- a/x-pack/legacy/plugins/rollup/server/types.ts +++ b/x-pack/legacy/plugins/rollup/server/types.ts @@ -11,7 +11,6 @@ export interface ServerShim { plugins: { xpack_main: XPackMainPlugin; rollup: any; - index_management: any; }; } diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/constants.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/constants.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/constants.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/constants.ts diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts similarity index 96% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts index e5f0b25d89c3e1..7e3e1fba9c44a6 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/home.helpers.ts @@ -12,10 +12,10 @@ import { TestBedConfig, findTestSubject, nextTick, -} from '../../../../../../test_utils'; -import { IndexManagementHome } from '../../../public/application/sections/home'; +} from '../../../../../test_utils'; +import { IndexManagementHome } from '../../../public/application/sections/home'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { BASE_PATH } from '../../../common/constants'; -import { indexManagementStore } from '../../../public/application/store'; +import { indexManagementStore } from '../../../public/application/store'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { Template } from '../../../common/types'; import { WithAppDependencies, services } from './setup_environment'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/http_requests.ts diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts similarity index 95% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/index.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts index 6dce4453a67f93..66021b531919a9 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/index.ts @@ -9,7 +9,7 @@ import { setup as templateCreateSetup } from './template_create.helpers'; import { setup as templateCloneSetup } from './template_clone.helpers'; import { setup as templateEditSetup } from './template_edit.helpers'; -export { nextTick, getRandomString, findTestSubject, TestBed } from '../../../../../../test_utils'; +export { nextTick, getRandomString, findTestSubject, TestBed } from '../../../../../test_utils'; export { setupEnvironment } from './setup_environment'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx similarity index 95% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx index 0212efe1f322d3..1eaf7efd173954 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/setup_environment.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +/* eslint-disable @kbn/eslint/no-restricted-paths */ import React from 'react'; import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; @@ -10,7 +11,7 @@ import axiosXhrAdapter from 'axios/lib/adapters/xhr'; import { notificationServiceMock, docLinksServiceMock, -} from '../../../../../../../src/core/public/mocks'; +} from '../../../../../../src/core/public/mocks'; import { AppContextProvider } from '../../../public/application/app_context'; import { httpService } from '../../../public/application/services/http'; import { breadcrumbService } from '../../../public/application/services/breadcrumbs'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts similarity index 85% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts index cd1b67c08d9345..36498b99ba1435 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_clone.helpers.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed, TestBedConfig } from '../../../../../../test_utils'; +import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { TemplateClone } from '../../../public/application/sections/template_clone'; +import { TemplateClone } from '../../../public/application/sections/template_clone'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { formSetup } from './template_form.helpers'; import { TEMPLATE_NAME } from './constants'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts similarity index 84% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts index 8e62bc25d6bd1d..14a44968a93c32 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_create.helpers.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed, TestBedConfig } from '../../../../../../test_utils'; +import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { TemplateCreate } from '../../../public/application/sections/template_create'; +import { TemplateCreate } from '../../../public/application/sections/template_create'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { formSetup, TestSubjects } from './template_form.helpers'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts similarity index 85% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts index cb1025234b48e9..af5fa8b79ecad6 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_edit.helpers.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed, TestBedConfig } from '../../../../../../test_utils'; +import { registerTestBed, TestBedConfig } from '../../../../../test_utils'; import { BASE_PATH } from '../../../common/constants'; -import { TemplateEdit } from '../../../public/application/sections/template_edit'; +import { TemplateEdit } from '../../../public/application/sections/template_edit'; // eslint-disable-line @kbn/eslint/no-restricted-paths import { formSetup, TestSubjects } from './template_form.helpers'; import { TEMPLATE_NAME } from './constants'; import { WithAppDependencies } from './setup_environment'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts similarity index 99% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts rename to x-pack/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts index a7c87723b33fb8..134c67c278b220 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/helpers/template_form.helpers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TestBed, SetupFunc, UnwrapPromise } from '../../../../../../test_utils'; +import { TestBed, SetupFunc, UnwrapPromise } from '../../../../../test_utils'; import { Template } from '../../../common/types'; import { nextTick } from './index'; diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/home.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/home.test.ts rename to x-pack/plugins/index_management/__jest__/client_integration/home.test.ts diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/template_clone.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/template_clone.test.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/template_clone.test.tsx rename to x-pack/plugins/index_management/__jest__/client_integration/template_clone.test.tsx diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/template_create.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/template_create.test.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/template_create.test.tsx rename to x-pack/plugins/index_management/__jest__/client_integration/template_create.test.tsx diff --git a/x-pack/legacy/plugins/index_management/__jest__/client_integration/template_edit.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/template_edit.test.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/client_integration/template_edit.test.tsx rename to x-pack/plugins/index_management/__jest__/client_integration/template_edit.test.tsx diff --git a/x-pack/legacy/plugins/index_management/__jest__/components/__snapshots__/index_table.test.js.snap b/x-pack/plugins/index_management/__jest__/components/__snapshots__/index_table.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/components/__snapshots__/index_table.test.js.snap rename to x-pack/plugins/index_management/__jest__/components/__snapshots__/index_table.test.js.snap diff --git a/x-pack/legacy/plugins/index_management/__jest__/components/index_table.test.js b/x-pack/plugins/index_management/__jest__/components/index_table.test.js similarity index 98% rename from x-pack/legacy/plugins/index_management/__jest__/components/index_table.test.js rename to x-pack/plugins/index_management/__jest__/components/index_table.test.js index 2b4fd894364580..15c3ef0b845624 100644 --- a/x-pack/legacy/plugins/index_management/__jest__/components/index_table.test.js +++ b/x-pack/plugins/index_management/__jest__/components/index_table.test.js @@ -20,13 +20,13 @@ import { setUiMetricService } from '../../public/application/services/api'; import { indexManagementStore } from '../../public/application/store'; import { setExtensionsService } from '../../public/application/store/selectors'; import { BASE_PATH, API_BASE_PATH } from '../../common/constants'; -import { mountWithIntl } from '../../../../../test_utils/enzyme_helpers'; +import { mountWithIntl } from '../../../../test_utils/enzyme_helpers'; import { ExtensionsService } from '../../public/services'; import sinon from 'sinon'; import { findTestSubject } from '@elastic/eui/lib/test'; /* eslint-disable @kbn/eslint/no-restricted-paths */ -import { notificationServiceMock } from '../../../../../../src/core/public/notifications/notifications_service.mock'; +import { notificationServiceMock } from '../../../../../src/core/public/notifications/notifications_service.mock'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/index_management/__jest__/lib/__snapshots__/flatten_object.test.js.snap b/x-pack/plugins/index_management/__jest__/lib/__snapshots__/flatten_object.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/lib/__snapshots__/flatten_object.test.js.snap rename to x-pack/plugins/index_management/__jest__/lib/__snapshots__/flatten_object.test.js.snap diff --git a/x-pack/legacy/plugins/index_management/__jest__/lib/flatten_object.test.js b/x-pack/plugins/index_management/__jest__/lib/flatten_object.test.js similarity index 100% rename from x-pack/legacy/plugins/index_management/__jest__/lib/flatten_object.test.js rename to x-pack/plugins/index_management/__jest__/lib/flatten_object.test.js diff --git a/x-pack/legacy/plugins/index_management/__mocks__/ace.js b/x-pack/plugins/index_management/__mocks__/ace.js similarity index 100% rename from x-pack/legacy/plugins/index_management/__mocks__/ace.js rename to x-pack/plugins/index_management/__mocks__/ace.js diff --git a/x-pack/legacy/plugins/index_management/__mocks__/ui/documentation_links.js b/x-pack/plugins/index_management/__mocks__/ui/documentation_links.js similarity index 100% rename from x-pack/legacy/plugins/index_management/__mocks__/ui/documentation_links.js rename to x-pack/plugins/index_management/__mocks__/ui/documentation_links.js diff --git a/x-pack/legacy/plugins/index_management/__mocks__/ui/notify.js b/x-pack/plugins/index_management/__mocks__/ui/notify.js similarity index 100% rename from x-pack/legacy/plugins/index_management/__mocks__/ui/notify.js rename to x-pack/plugins/index_management/__mocks__/ui/notify.js diff --git a/x-pack/legacy/plugins/index_management/common/constants/api_base_path.ts b/x-pack/plugins/index_management/common/constants/api_base_path.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/api_base_path.ts rename to x-pack/plugins/index_management/common/constants/api_base_path.ts diff --git a/x-pack/legacy/plugins/index_management/common/constants/base_path.ts b/x-pack/plugins/index_management/common/constants/base_path.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/base_path.ts rename to x-pack/plugins/index_management/common/constants/base_path.ts diff --git a/x-pack/legacy/plugins/index_management/common/constants/index.ts b/x-pack/plugins/index_management/common/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/index.ts rename to x-pack/plugins/index_management/common/constants/index.ts diff --git a/x-pack/legacy/plugins/index_management/common/constants/index_statuses.ts b/x-pack/plugins/index_management/common/constants/index_statuses.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/index_statuses.ts rename to x-pack/plugins/index_management/common/constants/index_statuses.ts diff --git a/x-pack/legacy/plugins/index_management/common/constants/invalid_characters.ts b/x-pack/plugins/index_management/common/constants/invalid_characters.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/invalid_characters.ts rename to x-pack/plugins/index_management/common/constants/invalid_characters.ts diff --git a/x-pack/legacy/plugins/index_management/common/constants/plugin.ts b/x-pack/plugins/index_management/common/constants/plugin.ts similarity index 86% rename from x-pack/legacy/plugins/index_management/common/constants/plugin.ts rename to x-pack/plugins/index_management/common/constants/plugin.ts index 2cd137f62d3dbf..e25f537edcf8da 100644 --- a/x-pack/legacy/plugins/index_management/common/constants/plugin.ts +++ b/x-pack/plugins/index_management/common/constants/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LicenseType } from '../../../../../plugins/licensing/common/types'; +import { LicenseType } from '../../../licensing/common/types'; const basicLicense: LicenseType = 'basic'; diff --git a/x-pack/legacy/plugins/index_management/common/constants/ui_metric.ts b/x-pack/plugins/index_management/common/constants/ui_metric.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/constants/ui_metric.ts rename to x-pack/plugins/index_management/common/constants/ui_metric.ts diff --git a/x-pack/legacy/plugins/index_management/common/index.ts b/x-pack/plugins/index_management/common/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/index.ts rename to x-pack/plugins/index_management/common/index.ts diff --git a/x-pack/legacy/plugins/index_management/common/lib/index.ts b/x-pack/plugins/index_management/common/lib/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/lib/index.ts rename to x-pack/plugins/index_management/common/lib/index.ts diff --git a/x-pack/legacy/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/lib/template_serialization.ts rename to x-pack/plugins/index_management/common/lib/template_serialization.ts diff --git a/x-pack/legacy/plugins/index_management/common/types/index.ts b/x-pack/plugins/index_management/common/types/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/types/index.ts rename to x-pack/plugins/index_management/common/types/index.ts diff --git a/x-pack/legacy/plugins/index_management/common/types/templates.ts b/x-pack/plugins/index_management/common/types/templates.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/common/types/templates.ts rename to x-pack/plugins/index_management/common/types/templates.ts diff --git a/x-pack/plugins/index_management/kibana.json b/x-pack/plugins/index_management/kibana.json new file mode 100644 index 00000000000000..7387a042988c01 --- /dev/null +++ b/x-pack/plugins/index_management/kibana.json @@ -0,0 +1,15 @@ +{ + "id": "indexManagement", + "version": "kibana", + "server": true, + "ui": true, + "requiredPlugins": [ + "home", + "licensing", + "management" + ], + "optionalPlugins": [ + "usageCollection" + ], + "configPath": ["xpack", "index_management"] +} diff --git a/x-pack/legacy/plugins/index_management/public/application/app.tsx b/x-pack/plugins/index_management/public/application/app.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/app.tsx rename to x-pack/plugins/index_management/public/application/app.tsx index 3b475f3baba04a..83997dd6ece184 100644 --- a/x-pack/legacy/plugins/index_management/public/application/app.tsx +++ b/x-pack/plugins/index_management/public/application/app.tsx @@ -16,7 +16,7 @@ import { useServices } from './app_context'; export const App = () => { const { uiMetricService } = useServices(); - useEffect(() => uiMetricService.trackMetric('loaded', UIM_APP_LOAD), []); + useEffect(() => uiMetricService.trackMetric('loaded', UIM_APP_LOAD), [uiMetricService]); return ( diff --git a/x-pack/legacy/plugins/index_management/public/application/app_context.tsx b/x-pack/plugins/index_management/public/application/app_context.tsx similarity index 90% rename from x-pack/legacy/plugins/index_management/public/application/app_context.tsx rename to x-pack/plugins/index_management/public/application/app_context.tsx index 12e0d362a29302..2bb618ad8efceb 100644 --- a/x-pack/legacy/plugins/index_management/public/application/app_context.tsx +++ b/x-pack/plugins/index_management/public/application/app_context.tsx @@ -5,9 +5,9 @@ */ import React, { createContext, useContext } from 'react'; -import { CoreStart } from '../../../../../../src/core/public'; +import { CoreStart } from '../../../../../src/core/public'; -import { UsageCollectionSetup } from '../../../../../../src/plugins/usage_collection/public'; +import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public'; import { IndexMgmtMetricsType } from '../types'; import { UiMetricService, NotificationService, HttpService } from './services'; import { ExtensionsService } from '../services'; diff --git a/x-pack/legacy/plugins/index_management/public/application/components/index.ts b/x-pack/plugins/index_management/public/application/components/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/index.ts rename to x-pack/plugins/index_management/public/application/components/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts similarity index 90% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts index e3313bfba56fd9..6d64cb73da4bdd 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/index.ts @@ -10,7 +10,7 @@ export { getRandomString, findTestSubject, TestBed, -} from '../../../../../../../../../../test_utils'; +} from '../../../../../../../../../test_utils'; export const componentHelpers = { mappingsEditor: { setup: mappingsEditorSetup }, diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts similarity index 85% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts index dcee956130a29f..acb416654023eb 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/helpers/mappings_editor.helpers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { registerTestBed } from '../../../../../../../../../../test_utils'; +import { registerTestBed } from '../../../../../../../../../test_utils'; import { MappingsEditor } from '../../../mappings_editor'; export const setup = (props: any) => diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/_index.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/_index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/_index.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/_index.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/_index.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/_index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/_index.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/_index.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/code_block.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/code_block.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/code_block.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/code_block.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx index 0c5c9e2a15b751..9b0b8420f9ea93 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form.tsx @@ -110,7 +110,7 @@ export const ConfigurationForm = React.memo(({ defaultValue }: Props) => { }); }); return subscription.unsubscribe; - }, [form]); + }, [form, dispatch]); useEffect(() => { if (didMountRef.current) { @@ -121,14 +121,14 @@ export const ConfigurationForm = React.memo(({ defaultValue }: Props) => { // Avoid reseting the form on component mount. didMountRef.current = true; } - }, [defaultValue]); + }, [defaultValue, form]); useEffect(() => { return () => { // On unmount => save in the state a snapshot of the current form data. dispatch({ type: 'configuration.save' }); }; - }, []); + }, [dispatch]); return ( diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form_schema.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form_schema.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form_schema.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/configuration_form_schema.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/dynamic_mapping_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/dynamic_mapping_section/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/meta_field_section/meta_field_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/routing_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/configuration_form/source_field_section/source_field_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/_index.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/_index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/_index.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/_index.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx similarity index 91% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx index 378d669dee69cb..400de4052afa4b 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields.tsx @@ -24,7 +24,7 @@ export const DocumentFields = React.memo(() => { if (editorType === 'json') { return deNormalize(fields); } - }, [editorType]); + }, [editorType, fields]); const editor = editorType === 'json' ? ( @@ -41,9 +41,12 @@ export const DocumentFields = React.memo(() => { return ; }; - const onSearchChange = useCallback((value: string) => { - dispatch({ type: 'search:update', value }); - }, []); + const onSearchChange = useCallback( + (value: string) => { + dispatch({ type: 'search:update', value }); + }, + [dispatch] + ); const searchTerm = search.term.trim(); diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields_header.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields_header.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields_header.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/document_fields_header.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/editor_toggle_controls.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/editor_toggle_controls.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/editor_toggle_controls.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/editor_toggle_controls.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx similarity index 86% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx index de3d70db31af4d..a91231352c1684 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzer_parameter_selects.tsx @@ -56,15 +56,21 @@ export const AnalyzerParameterSelects = ({ }); return subscription.unsubscribe; - }, [form]); + }, [form, onChange]); - const getSubOptionsMeta = (mainValue: string) => - mapOptionsToSubOptions !== undefined ? mapOptionsToSubOptions[mainValue] : undefined; + const getSubOptionsMeta = useCallback( + (mainValue: string) => + mapOptionsToSubOptions !== undefined ? mapOptionsToSubOptions[mainValue] : undefined, + [mapOptionsToSubOptions] + ); - const onMainValueChange = useCallback((mainValue: unknown) => { - const subOptionsMeta = getSubOptionsMeta(mainValue as string); - form.setFieldValue('sub', subOptionsMeta ? subOptionsMeta.options[0].value : undefined); - }, []); + const onMainValueChange = useCallback( + (mainValue: unknown) => { + const subOptionsMeta = getSubOptionsMeta(mainValue as string); + form.setFieldValue('sub', subOptionsMeta ? subOptionsMeta.options[0].value : undefined); + }, + [form, getSubOptionsMeta] + ); const renderSelect = (field: FieldHook, opts: Options) => { const isSuperSelect = areOptionsSuperSelect(opts); diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/analyzers_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/boost_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/boost_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/boost_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/boost_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_number_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_number_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_number_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_number_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_shape_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_shape_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_shape_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/coerce_shape_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/copy_to_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/copy_to_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/copy_to_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/copy_to_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/doc_values_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/doc_values_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/doc_values_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/doc_values_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/dynamic_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/eager_global_ordinals_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/eager_global_ordinals_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/eager_global_ordinals_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/eager_global_ordinals_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/enabled_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/enabled_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/enabled_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/enabled_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_absolute.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_absolute.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_absolute.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_absolute.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_percentage.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_percentage.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_percentage.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_frequency_filter_percentage.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/fielddata_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/format_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/format_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/format_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/format_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_malformed.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_malformed.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_malformed.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_malformed.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_z_value_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_z_value_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_z_value_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/ignore_z_value_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/index_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/locale_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/locale_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/locale_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/locale_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/max_shingle_size_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/max_shingle_size_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/max_shingle_size_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/max_shingle_size_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/name_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/name_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/name_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/name_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/norms_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/norms_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/norms_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/norms_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/null_value_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/null_value_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/null_value_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/null_value_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/orientation_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/orientation_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/orientation_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/orientation_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/path_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/path_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/path_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/path_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/relations_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/relations_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/relations_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/relations_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/similarity_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/similarity_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/similarity_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/similarity_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/split_queries_on_whitespace_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/split_queries_on_whitespace_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/split_queries_on_whitespace_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/split_queries_on_whitespace_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/store_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/store_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/store_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/store_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/term_vector_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/term_vector_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/term_vector_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/term_vector_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/type_parameter.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/type_parameter.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/type_parameter.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/field_parameters/type_parameter.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_field_list_item.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_field_list_item.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_field_list_item.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_field_list_item.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_index.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_index.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/_index.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx similarity index 83% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx index 5f1b8c0df770ea..60b025ce644efe 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/create_field.tsx @@ -66,7 +66,7 @@ export const CreateField = React.memo(function CreateFieldComponent({ }); return subscription.unsubscribe; - }, [form]); + }, [form, dispatch]); const cancel = () => { dispatch({ type: 'documentField.changeStatus', value: 'idle' }); @@ -108,43 +108,53 @@ export const CreateField = React.memo(function CreateFieldComponent({ * * @param type The selected field type */ - const getSubTypeMeta = ( - type: MainType - ): { subTypeLabel?: string; subTypeOptions?: ComboBoxOption[] } => { - const typeDefinition = TYPE_DEFINITION[type]; - const hasSubTypes = typeDefinition !== undefined && typeDefinition.subTypes; - - let subTypeOptions = hasSubTypes - ? typeDefinition - .subTypes!.types.map(subType => TYPE_DEFINITION[subType]) - .map( - subType => ({ value: subType.value as SubType, label: subType.label } as ComboBoxOption) - ) - : undefined; - - if (hasSubTypes) { - if (isMultiField) { - // If it is a multi-field, we need to filter out non-allowed types - subTypeOptions = filterTypesForMultiField(subTypeOptions!); - } else if (isRootLevelField === false) { - subTypeOptions = filterTypesForNonRootFields(subTypeOptions!); + const getSubTypeMeta = useCallback( + ( + type: MainType + ): { + subTypeLabel?: string; + subTypeOptions?: ComboBoxOption[]; + } => { + const typeDefinition = TYPE_DEFINITION[type]; + const hasSubTypes = typeDefinition !== undefined && typeDefinition.subTypes; + + let subTypeOptions = hasSubTypes + ? typeDefinition + .subTypes!.types.map(subType => TYPE_DEFINITION[subType]) + .map( + subType => + ({ value: subType.value as SubType, label: subType.label } as ComboBoxOption) + ) + : undefined; + + if (hasSubTypes) { + if (isMultiField) { + // If it is a multi-field, we need to filter out non-allowed types + subTypeOptions = filterTypesForMultiField(subTypeOptions!); + } else if (isRootLevelField === false) { + subTypeOptions = filterTypesForNonRootFields(subTypeOptions!); + } } - } - return { - subTypeOptions, - subTypeLabel: hasSubTypes ? typeDefinition.subTypes!.label : undefined, - }; - }; + return { + subTypeOptions, + subTypeLabel: hasSubTypes ? typeDefinition.subTypes!.label : undefined, + }; + }, + [isMultiField, isRootLevelField] + ); - const onTypeChange = (nextType: ComboBoxOption[]) => { - form.setFieldValue('type', nextType); + const onTypeChange = useCallback( + (nextType: ComboBoxOption[]) => { + form.setFieldValue('type', nextType); - if (nextType.length) { - const { subTypeOptions } = getSubTypeMeta(nextType[0].value as MainType); - form.setFieldValue('subType', subTypeOptions ? [subTypeOptions[0]] : undefined); - } - }; + if (nextType.length) { + const { subTypeOptions } = getSubTypeMeta(nextType[0].value as MainType); + form.setFieldValue('subType', subTypeOptions ? [subTypeOptions[0]] : undefined); + } + }, + [form, getSubTypeMeta] + ); const renderFormFields = useCallback( ({ type }) => { @@ -208,7 +218,7 @@ export const CreateField = React.memo(function CreateFieldComponent({
); }, - [form, isMultiField] + [getSubTypeMeta, isMultiField, isRootLevelField, onTypeChange] ); const renderFormActions = () => ( diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/alias_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/alias_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/alias_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/alias_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/dense_vector_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/dense_vector_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/dense_vector_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/dense_vector_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/scaled_float_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/scaled_float_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/scaled_float_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/scaled_float_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/token_count_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/token_count_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/token_count_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/create_field/required_parameters_forms/token_count_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/delete_field_provider.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/delete_field_provider.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/delete_field_provider.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/delete_field_provider.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_edit_field_form_row.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_edit_field_form_row.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_edit_field_form_row.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_edit_field_form_row.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_index.scss b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_index.scss rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/_index.scss diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/advanced_parameters_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/basic_parameters_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/basic_parameters_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/basic_parameters_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/basic_parameters_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx similarity index 97% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx index 284ae8803acb56..1f77584439568c 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_container.tsx @@ -32,11 +32,11 @@ export const EditFieldContainer = React.memo(({ field, allFields }: Props) => { }); return subscription.unsubscribe; - }, [form]); + }, [form, dispatch]); const exitEdit = useCallback(() => { dispatch({ type: 'documentField.changeStatus', value: 'idle' }); - }, []); + }, [dispatch]); return ; }); diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_form_row.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_header_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_header_form.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_header_form.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/edit_field_header_form.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/field_description_section.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/field_description_section.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/field_description_section.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/field_description_section.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/update_field_provider.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/update_field_provider.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/update_field_provider.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/edit_field/update_field_provider.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/alias_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/alias_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/alias_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/alias_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/binary_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/binary_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/binary_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/binary_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/boolean_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/boolean_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/boolean_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/boolean_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/completion_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/completion_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/completion_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/completion_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/date_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/date_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/date_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/date_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/dense_vector_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/dense_vector_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/dense_vector_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/dense_vector_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/flattened_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/flattened_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/flattened_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/flattened_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_point_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_point_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_point_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_point_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_shape_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_shape_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_shape_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/geo_shape_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/ip_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/ip_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/ip_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/ip_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/join_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/join_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/join_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/join_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/keyword_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/keyword_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/keyword_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/keyword_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/nested_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/nested_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/nested_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/nested_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/numeric_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/numeric_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/numeric_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/numeric_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/object_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/object_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/object_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/object_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/range_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/range_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/range_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/range_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/search_as_you_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/search_as_you_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/search_as_you_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/search_as_you_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/shape_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/shape_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/shape_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/shape_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/text_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/text_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/text_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/text_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/token_count_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/token_count_type.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/token_count_type.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/token_count_type.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx similarity index 92% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx index cff2d294fead95..55093e606cfa1f 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/fields_list_item_container.tsx @@ -23,7 +23,7 @@ export const FieldsListItemContainer = ({ fieldId, treeDepth, isLastItem }: Prop fields: { byId, maxNestedDepth }, } = useMappingsState(); - const getField = (id: string) => byId[id]; + const getField = useCallback((id: string) => byId[id], [byId]); const field: NormalizedField = getField(fieldId); const { childFields } = field; @@ -33,7 +33,7 @@ export const FieldsListItemContainer = ({ fieldId, treeDepth, isLastItem }: Prop const areActionButtonsVisible = status === 'idle'; const childFieldsArray = useMemo( () => (childFields !== undefined ? childFields.map(getField) : []), - [childFields] + [childFields, getField] ); const addField = useCallback(() => { @@ -41,18 +41,18 @@ export const FieldsListItemContainer = ({ fieldId, treeDepth, isLastItem }: Prop type: 'documentField.createField', value: fieldId, }); - }, [fieldId]); + }, [fieldId, dispatch]); const editField = useCallback(() => { dispatch({ type: 'documentField.editField', value: fieldId, }); - }, [fieldId]); + }, [fieldId, dispatch]); const toggleExpand = useCallback(() => { dispatch({ type: 'field.toggleExpand', value: { fieldId } }); - }, [fieldId]); + }, [fieldId, dispatch]); return ( { documentFields: { status, fieldToAddFieldTo }, } = useMappingsState(); - const getField = (fieldId: string) => byId[fieldId]; - const fields = useMemo(() => rootLevelFields.map(getField), [rootLevelFields]); + const getField = useCallback((fieldId: string) => byId[fieldId], [byId]); + const fields = useMemo(() => rootLevelFields.map(getField), [rootLevelFields, getField]); - const addField = () => { + const addField = useCallback(() => { dispatch({ type: 'documentField.createField' }); - }; + }, [dispatch]); useEffect(() => { /** @@ -32,7 +32,7 @@ export const DocumentFieldsTreeEditor = () => { if (status === 'idle' && fields.length === 0) { addField(); } - }, [fields, status]); + }, [addField, fields, status]); const renderCreateField = () => { // The "fieldToAddFieldTo" is undefined when adding to the top level "properties" object. diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/search_fields/search_result_item.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/fields_tree.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/fields_tree.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/fields_tree.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/fields_tree.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_from_json_button.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_from_json_button.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_from_json_button.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_from_json_button.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx index a9433d3a7530ff..f8e3eca7898d24 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.test.tsx @@ -19,7 +19,7 @@ jest.mock('@elastic/eui', () => ({ ), })); -import { registerTestBed, nextTick, TestBed } from '../../../../../../../../../test_utils'; +import { registerTestBed, nextTick, TestBed } from '../../../../../../../../test_utils'; import { LoadMappingsProvider } from './load_mappings_provider'; const ComponentToTest = ({ onJson }: { onJson: () => void }) => ( diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/load_mappings/load_mappings_provider.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/multiple_mappings_warning.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/multiple_mappings_warning.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/multiple_mappings_warning.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/multiple_mappings_warning.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx index 471217108ba6f5..f32fcb3956e1c3 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx @@ -69,7 +69,7 @@ export const TemplatesForm = React.memo(({ defaultValue }: Props) => { }); }); return subscription.unsubscribe; - }, [form]); + }, [form, dispatch]); useEffect(() => { if (didMountRef.current) { @@ -80,14 +80,14 @@ export const TemplatesForm = React.memo(({ defaultValue }: Props) => { // Avoid reseting the form on component mount. didMountRef.current = true; } - }, [defaultValue]); + }, [defaultValue, form]); useEffect(() => { return () => { // On unmount => save in the state a snapshot of the current form data. dispatch({ type: 'templates.save' }); }; - }, []); + }, [dispatch]); return ( <> diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form_schema.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form_schema.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form_schema.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form_schema.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/tree.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/tree.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/tree.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/tree.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/tree_item.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/tree_item.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/components/tree/tree_item.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/components/tree/tree_item.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/default_values.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/field_options.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/field_options.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/field_options.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/field_options.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/field_options_i18n.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/field_options_i18n.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/field_options_i18n.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/field_options_i18n.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/mappings_editor.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/mappings_editor.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/mappings_editor.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/mappings_editor.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/constants/parameters_definition.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/index_settings_context.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/index_settings_context.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/index_settings_context.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/index_settings_context.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/error_reporter.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/error_reporter.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/error_reporter.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/error_reporter.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.test.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.test.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/extract_mappings_definition.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/index.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.test.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/mappings_validator.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.test.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.test.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/search_fields.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/serializers.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/serializers.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/serializers.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/serializers.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.test.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/utils.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/validators.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/lib/validators.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/lib/validators.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/lib/validators.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx index d79a023386e8d6..b6345a7140e15b 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_editor.tsx @@ -78,7 +78,7 @@ export const MappingsEditor = React.memo(({ onUpdate, defaultValue, indexSetting isValid: true, }); } - }, [multipleMappingsDeclared]); + }, [multipleMappingsDeclared, onUpdate, defaultValue]); const changeTab = async (tab: TabName, state: State) => { if (selectedTab === 'advanced') { diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx rename to x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx index 65a1aa2858d142..247bd183baddf5 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/mappings_state.tsx @@ -168,7 +168,7 @@ export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: P }, isValid: state.isValid, }); - }, [state]); + }, [state, onUpdate]); useEffect(() => { /** @@ -187,7 +187,7 @@ export const MappingsState = React.memo(({ children, onUpdate, defaultValue }: P } else { didMountRef.current = true; } - }, [defaultValue]); + }, [defaultValue, parsedFieldsDefaultValue]); return ( diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/reducer.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/reducer.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/reducer.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/reducer.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts similarity index 72% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts index e99d8840d57dfe..2979015c07455d 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/shared_imports.ts @@ -24,7 +24,7 @@ export { VALIDATION_TYPES, ValidationFunc, ValidationFuncArg, -} from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; +} from '../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; export { CheckBoxField, @@ -39,14 +39,14 @@ export { ComboBoxField, ToggleField, JsonEditorField, -} from '../../../../../../../../src/plugins/es_ui_shared/static/forms/components'; +} from '../../../../../../../src/plugins/es_ui_shared/static/forms/components'; export { fieldFormatters, fieldValidators, -} from '../../../../../../../../src/plugins/es_ui_shared/static/forms/helpers'; +} from '../../../../../../../src/plugins/es_ui_shared/static/forms/helpers'; export { JsonEditor, OnJsonEditorUpdateHandler, -} from '../../../../../../../../src/plugins/es_ui_shared/public'; +} from '../../../../../../../src/plugins/es_ui_shared/public'; diff --git a/x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/types.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/types.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/mappings_editor/types.ts rename to x-pack/plugins/index_management/public/application/components/mappings_editor/types.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/no_match/index.ts b/x-pack/plugins/index_management/public/application/components/no_match/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/no_match/index.ts rename to x-pack/plugins/index_management/public/application/components/no_match/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/no_match/no_match.tsx b/x-pack/plugins/index_management/public/application/components/no_match/no_match.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/no_match/no_match.tsx rename to x-pack/plugins/index_management/public/application/components/no_match/no_match.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/page_error/index.ts b/x-pack/plugins/index_management/public/application/components/page_error/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/page_error/index.ts rename to x-pack/plugins/index_management/public/application/components/page_error/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx b/x-pack/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx rename to x-pack/plugins/index_management/public/application/components/page_error/page_error_forbidden.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/section_error.tsx b/x-pack/plugins/index_management/public/application/components/section_error.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/section_error.tsx rename to x-pack/plugins/index_management/public/application/components/section_error.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/section_loading.tsx b/x-pack/plugins/index_management/public/application/components/section_loading.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/section_loading.tsx rename to x-pack/plugins/index_management/public/application/components/section_loading.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_delete_modal.tsx b/x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_delete_modal.tsx rename to x-pack/plugins/index_management/public/application/components/template_delete_modal.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/index.ts b/x-pack/plugins/index_management/public/application/components/template_form/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/index.ts rename to x-pack/plugins/index_management/public/application/components/template_form/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/index.ts b/x-pack/plugins/index_management/public/application/components/template_form/steps/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/index.ts rename to x-pack/plugins/index_management/public/application/components/template_form/steps/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_aliases.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_aliases.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_aliases.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/steps/step_aliases.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx similarity index 94% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx index dd8d49a5690425..2f6e055b5d0c6d 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx @@ -7,15 +7,8 @@ import React, { useEffect } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiButtonEmpty, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { - useForm, - Form, - getUseField, -} from '../../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; -import { - getFormRow, - Field, -} from '../../../../../../../../../src/plugins/es_ui_shared/static/forms/components'; + +import { useForm, Form, getUseField, getFormRow, Field } from '../../../../shared_imports'; import { documentationService } from '../../../services/documentation'; import { StepProps } from '../types'; import { schemas, nameConfig, nameConfigWithoutValidations } from '../template_form_schemas'; @@ -80,11 +73,11 @@ export const StepLogistics: React.FunctionComponent = ({ useEffect(() => { onStepValidityChange(form.isValid); - }, [form.isValid]); + }, [form.isValid, onStepValidityChange]); useEffect(() => { setDataGetter(form.submit); - }, [form]); + }, [form.submit, setDataGetter]); const { name, indexPatterns, order, version } = fieldsMeta; diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/steps/step_mappings.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_review.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_review.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx index 09172bf5cd0caa..09da43b83c3c51 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_review.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx @@ -20,7 +20,7 @@ import { EuiCodeBlock, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { serializers } from '../../../../../../../../../src/plugins/es_ui_shared/static/forms/helpers'; +import { serializers } from '../../../../shared_imports'; import { serializeTemplate } from '../../../../../common/lib/template_serialization'; import { Template } from '../../../../../common/types'; diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_settings.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_settings.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/step_settings.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/steps/step_settings.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts b/x-pack/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts similarity index 83% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts rename to x-pack/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts index ae16a2e9263ff5..fbe479ea0cf235 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/use_json_step.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { isJSON } from '../../../../../../../../../src/plugins/es_ui_shared/static/validators/string'; +import { isJSON } from '../../../../shared_imports'; import { StepProps } from '../types'; interface Parameters { @@ -29,7 +29,7 @@ export const useJsonStep = ({ const [content, setContent] = useState(stringifyJson(defaultValue)); const [error, setError] = useState(null); - const validateContent = () => { + const validateContent = useCallback(() => { // We allow empty string as it will be converted to "{}"" const isValid = content.trim() === '' ? true : isJSON(content); if (!isValid) { @@ -42,20 +42,20 @@ export const useJsonStep = ({ setError(null); } return isValid; - }; + }, [content]); - const dataGetter = () => { + const dataGetter = useCallback(() => { const isValid = validateContent(); const value = isValid && content.trim() !== '' ? JSON.parse(content) : {}; const data = { [prop]: value }; return Promise.resolve({ isValid, data }); - }; + }, [content, validateContent, prop]); useEffect(() => { const isValid = validateContent(); onStepValidityChange(isValid); setDataGetter(dataGetter); - }, [content]); + }, [content, dataGetter, onStepValidityChange, setDataGetter, validateContent]); return { content, diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx similarity index 92% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx index 6a76e1d203b70f..58be9b2c633653 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx @@ -3,7 +3,7 @@ * 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, { Fragment, useState, useRef } from 'react'; +import React, { Fragment, useState, useRef, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton, @@ -14,7 +14,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import { serializers } from '../../../../../../../../src/plugins/es_ui_shared/static/forms/helpers'; +import { serializers } from '../../../shared_imports'; import { Template } from '../../../../common/types'; import { TemplateSteps } from './template_steps'; import { StepAliases, StepLogistics, StepMappings, StepSettings, StepReview } from './steps'; @@ -70,19 +70,25 @@ export const TemplateForm: React.FunctionComponent = ({ const CurrentStepComponent = stepComponentMap[currentStep]; const isStepValid = validation[currentStep].isValid; - const setStepDataGetter = (stepDataGetter: DataGetterFunc) => { - stepsDataGetters.current[currentStep] = stepDataGetter; - }; + const setStepDataGetter = useCallback( + (stepDataGetter: DataGetterFunc) => { + stepsDataGetters.current[currentStep] = stepDataGetter; + }, + [currentStep] + ); - const onStepValidityChange = (isValid: boolean | undefined) => { - setValidation(prev => ({ - ...prev, - [currentStep]: { - isValid, - errors: {}, - }, - })); - }; + const onStepValidityChange = useCallback( + (isValid: boolean | undefined) => { + setValidation(prev => ({ + ...prev, + [currentStep]: { + isValid, + errors: {}, + }, + })); + }, + [currentStep] + ); const validateAndGetDataFromCurrentStep = async () => { const validateAndGetData = stepsDataGetters.current[currentStep]; diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx similarity index 96% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx index ed2616cc64e381..9ff73b71adf50d 100644 --- a/x-pack/legacy/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx @@ -13,12 +13,9 @@ import { FIELD_TYPES, VALIDATION_TYPES, FieldConfig, -} from '../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; - -import { fieldFormatters, fieldValidators, -} from '../../../../../../../../src/plugins/es_ui_shared/static/forms/helpers'; +} from '../../../shared_imports'; import { INVALID_INDEX_PATTERN_CHARS, diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/template_steps.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_steps.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/template_steps.tsx rename to x-pack/plugins/index_management/public/application/components/template_form/template_steps.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/components/template_form/types.ts b/x-pack/plugins/index_management/public/application/components/template_form/types.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/components/template_form/types.ts rename to x-pack/plugins/index_management/public/application/components/template_form/types.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/constants/detail_panel_tabs.ts b/x-pack/plugins/index_management/public/application/constants/detail_panel_tabs.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/constants/detail_panel_tabs.ts rename to x-pack/plugins/index_management/public/application/constants/detail_panel_tabs.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/constants/index.ts b/x-pack/plugins/index_management/public/application/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/constants/index.ts rename to x-pack/plugins/index_management/public/application/constants/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/constants/refresh_intervals.ts b/x-pack/plugins/index_management/public/application/constants/refresh_intervals.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/constants/refresh_intervals.ts rename to x-pack/plugins/index_management/public/application/constants/refresh_intervals.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/index.tsx b/x-pack/plugins/index_management/public/application/index.tsx similarity index 94% rename from x-pack/legacy/plugins/index_management/public/application/index.tsx rename to x-pack/plugins/index_management/public/application/index.tsx index b9859903f14345..5850cb8d42f1aa 100644 --- a/x-pack/legacy/plugins/index_management/public/application/index.tsx +++ b/x-pack/plugins/index_management/public/application/index.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Provider } from 'react-redux'; import { render, unmountComponentAtNode } from 'react-dom'; -import { CoreStart } from '../../../../../../src/core/public'; +import { CoreStart } from '../../../../../src/core/public'; import { AppContextProvider, AppDependencies } from './app_context'; import { App } from './app'; diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/ace.js b/x-pack/plugins/index_management/public/application/lib/ace.js similarity index 94% rename from x-pack/legacy/plugins/index_management/public/application/lib/ace.js rename to x-pack/plugins/index_management/public/application/lib/ace.js index b9620dfbdb1207..3b37c8fb8870ed 100644 --- a/x-pack/legacy/plugins/index_management/public/application/lib/ace.js +++ b/x-pack/plugins/index_management/public/application/lib/ace.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import ace from 'ace'; +import brace from 'brace'; import 'brace/ext/language_tools'; const splitTokens = line => { @@ -43,14 +43,14 @@ const wordCompleter = words => { }; export const createAceEditor = (div, value, readOnly = true, autocompleteArray) => { - const editor = ace.edit(div); + const editor = brace.edit(div); editor.$blockScrolling = Infinity; editor.setValue(value, -1); const session = editor.getSession(); session.setUseWrapMode(true); session.setMode('ace/mode/json'); if (autocompleteArray) { - const languageTools = ace.acequire('ace/ext/language_tools'); + const languageTools = brace.acequire('ace/ext/language_tools'); const autocompleter = wordCompleter(autocompleteArray); languageTools.setCompleters([autocompleter]); } diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/edit_settings.js b/x-pack/plugins/index_management/public/application/lib/edit_settings.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/edit_settings.js rename to x-pack/plugins/index_management/public/application/lib/edit_settings.js diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/flatten_object.js b/x-pack/plugins/index_management/public/application/lib/flatten_object.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/flatten_object.js rename to x-pack/plugins/index_management/public/application/lib/flatten_object.js diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/flatten_panel_tree.js b/x-pack/plugins/index_management/public/application/lib/flatten_panel_tree.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/flatten_panel_tree.js rename to x-pack/plugins/index_management/public/application/lib/flatten_panel_tree.js diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/index_status_labels.js b/x-pack/plugins/index_management/public/application/lib/index_status_labels.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/index_status_labels.js rename to x-pack/plugins/index_management/public/application/lib/index_status_labels.js diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/manage_angular_lifecycle.ts b/x-pack/plugins/index_management/public/application/lib/manage_angular_lifecycle.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/manage_angular_lifecycle.ts rename to x-pack/plugins/index_management/public/application/lib/manage_angular_lifecycle.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/lib/render_badges.js b/x-pack/plugins/index_management/public/application/lib/render_badges.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/lib/render_badges.js rename to x-pack/plugins/index_management/public/application/lib/render_badges.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/home.tsx b/x-pack/plugins/index_management/public/application/sections/home/home.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/home.tsx rename to x-pack/plugins/index_management/public/application/sections/home/home.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index.ts b/x-pack/plugins/index_management/public/application/sections/home/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/detail_panel.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/edit_settings_json.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/edit_settings_json/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/summary/summary.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index.ts b/x-pack/plugins/index_management/public/application/sections/home/index_list/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_list.d.ts b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.d.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_list.d.ts rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.d.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_list.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_list.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_list.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js rename to x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/template_list/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_aliases.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_aliases.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_aliases.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_aliases.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_mappings.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_mappings.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_mappings.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_mappings.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_settings.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_settings.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_settings.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_settings.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx index ced8bd97e744b9..9c31b0d650449d 100644 --- a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/template_details.tsx @@ -32,7 +32,7 @@ import { } from '../../../../../../common/constants'; import { Template } from '../../../../../../common/types'; import { TemplateDeleteModal, SectionLoading, SectionError, Error } from '../../../../components'; -import { loadIndexTemplate } from '../../../../services/api'; +import { useLoadIndexTemplate } from '../../../../services/api'; import { decodePath } from '../../../../services/routing'; import { SendRequestResponse } from '../../../../../shared_imports'; import { useServices } from '../../../../app_context'; @@ -103,7 +103,7 @@ export const TemplateDetails: React.FunctionComponent = ({ }) => { const { uiMetricService } = useServices(); const decodedTemplateName = decodePath(templateName); - const { error, data: templateDetails, isLoading } = loadIndexTemplate(decodedTemplateName); + const { error, data: templateDetails, isLoading } = useLoadIndexTemplate(decodedTemplateName); // TS complains if we use destructuring here. Fixed in 3.6.0 (https://github.com/microsoft/TypeScript/pull/31711). const isManaged = templateDetails ? templateDetails.isManaged : undefined; const [templateToDelete, setTemplateToDelete] = useState>([]); diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx similarity index 97% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_list.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx index 71c32e2e0177ff..ffdb224f162713 100644 --- a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_list.tsx @@ -18,7 +18,7 @@ import { } from '@elastic/eui'; import { SectionError, SectionLoading, Error } from '../../../components'; import { TemplateTable } from './template_table'; -import { loadIndexTemplates } from '../../../services/api'; +import { useLoadIndexTemplates } from '../../../services/api'; import { Template } from '../../../../../common/types'; import { useServices } from '../../../app_context'; import { @@ -40,7 +40,7 @@ export const TemplateList: React.FunctionComponent { const { uiMetricService } = useServices(); - const { error, isLoading, data: templates, sendRequest: reload } = loadIndexTemplates(); + const { error, isLoading, data: templates, sendRequest: reload } = useLoadIndexTemplates(); let content; @@ -68,7 +68,7 @@ export const TemplateList: React.FunctionComponent { uiMetricService.trackMetric('loaded', UIM_TEMPLATE_LIST_LOAD); - }, []); + }, [uiMetricService]); if (isLoading) { content = ( diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_table/index.ts b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_table/index.ts rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx rename to x-pack/plugins/index_management/public/application/sections/home/template_list/template_table/template_table.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_clone/index.ts b/x-pack/plugins/index_management/public/application/sections/template_clone/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_clone/index.ts rename to x-pack/plugins/index_management/public/application/sections/template_clone/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_clone/template_clone.tsx b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx similarity index 96% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_clone/template_clone.tsx rename to x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx index 6659be5a2cf4e3..cf6ca3c0657773 100644 --- a/x-pack/legacy/plugins/index_management/public/application/sections/template_clone/template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_clone/template_clone.tsx @@ -11,7 +11,7 @@ import { TemplateForm, SectionLoading, SectionError, Error } from '../../compone import { breadcrumbService } from '../../services/breadcrumbs'; import { decodePath, getTemplateDetailsLink } from '../../services/routing'; import { Template } from '../../../../common/types'; -import { saveTemplate, loadIndexTemplate } from '../../services/api'; +import { saveTemplate, useLoadIndexTemplate } from '../../services/api'; interface MatchParams { name: string; @@ -27,7 +27,7 @@ export const TemplateClone: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const { error: templateToCloneError, data: templateToClone, isLoading } = loadIndexTemplate( + const { error: templateToCloneError, data: templateToClone, isLoading } = useLoadIndexTemplate( decodedTemplateName ); diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_create/index.ts b/x-pack/plugins/index_management/public/application/sections/template_create/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_create/index.ts rename to x-pack/plugins/index_management/public/application/sections/template_create/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_create/template_create.tsx b/x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_create/template_create.tsx rename to x-pack/plugins/index_management/public/application/sections/template_create/template_create.tsx diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_edit/index.ts b/x-pack/plugins/index_management/public/application/sections/template_edit/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_edit/index.ts rename to x-pack/plugins/index_management/public/application/sections/template_edit/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/sections/template_edit/template_edit.tsx b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx similarity index 96% rename from x-pack/legacy/plugins/index_management/public/application/sections/template_edit/template_edit.tsx rename to x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx index 69e446528a68d5..1e9d5f294de34c 100644 --- a/x-pack/legacy/plugins/index_management/public/application/sections/template_edit/template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx @@ -8,7 +8,7 @@ import { RouteComponentProps } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPageBody, EuiPageContent, EuiTitle, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { breadcrumbService } from '../../services/breadcrumbs'; -import { loadIndexTemplate, updateTemplate } from '../../services/api'; +import { useLoadIndexTemplate, updateTemplate } from '../../services/api'; import { decodePath, getTemplateDetailsLink } from '../../services/routing'; import { SectionLoading, SectionError, TemplateForm, Error } from '../../components'; import { Template } from '../../../../common/types'; @@ -27,7 +27,7 @@ export const TemplateEdit: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const { error, data: template, isLoading } = loadIndexTemplate(decodedTemplateName); + const { error, data: template, isLoading } = useLoadIndexTemplate(decodedTemplateName); useEffect(() => { breadcrumbService.setBreadcrumbs('templateEdit'); diff --git a/x-pack/legacy/plugins/index_management/public/application/services/api.ts b/x-pack/plugins/index_management/public/application/services/api.ts similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/services/api.ts rename to x-pack/plugins/index_management/public/application/services/api.ts index 642fd441b353a1..88887f40972e43 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/api.ts +++ b/x-pack/plugins/index_management/public/application/services/api.ts @@ -200,7 +200,7 @@ export async function loadIndexData(type: string, indexName: string) { } } -export function loadIndexTemplates() { +export function useLoadIndexTemplates() { return useRequest({ path: `${API_BASE_PATH}/templates`, method: 'get', @@ -220,7 +220,7 @@ export async function deleteTemplates(names: Array) { return result; } -export function loadIndexTemplate(name: Template['name']) { +export function useLoadIndexTemplate(name: Template['name']) { return useRequest({ path: `${API_BASE_PATH}/templates/${encodeURIComponent(name)}`, method: 'get', diff --git a/x-pack/legacy/plugins/index_management/public/application/services/breadcrumbs.ts b/x-pack/plugins/index_management/public/application/services/breadcrumbs.ts similarity index 96% rename from x-pack/legacy/plugins/index_management/public/application/services/breadcrumbs.ts rename to x-pack/plugins/index_management/public/application/services/breadcrumbs.ts index 299491756560ee..8128ccd545dceb 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/breadcrumbs.ts +++ b/x-pack/plugins/index_management/public/application/services/breadcrumbs.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; import { BASE_PATH } from '../../../common/constants'; -import { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public'; +import { ManagementAppMountParams } from '../../../../../../src/plugins/management/public'; type SetBreadcrumbs = ManagementAppMountParams['setBreadcrumbs']; diff --git a/x-pack/legacy/plugins/index_management/public/application/services/documentation.ts b/x-pack/plugins/index_management/public/application/services/documentation.ts similarity index 98% rename from x-pack/legacy/plugins/index_management/public/application/services/documentation.ts rename to x-pack/plugins/index_management/public/application/services/documentation.ts index e0f261e586b1e7..fdf07c43a0c8b2 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/documentation.ts +++ b/x-pack/plugins/index_management/public/application/services/documentation.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { DocLinksStart } from '../../../../../../../src/core/public'; +import { DocLinksStart } from '../../../../../../src/core/public'; import { DataType } from '../components/mappings_editor/types'; import { TYPE_DEFINITION } from '../components/mappings_editor/constants'; diff --git a/x-pack/legacy/plugins/index_management/public/application/services/health_to_color.ts b/x-pack/plugins/index_management/public/application/services/health_to_color.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/services/health_to_color.ts rename to x-pack/plugins/index_management/public/application/services/health_to_color.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/services/http.ts b/x-pack/plugins/index_management/public/application/services/http.ts similarity index 88% rename from x-pack/legacy/plugins/index_management/public/application/services/http.ts rename to x-pack/plugins/index_management/public/application/services/http.ts index a6973c263f00f2..931e5fcd21898f 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/http.ts +++ b/x-pack/plugins/index_management/public/application/services/http.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from '../../../../../../../src/core/public'; +import { HttpSetup } from '../../../../../../src/core/public'; export class HttpService { private client: any; diff --git a/x-pack/legacy/plugins/index_management/public/application/services/index.ts b/x-pack/plugins/index_management/public/application/services/index.ts similarity index 96% rename from x-pack/legacy/plugins/index_management/public/application/services/index.ts rename to x-pack/plugins/index_management/public/application/services/index.ts index 78ff8cb5c314ac..2334d32adf1314 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/index.ts +++ b/x-pack/plugins/index_management/public/application/services/index.ts @@ -21,7 +21,7 @@ export { loadIndexStats, loadIndexMapping, loadIndexData, - loadIndexTemplates, + useLoadIndexTemplates, } from './api'; export { healthToColor } from './health_to_color'; export { sortTable } from './sort_table'; diff --git a/x-pack/legacy/plugins/index_management/public/application/services/navigation.ts b/x-pack/plugins/index_management/public/application/services/navigation.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/services/navigation.ts rename to x-pack/plugins/index_management/public/application/services/navigation.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/services/notification.ts b/x-pack/plugins/index_management/public/application/services/notification.ts similarity index 93% rename from x-pack/legacy/plugins/index_management/public/application/services/notification.ts rename to x-pack/plugins/index_management/public/application/services/notification.ts index 0971ca77c004bb..82b9de22727471 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/notification.ts +++ b/x-pack/plugins/index_management/public/application/services/notification.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { NotificationsStart } from '../../../../../../../src/core/public'; +import { NotificationsStart } from '../../../../../../src/core/public'; export class NotificationService { private _toasts: any; diff --git a/x-pack/legacy/plugins/index_management/public/application/services/routing.ts b/x-pack/plugins/index_management/public/application/services/routing.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/services/routing.ts rename to x-pack/plugins/index_management/public/application/services/routing.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/services/sort_table.ts b/x-pack/plugins/index_management/public/application/services/sort_table.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/services/sort_table.ts rename to x-pack/plugins/index_management/public/application/services/sort_table.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/services/ui_metric.ts b/x-pack/plugins/index_management/public/application/services/ui_metric.ts similarity index 90% rename from x-pack/legacy/plugins/index_management/public/application/services/ui_metric.ts rename to x-pack/plugins/index_management/public/application/services/ui_metric.ts index 7c87ec9509085c..73d2ef5aced861 100644 --- a/x-pack/legacy/plugins/index_management/public/application/services/ui_metric.ts +++ b/x-pack/plugins/index_management/public/application/services/ui_metric.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ import { UiStatsMetricType } from '@kbn/analytics'; -import { UsageCollectionSetup } from '../../../../../../../src/plugins/usage_collection/public'; + +import { UsageCollectionSetup } from '../../../../../../src/plugins/usage_collection/public'; import { IndexMgmtMetricsType } from '../../types'; let uiMetricService: UiMetricService; @@ -23,7 +24,8 @@ export class UiMetricService { private track(type: T, name: string) { if (!this.usageCollection) { - throw Error('UiMetricService not initialized.'); + // Usage collection might have been disabled in Kibana config. + return; } this.usageCollection.reportUiStats(this.appName, type as UiStatsMetricType, name); } diff --git a/x-pack/legacy/plugins/index_management/public/application/services/use_request.ts b/x-pack/plugins/index_management/public/application/services/use_request.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/services/use_request.ts rename to x-pack/plugins/index_management/public/application/services/use_request.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/clear_cache_indices.js b/x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/clear_cache_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/clear_row_status.js b/x-pack/plugins/index_management/public/application/store/actions/clear_row_status.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/clear_row_status.js rename to x-pack/plugins/index_management/public/application/store/actions/clear_row_status.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/close_indices.js b/x-pack/plugins/index_management/public/application/store/actions/close_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/close_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/close_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/delete_indices.js b/x-pack/plugins/index_management/public/application/store/actions/delete_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/delete_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/delete_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/detail_panel.js b/x-pack/plugins/index_management/public/application/store/actions/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/detail_panel.js rename to x-pack/plugins/index_management/public/application/store/actions/detail_panel.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/edit_index_settings.js b/x-pack/plugins/index_management/public/application/store/actions/edit_index_settings.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/edit_index_settings.js rename to x-pack/plugins/index_management/public/application/store/actions/edit_index_settings.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/extension_action.js b/x-pack/plugins/index_management/public/application/store/actions/extension_action.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/extension_action.js rename to x-pack/plugins/index_management/public/application/store/actions/extension_action.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/flush_indices.js b/x-pack/plugins/index_management/public/application/store/actions/flush_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/flush_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/flush_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/forcemerge_indices.js b/x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/forcemerge_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/freeze_indices.js b/x-pack/plugins/index_management/public/application/store/actions/freeze_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/freeze_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/freeze_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/index.js b/x-pack/plugins/index_management/public/application/store/actions/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/index.js rename to x-pack/plugins/index_management/public/application/store/actions/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/load_index_data.js b/x-pack/plugins/index_management/public/application/store/actions/load_index_data.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/load_index_data.js rename to x-pack/plugins/index_management/public/application/store/actions/load_index_data.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/load_indices.js b/x-pack/plugins/index_management/public/application/store/actions/load_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/load_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/load_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/open_indices.js b/x-pack/plugins/index_management/public/application/store/actions/open_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/open_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/open_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/refresh_indices.js b/x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/refresh_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/reload_indices.js b/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/reload_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/reload_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/table_state.js b/x-pack/plugins/index_management/public/application/store/actions/table_state.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/table_state.js rename to x-pack/plugins/index_management/public/application/store/actions/table_state.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/unfreeze_indices.js b/x-pack/plugins/index_management/public/application/store/actions/unfreeze_indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/unfreeze_indices.js rename to x-pack/plugins/index_management/public/application/store/actions/unfreeze_indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/actions/update_index_settings.js b/x-pack/plugins/index_management/public/application/store/actions/update_index_settings.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/actions/update_index_settings.js rename to x-pack/plugins/index_management/public/application/store/actions/update_index_settings.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/index.ts b/x-pack/plugins/index_management/public/application/store/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/index.ts rename to x-pack/plugins/index_management/public/application/store/index.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/detail_panel.js b/x-pack/plugins/index_management/public/application/store/reducers/detail_panel.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/detail_panel.js rename to x-pack/plugins/index_management/public/application/store/reducers/detail_panel.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/index.js b/x-pack/plugins/index_management/public/application/store/reducers/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/index.js rename to x-pack/plugins/index_management/public/application/store/reducers/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/index_management.js b/x-pack/plugins/index_management/public/application/store/reducers/index_management.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/index_management.js rename to x-pack/plugins/index_management/public/application/store/reducers/index_management.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/indices.js b/x-pack/plugins/index_management/public/application/store/reducers/indices.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/indices.js rename to x-pack/plugins/index_management/public/application/store/reducers/indices.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/row_status.js b/x-pack/plugins/index_management/public/application/store/reducers/row_status.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/row_status.js rename to x-pack/plugins/index_management/public/application/store/reducers/row_status.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/reducers/table_state.js b/x-pack/plugins/index_management/public/application/store/reducers/table_state.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/reducers/table_state.js rename to x-pack/plugins/index_management/public/application/store/reducers/table_state.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/selectors/index.d.ts b/x-pack/plugins/index_management/public/application/store/selectors/index.d.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/selectors/index.d.ts rename to x-pack/plugins/index_management/public/application/store/selectors/index.d.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/store/selectors/index.js b/x-pack/plugins/index_management/public/application/store/selectors/index.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/selectors/index.js rename to x-pack/plugins/index_management/public/application/store/selectors/index.js diff --git a/x-pack/legacy/plugins/index_management/public/application/store/store.d.ts b/x-pack/plugins/index_management/public/application/store/store.d.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/store.d.ts rename to x-pack/plugins/index_management/public/application/store/store.d.ts diff --git a/x-pack/legacy/plugins/index_management/public/application/store/store.js b/x-pack/plugins/index_management/public/application/store/store.js similarity index 100% rename from x-pack/legacy/plugins/index_management/public/application/store/store.js rename to x-pack/plugins/index_management/public/application/store/store.js diff --git a/x-pack/legacy/plugins/index_management/public/index.scss b/x-pack/plugins/index_management/public/index.scss similarity index 100% rename from x-pack/legacy/plugins/index_management/public/index.scss rename to x-pack/plugins/index_management/public/index.scss diff --git a/x-pack/legacy/plugins/index_management/public/index.ts b/x-pack/plugins/index_management/public/index.ts similarity index 66% rename from x-pack/legacy/plugins/index_management/public/index.ts rename to x-pack/plugins/index_management/public/index.ts index 16e7bf21aee98d..6bb921ef648f34 100644 --- a/x-pack/legacy/plugins/index_management/public/index.ts +++ b/x-pack/plugins/index_management/public/index.ts @@ -3,19 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { npSetup } from 'ui/new_platform'; - +import './index.scss'; import { IndexMgmtUIPlugin, IndexMgmtSetup } from './plugin'; /** @public */ -export { IndexMgmtSetup }; - export const plugin = () => { return new IndexMgmtUIPlugin(); }; -// Temp. To be removed after moving to the "plugins" folder - -const { extensionsService } = plugin().setup(npSetup.core, npSetup.plugins); +export { IndexMgmtSetup }; -export { extensionsService }; +export { getIndexListUri } from './application/services/navigation'; diff --git a/x-pack/legacy/plugins/index_management/public/mocks.ts b/x-pack/plugins/index_management/public/mocks.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/mocks.ts rename to x-pack/plugins/index_management/public/mocks.ts diff --git a/x-pack/legacy/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts similarity index 90% rename from x-pack/legacy/plugins/index_management/public/plugin.ts rename to x-pack/plugins/index_management/public/plugin.ts index 539324766cf955..c1b26fe3ca56b4 100644 --- a/x-pack/legacy/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -5,10 +5,10 @@ */ import { i18n } from '@kbn/i18n'; -import { CoreSetup } from '../../../../../src/core/public'; -import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public'; -import { ManagementSetup } from '../../../../../src/plugins/management/public'; -import { UIM_APP_NAME } from '../common/constants'; +import { CoreSetup } from '../../../../src/core/public'; +import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; +import { ManagementSetup } from '../../../../src/plugins/management/public'; +import { UIM_APP_NAME, PLUGIN } from '../common/constants'; import { AppDependencies } from './application'; import { httpService } from './application/services/http'; @@ -52,7 +52,7 @@ export class IndexMgmtUIPlugin { this.uiMetricService.setup(usageCollection); management.sections.getSection('elasticsearch')!.registerApp({ - id: 'index_management', + id: PLUGIN.id, title: i18n.translate('xpack.idxMgmt.appTitle', { defaultMessage: 'Index Management' }), order: 1, mount: async ({ element, setBreadcrumbs }) => { diff --git a/x-pack/legacy/plugins/index_management/public/services/extensions_service.mock.ts b/x-pack/plugins/index_management/public/services/extensions_service.mock.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/services/extensions_service.mock.ts rename to x-pack/plugins/index_management/public/services/extensions_service.mock.ts diff --git a/x-pack/legacy/plugins/index_management/public/services/extensions_service.ts b/x-pack/plugins/index_management/public/services/extensions_service.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/services/extensions_service.ts rename to x-pack/plugins/index_management/public/services/extensions_service.ts diff --git a/x-pack/legacy/plugins/index_management/public/services/index.ts b/x-pack/plugins/index_management/public/services/index.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/services/index.ts rename to x-pack/plugins/index_management/public/services/index.ts diff --git a/x-pack/plugins/index_management/public/shared_imports.ts b/x-pack/plugins/index_management/public/shared_imports.ts new file mode 100644 index 00000000000000..cd2964df23d9bf --- /dev/null +++ b/x-pack/plugins/index_management/public/shared_imports.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { + SendRequestConfig, + SendRequestResponse, + UseRequestConfig, + sendRequest, + useRequest, +} from '../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; + +export { + FormSchema, + FIELD_TYPES, + VALIDATION_TYPES, + FieldConfig, + useForm, + Form, + getUseField, +} from '../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib'; + +export { + fieldFormatters, + fieldValidators, + serializers, +} from '../../../../src/plugins/es_ui_shared/static/forms/helpers'; + +export { getFormRow, Field } from '../../../../src/plugins/es_ui_shared/static/forms/components'; + +export { isJSON } from '../../../../src/plugins/es_ui_shared/static/validators/string'; diff --git a/x-pack/legacy/plugins/index_management/public/types.ts b/x-pack/plugins/index_management/public/types.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/public/types.ts rename to x-pack/plugins/index_management/public/types.ts diff --git a/x-pack/legacy/plugins/index_management/public/shared_imports.ts b/x-pack/plugins/index_management/server/config.ts similarity index 52% rename from x-pack/legacy/plugins/index_management/public/shared_imports.ts rename to x-pack/plugins/index_management/server/config.ts index cbc4dde7448ff0..5f03575d3ff436 100644 --- a/x-pack/legacy/plugins/index_management/public/shared_imports.ts +++ b/x-pack/plugins/index_management/server/config.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - SendRequestConfig, - SendRequestResponse, - UseRequestConfig, - sendRequest, - useRequest, -} from '../../../../../src/plugins/es_ui_shared/public/request/np_ready_request'; +import { schema, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type IndexManagementConfig = TypeOf; diff --git a/x-pack/legacy/plugins/index_management/server/index.ts b/x-pack/plugins/index_management/server/index.ts similarity index 67% rename from x-pack/legacy/plugins/index_management/server/index.ts rename to x-pack/plugins/index_management/server/index.ts index 866b374740d3b2..e4102711708cbb 100644 --- a/x-pack/legacy/plugins/index_management/server/index.ts +++ b/x-pack/plugins/index_management/server/index.ts @@ -5,8 +5,18 @@ */ import { PluginInitializerContext } from 'src/core/server'; + import { IndexMgmtServerPlugin } from './plugin'; +import { configSchema } from './config'; export const plugin = (ctx: PluginInitializerContext) => new IndexMgmtServerPlugin(ctx); +export const config = { + schema: configSchema, +}; + +/** @public */ export { Dependencies } from './types'; +export { IndexMgmtSetup } from './plugin'; +export { Index } from './types'; +export { IndexManagementConfig } from './config'; diff --git a/x-pack/legacy/plugins/index_management/server/lib/fetch_aliases.test.ts b/x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/server/lib/fetch_aliases.test.ts rename to x-pack/plugins/index_management/server/lib/fetch_aliases.test.ts diff --git a/x-pack/legacy/plugins/index_management/server/lib/fetch_aliases.ts b/x-pack/plugins/index_management/server/lib/fetch_aliases.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/server/lib/fetch_aliases.ts rename to x-pack/plugins/index_management/server/lib/fetch_aliases.ts diff --git a/x-pack/legacy/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/server/lib/fetch_indices.ts rename to x-pack/plugins/index_management/server/lib/fetch_indices.ts diff --git a/x-pack/legacy/plugins/index_management/server/lib/get_managed_templates.ts b/x-pack/plugins/index_management/server/lib/get_managed_templates.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/server/lib/get_managed_templates.ts rename to x-pack/plugins/index_management/server/lib/get_managed_templates.ts diff --git a/x-pack/legacy/plugins/index_management/server/lib/is_es_error.ts b/x-pack/plugins/index_management/server/lib/is_es_error.ts similarity index 100% rename from x-pack/legacy/plugins/index_management/server/lib/is_es_error.ts rename to x-pack/plugins/index_management/server/lib/is_es_error.ts diff --git a/x-pack/legacy/plugins/index_management/server/plugin.ts b/x-pack/plugins/index_management/server/plugin.ts similarity index 94% rename from x-pack/legacy/plugins/index_management/server/plugin.ts rename to x-pack/plugins/index_management/server/plugin.ts index 95d27e1cf16bae..a0a9151cdb71f5 100644 --- a/x-pack/legacy/plugins/index_management/server/plugin.ts +++ b/x-pack/plugins/index_management/server/plugin.ts @@ -24,8 +24,8 @@ export class IndexMgmtServerPlugin implements Plugin Date: Tue, 25 Feb 2020 09:05:22 +0100 Subject: [PATCH 21/73] [SIEM] Upgrades cypress to version 4.0.2 (#58400) * upgrades cypress to version 4.0.2 * fixes failing tests --- .../timeline_search_or_filter.spec.ts | 5 +- .../cypress/integration/url_state.spec.ts | 5 +- .../cypress/tasks/hosts/authentications.ts | 4 + .../cypress/tasks/hosts/uncommon_processes.ts | 4 + .../plugins/siem/cypress/tasks/timeline.ts | 5 +- .../components/fields_browser/header.test.tsx | 2 - x-pack/package.json | 2 +- yarn.lock | 301 ++++++++---------- 8 files changed, 159 insertions(+), 169 deletions(-) diff --git a/x-pack/legacy/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts index c06fd69a558a40..f738ff792049ad 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/timeline_search_or_filter.spec.ts @@ -24,6 +24,9 @@ describe('timeline search or filter KQL bar', () => { cy.get(SERVER_SIDE_EVENT_COUNT) .invoke('text') - .should('be.above', 0); + .then(strCount => { + const intCount = +strCount; + cy.wrap(intCount).should('be.above', 0); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/cypress/integration/url_state.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/url_state.spec.ts index cabdb98fa5b676..11c0562eb3638d 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/url_state.spec.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/url_state.spec.ts @@ -236,7 +236,10 @@ describe('url state', () => { cy.get(SERVER_SIDE_EVENT_COUNT) .invoke('text') - .should('be.above', 0); + .then(strCount => { + const intCount = +strCount; + cy.wrap(intCount).should('be.above', 0); + }); const bestTimelineName = 'The Best Timeline'; addNameToTimeline(bestTimelineName); diff --git a/x-pack/legacy/plugins/siem/cypress/tasks/hosts/authentications.ts b/x-pack/legacy/plugins/siem/cypress/tasks/hosts/authentications.ts index f5f15150e8ac31..ce3767a3403762 100644 --- a/x-pack/legacy/plugins/siem/cypress/tasks/hosts/authentications.ts +++ b/x-pack/legacy/plugins/siem/cypress/tasks/hosts/authentications.ts @@ -5,7 +5,11 @@ */ import { AUTHENTICATIONS_TABLE } from '../../screens/hosts/authentications'; +import { REFRESH_BUTTON } from '../../screens/siem_header'; export const waitForAuthenticationsToBeLoaded = () => { cy.get(AUTHENTICATIONS_TABLE).should('exist'); + cy.get(REFRESH_BUTTON) + .invoke('text') + .should('not.equal', 'Updating'); }; diff --git a/x-pack/legacy/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts b/x-pack/legacy/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts index c44249acdd9649..a28a7df07c3f82 100644 --- a/x-pack/legacy/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts +++ b/x-pack/legacy/plugins/siem/cypress/tasks/hosts/uncommon_processes.ts @@ -5,7 +5,11 @@ */ import { UNCOMMON_PROCESSES_TABLE } from '../../screens/hosts/uncommon_processes'; +import { REFRESH_BUTTON } from '../../screens/siem_header'; export const waitForUncommonProcessesToBeLoaded = () => { cy.get(UNCOMMON_PROCESSES_TABLE).should('exist'); + cy.get(REFRESH_BUTTON) + .invoke('text') + .should('not.equal', 'Updating'); }; diff --git a/x-pack/legacy/plugins/siem/cypress/tasks/timeline.ts b/x-pack/legacy/plugins/siem/cypress/tasks/timeline.ts index 76acdad990a7e0..c218d5153356b6 100644 --- a/x-pack/legacy/plugins/siem/cypress/tasks/timeline.ts +++ b/x-pack/legacy/plugins/siem/cypress/tasks/timeline.ts @@ -65,7 +65,10 @@ export const populateTimeline = () => { executeTimelineKQL(hostExistsQuery); cy.get(SERVER_SIDE_EVENT_COUNT) .invoke('text') - .should('be.above', 0); + .then(strCount => { + const intCount = +strCount; + cy.wrap(intCount).should('be.above', 0); + }); }; export const uncheckTimestampToggleField = () => { diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx index 42689065354d00..2abc2fd1046e06 100644 --- a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx @@ -6,11 +6,9 @@ import { mount } from 'enzyme'; import React from 'react'; - import { mockBrowserFields } from '../../containers/source/mock'; import { TestProviders } from '../../mock'; import { defaultHeaders } from '../timeline/body/column_headers/default_headers'; - import { Header } from './header'; const timelineId = 'test'; diff --git a/x-pack/package.json b/x-pack/package.json index 551e466893f931..f76b0182ea228d 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -117,7 +117,7 @@ "cheerio": "0.22.0", "commander": "3.0.2", "copy-webpack-plugin": "^5.0.4", - "cypress": "^3.6.1", + "cypress": "^4.0.2", "cypress-multi-reporters": "^1.2.3", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", diff --git a/yarn.lock b/yarn.lock index 8ea23c17b8b8b2..f46e869909e2e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7023,13 +7023,6 @@ async@2.4.0: dependencies: lodash "^4.14.0" -async@2.6.1, async@^2.6.0, async@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== - dependencies: - lodash "^4.17.10" - async@^2.0.0, async@^2.1.4: version "2.6.0" resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" @@ -7037,6 +7030,13 @@ async@^2.0.0, async@^2.1.4: dependencies: lodash "^4.14.0" +async@^2.6.0, async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + async@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -7044,6 +7044,11 @@ async@^2.6.3: dependencies: lodash "^4.17.14" +async@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== + async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" @@ -7909,6 +7914,11 @@ bluebird@3.5.5, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== +bluebird@3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + bluebird@^3.3.0, bluebird@^3.3.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -8536,12 +8546,10 @@ cacheable-request@^2.1.1: normalize-url "2.0.1" responselike "1.0.2" -cachedir@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-1.3.0.tgz#5e01928bf2d95b5edd94b0942188246740e0dbc4" - integrity sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg== - dependencies: - os-homedir "^1.0.1" +cachedir@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== caching-transform@^3.0.2: version "3.0.2" @@ -8806,6 +8814,14 @@ chalk@2.4.2, chalk@^2.3.2, chalk@^2.4.2, chalk@~2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@3.0.0, chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -8835,14 +8851,6 @@ chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.2.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" @@ -9087,11 +9095,6 @@ ci-info@^1.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.2.tgz#03561259db48d0474c8bdc90f5b47b068b6bbfb4" integrity sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA== -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" @@ -9596,11 +9599,6 @@ commander@2, commander@2.19.0, commander@^2.11.0, commander@^2.12.2: resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - commander@2.17.x, commander@~2.17.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -9611,6 +9609,11 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== +commander@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" + integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== + commander@^2.13.0, commander@^2.15.1, commander@^2.16.0, commander@^2.19.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" @@ -10646,41 +10649,42 @@ cypress-multi-reporters@^1.2.3: debug "^4.1.1" lodash "^4.17.11" -cypress@^3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.6.1.tgz#4420957923879f60b7a5146ccbf81841a149b653" - integrity sha512-6n0oqENdz/oQ7EJ6IgESNb2M7Bo/70qX9jSJsAziJTC3kICfEMmJUlrAnP9bn+ut24MlXQST5nRXhUP5nRIx6A== +cypress@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.0.2.tgz#ede194d7bc73fb449f8de553c9e1db4ca15309ef" + integrity sha512-WRzxOoSd+TxyXKa7Zi9orz3ii5VW7yhhVYstCU+EpOKfPan9x5Ww2Clucmy4H/W0GHUYAo7GYFZRD33ZCSNBQA== dependencies: "@cypress/listr-verbose-renderer" "0.4.1" "@cypress/xvfb" "1.2.4" "@types/sizzle" "2.3.2" arch "2.1.1" - bluebird "3.5.0" - cachedir "1.3.0" - chalk "2.4.2" + bluebird "3.7.2" + cachedir "2.3.0" + chalk "3.0.0" check-more-types "2.24.0" - commander "2.15.1" + commander "4.1.0" common-tags "1.8.0" - debug "3.2.6" - execa "0.10.0" + debug "4.1.1" + eventemitter2 "4.1.2" + execa "3.3.0" executable "4.1.1" extract-zip "1.6.7" - fs-extra "5.0.0" - getos "3.1.1" - is-ci "1.2.1" + fs-extra "8.1.0" + getos "3.1.4" + is-ci "2.0.0" is-installed-globally "0.1.0" lazy-ass "1.6.0" - listr "0.12.0" + listr "0.14.3" lodash "4.17.15" - log-symbols "2.2.0" + log-symbols "3.0.0" minimist "1.2.0" moment "2.24.0" - ramda "0.24.1" + ramda "0.26.1" request "2.88.0" request-progress "3.0.0" - supports-color "5.5.0" + supports-color "7.1.0" tmp "0.1.0" - untildify "3.0.3" + untildify "4.0.0" url "0.11.0" yauzl "2.10.0" @@ -11065,7 +11069,7 @@ debug@4.1.0: dependencies: ms "^2.1.1" -debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4.1.1, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -13028,6 +13032,11 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== +eventemitter2@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-4.1.2.tgz#0e1a8477af821a6ef3995b311bf74c23a5247f15" + integrity sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU= + eventemitter2@~0.4.13: version "0.4.14" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" @@ -13078,19 +13087,6 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== -execa@0.10.0, execa@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" - integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== - dependencies: - cross-spawn "^6.0.0" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@1.0.0, execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -13104,6 +13100,22 @@ execa@1.0.0, execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1" + integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + execa@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-0.1.1.tgz#b09c2a9309bc0ef0501479472db3180f8d4c3edd" @@ -13113,6 +13125,19 @@ execa@^0.1.1: object-assign "^4.0.1" strip-eof "^1.0.0" +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" @@ -14321,12 +14346,12 @@ fs-exists-sync@^0.1.0: resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0= -fs-extra@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" - integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== +fs-extra@8.1.0, fs-extra@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: - graceful-fs "^4.1.2" + graceful-fs "^4.2.0" jsonfile "^4.0.0" universalify "^0.1.0" @@ -14368,15 +14393,6 @@ fs-extra@^7.0.0, fs-extra@^7.0.1, fs-extra@~7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -14703,12 +14719,12 @@ getopts@^2.2.5: resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b" integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA== -getos@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.1.tgz#967a813cceafee0156b0483f7cffa5b3eff029c5" - integrity sha512-oUP1rnEhAr97rkitiszGP9EgDVYnmchgFzfqRzSkgtfv7ai6tEi7Ko8GgjNXts7VLWEqrTWyhsOKLe5C5b/Zkg== +getos@3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.4.tgz#29cdf240ed10a70c049add7b6f8cb08c81876faf" + integrity sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw== dependencies: - async "2.6.1" + async "^3.1.0" getos@^3.1.0: version "3.1.0" @@ -17152,12 +17168,12 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== -is-ci@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== +is-ci@2.0.0, is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== dependencies: - ci-info "^1.5.0" + ci-info "^2.0.0" is-ci@^1.0.10: version "1.1.0" @@ -17166,13 +17182,6 @@ is-ci@^1.0.10: dependencies: ci-info "^1.0.0" -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -19254,20 +19263,6 @@ listr-update-renderer@0.5.0, listr-update-renderer@^0.5.0: log-update "^2.3.0" strip-ansi "^3.0.1" -listr-update-renderer@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" - integrity sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk= - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - strip-ansi "^3.0.1" - listr-update-renderer@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" @@ -19302,28 +19297,6 @@ listr-verbose-renderer@^0.5.0: date-fns "^1.27.2" figures "^2.0.0" -listr@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" - integrity sha1-a84sD1YD+klYDqF81qAMwOX6RRo= - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - figures "^1.7.0" - indent-string "^2.1.0" - is-promise "^2.1.0" - is-stream "^1.1.0" - listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.2.0" - listr-verbose-renderer "^0.4.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - ora "^0.2.3" - p-map "^1.1.1" - rxjs "^5.0.0-beta.11" - stream-to-observable "^0.1.0" - strip-ansi "^3.0.1" - listr@0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" @@ -19824,6 +19797,13 @@ log-symbols@2.2.0, log-symbols@^2.0.0, log-symbols@^2.1.0, log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +log-symbols@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + log-symbols@^1.0.1, log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" @@ -23983,21 +23963,16 @@ railroad-diagrams@^1.0.0: resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= -ramda@0.24.1: - version "0.24.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" - integrity sha1-w7d1UZfzW43DUCIoJixMkd22uFc= +ramda@0.26.1, ramda@^0.26, ramda@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" + integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== ramda@^0.21.0: version "0.21.0" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= -ramda@^0.26, ramda@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" - integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== - randexp@0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" @@ -26375,7 +26350,7 @@ rxjs@6.5.2: dependencies: tslib "^1.9.0" -rxjs@^5.0.0-beta.11, rxjs@^5.5.2: +rxjs@^5.5.2: version "5.5.12" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== @@ -27815,11 +27790,6 @@ stream-spigot@~2.1.2: dependencies: readable-stream "~1.1.0" -stream-to-observable@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" - integrity sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4= - streamroller@0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-0.7.0.tgz#a1d1b7cf83d39afb0d63049a5acbf93493bdf64b" @@ -28291,13 +28261,6 @@ supertest@^3.1.0: methods "~1.1.2" superagent "3.8.2" -supports-color@5.5.0, supports-color@^5.0.0, supports-color@^5.4.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" @@ -28312,6 +28275,13 @@ supports-color@6.1.0, supports-color@^6.0.0, supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@7.1.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + supports-color@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" @@ -28329,6 +28299,13 @@ supports-color@^3.1.0, supports-color@^3.1.2, supports-color@^3.2.3: dependencies: has-flag "^1.0.0" +supports-color@^5.0.0, supports-color@^5.4.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + supports-color@^5.2.0, supports-color@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" @@ -28343,13 +28320,6 @@ supports-color@^7.0.0: dependencies: has-flag "^4.0.0" -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== - dependencies: - has-flag "^4.0.0" - supports-hyperlinks@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" @@ -30241,10 +30211,10 @@ unstated@^2.1.1: dependencies: create-react-context "^0.1.5" -untildify@3.0.3, untildify@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" - integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== +untildify@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== untildify@^2.0.0: version "2.1.0" @@ -30253,6 +30223,11 @@ untildify@^2.0.0: dependencies: os-homedir "^1.0.0" +untildify@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" + integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== + unzip-response@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" From a60b25f9ad45cbc8efb5f362d30996c0d49baa2b Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 25 Feb 2020 09:05:53 +0100 Subject: [PATCH 22/73] fix short url in spaces (#58313) --- src/plugins/share/server/routes/goto.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/share/server/routes/goto.ts b/src/plugins/share/server/routes/goto.ts index 5c3a4e441099fb..0c5b74915e58a6 100644 --- a/src/plugins/share/server/routes/goto.ts +++ b/src/plugins/share/server/routes/goto.ts @@ -23,6 +23,7 @@ import { schema } from '@kbn/config-schema'; import { shortUrlAssertValid } from './lib/short_url_assert_valid'; import { ShortUrlLookupService } from './lib/short_url_lookup'; import { getGotoPath } from '../../common/short_url_routes'; +import { modifyUrl } from '../../../../core/utils'; export const createGotoRoute = ({ router, @@ -49,9 +50,16 @@ export const createGotoRoute = ({ const uiSettings = context.core.uiSettings.client; const stateStoreInSessionStorage = await uiSettings.get('state:storeInSessionStorage'); if (!stateStoreInSessionStorage) { + const basePath = http.basePath.get(request); + + const prependedUrl = modifyUrl(url, parts => { + if (!parts.hostname && parts.pathname && parts.pathname.startsWith('/')) { + parts.pathname = `${basePath}${parts.pathname}`; + } + }); return response.redirected({ headers: { - location: http.basePath.prepend(url), + location: prependedUrl, }, }); } From 1a96ff3c302c08ea049245a05c716ecd43ca0485 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Tue, 25 Feb 2020 11:00:10 +0100 Subject: [PATCH 23/73] [ML] Functional tests - stabilize typing during df analytics creation (#58227) This PR makes the typing in data frame analytics tests more robust. --- .../data_frame_analytics_creation.ts | 24 ++++++++++++------- x-pack/test/functional/services/ml.ts | 5 +++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/x-pack/test/functional/services/machine_learning/data_frame_analytics_creation.ts b/x-pack/test/functional/services/machine_learning/data_frame_analytics_creation.ts index b4e455ebaa63fd..96dc8993c3d35e 100644 --- a/x-pack/test/functional/services/machine_learning/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/machine_learning/data_frame_analytics_creation.ts @@ -6,10 +6,12 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; +import { MlCommon } from './common'; -export function MachineLearningDataFrameAnalyticsCreationProvider({ - getService, -}: FtrProviderContext) { +export function MachineLearningDataFrameAnalyticsCreationProvider( + { getService }: FtrProviderContext, + mlCommon: MlCommon +) { const testSubjects = getService('testSubjects'); const comboBox = getService('comboBox'); const retry = getService('retry'); @@ -85,14 +87,14 @@ export function MachineLearningDataFrameAnalyticsCreationProvider({ }, async setJobId(jobId: string) { - await testSubjects.setValue('mlAnalyticsCreateJobFlyoutJobIdInput', jobId, { + await mlCommon.setValueWithChecks('mlAnalyticsCreateJobFlyoutJobIdInput', jobId, { clearWithKeyboard: true, }); await this.assertJobIdValue(jobId); }, async setJobDescription(jobDescription: string) { - await testSubjects.setValue('mlDFAnalyticsJobCreationJobDescription', jobDescription, { + await mlCommon.setValueWithChecks('mlDFAnalyticsJobCreationJobDescription', jobDescription, { clearWithKeyboard: true, }); await this.assertJobDescriptionValue(jobDescription); @@ -136,9 +138,13 @@ export function MachineLearningDataFrameAnalyticsCreationProvider({ }, async setDestIndex(destIndex: string) { - await testSubjects.setValue('mlAnalyticsCreateJobFlyoutDestinationIndexInput', destIndex, { - clearWithKeyboard: true, - }); + await mlCommon.setValueWithChecks( + 'mlAnalyticsCreateJobFlyoutDestinationIndexInput', + destIndex, + { + clearWithKeyboard: true, + } + ); await this.assertDestIndexValue(destIndex); }, @@ -248,7 +254,7 @@ export function MachineLearningDataFrameAnalyticsCreationProvider({ }, async setModelMemory(modelMemory: string) { - await testSubjects.setValue('mlAnalyticsCreateJobFlyoutModelMemoryInput', modelMemory, { + await mlCommon.setValueWithChecks('mlAnalyticsCreateJobFlyoutModelMemoryInput', modelMemory, { clearWithKeyboard: true, }); await this.assertModelMemoryValue(modelMemory); diff --git a/x-pack/test/functional/services/ml.ts b/x-pack/test/functional/services/ml.ts index 2660a90662dec3..354e0907375ca4 100644 --- a/x-pack/test/functional/services/ml.ts +++ b/x-pack/test/functional/services/ml.ts @@ -42,7 +42,10 @@ export function MachineLearningProvider(context: FtrProviderContext) { const api = MachineLearningAPIProvider(context); const customUrls = MachineLearningCustomUrlsProvider(context); const dataFrameAnalytics = MachineLearningDataFrameAnalyticsProvider(context, api); - const dataFrameAnalyticsCreation = MachineLearningDataFrameAnalyticsCreationProvider(context); + const dataFrameAnalyticsCreation = MachineLearningDataFrameAnalyticsCreationProvider( + context, + common + ); const dataFrameAnalyticsTable = MachineLearningDataFrameAnalyticsTableProvider(context); const dataVisualizer = MachineLearningDataVisualizerProvider(context); const dataVisualizerIndexBased = MachineLearningDataVisualizerIndexBasedProvider(context); From 737205fb9b0c5b27ff06331598802a2e57365ffb Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Tue, 25 Feb 2020 13:19:02 +0300 Subject: [PATCH 24/73] Move src/legacy/ui/public/notify/app_redirect to kibana_legacy (#58127) Co-authored-by: Elastic Machine --- .../core_plugins/kibana/public/kibana.js | 6 ++-- src/legacy/ui/public/notify/index.js | 1 - .../notify/app_redirect/app_redirect.test.ts} | 32 +++++++++++-------- .../notify/app_redirect/app_redirect.ts} | 9 +++--- .../public/notify/app_redirect/index.ts} | 0 .../kibana_legacy/public/notify/index.ts | 1 + .../dashboard_mode/public/dashboard_viewer.js | 6 ++-- .../plugins/graph/public/application.ts | 2 +- .../plugins/graph/public/legacy_imports.ts | 2 -- 9 files changed, 33 insertions(+), 26 deletions(-) rename src/{legacy/ui/public/notify/app_redirect/app_redirect.test.js => plugins/kibana_legacy/public/notify/app_redirect/app_redirect.test.ts} (75%) rename src/{legacy/ui/public/notify/app_redirect/app_redirect.js => plugins/kibana_legacy/public/notify/app_redirect/app_redirect.ts} (82%) rename src/{legacy/ui/public/notify/app_redirect/index.js => plugins/kibana_legacy/public/notify/app_redirect/index.ts} (100%) diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js index d77fc780f4cc26..384c6bd80ec33b 100644 --- a/src/legacy/core_plugins/kibana/public/kibana.js +++ b/src/legacy/core_plugins/kibana/public/kibana.js @@ -53,7 +53,7 @@ import './management'; import './dev_tools'; import 'ui/agg_response'; import 'ui/agg_types'; -import { showAppRedirectNotification } from 'ui/notify'; +import { showAppRedirectNotification } from '../../../../plugins/kibana_legacy/public'; import 'leaflet'; import { localApplicationService } from './local_application_service'; @@ -68,4 +68,6 @@ routes.otherwise({ redirectTo: `/${config.defaultAppId || 'discover'}`, }); -uiModules.get('kibana').run(showAppRedirectNotification); +uiModules + .get('kibana') + .run($location => showAppRedirectNotification($location, npSetup.core.notifications.toasts)); diff --git a/src/legacy/ui/public/notify/index.js b/src/legacy/ui/public/notify/index.js index f7526f3b8f8fda..7ec6a394d7e885 100644 --- a/src/legacy/ui/public/notify/index.js +++ b/src/legacy/ui/public/notify/index.js @@ -19,5 +19,4 @@ export { fatalError, addFatalErrorCallback } from './fatal_error'; export { toastNotifications } from './toasts'; -export { addAppRedirectMessageToUrl, showAppRedirectNotification } from './app_redirect'; export { banners } from './banners'; diff --git a/src/legacy/ui/public/notify/app_redirect/app_redirect.test.js b/src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.test.ts similarity index 75% rename from src/legacy/ui/public/notify/app_redirect/app_redirect.test.js rename to src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.test.ts index a23aabe6ad88e5..efb1393ff0b16c 100644 --- a/src/legacy/ui/public/notify/app_redirect/app_redirect.test.js +++ b/src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.test.ts @@ -17,17 +17,12 @@ * under the License. */ +import { ILocationService } from 'angular'; +import { ToastsStart } from '../../../../../core/public'; import { addAppRedirectMessageToUrl, showAppRedirectNotification } from './app_redirect'; let isToastAdded = false; - -jest.mock('../toasts', () => ({ - toastNotifications: { - addDanger: () => { - isToastAdded = true; - }, - }, -})); +const toasts: ToastsStart = {} as ToastsStart; describe('addAppRedirectMessageToUrl', () => { test('adds a message to the URL', () => { @@ -39,20 +34,29 @@ describe('addAppRedirectMessageToUrl', () => { describe('showAppRedirectNotification', () => { beforeEach(() => { isToastAdded = false; + toasts.addDanger = (): any => { + isToastAdded = true; + }; }); test(`adds a toast when there's a message in the URL`, () => { - showAppRedirectNotification({ - search: () => ({ app_redirect_message: 'redirect message' }), - }); + showAppRedirectNotification( + { + search: () => ({ app_redirect_message: 'redirect message' }), + } as ILocationService, + toasts + ); expect(isToastAdded).toBe(true); }); test(`doesn't add a toast when there's no message in the URL`, () => { - showAppRedirectNotification({ - search: () => ({ app_redirect_message: '' }), - }); + showAppRedirectNotification( + { + search: () => ({ app_redirect_message: '' }), + } as ILocationService, + toasts + ); expect(isToastAdded).toBe(false); }); diff --git a/src/legacy/ui/public/notify/app_redirect/app_redirect.js b/src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.ts similarity index 82% rename from src/legacy/ui/public/notify/app_redirect/app_redirect.js rename to src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.ts index a92e5401e5e755..e79ab4b2fbc6d8 100644 --- a/src/legacy/ui/public/notify/app_redirect/app_redirect.js +++ b/src/plugins/kibana_legacy/public/notify/app_redirect/app_redirect.ts @@ -17,12 +17,13 @@ * under the License. */ +import { ILocationService } from 'angular'; import { modifyUrl } from '../../../../../core/utils'; -import { toastNotifications } from '../toasts'; +import { ToastsStart } from '../../../../../core/public'; const APP_REDIRECT_MESSAGE_PARAM = 'app_redirect_message'; -export function addAppRedirectMessageToUrl(url, message) { +export function addAppRedirectMessageToUrl(url: string, message: string) { return modifyUrl(url, urlParts => { urlParts.hash = modifyUrl(urlParts.hash || '', hashParts => { hashParts.query[APP_REDIRECT_MESSAGE_PARAM] = message; @@ -32,7 +33,7 @@ export function addAppRedirectMessageToUrl(url, message) { // If an app needs to redirect, e.g. due to an expired license, it can surface a message via // the URL query params. -export function showAppRedirectNotification($location) { +export function showAppRedirectNotification($location: ILocationService, toasts: ToastsStart) { const queryString = $location.search(); if (!queryString[APP_REDIRECT_MESSAGE_PARAM]) { @@ -42,5 +43,5 @@ export function showAppRedirectNotification($location) { const message = queryString[APP_REDIRECT_MESSAGE_PARAM]; $location.search(APP_REDIRECT_MESSAGE_PARAM, null); - toastNotifications.addDanger(message); + toasts.addDanger(message); } diff --git a/src/legacy/ui/public/notify/app_redirect/index.js b/src/plugins/kibana_legacy/public/notify/app_redirect/index.ts similarity index 100% rename from src/legacy/ui/public/notify/app_redirect/index.js rename to src/plugins/kibana_legacy/public/notify/app_redirect/index.ts diff --git a/src/plugins/kibana_legacy/public/notify/index.ts b/src/plugins/kibana_legacy/public/notify/index.ts index 6aa4e36ab7227a..b6f29876c27372 100644 --- a/src/plugins/kibana_legacy/public/notify/index.ts +++ b/src/plugins/kibana_legacy/public/notify/index.ts @@ -18,3 +18,4 @@ */ export * from './toasts'; export * from './lib'; +export { addAppRedirectMessageToUrl, showAppRedirectNotification } from './app_redirect'; diff --git a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js index 8ca023aa90cf12..e0e49fe59daf46 100644 --- a/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js +++ b/x-pack/legacy/plugins/dashboard_mode/public/dashboard_viewer.js @@ -37,7 +37,7 @@ import 'plugins/kibana/dashboard/legacy'; import { npStart } from 'ui/new_platform'; import { localApplicationService } from 'plugins/kibana/local_application_service'; -import { showAppRedirectNotification } from 'ui/notify'; +import { showAppRedirectNotification } from '../../../../../src/plugins/kibana_legacy/public'; import { DashboardConstants, createDashboardEditUrl } from 'plugins/kibana/dashboard'; npStart.plugins.kibanaLegacy.dashboardConfig.turnHideWriteControlsOn(); @@ -51,7 +51,9 @@ chrome.setRootController('kibana', function() { npStart.core.chrome.navLinks.showOnly('kibana:dashboard'); }); -uiModules.get('kibana').run(showAppRedirectNotification); +uiModules + .get('kibana') + .run($location => showAppRedirectNotification($location, npStart.core.notifications.toasts)); /** * If there is a configured `kibana.defaultAppId`, and it is a dashboard ID, we'll diff --git a/x-pack/legacy/plugins/graph/public/application.ts b/x-pack/legacy/plugins/graph/public/application.ts index 80a797b7f07243..7bd18f841b4787 100644 --- a/x-pack/legacy/plugins/graph/public/application.ts +++ b/x-pack/legacy/plugins/graph/public/application.ts @@ -24,7 +24,6 @@ import { configureAppAngularModule, createTopNavDirective, createTopNavHelper, - addAppRedirectMessageToUrl, } from './legacy_imports'; // @ts-ignore import { initGraphApp } from './app'; @@ -37,6 +36,7 @@ import { checkLicense } from '../../../../plugins/graph/common/check_license'; import { NavigationPublicPluginStart as NavigationStart } from '../../../../../src/plugins/navigation/public'; import { createSavedWorkspacesLoader } from './services/persistence/saved_workspace_loader'; import { Storage } from '../../../../../src/plugins/kibana_utils/public'; +import { addAppRedirectMessageToUrl } from '../../../../../src/plugins/kibana_legacy/public'; /** * These are dependencies of the Graph app besides the base dependencies diff --git a/x-pack/legacy/plugins/graph/public/legacy_imports.ts b/x-pack/legacy/plugins/graph/public/legacy_imports.ts index ac518d34551dba..84fafdb580abe3 100644 --- a/x-pack/legacy/plugins/graph/public/legacy_imports.ts +++ b/x-pack/legacy/plugins/graph/public/legacy_imports.ts @@ -8,6 +8,4 @@ import 'ace'; // @ts-ignore export { createTopNavDirective, createTopNavHelper } from 'ui/kbn_top_nav/kbn_top_nav'; -// @ts-ignore -export { addAppRedirectMessageToUrl } from 'ui/notify'; export { configureAppAngularModule } from '../../../../../src/plugins/kibana_legacy/public'; From 5910e83722ae3c211731f9671e6ceee438d75aca Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Tue, 25 Feb 2020 11:27:25 +0100 Subject: [PATCH 25/73] hide welcome screen for cloud (#58371) --- x-pack/test/functional/page_objects/security_page.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x-pack/test/functional/page_objects/security_page.js b/x-pack/test/functional/page_objects/security_page.js index 3bcba7cbd16969..5889a374e443e1 100644 --- a/x-pack/test/functional/page_objects/security_page.js +++ b/x-pack/test/functional/page_objects/security_page.js @@ -30,6 +30,11 @@ export function SecurityPageProvider({ getService, getPageObjects }) { const rawDataTabLocator = 'a[id=rawdata-tab]'; await PageObjects.common.navigateToApp('login'); + + // ensure welcome screen won't be shown. This is relevant for environments which don't allow + // to use the yml setting, e.g. cloud + await browser.setLocalStorageItem('home:welcome:show', 'false'); + await testSubjects.setValue('loginUsername', username); await testSubjects.setValue('loginPassword', password); await testSubjects.click('loginSubmit'); From 506268c926d18f27133d93f419c0b594eca609aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 25 Feb 2020 10:31:35 +0000 Subject: [PATCH 26/73] [Telemetry] Separate the license retrieval from the stats in the usage collectors (#57332) * [Telemetry] Merge OSS and XPack usage collectors * Create X-Pack collector again * Separate the license retrieval from the stats * Fix telemetry tests with new fields * Use Promise.all to retrieve license and stats at the same time * Fix moment mock Co-authored-by: Elastic Machine --- .../telemetry/server/collection_manager.ts | 56 +- ...et_cluster_info.js => get_cluster_info.ts} | 24 +- .../telemetry_collection/get_local_license.ts | 90 ++ .../telemetry_collection/get_local_stats.ts | 26 +- .../server/telemetry_collection/index.ts | 1 - .../register_collection.ts | 2 + .../public/services/telemetry_service.test.ts | 10 + .../public/services/telemetry_service.ts | 5 +- .../get_all_stats.test.ts | 12 +- .../telemetry_collection/get_all_stats.ts | 41 +- .../telemetry_collection/get_es_stats.ts | 11 +- .../telemetry_collection/get_licenses.test.ts | 84 ++ .../telemetry_collection/get_licenses.ts | 84 ++ .../register_monitoring_collection.ts | 2 + .../get_stats_with_xpack.test.ts.snap | 118 ++ .../__tests__/get_xpack.js | 105 +- .../server/telemetry_collection/constants.ts | 1 + .../get_stats_with_xpack.test.ts | 113 ++ .../get_stats_with_xpack.ts | 28 +- .../server/telemetry_collection/get_xpack.js | 85 -- .../server/telemetry_collection/get_xpack.ts | 25 + .../register_xpack_collection.ts | 2 + .../apis/telemetry/fixtures/basiccluster.json | 7 + .../apis/telemetry/fixtures/multicluster.json | 1002 ++++++++++++++++- 24 files changed, 1671 insertions(+), 263 deletions(-) rename src/legacy/core_plugins/telemetry/server/telemetry_collection/{get_cluster_info.js => get_cluster_info.ts} (61%) create mode 100644 src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license.ts create mode 100644 x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts create mode 100644 x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.ts create mode 100644 x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__snapshots__/get_stats_with_xpack.test.ts.snap create mode 100644 x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.test.ts delete mode 100644 x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.js create mode 100644 x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.ts diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts index 0394dea343adfc..715ca56e290a25 100644 --- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts +++ b/src/legacy/core_plugins/telemetry/server/collection_manager.ts @@ -20,6 +20,7 @@ import { encryptTelemetry } from './collectors'; import { CallCluster } from '../../elasticsearch'; import { UsageCollectionSetup } from '../../../../plugins/usage_collection/server'; +import { ESLicense } from './telemetry_collection/get_local_license'; export type EncryptedStatsGetterConfig = { unencrypted: false } & { server: any; @@ -45,22 +46,38 @@ export interface StatsCollectionConfig { end: string | number; } +export interface BasicStatsPayload { + timestamp: string; + cluster_uuid: string; + cluster_name: string; + version: string; + cluster_stats: object; + collection?: string; + stack_stats: object; +} + export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig; export type ClusterDetailsGetter = (config: StatsCollectionConfig) => Promise; -export type StatsGetter = ( +export type StatsGetter = ( + clustersDetails: ClusterDetails[], + config: StatsCollectionConfig +) => Promise; +export type LicenseGetter = ( clustersDetails: ClusterDetails[], config: StatsCollectionConfig -) => Promise; +) => Promise<{ [clusterUuid: string]: ESLicense | undefined }>; -interface CollectionConfig { +interface CollectionConfig { title: string; priority: number; esCluster: string; - statsGetter: StatsGetter; + statsGetter: StatsGetter; clusterDetailsGetter: ClusterDetailsGetter; + licenseGetter: LicenseGetter; } interface Collection { statsGetter: StatsGetter; + licenseGetter: LicenseGetter; clusterDetailsGetter: ClusterDetailsGetter; esCluster: string; title: string; @@ -70,8 +87,15 @@ export class TelemetryCollectionManager { private usageGetterMethodPriority = -1; private collections: Collection[] = []; - public setCollection = (collectionConfig: CollectionConfig) => { - const { title, priority, esCluster, statsGetter, clusterDetailsGetter } = collectionConfig; + public setCollection = (collectionConfig: CollectionConfig) => { + const { + title, + priority, + esCluster, + statsGetter, + clusterDetailsGetter, + licenseGetter, + } = collectionConfig; if (typeof priority !== 'number') { throw new Error('priority must be set.'); @@ -88,10 +112,14 @@ export class TelemetryCollectionManager { throw Error('esCluster name must be set for the getCluster method.'); } if (!clusterDetailsGetter) { - throw Error('Cluser UUIds method is not set.'); + throw Error('Cluster UUIds method is not set.'); + } + if (!licenseGetter) { + throw Error('License getter method not set.'); } this.collections.unshift({ + licenseGetter, statsGetter, clusterDetailsGetter, esCluster, @@ -141,7 +169,19 @@ export class TelemetryCollectionManager { return; } - return await collection.statsGetter(clustersDetails, statsCollectionConfig); + const [stats, licenses] = await Promise.all([ + collection.statsGetter(clustersDetails, statsCollectionConfig), + collection.licenseGetter(clustersDetails, statsCollectionConfig), + ]); + + return stats.map(stat => { + const license = licenses[stat.cluster_uuid]; + return { + ...(license ? { license } : {}), + ...stat, + collectionSource: collection.title, + }; + }); }; public getOptInStats = async (optInStatus: boolean, config: StatsGetterConfig) => { diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.ts similarity index 61% rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.js rename to src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.ts index 2e4ed0b36ed26d..67812457ed4ec9 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.js +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_info.ts @@ -17,14 +17,32 @@ * under the License. */ +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; + +// This can be removed when the ES client improves the types +export interface ESClusterInfo { + cluster_uuid: string; + cluster_name: string; + version: { + number: string; + build_flavor: string; + build_type: string; + build_hash: string; + build_date: string; + build_snapshot?: boolean; + lucene_version: string; + minimum_wire_compatibility_version: string; + minimum_index_compatibility_version: string; + }; +} + /** * Get the cluster info from the connected cluster. * * This is the equivalent to GET / * * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} The response from Elasticsearch. */ -export function getClusterInfo(callCluster) { - return callCluster('info'); +export function getClusterInfo(callCluster: CallCluster) { + return callCluster('info'); } diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license.ts new file mode 100644 index 00000000000000..589392ffb60953 --- /dev/null +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license.ts @@ -0,0 +1,90 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; +import { LicenseGetter } from '../collection_manager'; + +// From https://www.elastic.co/guide/en/elasticsearch/reference/current/get-license.html +export interface ESLicense { + status: string; + uid: string; + type: string; + issue_date: string; + issue_date_in_millis: number; + expiry_date: string; + expirty_date_in_millis: number; + max_nodes: number; + issued_to: string; + issuer: string; + start_date_in_millis: number; +} +let cachedLicense: ESLicense | undefined; + +function fetchLicense(callCluster: CallCluster, local: boolean) { + return callCluster<{ license: ESLicense }>('transport.request', { + method: 'GET', + path: '/_license', + query: { + local, + // For versions >= 7.6 and < 8.0, this flag is needed otherwise 'platinum' is returned for 'enterprise' license. + accept_enterprise: 'true', + }, + }); +} + +/** + * Get the cluster's license from the connected node. + * + * This is the equivalent of GET /_license?local=true . + * + * Like any X-Pack related API, X-Pack must installed for this to work. + */ +async function getLicenseFromLocalOrMaster(callCluster: CallCluster) { + // Fetching the local license is cheaper than getting it from the master and good enough + const { license } = await fetchLicense(callCluster, true).catch(async err => { + if (cachedLicense) { + try { + // Fallback to the master node's license info + const response = await fetchLicense(callCluster, false); + return response; + } catch (masterError) { + if (masterError.statusCode === 404) { + // If the master node does not have a license, we can assume there is no license + cachedLicense = undefined; + } else { + // Any other errors from the master node, throw and do not send any telemetry + throw err; + } + } + } + return { license: void 0 }; + }); + + if (license) { + cachedLicense = license; + } + return license; +} + +export const getLocalLicense: LicenseGetter = async (clustersDetails, { callCluster }) => { + const license = await getLicenseFromLocalOrMaster(callCluster); + + // It should be called only with 1 cluster element in the clustersDetails array, but doing reduce just in case. + return clustersDetails.reduce((acc, { clusterUuid }) => ({ ...acc, [clusterUuid]: license }), {}); +}; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts index 8adb6d237bee81..d99710deb1cbc9 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts @@ -17,11 +17,8 @@ * under the License. */ -import { get, omit } from 'lodash'; -// @ts-ignore -import { getClusterInfo } from './get_cluster_info'; +import { getClusterInfo, ESClusterInfo } from './get_cluster_info'; import { getClusterStats } from './get_cluster_stats'; -// @ts-ignore import { getKibana, handleKibanaStats, KibanaUsageStats } from './get_kibana'; import { StatsGetter } from '../collection_manager'; @@ -33,20 +30,19 @@ import { StatsGetter } from '../collection_manager'; * @param {Object} clusterInfo Cluster info (GET /) * @param {Object} clusterStats Cluster stats (GET /_cluster/stats) * @param {Object} kibana The Kibana Usage stats - * @return {Object} A combined object containing the different responses. */ export function handleLocalStats( server: any, - clusterInfo: any, - clusterStats: any, + { cluster_name, cluster_uuid, version }: ESClusterInfo, + { _nodes, cluster_name: clusterName, ...clusterStats }: any, kibana: KibanaUsageStats ) { return { timestamp: new Date().toISOString(), - cluster_uuid: get(clusterInfo, 'cluster_uuid'), - cluster_name: get(clusterInfo, 'cluster_name'), - version: get(clusterInfo, 'version.number'), - cluster_stats: omit(clusterStats, '_nodes', 'cluster_name'), + cluster_uuid, + cluster_name, + version: version.number, + cluster_stats: clusterStats, collection: 'local', stack_stats: { kibana: handleKibanaStats(server, kibana), @@ -54,14 +50,12 @@ export function handleLocalStats( }; } +export type TelemetryLocalStats = ReturnType; + /** * Get statistics for all products joined by Elasticsearch cluster. - * - * @param {Object} server The Kibana server instance used to call ES as the internal user - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} The object containing the current Elasticsearch cluster's telemetry. */ -export const getLocalStats: StatsGetter = async (clustersDetails, config) => { +export const getLocalStats: StatsGetter = async (clustersDetails, config) => { const { server, callCluster, usageCollection } = config; return await Promise.all( diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts index 7f228dbc5e6f69..9ac94216c21bc6 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts @@ -17,7 +17,6 @@ * under the License. */ -// @ts-ignore export { getLocalStats } from './get_local_stats'; export { getClusterUuids } from './get_cluster_stats'; export { registerCollection } from './register_collection'; diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts index faf8e9de79194b..6580b47dba08ef 100644 --- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts +++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts @@ -39,6 +39,7 @@ import { telemetryCollectionManager } from '../collection_manager'; import { getLocalStats } from './get_local_stats'; import { getClusterUuids } from './get_cluster_stats'; +import { getLocalLicense } from './get_local_license'; export function registerCollection() { telemetryCollectionManager.setCollection({ @@ -47,5 +48,6 @@ export function registerCollection() { priority: 0, statsGetter: getLocalStats, clusterDetailsGetter: getClusterUuids, + licenseGetter: getLocalLicense, }); } diff --git a/src/plugins/telemetry/public/services/telemetry_service.test.ts b/src/plugins/telemetry/public/services/telemetry_service.test.ts index 0ebcd52f1423c3..0a49b0ae3084e3 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.test.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.test.ts @@ -26,9 +26,18 @@ const mockSubtract = jest.fn().mockImplementation(() => { }; }); +const mockClone = jest.fn().mockImplementation(() => { + return { + clone: mockClone, + subtract: mockSubtract, + toISOString: jest.fn(), + }; +}); + jest.mock('moment', () => { return jest.fn().mockImplementation(() => { return { + clone: mockClone, subtract: mockSubtract, toISOString: jest.fn(), }; @@ -43,6 +52,7 @@ describe('TelemetryService', () => { expect(telemetryService['http'].post).toBeCalledWith('/api/telemetry/v2/clusters/_stats', { body: JSON.stringify({ unencrypted: false, timeRange: {} }), }); + expect(mockClone).toBeCalled(); expect(mockSubtract).toBeCalledWith(20, 'minutes'); }); }); diff --git a/src/plugins/telemetry/public/services/telemetry_service.ts b/src/plugins/telemetry/public/services/telemetry_service.ts index 073886e7d1327f..cb91451bd8ef49 100644 --- a/src/plugins/telemetry/public/services/telemetry_service.ts +++ b/src/plugins/telemetry/public/services/telemetry_service.ts @@ -92,7 +92,10 @@ export class TelemetryService { body: JSON.stringify({ unencrypted, timeRange: { - min: now.subtract(20, 'minutes').toISOString(), + min: now + .clone() // Need to clone it to avoid mutation (and max being the same value) + .subtract(20, 'minutes') + .toISOString(), max: now.toISOString(), }, }), diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts index 470642f9dd8a3e..dcc7924fe171a9 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts @@ -5,7 +5,7 @@ */ import sinon from 'sinon'; -import { addStackStats, getAllStats, handleAllStats } from './get_all_stats'; +import { getStackStats, getAllStats, handleAllStats } from './get_all_stats'; import { ESClusterStats } from './get_es_stats'; import { KibanaStats } from './get_kibana_stats'; import { ClustersHighLevelStats } from './get_high_level_stats'; @@ -223,7 +223,8 @@ describe('get_all_stats', () => { beats: {}, }); - expect(clusters).toStrictEqual(expectedClusters); + const [a, b, c] = expectedClusters; + expect(clusters).toStrictEqual([a, b, { ...c, stack_stats: {} }]); }); it('handles no clusters response', () => { @@ -233,9 +234,8 @@ describe('get_all_stats', () => { }); }); - describe('addStackStats', () => { + describe('getStackStats', () => { it('searches for clusters', () => { - const cluster = { cluster_uuid: 'a' }; const stats = { a: { count: 2, @@ -250,9 +250,7 @@ describe('get_all_stats', () => { }, }; - addStackStats(cluster as ESClusterStats, stats, 'xyz'); - - expect((cluster as any).stack_stats.xyz).toStrictEqual(stats.a); + expect(getStackStats('a', stats, 'xyz')).toStrictEqual({ xyz: stats.a }); }); }); }); diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.ts index aa5e937387dafb..a6ed5254dabd50 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_all_stats.ts @@ -61,38 +61,31 @@ export function handleAllStats( } ) { return clusters.map(cluster => { - // if they are using Kibana or Logstash, then add it to the cluster details under cluster.stack_stats - addStackStats(cluster, kibana, KIBANA_SYSTEM_ID); - addStackStats(cluster, logstash, LOGSTASH_SYSTEM_ID); - addStackStats(cluster, beats, BEATS_SYSTEM_ID); - mergeXPackStats(cluster, kibana, 'graph_workspace', 'graph'); // copy graph_workspace info out of kibana, merge it into stack_stats.xpack.graph + const stats = { + ...cluster, + stack_stats: { + ...cluster.stack_stats, + // if they are using Kibana or Logstash, then add it to the cluster details under cluster.stack_stats + ...getStackStats(cluster.cluster_uuid, kibana, KIBANA_SYSTEM_ID), + ...getStackStats(cluster.cluster_uuid, logstash, LOGSTASH_SYSTEM_ID), + ...getStackStats(cluster.cluster_uuid, beats, BEATS_SYSTEM_ID), + }, + }; - return cluster; + mergeXPackStats(stats, kibana, 'graph_workspace', 'graph'); // copy graph_workspace info out of kibana, merge it into stack_stats.xpack.graph + + return stats; }); } -/** - * Add product data to the {@code cluster}, only if it exists for the current {@code cluster}. - * - * @param {Object} cluster The current Elasticsearch cluster stats - * @param {Object} allProductStats Product stats, keyed by Cluster UUID - * @param {String} product The product name being added (e.g., 'kibana' or 'logstash') - */ -export function addStackStats( - cluster: ESClusterStats & { stack_stats?: { [product: string]: K } }, +export function getStackStats( + clusterUuid: string, allProductStats: T, product: string ) { - const productStats = allProductStats[cluster.cluster_uuid]; - + const productStats = allProductStats[clusterUuid]; // Don't add it if they're not using (or configured to report stats) this product for this cluster - if (productStats) { - if (!cluster.stack_stats) { - cluster.stack_stats = {}; - } - - cluster.stack_stats[product] = productStats; - } + return productStats ? { [product]: productStats } : {}; } export function mergeXPackStats( diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_es_stats.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_es_stats.ts index f0ae1163d3f52b..2f2fffd3f08237 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_es_stats.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_es_stats.ts @@ -48,11 +48,6 @@ export function fetchElasticsearchStats( 'hits.hits._source.timestamp', 'hits.hits._source.cluster_name', 'hits.hits._source.version', - 'hits.hits._source.license.status', // license data only includes necessary fields to drive UI - 'hits.hits._source.license.type', - 'hits.hits._source.license.issue_date', - 'hits.hits._source.license.expiry_date', - 'hits.hits._source.license.expiry_date_in_millis', 'hits.hits._source.cluster_stats', 'hits.hits._source.stack_stats', ], @@ -79,7 +74,11 @@ export function fetchElasticsearchStats( export interface ESClusterStats { cluster_uuid: string; - type: 'cluster_stats'; + cluster_name: string; + timestamp: string; + version: string; + cluster_stats: object; + stack_stats?: object; } /** diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts new file mode 100644 index 00000000000000..bb8326ce0b63a9 --- /dev/null +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.test.ts @@ -0,0 +1,84 @@ +/* + * 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 sinon from 'sinon'; +import { getLicenses, handleLicenses, fetchLicenses } from './get_licenses'; + +describe('get_licenses', () => { + const callWith = sinon.stub(); + const size = 123; + const server = { + config: sinon.stub().returns({ + get: sinon + .stub() + .withArgs('xpack.monitoring.elasticsearch.index_pattern') + .returns('.monitoring-es-N-*') + .withArgs('xpack.monitoring.max_bucket_size') + .returns(size), + }), + }; + const response = { + hits: { + hits: [ + { _id: 'abc', _source: { cluster_uuid: 'abc', license: { type: 'basic' } } }, + { _id: 'xyz', _source: { cluster_uuid: 'xyz', license: { type: 'basic' } } }, + { _id: '123', _source: { cluster_uuid: '123' } }, + ], + }, + }; + const expectedClusters = response.hits.hits.map(hit => hit._source); + const clusterUuids = expectedClusters.map(cluster => ({ clusterUuid: cluster.cluster_uuid })); + const expectedLicenses = { + abc: { type: 'basic' }, + xyz: { type: 'basic' }, + '123': void 0, + }; + + describe('getLicenses', () => { + it('returns clusters', async () => { + callWith.withArgs('search').returns(Promise.resolve(response)); + + expect( + await getLicenses(clusterUuids, { server, callCluster: callWith } as any) + ).toStrictEqual(expectedLicenses); + }); + }); + + describe('fetchLicenses', () => { + it('searches for clusters', async () => { + callWith.returns(response); + + expect( + await fetchLicenses( + server, + callWith, + clusterUuids.map(({ clusterUuid }) => clusterUuid) + ) + ).toStrictEqual(response); + }); + }); + + describe('handleLicenses', () => { + // filterPath makes it easy to ignore anything unexpected because it will come back empty + it('handles unexpected response', () => { + const clusters = handleLicenses({} as any); + + expect(clusters).toStrictEqual({}); + }); + + it('handles valid response', () => { + const clusters = handleLicenses(response as any); + + expect(clusters).toStrictEqual(expectedLicenses); + }); + + it('handles no hits response', () => { + const clusters = handleLicenses({ hits: { hits: [] } } as any); + + expect(clusters).toStrictEqual({}); + }); + }); +}); diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.ts new file mode 100644 index 00000000000000..7364227e7dc92d --- /dev/null +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/get_licenses.ts @@ -0,0 +1,84 @@ +/* + * 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 { + StatsCollectionConfig, + LicenseGetter, +} from 'src/legacy/core_plugins/telemetry/server/collection_manager'; +import { SearchResponse } from 'elasticsearch'; +import { ESLicense } from 'src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; + +/** + * Get statistics for all selected Elasticsearch clusters. + */ +export const getLicenses: LicenseGetter = async (clustersDetails, { server, callCluster }) => { + const clusterUuids = clustersDetails.map(({ clusterUuid }) => clusterUuid); + const response = await fetchLicenses(server, callCluster, clusterUuids); + return handleLicenses(response); +}; + +/** + * Fetch the Elasticsearch stats. + * + * @param {Object} server The server instance + * @param {function} callCluster The callWithRequest or callWithInternalUser handler + * @param {Array} clusterUuids Cluster UUIDs to limit the request against + * + * Returns the response for the aggregations to fetch details for the product. + */ +export function fetchLicenses( + server: StatsCollectionConfig['server'], + callCluster: StatsCollectionConfig['callCluster'], + clusterUuids: string[] +) { + const config = server.config(); + const params = { + index: INDEX_PATTERN_ELASTICSEARCH, + size: config.get('monitoring.ui.max_bucket_size'), + ignoreUnavailable: true, + filterPath: ['hits.hits._source.cluster_uuid', 'hits.hits._source.license'], + body: { + query: { + bool: { + filter: [ + /* + * Note: Unlike most places, we don't care about the old _type: cluster_stats because it would NOT + * have the license in it (that used to be in the .monitoring-data-2 index in cluster_info) + */ + { term: { type: 'cluster_stats' } }, + { terms: { cluster_uuid: clusterUuids } }, + ], + }, + }, + collapse: { field: 'cluster_uuid' }, + sort: { timestamp: { order: 'desc' } }, + }, + }; + + return callCluster('search', params); +} + +export interface ESClusterStatsWithLicense { + cluster_uuid: string; + type: 'cluster_stats'; + license?: ESLicense; +} + +/** + * Extract the cluster stats for each cluster. + */ +export function handleLicenses(response: SearchResponse) { + const clusters = response.hits?.hits || []; + + return clusters.reduce( + (acc, { _source }) => ({ + ...acc, + [_source.cluster_uuid]: _source.license, + }), + {} + ); +} diff --git a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts index f0fda5229cb5c6..0b14eb05f796f0 100644 --- a/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts +++ b/x-pack/legacy/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts @@ -7,6 +7,7 @@ import { telemetryCollectionManager } from '../../../../../../src/legacy/core_plugins/telemetry/server'; import { getAllStats } from './get_all_stats'; import { getClusterUuids } from './get_cluster_uuids'; +import { getLicenses } from './get_licenses'; export function registerMonitoringCollection() { telemetryCollectionManager.setCollection({ @@ -15,5 +16,6 @@ export function registerMonitoringCollection() { priority: 2, statsGetter: getAllStats, clusterDetailsGetter: getClusterUuids, + licenseGetter: getLicenses, }); } diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__snapshots__/get_stats_with_xpack.test.ts.snap b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__snapshots__/get_stats_with_xpack.test.ts.snap new file mode 100644 index 00000000000000..1a70504dc93918 --- /dev/null +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__snapshots__/get_stats_with_xpack.test.ts.snap @@ -0,0 +1,118 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Telemetry Collection: Get Aggregated Stats OSS-like telemetry (no license nor X-Pack telemetry) 1`] = ` +Array [ + Object { + "cluster_name": "test", + "cluster_stats": Object {}, + "cluster_uuid": "test", + "collection": "local", + "stack_stats": Object { + "kibana": Object { + "count": 1, + "great": "googlymoogly", + "indices": 1, + "os": Object { + "platformReleases": Array [ + Object { + "count": 1, + "platformRelease": "iv", + }, + ], + "platforms": Array [ + Object { + "count": 1, + "platform": "rocky", + }, + ], + }, + "plugins": Object { + "clouds": Object { + "chances": 95, + }, + "localization": Object { + "integrities": Object {}, + "labelsCount": 0, + "locale": "en", + }, + "rain": Object { + "chances": 2, + }, + "snow": Object { + "chances": 0, + }, + "sun": Object { + "chances": 5, + }, + }, + "versions": Array [ + Object { + "count": 1, + "version": "8675309", + }, + ], + }, + }, + "version": "8.0.0", + }, +] +`; + +exports[`Telemetry Collection: Get Aggregated Stats X-Pack telemetry (license + X-Pack) 1`] = ` +Array [ + Object { + "cluster_name": "test", + "cluster_stats": Object {}, + "cluster_uuid": "test", + "collection": "local", + "stack_stats": Object { + "kibana": Object { + "count": 1, + "great": "googlymoogly", + "indices": 1, + "os": Object { + "platformReleases": Array [ + Object { + "count": 1, + "platformRelease": "iv", + }, + ], + "platforms": Array [ + Object { + "count": 1, + "platform": "rocky", + }, + ], + }, + "plugins": Object { + "clouds": Object { + "chances": 95, + }, + "localization": Object { + "integrities": Object {}, + "labelsCount": 0, + "locale": "en", + }, + "rain": Object { + "chances": 2, + }, + "snow": Object { + "chances": 0, + }, + "sun": Object { + "chances": 5, + }, + }, + "versions": Array [ + Object { + "count": 1, + "version": "8675309", + }, + ], + }, + "xpack": Object {}, + }, + "version": "8.0.0", + }, +] +`; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__tests__/get_xpack.js b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__tests__/get_xpack.js index eca130b4d74659..eb03701fd195b5 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__tests__/get_xpack.js +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/__tests__/get_xpack.js @@ -8,42 +8,7 @@ import expect from '@kbn/expect'; import sinon from 'sinon'; import { TIMEOUT } from '../constants'; -import { getXPackLicense, getXPackUsage, getXPack, handleXPack } from '../get_xpack'; - -function mockGetXPackLicense(callCluster, license, req) { - callCluster - .withArgs(req, 'transport.request', { - method: 'GET', - path: '/_license', - query: { - local: 'true', - accept_enterprise: 'true', - }, - }) - .returns( - license.then( - response => ({ license: response }), - () => {} // Catch error so that we don't emit UnhandledPromiseRejectionWarning for tests with invalid license - ) - ); - - callCluster - .withArgs('transport.request', { - method: 'GET', - path: '/_license', - query: { - local: 'true', - accept_enterprise: 'true', - }, - }) - // conveniently wraps the passed in license object as { license: response }, like it really is - .returns( - license.then( - response => ({ license: response }), - () => {} // Catch error so that we don't emit UnhandledPromiseRejectionWarning for tests with invalid license - ) - ); -} +import { getXPackUsage } from '../get_xpack'; function mockGetXPackUsage(callCluster, usage, req) { callCluster @@ -67,31 +32,7 @@ function mockGetXPackUsage(callCluster, usage, req) { .returns(usage); } -/** - * Mock getXPack responses. - * - * @param {Function} callCluster Sinon function mock. - * @param {Promise} license Promised license response. - * @param {Promise} usage Promised usage response. - * @param {Object} usage reqeust object. - */ -export function mockGetXPack(callCluster, license, usage, req) { - mockGetXPackLicense(callCluster, license, req); - mockGetXPackUsage(callCluster, usage, req); -} - describe('get_xpack', () => { - describe('getXPackLicense', () => { - it('uses callCluster to get /_license API', async () => { - const response = { type: 'basic' }; - const callCluster = sinon.stub(); - - mockGetXPackLicense(callCluster, Promise.resolve(response)); - - expect(await getXPackLicense(callCluster)).to.eql(response); - }); - }); - describe('getXPackUsage', () => { it('uses callCluster to get /_xpack/usage API', () => { const response = Promise.resolve({}); @@ -102,48 +43,4 @@ describe('get_xpack', () => { expect(getXPackUsage(callCluster)).to.be(response); }); }); - - describe('handleXPack', () => { - it('uses data as expected', () => { - const license = { fake: 'data' }; - const usage = { also: 'fake', nested: { object: { data: [{ field: 1 }, { field: 2 }] } } }; - - expect(handleXPack(license, usage)).to.eql({ license, stack_stats: { xpack: usage } }); - }); - }); - - describe('getXPack', () => { - it('returns the formatted response object', async () => { - const license = { fancy: 'license' }; - const xpack = { also: 'fancy' }; - - const callCluster = sinon.stub(); - - mockGetXPack(callCluster, Promise.resolve(license), Promise.resolve(xpack)); - - const data = await getXPack(callCluster); - - expect(data).to.eql({ license, xpack }); - }); - - it('returns empty object upon license failure', async () => { - const callCluster = sinon.stub(); - - mockGetXPack(callCluster, Promise.reject(new Error()), Promise.resolve({ also: 'fancy' })); - - const data = await getXPack(callCluster); - - expect(data).to.eql({}); - }); - - it('returns empty object upon usage failure', async () => { - const callCluster = sinon.stub(); - - mockGetXPack(callCluster, Promise.resolve({ fancy: 'license' }), Promise.reject(new Error())); - - const data = await getXPack(callCluster); - - expect(data).to.eql({}); - }); - }); }); diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/constants.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/constants.ts index c89fbe416a0cca..b6f1aabab95c49 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/constants.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/constants.ts @@ -7,4 +7,5 @@ /** * The timeout used by each request, whenever a timeout can be specified. */ + export const TIMEOUT = '30s'; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.test.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.test.ts new file mode 100644 index 00000000000000..b85cbd96610228 --- /dev/null +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.test.ts @@ -0,0 +1,113 @@ +/* + * 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 { getStatsWithXpack } from './get_stats_with_xpack'; + +const kibana = { + kibana: { + great: 'googlymoogly', + versions: [{ version: '8675309', count: 1 }], + }, + kibana_stats: { + os: { + platform: 'rocky', + platformRelease: 'iv', + }, + }, + localization: { + locale: 'en', + labelsCount: 0, + integrities: {}, + }, + sun: { chances: 5 }, + clouds: { chances: 95 }, + rain: { chances: 2 }, + snow: { chances: 0 }, +}; + +const getMockServer = (getCluster = jest.fn()) => ({ + log(tags: string[], message: string) { + // eslint-disable-next-line no-console + console.log({ tags, message }); + }, + config() { + return { + get(item: string) { + switch (item) { + case 'pkg.version': + return '8675309-snapshot'; + default: + throw Error(`unexpected config.get('${item}') received.`); + } + }, + }; + }, + plugins: { + elasticsearch: { getCluster }, + }, +}); + +const mockUsageCollection = (kibanaUsage = kibana) => ({ + bulkFetch: () => kibanaUsage, + toObject: (data: any) => data, +}); + +describe('Telemetry Collection: Get Aggregated Stats', () => { + test('OSS-like telemetry (no license nor X-Pack telemetry)', async () => { + const callCluster = jest.fn(async (method: string, options: { path?: string }) => { + switch (method) { + case 'transport.request': + if (options.path === '/_license' || options.path === '/_xpack/usage') { + // eslint-disable-next-line no-throw-literal + throw { statusCode: 404 }; + } + return {}; + case 'info': + return { cluster_uuid: 'test', cluster_name: 'test', version: { number: '8.0.0' } }; + default: + return {}; + } + }); + const usageCollection = mockUsageCollection(); + const server = getMockServer(); + + const stats = await getStatsWithXpack([{ clusterUuid: '1234' }], { + callCluster, + usageCollection, + server, + } as any); + expect(stats.map(({ timestamp, ...rest }) => rest)).toMatchSnapshot(); + }); + + test('X-Pack telemetry (license + X-Pack)', async () => { + const callCluster = jest.fn(async (method: string, options: { path?: string }) => { + switch (method) { + case 'transport.request': + if (options.path === '/_license') { + return { + license: { type: 'basic' }, + }; + } + if (options.path === '/_xpack/usage') { + return {}; + } + case 'info': + return { cluster_uuid: 'test', cluster_name: 'test', version: { number: '8.0.0' } }; + default: + return {}; + } + }); + const usageCollection = mockUsageCollection(); + const server = getMockServer(); + + const stats = await getStatsWithXpack([{ clusterUuid: '1234' }], { + callCluster, + usageCollection, + server, + } as any); + expect(stats.map(({ timestamp, ...rest }) => rest)).toMatchSnapshot(); + }); +}); diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts index 41076d96231c93..ea7465f66f120e 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_stats_with_xpack.ts @@ -4,19 +4,33 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore -import { getXPack } from './get_xpack'; -import { getLocalStats } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection'; import { StatsGetter } from '../../../../../../src/legacy/core_plugins/telemetry/server/collection_manager'; +import { + getLocalStats, + TelemetryLocalStats, +} from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats'; +import { getXPackUsage } from './get_xpack'; -export const getStatsWithXpack: StatsGetter = async function(clustersDetails, config) { +export type TelemetryAggregatedStats = TelemetryLocalStats & { + stack_stats: { xpack?: object }; +}; + +export const getStatsWithXpack: StatsGetter = async function( + clustersDetails, + config +) { const { callCluster } = config; const clustersLocalStats = await getLocalStats(clustersDetails, config); - const { license, xpack } = await getXPack(callCluster); + const xpack = await getXPackUsage(callCluster).catch(() => undefined); // We want to still report something (and do not lose the license) even when this method fails. return clustersLocalStats.map(localStats => { - localStats.license = license; - localStats.stack_stats.xpack = xpack; + if (xpack) { + return { + ...localStats, + stack_stats: { ...localStats.stack_stats, xpack }, + }; + } + return localStats; }); }; diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.js b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.js deleted file mode 100644 index aaeb890981aa1c..00000000000000 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.js +++ /dev/null @@ -1,85 +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 { TIMEOUT } from './constants'; - -/** - * Get the cluster stats from the connected cluster. - * - * This is the equivalent of GET /_license?local=true . - * - * Like any X-Pack related API, X-Pack must installed for this to work. - * - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} The response from Elasticsearch. - */ -export function getXPackLicense(callCluster) { - return callCluster('transport.request', { - method: 'GET', - path: '/_license', - query: { - // Fetching the local license is cheaper than getting it from the master and good enough - local: 'true', - // For versions >= 7.6 and < 8.0, this flag is needed otherwise 'platinum' is returned for 'enterprise' license. - accept_enterprise: 'true', - }, - }).then(({ license }) => license); -} - -/** - * Get the cluster stats from the connected cluster. - * - * This is the equivalent of GET /_xpack/usage?master_timeout=${TIMEOUT} - * - * Like any X-Pack related API, X-Pack must installed for this to work. - * - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} The response from Elasticsearch equivalent to GET /_cluster/stats. - */ -export function getXPackUsage(callCluster) { - return callCluster('transport.request', { - method: 'GET', - path: '/_xpack/usage', - query: { - master_timeout: TIMEOUT, - }, - }); -} - -/** - * Combine the X-Pack responses into a single response as Monitoring does already. - * - * @param {Object} license The license returned from /_license - * @param {Object} usage The usage details returned from /_xpack/usage - * @return {Object} An object containing both the license and usage. - */ -export function handleXPack(license, usage) { - return { - license, - stack_stats: { - xpack: usage, - }, - }; -} - -/** - * Combine all X-Pack requests as a singular request that is ignored upon failure. - * - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) - * @return {Promise} - */ -export function getXPack(callCluster) { - return Promise.all([getXPackLicense(callCluster), getXPackUsage(callCluster)]) - .then(([license, xpack]) => { - return { - license, - xpack, - }; - }) - .catch(() => { - return {}; - }); -} diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.ts new file mode 100644 index 00000000000000..9b69540007e5f7 --- /dev/null +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/get_xpack.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; +import { TIMEOUT } from './constants'; + +/** + * Get the cluster stats from the connected cluster. + * + * This is the equivalent of GET /_xpack/usage?master_timeout=${TIMEOUT} + * + * Like any X-Pack related API, X-Pack must installed for this to work. + */ +export function getXPackUsage(callCluster: CallCluster) { + return callCluster('transport.request', { + method: 'GET', + path: '/_xpack/usage', + query: { + master_timeout: TIMEOUT, + }, + }); +} diff --git a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts index 57faf2da90d092..04445d7bde7d7b 100644 --- a/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts +++ b/x-pack/legacy/plugins/xpack_main/server/telemetry_collection/register_xpack_collection.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { getLocalLicense } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_license'; import { telemetryCollectionManager } from '../../../../../../src/legacy/core_plugins/telemetry/server'; import { getClusterUuids } from '../../../../../../src/legacy/core_plugins/telemetry/server/telemetry_collection'; import { getStatsWithXpack } from './get_stats_with_xpack'; @@ -15,5 +16,6 @@ export function registerMonitoringCollection() { priority: 1, statsGetter: getStatsWithXpack, clusterDetailsGetter: getClusterUuids, + licenseGetter: getLocalLicense, }); } diff --git a/x-pack/test/api_integration/apis/telemetry/fixtures/basiccluster.json b/x-pack/test/api_integration/apis/telemetry/fixtures/basiccluster.json index 5c3c8cfcab7a64..a0097f53ac93b9 100644 --- a/x-pack/test/api_integration/apis/telemetry/fixtures/basiccluster.json +++ b/x-pack/test/api_integration/apis/telemetry/fixtures/basiccluster.json @@ -1,6 +1,7 @@ [ { "cluster_name": "docker-cluster", + "collectionSource": "monitoring", "cluster_stats": { "indices": { "completion": { @@ -161,6 +162,12 @@ }, "cluster_uuid": "ooEYzl3fSL222Y6eVm7SAA", "license": { + "uid": "79dc3adb-e85e-4cef-a985-9b74eb6c07c1", + "issue_date_in_millis": 1532383643540, + "issued_to": "docker-cluster", + "issuer": "elasticsearch", + "max_nodes": 1000, + "start_date_in_millis": -1, "issue_date": "2018-07-23T22:07:23.540Z", "status": "active", "type": "basic" diff --git a/x-pack/test/api_integration/apis/telemetry/fixtures/multicluster.json b/x-pack/test/api_integration/apis/telemetry/fixtures/multicluster.json index 2e6a75ee75972d..6cc9c55157b282 100644 --- a/x-pack/test/api_integration/apis/telemetry/fixtures/multicluster.json +++ b/x-pack/test/api_integration/apis/telemetry/fixtures/multicluster.json @@ -1 +1,1001 @@ -[{"cluster_uuid":"6d-9tDFTRe-qT5GoBytdlQ","timestamp":"2017-08-15T22:10:59.952Z","cluster_name":"clustertwo","version":"7.0.0-alpha1","license":{"status":"active","type":"basic","issue_date":"2014-09-29T00:00:00.000Z","expiry_date":"2030-08-29T23:59:59.999Z","expiry_date_in_millis":1914278399999},"cluster_stats":{"timestamp":1502835059952,"status":"green","indices":{"count":1,"shards":{"total":1,"primaries":1,"replication":0,"index":{"shards":{"min":1,"max":1,"avg":1},"primaries":{"min":1,"max":1,"avg":1},"replication":{"min":0,"max":0,"avg":0}}},"docs":{"count":8,"deleted":0},"store":{"size_in_bytes":34095},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":8,"memory_in_bytes":13852,"terms_memory_in_bytes":10412,"stored_fields_memory_in_bytes":2496,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":256,"points_memory_in_bytes":8,"doc_values_memory_in_bytes":680,"index_writer_memory_in_bytes":0,"version_map_memory_in_bytes":0,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}}},"nodes":{"count":{"total":1,"data":1,"coordinating_only":0,"master":1,"ingest":1},"versions":["7.0.0-alpha1"],"os":{"available_processors":4,"allocated_processors":1,"names":[{"name":"Mac OS X","count":1}],"mem":{"total_in_bytes":17179869184,"free_in_bytes":183799808,"used_in_bytes":16996069376,"free_percent":1,"used_percent":99}},"process":{"cpu":{"percent":0},"open_file_descriptors":{"min":163,"max":163,"avg":163}},"jvm":{"max_uptime_in_millis":701043,"versions":[{"vm_version":"25.121-b13","count":1,"vm_vendor":"Oracle Corporation","version":"1.8.0_121","vm_name":"Java HotSpot(TM) 64-Bit Server VM"}],"mem":{"heap_used_in_bytes":204299464,"heap_max_in_bytes":628555776},"threads":40},"fs":{"total_in_bytes":499065712640,"free_in_bytes":200665341952,"available_in_bytes":200403197952},"plugins":[{"classname":"org.elasticsearch.xpack.XPackPlugin","name":"x-pack","description":"Elasticsearch Expanded Pack Plugin","version":"7.0.0-alpha1","has_native_controller":true}],"network_types":{"transport_types":{"security4":1},"http_types":{"security4":1}}}},"stack_stats":{"xpack":{"security":{"available":false,"enabled":true,"realms":{"file":{"available":false,"enabled":false},"ldap":{"available":false,"enabled":false},"native":{"available":false,"enabled":false},"active_directory":{"available":false,"enabled":false},"pki":{"available":false,"enabled":false}},"roles":{"native":{"size":1,"dls":false,"fls":false},"file":{"size":0,"dls":false,"fls":false}},"role_mapping":{"native":{"size":0,"enabled":0}},"ssl":{"http":{"enabled":false}},"audit":{"outputs":["logfile"],"enabled":false},"ipfilter":{"http":false,"transport":false},"anonymous":{"enabled":false}},"monitoring":{"available":true,"enabled":true,"enabled_exporters":{"http":1}},"watcher":{"available":false,"enabled":true,"execution":{"actions":{"_all":{"total":0,"total_time_in_ms":0}}}},"graph":{"available":false,"enabled":true},"ml":{"available":false,"enabled":true,"jobs":{"_all":{"count":0,"detectors":{"total":0,"min":0,"avg":0,"max":0},"model_size":{"total":0,"min":0,"avg":0,"max":0}}},"datafeeds":{"_all":{"count":0}}},"logstash":{"available":false,"enabled":true},"ccr":{"auto_follow_patterns_count":0,"available":true,"follower_indices_count":0,"enabled":true}}}},{"cluster_uuid":"lOF8kofiS_2DX58o9mXJ1Q","timestamp":"2017-08-15T22:10:54.610Z","cluster_name":"monitoring-one","version":"7.0.0-alpha1","license":{"status":"active","type":"trial","issue_date":"2017-08-15T21:58:28.997Z","expiry_date":"2017-09-14T21:58:28.997Z","expiry_date_in_millis":1505426308997},"cluster_stats":{"timestamp":1502835054610,"status":"yellow","indices":{"count":8,"shards":{"total":8,"primaries":8,"replication":0,"index":{"shards":{"min":1,"max":1,"avg":1},"primaries":{"min":1,"max":1,"avg":1},"replication":{"min":0,"max":0,"avg":0}}},"docs":{"count":3997,"deleted":69},"store":{"size_in_bytes":2647163},"fielddata":{"memory_size_in_bytes":2104,"evictions":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":36,"memory_in_bytes":278961,"terms_memory_in_bytes":166031,"stored_fields_memory_in_bytes":11544,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":6784,"points_memory_in_bytes":3250,"doc_values_memory_in_bytes":91352,"index_writer_memory_in_bytes":205347,"version_map_memory_in_bytes":26362,"fixed_bit_set_memory_in_bytes":992,"max_unsafe_auto_id_timestamp":-1,"file_sizes":{}}},"nodes":{"count":{"total":1,"data":1,"coordinating_only":0,"master":1,"ingest":1},"versions":["7.0.0-alpha1"],"os":{"available_processors":4,"allocated_processors":1,"names":[{"name":"Mac OS X","count":1}],"mem":{"total_in_bytes":17179869184,"free_in_bytes":86732800,"used_in_bytes":17093136384,"free_percent":1,"used_percent":99}},"process":{"cpu":{"percent":2},"open_file_descriptors":{"min":178,"max":178,"avg":178}},"jvm":{"max_uptime_in_millis":761002,"versions":[{"vm_version":"25.121-b13","count":1,"vm_vendor":"Oracle Corporation","version":"1.8.0_121","vm_name":"Java HotSpot(TM) 64-Bit Server VM"}],"mem":{"heap_used_in_bytes":133041176,"heap_max_in_bytes":628555776},"threads":42},"fs":{"total_in_bytes":499065712640,"free_in_bytes":200665792512,"available_in_bytes":200403648512},"plugins":[{"classname":"org.elasticsearch.xpack.XPackPlugin","name":"x-pack","description":"Elasticsearch Expanded Pack Plugin","version":"7.0.0-alpha1","has_native_controller":true}],"network_types":{"transport_types":{"security4":1},"http_types":{"security4":1}}}},"stack_stats":{"xpack":{"security":{"available":true,"enabled":true,"realms":{"file":{"name":["default_file"],"available":true,"size":[0],"enabled":true,"order":[2147483647]},"ldap":{"available":true,"enabled":false},"native":{"name":["default_native"],"available":true,"size":[2],"enabled":true,"order":[2147483647]},"active_directory":{"available":true,"enabled":false},"pki":{"available":true,"enabled":false}},"roles":{"native":{"size":1,"dls":false,"fls":false},"file":{"size":0,"dls":false,"fls":false}},"role_mapping":{"native":{"size":0,"enabled":0}},"ssl":{"http":{"enabled":false}},"audit":{"outputs":["logfile"],"enabled":false},"ipfilter":{"http":false,"transport":false},"anonymous":{"enabled":false}},"monitoring":{"available":true,"enabled":true,"enabled_exporters":{"local":1}},"watcher":{"available":true,"enabled":true,"execution":{"actions":{"index":{"total":14,"total_time_in_ms":158},"_all":{"total":110,"total_time_in_ms":2245},"email":{"total":14,"total_time_in_ms":3}}}},"graph":{"available":true,"enabled":true},"ml":{"available":true,"enabled":true,"jobs":{"_all":{"count":0,"detectors":{"total":0,"min":0,"avg":0,"max":0},"model_size":{"total":0,"min":0,"avg":0,"max":0}}},"datafeeds":{"_all":{"count":0}}},"logstash":{"available":true,"enabled":true},"ccr":{"auto_follow_patterns_count":0,"available":true,"follower_indices_count":0,"enabled":true}}}},{"cluster_uuid":"TkHOX_-1TzWwbROwQJU5IA","timestamp":"2017-08-15T22:10:52.642Z","cluster_name":"clusterone","version":"7.0.0-alpha1","license":{"status":"active","type":"trial","issue_date":"2017-08-15T21:58:47.135Z","expiry_date":"2017-09-14T21:58:47.135Z","expiry_date_in_millis":1505426327135},"cluster_stats":{"timestamp":1502835052641,"status":"green","indices":{"count":5,"shards":{"total":26,"primaries":13,"replication":1,"index":{"shards":{"min":2,"max":10,"avg":5.2},"primaries":{"min":1,"max":5,"avg":2.6},"replication":{"min":1,"max":1,"avg":1}}},"docs":{"count":150,"deleted":0},"store":{"size_in_bytes":4838464},"fielddata":{"memory_size_in_bytes":0,"evictions":0},"query_cache":{"memory_size_in_bytes":0,"total_count":0,"hit_count":0,"miss_count":0,"cache_size":0,"cache_count":0,"evictions":0},"completion":{"size_in_bytes":0},"segments":{"count":76,"memory_in_bytes":1907922,"terms_memory_in_bytes":1595112,"stored_fields_memory_in_bytes":23744,"term_vectors_memory_in_bytes":0,"norms_memory_in_bytes":197184,"points_memory_in_bytes":3818,"doc_values_memory_in_bytes":88064,"index_writer_memory_in_bytes":7006184,"version_map_memory_in_bytes":260,"fixed_bit_set_memory_in_bytes":0,"max_unsafe_auto_id_timestamp":1502834982386,"file_sizes":{}}},"nodes":{"count":{"total":2,"data":2,"coordinating_only":0,"master":2,"ingest":2},"versions":["7.0.0-alpha1"],"os":{"available_processors":8,"allocated_processors":2,"names":[{"name":"Mac OS X","count":2}],"mem":{"total_in_bytes":34359738368,"free_in_bytes":332099584,"used_in_bytes":34027638784,"free_percent":1,"used_percent":99}},"process":{"cpu":{"percent":2},"open_file_descriptors":{"min":218,"max":237,"avg":227}},"jvm":{"max_uptime_in_millis":741786,"versions":[{"vm_version":"25.121-b13","count":2,"vm_vendor":"Oracle Corporation","version":"1.8.0_121","vm_name":"Java HotSpot(TM) 64-Bit Server VM"}],"mem":{"heap_used_in_bytes":465621856,"heap_max_in_bytes":1257111552},"threads":92},"fs":{"total_in_bytes":499065712640,"free_in_bytes":200666353664,"available_in_bytes":200404209664},"plugins":[{"classname":"org.elasticsearch.xpack.XPackPlugin","name":"x-pack","description":"Elasticsearch Expanded Pack Plugin","version":"7.0.0-alpha1","has_native_controller":true}],"network_types":{"transport_types":{"security4":2},"http_types":{"security4":2}}}},"stack_stats":{"xpack":{"security":{"available":true,"enabled":true,"realms":{"file":{"name":["default_file"],"available":true,"size":[0],"enabled":true,"order":[2147483647]},"ldap":{"available":true,"enabled":false},"native":{"name":["default_native"],"available":true,"size":[1],"enabled":true,"order":[2147483647]},"active_directory":{"available":true,"enabled":false},"pki":{"available":true,"enabled":false}},"roles":{"native":{"size":1,"dls":false,"fls":false},"file":{"size":0,"dls":false,"fls":false}},"role_mapping":{"native":{"size":0,"enabled":0}},"ssl":{"http":{"enabled":false}},"audit":{"outputs":["logfile"],"enabled":false},"ipfilter":{"http":false,"transport":false},"anonymous":{"enabled":false}},"monitoring":{"available":true,"enabled":true,"enabled_exporters":{"http":1}},"watcher":{"available":true,"enabled":true,"execution":{"actions":{"_all":{"total":0,"total_time_in_ms":0}}}},"graph":{"available":true,"enabled":true,"graph_workspace":{"total":0}},"ml":{"available":true,"enabled":true,"jobs":{"_all":{"count":3,"detectors":{"total":3,"min":1,"avg":1,"max":1},"model_size":{"total":0,"min":0,"avg":0,"max":0}},"opened":{"count":1,"detectors":{"total":1,"min":1,"avg":1,"max":1},"model_size":{"total":0,"min":0,"avg":0,"max":0}},"closed":{"count":2,"detectors":{"total":2,"min":1,"avg":1,"max":1},"model_size":{"total":0,"min":0,"avg":0,"max":0}}},"datafeeds":{"_all":{"count":0}}},"logstash":{"available":true,"enabled":true},"ccr":{"auto_follow_patterns_count":0,"available":true,"follower_indices_count":0,"enabled":true}},"kibana":{"count":1,"versions":[{"version":"7.0.0-alpha1","count":1}],"os":{"platforms":[],"platformReleases":[],"distros":[],"distroReleases":[]},"dashboard":{"total":0},"visualization":{"total":0},"search":{"total":0},"index_pattern":{"total":0},"graph_workspace":{"total":0},"timelion_sheet":{"total":0},"indices":1,"plugins":{}},"logstash":{"count":1,"versions":[{"version":"7.0.0-alpha1","count":1}],"os":{"platforms":[],"platformReleases":[],"distros":[],"distroReleases":[]}}}}] +[ + { + "cluster_uuid": "6d-9tDFTRe-qT5GoBytdlQ", + "collectionSource": "monitoring", + "timestamp": "2017-08-15T22:10:59.952Z", + "cluster_name": "clustertwo", + "version": "7.0.0-alpha1", + "license": { + "status": "active", + "type": "basic", + "issue_date": "2014-09-29T00:00:00.000Z", + "expiry_date": "2030-08-29T23:59:59.999Z", + "expiry_date_in_millis": 1914278399999, + "issue_date_in_millis": 1411948800000, + "issued_to": "issuedTo", + "issuer": "issuer", + "max_nodes": 1, + "uid": "893361dc-9749-4997-93cb-802e3d7fa4a8", + "hkey": null + }, + "cluster_stats": { + "timestamp": 1502835059952, + "status": "green", + "indices": { + "count": 1, + "shards": { + "total": 1, + "primaries": 1, + "replication": 0, + "index": { + "shards": { + "min": 1, + "max": 1, + "avg": 1 + }, + "primaries": { + "min": 1, + "max": 1, + "avg": 1 + }, + "replication": { + "min": 0, + "max": 0, + "avg": 0 + } + } + }, + "docs": { + "count": 8, + "deleted": 0 + }, + "store": { + "size_in_bytes": 34095 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 8, + "memory_in_bytes": 13852, + "terms_memory_in_bytes": 10412, + "stored_fields_memory_in_bytes": 2496, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 256, + "points_memory_in_bytes": 8, + "doc_values_memory_in_bytes": 680, + "index_writer_memory_in_bytes": 0, + "version_map_memory_in_bytes": 0, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + } + }, + "nodes": { + "count": { + "total": 1, + "data": 1, + "coordinating_only": 0, + "master": 1, + "ingest": 1 + }, + "versions": [ + "7.0.0-alpha1" + ], + "os": { + "available_processors": 4, + "allocated_processors": 1, + "names": [ + { + "name": "Mac OS X", + "count": 1 + } + ], + "mem": { + "total_in_bytes": 17179869184, + "free_in_bytes": 183799808, + "used_in_bytes": 16996069376, + "free_percent": 1, + "used_percent": 99 + } + }, + "process": { + "cpu": { + "percent": 0 + }, + "open_file_descriptors": { + "min": 163, + "max": 163, + "avg": 163 + } + }, + "jvm": { + "max_uptime_in_millis": 701043, + "versions": [ + { + "vm_version": "25.121-b13", + "count": 1, + "vm_vendor": "Oracle Corporation", + "version": "1.8.0_121", + "vm_name": "Java HotSpot(TM) 64-Bit Server VM" + } + ], + "mem": { + "heap_used_in_bytes": 204299464, + "heap_max_in_bytes": 628555776 + }, + "threads": 40 + }, + "fs": { + "total_in_bytes": 499065712640, + "free_in_bytes": 200665341952, + "available_in_bytes": 200403197952 + }, + "plugins": [ + { + "classname": "org.elasticsearch.xpack.XPackPlugin", + "name": "x-pack", + "description": "Elasticsearch Expanded Pack Plugin", + "version": "7.0.0-alpha1", + "has_native_controller": true + } + ], + "network_types": { + "transport_types": { + "security4": 1 + }, + "http_types": { + "security4": 1 + } + } + } + }, + "stack_stats": { + "xpack": { + "security": { + "available": false, + "enabled": true, + "realms": { + "file": { + "available": false, + "enabled": false + }, + "ldap": { + "available": false, + "enabled": false + }, + "native": { + "available": false, + "enabled": false + }, + "active_directory": { + "available": false, + "enabled": false + }, + "pki": { + "available": false, + "enabled": false + } + }, + "roles": { + "native": { + "size": 1, + "dls": false, + "fls": false + }, + "file": { + "size": 0, + "dls": false, + "fls": false + } + }, + "role_mapping": { + "native": { + "size": 0, + "enabled": 0 + } + }, + "ssl": { + "http": { + "enabled": false + } + }, + "audit": { + "outputs": [ + "logfile" + ], + "enabled": false + }, + "ipfilter": { + "http": false, + "transport": false + }, + "anonymous": { + "enabled": false + } + }, + "monitoring": { + "available": true, + "enabled": true, + "enabled_exporters": { + "http": 1 + } + }, + "watcher": { + "available": false, + "enabled": true, + "execution": { + "actions": { + "_all": { + "total": 0, + "total_time_in_ms": 0 + } + } + } + }, + "graph": { + "available": false, + "enabled": true + }, + "ml": { + "available": false, + "enabled": true, + "jobs": { + "_all": { + "count": 0, + "detectors": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + }, + "model_size": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + } + } + }, + "datafeeds": { + "_all": { + "count": 0 + } + } + }, + "logstash": { + "available": false, + "enabled": true + }, + "ccr": { + "auto_follow_patterns_count": 0, + "available": true, + "follower_indices_count": 0, + "enabled": true + } + } + } + }, + { + "cluster_uuid": "lOF8kofiS_2DX58o9mXJ1Q", + "collectionSource": "monitoring", + "timestamp": "2017-08-15T22:10:54.610Z", + "cluster_name": "monitoring-one", + "version": "7.0.0-alpha1", + "license": { + "status": "active", + "type": "trial", + "issue_date": "2017-08-15T21:58:28.997Z", + "expiry_date": "2017-09-14T21:58:28.997Z", + "expiry_date_in_millis": 1505426308997, + "issue_date_in_millis": 1502834308997, + "issued_to": "monitoring-one", + "issuer": "elasticsearch", + "max_nodes": 1000, + "start_date_in_millis": -1, + "uid": "e5f6e897-0db5-4042-ad7c-6628ddc91691", + "hkey": null + }, + "cluster_stats": { + "timestamp": 1502835054610, + "status": "yellow", + "indices": { + "count": 8, + "shards": { + "total": 8, + "primaries": 8, + "replication": 0, + "index": { + "shards": { + "min": 1, + "max": 1, + "avg": 1 + }, + "primaries": { + "min": 1, + "max": 1, + "avg": 1 + }, + "replication": { + "min": 0, + "max": 0, + "avg": 0 + } + } + }, + "docs": { + "count": 3997, + "deleted": 69 + }, + "store": { + "size_in_bytes": 2647163 + }, + "fielddata": { + "memory_size_in_bytes": 2104, + "evictions": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 36, + "memory_in_bytes": 278961, + "terms_memory_in_bytes": 166031, + "stored_fields_memory_in_bytes": 11544, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 6784, + "points_memory_in_bytes": 3250, + "doc_values_memory_in_bytes": 91352, + "index_writer_memory_in_bytes": 205347, + "version_map_memory_in_bytes": 26362, + "fixed_bit_set_memory_in_bytes": 992, + "max_unsafe_auto_id_timestamp": -1, + "file_sizes": {} + } + }, + "nodes": { + "count": { + "total": 1, + "data": 1, + "coordinating_only": 0, + "master": 1, + "ingest": 1 + }, + "versions": [ + "7.0.0-alpha1" + ], + "os": { + "available_processors": 4, + "allocated_processors": 1, + "names": [ + { + "name": "Mac OS X", + "count": 1 + } + ], + "mem": { + "total_in_bytes": 17179869184, + "free_in_bytes": 86732800, + "used_in_bytes": 17093136384, + "free_percent": 1, + "used_percent": 99 + } + }, + "process": { + "cpu": { + "percent": 2 + }, + "open_file_descriptors": { + "min": 178, + "max": 178, + "avg": 178 + } + }, + "jvm": { + "max_uptime_in_millis": 761002, + "versions": [ + { + "vm_version": "25.121-b13", + "count": 1, + "vm_vendor": "Oracle Corporation", + "version": "1.8.0_121", + "vm_name": "Java HotSpot(TM) 64-Bit Server VM" + } + ], + "mem": { + "heap_used_in_bytes": 133041176, + "heap_max_in_bytes": 628555776 + }, + "threads": 42 + }, + "fs": { + "total_in_bytes": 499065712640, + "free_in_bytes": 200665792512, + "available_in_bytes": 200403648512 + }, + "plugins": [ + { + "classname": "org.elasticsearch.xpack.XPackPlugin", + "name": "x-pack", + "description": "Elasticsearch Expanded Pack Plugin", + "version": "7.0.0-alpha1", + "has_native_controller": true + } + ], + "network_types": { + "transport_types": { + "security4": 1 + }, + "http_types": { + "security4": 1 + } + } + } + }, + "stack_stats": { + "xpack": { + "security": { + "available": true, + "enabled": true, + "realms": { + "file": { + "name": [ + "default_file" + ], + "available": true, + "size": [ + 0 + ], + "enabled": true, + "order": [ + 2147483647 + ] + }, + "ldap": { + "available": true, + "enabled": false + }, + "native": { + "name": [ + "default_native" + ], + "available": true, + "size": [ + 2 + ], + "enabled": true, + "order": [ + 2147483647 + ] + }, + "active_directory": { + "available": true, + "enabled": false + }, + "pki": { + "available": true, + "enabled": false + } + }, + "roles": { + "native": { + "size": 1, + "dls": false, + "fls": false + }, + "file": { + "size": 0, + "dls": false, + "fls": false + } + }, + "role_mapping": { + "native": { + "size": 0, + "enabled": 0 + } + }, + "ssl": { + "http": { + "enabled": false + } + }, + "audit": { + "outputs": [ + "logfile" + ], + "enabled": false + }, + "ipfilter": { + "http": false, + "transport": false + }, + "anonymous": { + "enabled": false + } + }, + "monitoring": { + "available": true, + "enabled": true, + "enabled_exporters": { + "local": 1 + } + }, + "watcher": { + "available": true, + "enabled": true, + "execution": { + "actions": { + "index": { + "total": 14, + "total_time_in_ms": 158 + }, + "_all": { + "total": 110, + "total_time_in_ms": 2245 + }, + "email": { + "total": 14, + "total_time_in_ms": 3 + } + } + } + }, + "graph": { + "available": true, + "enabled": true + }, + "ml": { + "available": true, + "enabled": true, + "jobs": { + "_all": { + "count": 0, + "detectors": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + }, + "model_size": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + } + } + }, + "datafeeds": { + "_all": { + "count": 0 + } + } + }, + "logstash": { + "available": true, + "enabled": true + }, + "ccr": { + "auto_follow_patterns_count": 0, + "available": true, + "follower_indices_count": 0, + "enabled": true + } + } + } + }, + { + "cluster_uuid": "TkHOX_-1TzWwbROwQJU5IA", + "collectionSource": "monitoring", + "timestamp": "2017-08-15T22:10:52.642Z", + "cluster_name": "clusterone", + "version": "7.0.0-alpha1", + "license": { + "status": "active", + "type": "trial", + "issue_date": "2017-08-15T21:58:47.135Z", + "expiry_date": "2017-09-14T21:58:47.135Z", + "expiry_date_in_millis": 1505426327135, + "issue_date_in_millis": 1502834327135, + "issued_to": "clusterone", + "issuer": "elasticsearch", + "max_nodes": 1000, + "start_date_in_millis": -1, + "uid": "e5e99511-0928-41a3-97b0-ec77fa5e3b4c", + "hkey": null + }, + "cluster_stats": { + "timestamp": 1502835052641, + "status": "green", + "indices": { + "count": 5, + "shards": { + "total": 26, + "primaries": 13, + "replication": 1, + "index": { + "shards": { + "min": 2, + "max": 10, + "avg": 5.2 + }, + "primaries": { + "min": 1, + "max": 5, + "avg": 2.6 + }, + "replication": { + "min": 1, + "max": 1, + "avg": 1 + } + } + }, + "docs": { + "count": 150, + "deleted": 0 + }, + "store": { + "size_in_bytes": 4838464 + }, + "fielddata": { + "memory_size_in_bytes": 0, + "evictions": 0 + }, + "query_cache": { + "memory_size_in_bytes": 0, + "total_count": 0, + "hit_count": 0, + "miss_count": 0, + "cache_size": 0, + "cache_count": 0, + "evictions": 0 + }, + "completion": { + "size_in_bytes": 0 + }, + "segments": { + "count": 76, + "memory_in_bytes": 1907922, + "terms_memory_in_bytes": 1595112, + "stored_fields_memory_in_bytes": 23744, + "term_vectors_memory_in_bytes": 0, + "norms_memory_in_bytes": 197184, + "points_memory_in_bytes": 3818, + "doc_values_memory_in_bytes": 88064, + "index_writer_memory_in_bytes": 7006184, + "version_map_memory_in_bytes": 260, + "fixed_bit_set_memory_in_bytes": 0, + "max_unsafe_auto_id_timestamp": 1502834982386, + "file_sizes": {} + } + }, + "nodes": { + "count": { + "total": 2, + "data": 2, + "coordinating_only": 0, + "master": 2, + "ingest": 2 + }, + "versions": [ + "7.0.0-alpha1" + ], + "os": { + "available_processors": 8, + "allocated_processors": 2, + "names": [ + { + "name": "Mac OS X", + "count": 2 + } + ], + "mem": { + "total_in_bytes": 34359738368, + "free_in_bytes": 332099584, + "used_in_bytes": 34027638784, + "free_percent": 1, + "used_percent": 99 + } + }, + "process": { + "cpu": { + "percent": 2 + }, + "open_file_descriptors": { + "min": 218, + "max": 237, + "avg": 227 + } + }, + "jvm": { + "max_uptime_in_millis": 741786, + "versions": [ + { + "vm_version": "25.121-b13", + "count": 2, + "vm_vendor": "Oracle Corporation", + "version": "1.8.0_121", + "vm_name": "Java HotSpot(TM) 64-Bit Server VM" + } + ], + "mem": { + "heap_used_in_bytes": 465621856, + "heap_max_in_bytes": 1257111552 + }, + "threads": 92 + }, + "fs": { + "total_in_bytes": 499065712640, + "free_in_bytes": 200666353664, + "available_in_bytes": 200404209664 + }, + "plugins": [ + { + "classname": "org.elasticsearch.xpack.XPackPlugin", + "name": "x-pack", + "description": "Elasticsearch Expanded Pack Plugin", + "version": "7.0.0-alpha1", + "has_native_controller": true + } + ], + "network_types": { + "transport_types": { + "security4": 2 + }, + "http_types": { + "security4": 2 + } + } + } + }, + "stack_stats": { + "xpack": { + "security": { + "available": true, + "enabled": true, + "realms": { + "file": { + "name": [ + "default_file" + ], + "available": true, + "size": [ + 0 + ], + "enabled": true, + "order": [ + 2147483647 + ] + }, + "ldap": { + "available": true, + "enabled": false + }, + "native": { + "name": [ + "default_native" + ], + "available": true, + "size": [ + 1 + ], + "enabled": true, + "order": [ + 2147483647 + ] + }, + "active_directory": { + "available": true, + "enabled": false + }, + "pki": { + "available": true, + "enabled": false + } + }, + "roles": { + "native": { + "size": 1, + "dls": false, + "fls": false + }, + "file": { + "size": 0, + "dls": false, + "fls": false + } + }, + "role_mapping": { + "native": { + "size": 0, + "enabled": 0 + } + }, + "ssl": { + "http": { + "enabled": false + } + }, + "audit": { + "outputs": [ + "logfile" + ], + "enabled": false + }, + "ipfilter": { + "http": false, + "transport": false + }, + "anonymous": { + "enabled": false + } + }, + "monitoring": { + "available": true, + "enabled": true, + "enabled_exporters": { + "http": 1 + } + }, + "watcher": { + "available": true, + "enabled": true, + "execution": { + "actions": { + "_all": { + "total": 0, + "total_time_in_ms": 0 + } + } + } + }, + "graph": { + "available": true, + "enabled": true, + "graph_workspace": { + "total": 0 + } + }, + "ml": { + "available": true, + "enabled": true, + "jobs": { + "_all": { + "count": 3, + "detectors": { + "total": 3, + "min": 1, + "avg": 1, + "max": 1 + }, + "model_size": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + } + }, + "opened": { + "count": 1, + "detectors": { + "total": 1, + "min": 1, + "avg": 1, + "max": 1 + }, + "model_size": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + } + }, + "closed": { + "count": 2, + "detectors": { + "total": 2, + "min": 1, + "avg": 1, + "max": 1 + }, + "model_size": { + "total": 0, + "min": 0, + "avg": 0, + "max": 0 + } + } + }, + "datafeeds": { + "_all": { + "count": 0 + } + } + }, + "logstash": { + "available": true, + "enabled": true + }, + "ccr": { + "auto_follow_patterns_count": 0, + "available": true, + "follower_indices_count": 0, + "enabled": true + } + }, + "kibana": { + "count": 1, + "versions": [ + { + "version": "7.0.0-alpha1", + "count": 1 + } + ], + "os": { + "platforms": [], + "platformReleases": [], + "distros": [], + "distroReleases": [] + }, + "dashboard": { + "total": 0 + }, + "visualization": { + "total": 0 + }, + "search": { + "total": 0 + }, + "index_pattern": { + "total": 0 + }, + "graph_workspace": { + "total": 0 + }, + "timelion_sheet": { + "total": 0 + }, + "indices": 1, + "plugins": {} + }, + "logstash": { + "count": 1, + "versions": [ + { + "version": "7.0.0-alpha1", + "count": 1 + } + ], + "os": { + "platforms": [], + "platformReleases": [], + "distros": [], + "distroReleases": [] + } + } + } + } +] From 900a8290fb9b544e958089adc03aeee34786b7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Tue, 25 Feb 2020 11:52:37 +0100 Subject: [PATCH 27/73] [Logs UI] Unskip and stabilitize log column configuration tests (#58392) This attempts to make the log column configuration tests more robust to inconsistent DOM and interaction timing. fixes #58059 --- .../apps/infra/logs_source_configuration.ts | 3 +- .../infra_source_configuration_form.ts | 30 +++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/x-pack/test/functional/apps/infra/logs_source_configuration.ts b/x-pack/test/functional/apps/infra/logs_source_configuration.ts index 1dfbe3526ce409..ecad5a40ec42e9 100644 --- a/x-pack/test/functional/apps/infra/logs_source_configuration.ts +++ b/x-pack/test/functional/apps/infra/logs_source_configuration.ts @@ -15,8 +15,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const pageObjects = getPageObjects(['common', 'infraLogs']); const retry = getService('retry'); - // FLAKY: https://github.com/elastic/kibana/issues/58059 - describe.skip('Logs Source Configuration', function() { + describe('Logs Source Configuration', function() { this.tags('smoke'); before(async () => { diff --git a/x-pack/test/functional/services/infra_source_configuration_form.ts b/x-pack/test/functional/services/infra_source_configuration_form.ts index ab61d5232fa1c7..dbae6f00f75a22 100644 --- a/x-pack/test/functional/services/infra_source_configuration_form.ts +++ b/x-pack/test/functional/services/infra_source_configuration_form.ts @@ -36,25 +36,37 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider return await testSubjects.find('~addLogColumnPopover'); }, async addTimestampLogColumn() { - await (await this.getAddLogColumnButton()).click(); + // try to open the popover + const popover = await retry.try(async () => { + await (await this.getAddLogColumnButton()).click(); + return this.getAddLogColumnPopover(); + }); + + // try to select the timestamp field await retry.try(async () => { - await ( - await testSubjects.findDescendant( - '~addTimestampLogColumn', - await this.getAddLogColumnPopover() - ) - ).click(); + await (await testSubjects.findDescendant('~addTimestampLogColumn', popover)).click(); }); + + // wait for timestamp panel to show up + await testSubjects.findDescendant('~systemLogColumnPanel:Timestamp', await this.getForm()); }, async addFieldLogColumn(fieldName: string) { - await (await this.getAddLogColumnButton()).click(); + // try to open the popover + const popover = await retry.try(async () => { + await (await this.getAddLogColumnButton()).click(); + return this.getAddLogColumnPopover(); + }); + + // try to select the given field await retry.try(async () => { - const popover = await this.getAddLogColumnPopover(); await (await testSubjects.findDescendant('~fieldSearchInput', popover)).type(fieldName); await ( await testSubjects.findDescendant(`~addFieldLogColumn:${fieldName}`, popover) ).click(); }); + + // wait for field panel to show up + await testSubjects.findDescendant(`~fieldLogColumnPanel:${fieldName}`, await this.getForm()); }, async getLogColumnPanels(): Promise { return await testSubjects.findAllDescendant('~logColumnPanel', await this.getForm()); From 31cc2015b73e1035acf409373890ffef7d475b60 Mon Sep 17 00:00:00 2001 From: David Roberts Date: Tue, 25 Feb 2020 12:18:35 +0000 Subject: [PATCH 28/73] [ML] Use event.timezone instead of beat.timezone in file upload (#58447) This is because beat.timezone was renamed to event.timezone in elastic/beats#9458 The corresponding file structure finder change is elastic/elasticsearch#52720 --- .../components/import_view/importer/importer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/importer.js b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/importer.js index 710fa49e641679..27899a58beed2f 100644 --- a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/importer.js +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/importer.js @@ -148,17 +148,17 @@ function populateFailures(error, failures, chunkCount) { } } -// The file structure endpoint sets the timezone to be {{ beat.timezone }} +// The file structure endpoint sets the timezone to be {{ event.timezone }} // as that's the variable Filebeat would send the client timezone in. // In this data import function the UI is effectively performing the role of Filebeat, // i.e. doing basic parsing, processing and conversion to JSON before forwarding to the ingest pipeline. // But it's not sending every single field that Filebeat would add, so the ingest pipeline -// cannot look for a beat.timezone variable in each input record. -// Therefore we need to replace {{ beat.timezone }} with the actual browser timezone +// cannot look for a event.timezone variable in each input record. +// Therefore we need to replace {{ event.timezone }} with the actual browser timezone function updatePipelineTimezone(ingestPipeline) { if (ingestPipeline !== undefined && ingestPipeline.processors && ingestPipeline.processors) { const dateProcessor = ingestPipeline.processors.find( - p => p.date !== undefined && p.date.timezone === '{{ beat.timezone }}' + p => p.date !== undefined && p.date.timezone === '{{ event.timezone }}' ); if (dateProcessor) { From 6fc6cb8b363b4a1ea7e07ce8d491874ca4fbb864 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Tue, 25 Feb 2020 13:22:29 +0100 Subject: [PATCH 29/73] [ML] Functional tests - adjust classification model memory (#58445) This PR increases the model memory setting in the classification creation test. --- .../data_frame_analytics/classification_creation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/machine_learning/data_frame_analytics/classification_creation.ts b/x-pack/test/functional/apps/machine_learning/data_frame_analytics/classification_creation.ts index 798a04cae37405..1bcdeef394c002 100644 --- a/x-pack/test/functional/apps/machine_learning/data_frame_analytics/classification_creation.ts +++ b/x-pack/test/functional/apps/machine_learning/data_frame_analytics/classification_creation.ts @@ -36,7 +36,7 @@ export default function({ getService }: FtrProviderContext) { }, dependentVariable: 'y', trainingPercent: '20', - modelMemory: '105mb', + modelMemory: '200mb', createIndexPattern: true, expected: { row: { From db276d18945246421068e480c7dd5322487cb276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez?= Date: Tue, 25 Feb 2020 13:39:13 +0100 Subject: [PATCH 30/73] =?UTF-8?q?[Logs=20/=20Metrics=20UI]=20Remove=20path?= =?UTF-8?q?=20prefix=20from=20ViewSourceConfigur=E2=80=A6=20(#58238)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the NP the routes have already the app name on them. Adding it to this button made the app name double /app/metrics/metrics/settings /app/logs/logs/settings The button only needs to go to the settings page within the app where it's being loaded, so we can safely drop the prefix. Closes #58233 --- .../public/components/source_configuration/index.ts | 5 +---- .../view_source_configuration_button.tsx | 9 +-------- .../public/pages/infrastructure/snapshot/index.tsx | 10 ++-------- .../pages/logs/stream/page_no_indices_content.tsx | 10 ++-------- .../public/pages/metrics/components/invalid_node.tsx | 10 ++-------- 5 files changed, 8 insertions(+), 36 deletions(-) diff --git a/x-pack/plugins/infra/public/components/source_configuration/index.ts b/x-pack/plugins/infra/public/components/source_configuration/index.ts index 4879a53ca329d6..98825567cc204b 100644 --- a/x-pack/plugins/infra/public/components/source_configuration/index.ts +++ b/x-pack/plugins/infra/public/components/source_configuration/index.ts @@ -5,7 +5,4 @@ */ export { SourceConfigurationSettings } from './source_configuration_settings'; -export { - ViewSourceConfigurationButton, - ViewSourceConfigurationButtonHrefBase, -} from './view_source_configuration_button'; +export { ViewSourceConfigurationButton } from './view_source_configuration_button'; diff --git a/x-pack/plugins/infra/public/components/source_configuration/view_source_configuration_button.tsx b/x-pack/plugins/infra/public/components/source_configuration/view_source_configuration_button.tsx index 9b584b2ef3bd0b..9c3a40fb7ecf08 100644 --- a/x-pack/plugins/infra/public/components/source_configuration/view_source_configuration_button.tsx +++ b/x-pack/plugins/infra/public/components/source_configuration/view_source_configuration_button.tsx @@ -8,23 +8,16 @@ import { EuiButton } from '@elastic/eui'; import React from 'react'; import { Route } from 'react-router-dom'; -export enum ViewSourceConfigurationButtonHrefBase { - infrastructure = 'infrastructure', - logs = 'logs', -} - interface ViewSourceConfigurationButtonProps { 'data-test-subj'?: string; - hrefBase: ViewSourceConfigurationButtonHrefBase; children: React.ReactNode; } export const ViewSourceConfigurationButton = ({ 'data-test-subj': dataTestSubj, - hrefBase, children, }: ViewSourceConfigurationButtonProps) => { - const href = `/${hrefBase}/settings`; + const href = '/settings'; return ( {
{uiCapabilities?.infrastructure?.configureSource ? ( - + {i18n.translate('xpack.infra.configureSourceActionLabel', { defaultMessage: 'Change source configuration', })} diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_no_indices_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_no_indices_content.tsx index 1294007240027b..739bad5689a96f 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_no_indices_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_no_indices_content.tsx @@ -10,10 +10,7 @@ import { identity } from 'fp-ts/lib/function'; import React from 'react'; import { NoIndices } from '../../../components/empty_states/no_indices'; -import { - ViewSourceConfigurationButton, - ViewSourceConfigurationButtonHrefBase, -} from '../../../components/source_configuration'; +import { ViewSourceConfigurationButton } from '../../../components/source_configuration'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; export const LogsPageNoIndicesContent = () => { @@ -49,10 +46,7 @@ export const LogsPageNoIndicesContent = () => { {canConfigureSource ? ( - + {i18n.translate('xpack.infra.configureSourceActionLabel', { defaultMessage: 'Change source configuration', })} diff --git a/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx b/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx index fde3b61de50b58..43f684cd5a5853 100644 --- a/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/components/invalid_node.tsx @@ -10,10 +10,7 @@ import { identity } from 'fp-ts/lib/function'; import React from 'react'; import { euiStyled } from '../../../../../observability/public'; -import { - ViewSourceConfigurationButton, - ViewSourceConfigurationButtonHrefBase, -} from '../../../components/source_configuration'; +import { ViewSourceConfigurationButton } from '../../../components/source_configuration'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; interface InvalidNodeErrorProps { @@ -59,10 +56,7 @@ export const InvalidNodeError: React.FunctionComponent = - + Date: Tue, 25 Feb 2020 07:18:04 -0600 Subject: [PATCH 31/73] [Uptime] Improve refresh handling when generating test data (#58285) When generating test data we refresh excessively, this can fill up the ES queues and break the tests if we run massive tests. I originally ran into this with https://github.com/elastic/kibana/pull/58078/ which I closed due to finding a better approach. While none of our current tests have the scale to expose this problem, we certainly will add tests that do later, so we should keep this change. Co-authored-by: Elastic Machine --- .../uptime/graphql/helpers/make_checks.ts | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/x-pack/test/api_integration/apis/uptime/graphql/helpers/make_checks.ts b/x-pack/test/api_integration/apis/uptime/graphql/helpers/make_checks.ts index f89905f0da04fe..4d3167b14b86f2 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/helpers/make_checks.ts +++ b/x-pack/test/api_integration/apis/uptime/graphql/helpers/make_checks.ts @@ -13,7 +13,8 @@ export const makePing = async ( es: any, monitorId: string, fields: { [key: string]: any }, - mogrify: (doc: any) => any + mogrify: (doc: any) => any, + refresh: boolean = true ) => { const baseDoc = { tcp: { @@ -103,7 +104,7 @@ export const makePing = async ( await es.index({ index: INDEX_NAME, - refresh: true, + refresh, body: doc, }); @@ -115,7 +116,8 @@ export const makeCheck = async ( monitorId: string, numIps: number, fields: { [key: string]: any }, - mogrify: (doc: any) => any + mogrify: (doc: any) => any, + refresh: boolean = true ) => { const cgFields = { monitor: { @@ -137,11 +139,16 @@ export const makeCheck = async ( if (i === numIps - 1) { pingFields.summary = summary; } - const doc = await makePing(es, monitorId, pingFields, mogrify); + const doc = await makePing(es, monitorId, pingFields, mogrify, false); docs.push(doc); // @ts-ignore summary[doc.monitor.status]++; } + + if (refresh) { + es.indices.refresh(); + } + return docs; }; @@ -152,7 +159,8 @@ export const makeChecks = async ( numIps: number, every: number, // number of millis between checks fields: { [key: string]: any } = {}, - mogrify: (doc: any) => any = d => d + mogrify: (doc: any) => any = d => d, + refresh: boolean = true ) => { const checks = []; const oldestTime = new Date().getTime() - numChecks * every; @@ -169,7 +177,11 @@ export const makeChecks = async ( }, }, }); - checks.push(await makeCheck(es, monitorId, numIps, fields, mogrify)); + checks.push(await makeCheck(es, monitorId, numIps, fields, mogrify, false)); + } + + if (refresh) { + es.indices.refresh(); } return checks; @@ -183,19 +195,29 @@ export const makeChecksWithStatus = async ( every: number, fields: { [key: string]: any } = {}, status: 'up' | 'down', - mogrify: (doc: any) => any = d => d + mogrify: (doc: any) => any = d => d, + refresh: boolean = true ) => { const oppositeStatus = status === 'up' ? 'down' : 'up'; - return await makeChecks(es, monitorId, numChecks, numIps, every, fields, d => { - d.monitor.status = status; - if (d.summary) { - d.summary[status] += d.summary[oppositeStatus]; - d.summary[oppositeStatus] = 0; - } - - return mogrify(d); - }); + return await makeChecks( + es, + monitorId, + numChecks, + numIps, + every, + fields, + d => { + d.monitor.status = status; + if (d.summary) { + d.summary[status] += d.summary[oppositeStatus]; + d.summary[oppositeStatus] = 0; + } + + return mogrify(d); + }, + refresh + ); }; // Helper for processing a list of checks to find the time picker bounds. From b756cc3915fe62d405f006fd32bf8678f4c5e402 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 25 Feb 2020 13:39:50 +0000 Subject: [PATCH 32/73] [ML] Adding filebeat config to file dataviz (#58152) * [ML] Adding filebeat config to file dataviz * adding extra help text * removing commented out code * adding extra blank line to processors section * cleaning up types * moving hosts line out of function * typo in config text * updating config based on review * tiny refactor * translating paths text --- .../ml/common/types/file_datavisualizer.ts | 31 +++ .../plugins/ml/public/application/app.tsx | 4 + .../contexts/kibana/kibana_context.ts | 2 + .../filebeat_config_flyout/filebeat_config.ts | 71 +++++++ .../filebeat_config_flyout.tsx | 162 +++++++++++++++ .../filebeat_config_flyout/index.ts | 7 + .../components/import_view/import_view.js | 24 +++ .../import_view/importer/message_importer.js | 5 + .../results_links/{index.js => index.ts} | 0 .../components/results_links/results_links.js | 182 ----------------- .../results_links/results_links.tsx | 190 ++++++++++++++++++ .../application/util/dependency_cache.ts | 10 + x-pack/legacy/plugins/ml/public/legacy.ts | 4 +- x-pack/legacy/plugins/ml/public/plugin.ts | 3 +- .../file_data_visualizer.ts | 27 +-- 15 files changed, 513 insertions(+), 209 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/common/types/file_datavisualizer.ts create mode 100644 x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config.ts create mode 100644 x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config_flyout.tsx create mode 100644 x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/index.ts rename x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/{index.js => index.ts} (100%) delete mode 100644 x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.js create mode 100644 x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.tsx diff --git a/x-pack/legacy/plugins/ml/common/types/file_datavisualizer.ts b/x-pack/legacy/plugins/ml/common/types/file_datavisualizer.ts new file mode 100644 index 00000000000000..bc03f82673a1fe --- /dev/null +++ b/x-pack/legacy/plugins/ml/common/types/file_datavisualizer.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface FindFileStructureResponse { + charset: string; + has_header_row: boolean; + has_byte_order_marker: boolean; + format: string; + field_stats: { + [fieldName: string]: { + count: number; + cardinality: number; + top_hits: Array<{ count: number; value: any }>; + }; + }; + sample_start: string; + num_messages_analyzed: number; + mappings: { + [fieldName: string]: { + type: string; + }; + }; + quote: string; + delimiter: string; + need_client_timezone: boolean; + num_lines_analyzed: number; + column_names: string[]; +} diff --git a/x-pack/legacy/plugins/ml/public/application/app.tsx b/x-pack/legacy/plugins/ml/public/application/app.tsx index 24cbfbfb346dd5..add27193deb77d 100644 --- a/x-pack/legacy/plugins/ml/public/application/app.tsx +++ b/x-pack/legacy/plugins/ml/public/application/app.tsx @@ -12,6 +12,7 @@ import 'ace'; import { AppMountParameters, CoreStart } from 'kibana/public'; import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { SecurityPluginSetup } from '../../../../../plugins/security/public'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import { setDependencyCache, clearCache } from './util/dependency_cache'; @@ -20,6 +21,7 @@ import { MlRouter } from './routing'; export interface MlDependencies extends AppMountParameters { data: DataPublicPluginStart; + security: SecurityPluginSetup; __LEGACY: { XSRF: string; APP_URL: string; @@ -49,6 +51,7 @@ const App: FC = ({ coreStart, deps }) => { APP_URL: deps.__LEGACY.APP_URL, application: coreStart.application, http: coreStart.http, + security: deps.security, }); deps.onAppLeave(actions => { clearCache(); @@ -64,6 +67,7 @@ const App: FC = ({ coreStart, deps }) => { const services = { appName: 'ML', data: deps.data, + security: deps.security, ...coreStart, }; diff --git a/x-pack/legacy/plugins/ml/public/application/contexts/kibana/kibana_context.ts b/x-pack/legacy/plugins/ml/public/application/contexts/kibana/kibana_context.ts index aaf539322809b9..5fcd7c5473d3bc 100644 --- a/x-pack/legacy/plugins/ml/public/application/contexts/kibana/kibana_context.ts +++ b/x-pack/legacy/plugins/ml/public/application/contexts/kibana/kibana_context.ts @@ -10,9 +10,11 @@ import { useKibana, KibanaReactContextValue, } from '../../../../../../../../src/plugins/kibana_react/public'; +import { SecurityPluginSetup } from '../../../../../../../plugins/security/public'; interface StartPlugins { data: DataPublicPluginStart; + security: SecurityPluginSetup; } export type StartServices = CoreStart & StartPlugins; // eslint-disable-next-line react-hooks/rules-of-hooks diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config.ts b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config.ts new file mode 100644 index 00000000000000..3344cdf991e6b9 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config.ts @@ -0,0 +1,71 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { FindFileStructureResponse } from '../../../../../../common/types/file_datavisualizer'; + +export function createFilebeatConfig( + index: string, + results: FindFileStructureResponse, + ingestPipelineId: string, + username: string | null +) { + return [ + 'filebeat.inputs:', + '- type: log', + ...getPaths(), + ...getEncoding(results), + ...getExcludeLines(results), + ...getMultiline(results), + '', + ...getProcessors(results), + 'output.elasticsearch:', + ' hosts: [""]', + ...getUserDetails(username), + ` index: "${index}"`, + ` pipeline: "${ingestPipelineId}"`, + '', + 'setup:', + ' template.enabled: false', + ' ilm.enabled: false', + ].join('\n'); +} + +function getPaths() { + const txt = i18n.translate('xpack.ml.fileDatavisualizer.fileBeatConfig.paths', { + defaultMessage: 'add path to your files here', + }); + return [' paths:', ` - '<${txt}>'`]; +} + +function getEncoding(results: any) { + return results.charset !== 'UTF-8' ? [` encoding: ${results.charset}`] : []; +} + +function getExcludeLines(results: any) { + return results.exclude_lines_pattern !== undefined + ? [` exclude_lines: ['${results.exclude_lines_pattern.replace(/'/g, "''")}']`] + : []; +} + +function getMultiline(results: any) { + return results.multiline_start_pattern !== undefined + ? [ + ' multiline:', + ` pattern: '${results.multiline_start_pattern.replace(/'/g, "''")}'`, + ' match: after', + ' negate: true', + ] + : []; +} + +function getProcessors(results: any) { + return results.need_client_timezone === true ? ['processors:', '- add_locale: ~', ''] : []; +} + +function getUserDetails(username: string | null) { + return username !== null ? [` username: "${username}"`, ' password: ""'] : []; +} diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config_flyout.tsx b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config_flyout.tsx new file mode 100644 index 00000000000000..30fc74acbabf49 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/filebeat_config_flyout.tsx @@ -0,0 +1,162 @@ +/* + * 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. + */ +/* + * 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, { FC, useState, useEffect } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + EuiFlyout, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiButtonEmpty, + EuiTitle, + EuiFlyoutBody, + EuiSpacer, + EuiCodeBlock, + EuiCode, + EuiCopy, +} from '@elastic/eui'; +import { createFilebeatConfig } from './filebeat_config'; +import { useMlKibana } from '../../../../contexts/kibana'; +import { FindFileStructureResponse } from '../../../../../../common/types/file_datavisualizer'; + +export enum EDITOR_MODE { + HIDDEN, + READONLY, + EDITABLE, +} +interface Props { + index: string; + results: FindFileStructureResponse; + indexPatternId: string; + ingestPipelineId: string; + closeFlyout(): void; +} +export const FilebeatConfigFlyout: FC = ({ + index, + results, + indexPatternId, + ingestPipelineId, + closeFlyout, +}) => { + const [fileBeatConfig, setFileBeatConfig] = useState(''); + const [username, setUsername] = useState(null); + const { + services: { security }, + } = useMlKibana(); + + useEffect(() => { + security.authc.getCurrentUser().then(user => { + setUsername(user.username === undefined ? null : user.username); + }); + }, []); + + useEffect(() => { + const config = createFilebeatConfig(index, results, ingestPipelineId, username); + setFileBeatConfig(config); + }, [username]); + + return ( + + + + + + + + + + + + + + + + {copy => ( + + + + )} + + + + + + ); +}; + +const Contents: FC<{ + value: string; + index: string; + username: string | null; +}> = ({ value, index, username }) => { + return ( + + +
+ +
+
+ +

+ {index} }} + /> +

+

+ filebeat.yml }} + /> +

+ + + + {value} + + +

+ {username === null ? ( + {''}, + }} + /> + ) : ( + {username}, + password: {''}, + esUrl: {''}, + }} + /> + )} +

+
+ ); +}; diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/index.ts b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/index.ts new file mode 100644 index 00000000000000..9286b92c2ab97c --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/filebeat_config_flyout/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { FilebeatConfigFlyout } from './filebeat_config_flyout'; diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/import_view.js b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/import_view.js index beb5918e277aed..bdfc27099a1853 100644 --- a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/import_view.js +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/import_view.js @@ -20,6 +20,7 @@ import { import { i18n } from '@kbn/i18n'; import { importerFactory } from './importer'; import { ResultsLinks } from '../results_links'; +import { FilebeatConfigFlyout } from '../filebeat_config_flyout'; import { ImportProgress, IMPORT_STATUS } from '../import_progress'; import { ImportErrors } from '../import_errors'; import { ImportSummary } from '../import_summary'; @@ -64,6 +65,7 @@ const DEFAULT_STATE = { indexNameError: '', indexPatternNameError: '', timeFieldName: undefined, + isFilebeatFlyoutVisible: false, }; export class ImportView extends Component { @@ -384,6 +386,16 @@ export class ImportView extends Component { }); }; + showFilebeatFlyout = () => { + this.setState({ isFilebeatFlyoutVisible: true }); + this.props.hideBottomBar(); + }; + + closeFilebeatFlyout = () => { + this.setState({ isFilebeatFlyoutVisible: false }); + this.props.showBottomBar(); + }; + async loadIndexNames() { const indices = await ml.getIndices(); const indexNames = indices.map(i => i.name); @@ -424,6 +436,7 @@ export class ImportView extends Component { indexNameError, indexPatternNameError, timeFieldName, + isFilebeatFlyoutVisible, } = this.state; const createPipeline = pipelineString !== ''; @@ -549,7 +562,18 @@ export class ImportView extends Component { indexPatternId={indexPatternId} timeFieldName={timeFieldName} createIndexPattern={createIndexPattern} + showFilebeatFlyout={this.showFilebeatFlyout} /> + + {isFilebeatFlyoutVisible && ( + + )} )} diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/message_importer.js b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/message_importer.js index 840248817945a2..c2d3ac69f0963f 100644 --- a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/message_importer.js +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/import_view/importer/message_importer.js @@ -77,6 +77,11 @@ export class MessageImporter extends Importer { if (this.multilineStartRegex === null || line.match(this.multilineStartRegex) !== null) { this.addMessage(data, message); message = ''; + } else if (data.length === 0) { + // discard everything before the first line that is considered the first line of a message + // as it could be left over partial data from a spilt or rolled over log, + // or could be a blank line after the header in a csv file + return ''; } else { message += '\n'; } diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/index.js b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/index.ts similarity index 100% rename from x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/index.js rename to x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/index.ts diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.js b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.js deleted file mode 100644 index aaebca2f58963a..00000000000000 --- a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.js +++ /dev/null @@ -1,182 +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 { FormattedMessage } from '@kbn/i18n/react'; -import React, { Component } from 'react'; - -import { EuiFlexGroup, EuiFlexItem, EuiCard, EuiIcon } from '@elastic/eui'; - -import moment from 'moment'; - -import { ml } from '../../../../services/ml_api_service'; -import { isFullLicense } from '../../../../license/check_license'; -import { checkPermission } from '../../../../privilege/check_privilege'; -import { mlNodesAvailable } from '../../../../ml_nodes_check/check_ml_nodes'; -import { withKibana } from '../../../../../../../../../../src/plugins/kibana_react/public'; - -const RECHECK_DELAY_MS = 3000; - -class ResultsLinksUI extends Component { - constructor(props) { - super(props); - - this.state = { - from: 'now-30m', - to: 'now', - }; - - this.recheckTimeout = null; - this.showCreateJobLink = true; - } - - componentDidMount() { - this.showCreateJobLink = checkPermission('canCreateJob') && mlNodesAvailable(); - // if this data has a time field, - // find the start and end times - if (this.props.timeFieldName !== undefined) { - this.updateTimeValues(); - } - } - - componentWillUnmount() { - clearTimeout(this.recheckTimeout); - } - - async updateTimeValues(recheck = true) { - const { index, timeFieldName } = this.props; - - const { from, to } = await getFullTimeRange(index, timeFieldName); - this.setState({ - from: from === null ? this.state.from : from, - to: to === null ? this.state.to : to, - }); - - // these links may have been drawn too quickly for the index to be ready - // to give us the correct start and end times. - // especially if the data was small. - // so if the start and end were null, try again in 3s - // the timeout is cleared when this component unmounts. just in case the user - // resets the form or navigates away within 3s - if (recheck && (from === null || to === null)) { - this.recheckTimeout = setTimeout(() => { - this.updateTimeValues(false); - }, RECHECK_DELAY_MS); - } - } - - render() { - const { index, indexPatternId, timeFieldName, createIndexPattern } = this.props; - - const { from, to } = this.state; - - const _g = - this.props.timeFieldName !== undefined - ? `&_g=(time:(from:'${from}',mode:quick,to:'${to}'))` - : ''; - - const { basePath } = this.props.kibana.services.http; - return ( - - {createIndexPattern && ( - - } - title={ - - } - description="" - href={`${basePath.get()}/app/kibana#/discover?&_a=(index:'${indexPatternId}')${_g}`} - /> - - )} - - {isFullLicense() === true && - timeFieldName !== undefined && - this.showCreateJobLink && - createIndexPattern && ( - - } - title={ - - } - description="" - href={`#/jobs/new_job/step/job_type?index=${indexPatternId}${_g}`} - /> - - )} - - {createIndexPattern && ( - - } - title={ - - } - description="" - href={`#/jobs/new_job/datavisualizer?index=${indexPatternId}${_g}`} - /> - - )} - - - } - title={ - - } - description="" - href={`${basePath.get()}/app/kibana#/management/elasticsearch/index_management/indices/filter/${index}`} - /> - - - - } - title={ - - } - description="" - href={`${basePath.get()}/app/kibana#/management/kibana/index_patterns/${ - createIndexPattern ? indexPatternId : '' - }`} - /> - - - ); - } -} - -export const ResultsLinks = withKibana(ResultsLinksUI); - -async function getFullTimeRange(index, timeFieldName) { - const query = { bool: { must: [{ query_string: { analyze_wildcard: true, query: '*' } }] } }; - const resp = await ml.getTimeFieldRange({ - index, - timeFieldName, - query, - }); - - return { - from: moment(resp.start.epoch).toISOString(), - to: moment(resp.end.epoch).toISOString(), - }; -} diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.tsx b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.tsx new file mode 100644 index 00000000000000..debadba19051b7 --- /dev/null +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/components/results_links/results_links.tsx @@ -0,0 +1,190 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { FC, useState, useEffect } from 'react'; +import moment from 'moment'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiFlexGroup, EuiFlexItem, EuiCard, EuiIcon } from '@elastic/eui'; +import { ml } from '../../../../services/ml_api_service'; +import { isFullLicense } from '../../../../license/check_license'; +import { checkPermission } from '../../../../privilege/check_privilege'; +import { mlNodesAvailable } from '../../../../ml_nodes_check/check_ml_nodes'; +import { useMlKibana } from '../../../../contexts/kibana'; + +const RECHECK_DELAY_MS = 3000; + +interface Props { + index: string; + indexPatternId: string; + timeFieldName?: string; + createIndexPattern: boolean; + showFilebeatFlyout(): void; +} + +export const ResultsLinks: FC = ({ + index, + indexPatternId, + timeFieldName, + createIndexPattern, + showFilebeatFlyout, +}) => { + const [duration, setDuration] = useState({ + from: 'now-30m', + to: 'now', + }); + const [showCreateJobLink, setShowCreateJobLink] = useState(false); + const [globalStateString, setGlobalStateString] = useState(''); + const { + services: { + http: { basePath }, + }, + } = useMlKibana(); + + useEffect(() => { + setShowCreateJobLink(checkPermission('canCreateJob') && mlNodesAvailable()); + updateTimeValues(); + }, []); + + useEffect(() => { + const _g = + timeFieldName !== undefined + ? `&_g=(time:(from:'${duration.from}',mode:quick,to:'${duration.to}'))` + : ''; + setGlobalStateString(_g); + }, [duration]); + + async function updateTimeValues(recheck = true) { + if (timeFieldName !== undefined) { + const { from, to } = await getFullTimeRange(index, timeFieldName); + setDuration({ + from: from === null ? duration.from : from, + to: to === null ? duration.to : to, + }); + + // these links may have been drawn too quickly for the index to be ready + // to give us the correct start and end times. + // especially if the data was small. + // so if the start and end were null, try again in 3s + if (recheck && (from === null || to === null)) { + setTimeout(() => { + updateTimeValues(false); + }, RECHECK_DELAY_MS); + } + } + } + + return ( + + {createIndexPattern && ( + + } + title={ + + } + description="" + href={`${basePath.get()}/app/kibana#/discover?&_a=(index:'${indexPatternId}')${globalStateString}`} + /> + + )} + + {isFullLicense() === true && + timeFieldName !== undefined && + showCreateJobLink && + createIndexPattern && ( + + } + title={ + + } + description="" + href={`#/jobs/new_job/step/job_type?index=${indexPatternId}${globalStateString}`} + /> + + )} + + {createIndexPattern && ( + + } + title={ + + } + description="" + href={`#/jobs/new_job/datavisualizer?index=${indexPatternId}${globalStateString}`} + /> + + )} + + + } + title={ + + } + description="" + href={`${basePath.get()}/app/kibana#/management/elasticsearch/index_management/indices/filter/${index}`} + /> + + + + } + title={ + + } + description="" + href={`${basePath.get()}/app/kibana#/management/kibana/index_patterns/${ + createIndexPattern ? indexPatternId : '' + }`} + /> + + + } + title={ + + } + description="" + onClick={showFilebeatFlyout} + /> + + + ); +}; + +async function getFullTimeRange(index: string, timeFieldName: string) { + const query = { bool: { must: [{ query_string: { analyze_wildcard: true, query: '*' } }] } }; + const resp = await ml.getTimeFieldRange({ + index, + timeFieldName, + query, + }); + + return { + from: moment(resp.start.epoch).toISOString(), + to: moment(resp.end.epoch).toISOString(), + }; +} diff --git a/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts index 8857485a586441..f837d90dba8fe9 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts @@ -20,6 +20,7 @@ import { ChromeRecentlyAccessed, IBasePath, } from 'kibana/public'; +import { SecurityPluginSetup } from '../../../../../../plugins/security/public'; export interface DependencyCache { timefilter: TimefilterSetup | null; @@ -38,6 +39,7 @@ export interface DependencyCache { APP_URL: string | null; application: ApplicationStart | null; http: HttpStart | null; + security: SecurityPluginSetup | null; } const cache: DependencyCache = { @@ -57,6 +59,7 @@ const cache: DependencyCache = { APP_URL: null, application: null, http: null, + security: null, }; export function setDependencyCache(deps: Partial) { @@ -189,6 +192,13 @@ export function getHttp() { return cache.http; } +export function getSecurity() { + if (cache.security === null) { + throw new Error("security hasn't been initialized"); + } + return cache.security; +} + export function clearCache() { console.log('clearing dependency cache'); // eslint-disable-line no-console Object.keys(cache).forEach(k => { diff --git a/x-pack/legacy/plugins/ml/public/legacy.ts b/x-pack/legacy/plugins/ml/public/legacy.ts index bf431f0986d68a..40a1afa06b5a64 100644 --- a/x-pack/legacy/plugins/ml/public/legacy.ts +++ b/x-pack/legacy/plugins/ml/public/legacy.ts @@ -6,14 +6,16 @@ import chrome from 'ui/chrome'; import { npSetup, npStart } from 'ui/new_platform'; - import { PluginInitializerContext } from 'src/core/public'; +import { SecurityPluginSetup } from '../../../../plugins/security/public'; + import { plugin } from '.'; const pluginInstance = plugin({} as PluginInitializerContext); export const setup = pluginInstance.setup(npSetup.core, { data: npStart.plugins.data, + security: ((npSetup.plugins as unknown) as { security: SecurityPluginSetup }).security, // security isn't in the PluginsSetup interface, but does exist __LEGACY: { XSRF: chrome.getXsrfToken(), // @ts-ignore getAppUrl is missing from chrome's definition diff --git a/x-pack/legacy/plugins/ml/public/plugin.ts b/x-pack/legacy/plugins/ml/public/plugin.ts index 79af300bce4ec0..cb39b31a32b148 100644 --- a/x-pack/legacy/plugins/ml/public/plugin.ts +++ b/x-pack/legacy/plugins/ml/public/plugin.ts @@ -8,7 +8,7 @@ import { Plugin, CoreStart, CoreSetup } from 'src/core/public'; import { MlDependencies } from './application/app'; export class MlPlugin implements Plugin { - setup(core: CoreSetup, { data, __LEGACY }: MlDependencies) { + setup(core: CoreSetup, { data, security, __LEGACY }: MlDependencies) { core.application.register({ id: 'ml', title: 'Machine learning', @@ -21,6 +21,7 @@ export class MlPlugin implements Plugin { onAppLeave: params.onAppLeave, data, __LEGACY, + security, }); }, }); diff --git a/x-pack/legacy/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts b/x-pack/legacy/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts index fd5b5221393fc9..9f30f609c60b63 100644 --- a/x-pack/legacy/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts +++ b/x-pack/legacy/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts @@ -6,6 +6,7 @@ import Boom from 'boom'; import { RequestHandlerContext } from 'kibana/server'; +import { FindFileStructureResponse } from '../../../common/types/file_datavisualizer'; export type InputData = any[]; @@ -20,31 +21,7 @@ export type FormattedOverrides = InputOverrides & { }; export interface AnalysisResult { - results: { - charset: string; - has_header_row: boolean; - has_byte_order_marker: boolean; - format: string; - field_stats: { - [fieldName: string]: { - count: number; - cardinality: number; - top_hits: Array<{ count: number; value: any }>; - }; - }; - sample_start: string; - num_messages_analyzed: number; - mappings: { - [fieldName: string]: { - type: string; - }; - }; - quote: string; - delimiter: string; - need_client_timezone: boolean; - num_lines_analyzed: number; - column_names: string[]; - }; + results: FindFileStructureResponse; overrides?: FormattedOverrides; } From afb5d8fa5847cdb7e4f7d6d8742a73486815007f Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Tue, 25 Feb 2020 07:43:46 -0600 Subject: [PATCH 33/73] Fix service map popover transaction duration (#58422) It's already microseconds, so not converting it fixes it. Checked services to see if all metrics match now and they do! Fixes #55679 --- .../app/ServiceMap/Popover/ServiceMetricList.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx index 50ce918ea7037c..3a6b4c5ebcaac2 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/ServiceMetricList.tsx @@ -16,12 +16,7 @@ import { isNumber } from 'lodash'; import React from 'react'; import styled from 'styled-components'; import { ServiceNodeMetrics } from '../../../../../../../../plugins/apm/common/service_map'; -import { - asDuration, - asPercent, - toMicroseconds, - tpmUnit -} from '../../../../utils/formatters'; +import { asDuration, asPercent, tpmUnit } from '../../../../utils/formatters'; function LoadingSpinner() { return ( @@ -70,7 +65,7 @@ export function ServiceMetricList({ } ), description: isNumber(avgTransactionDuration) - ? asDuration(toMicroseconds(avgTransactionDuration, 'milliseconds')) + ? asDuration(avgTransactionDuration) : null }, { From db05fb6738cd906bf231a28d58d5c17d6efe201c Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Tue, 25 Feb 2020 15:00:28 +0100 Subject: [PATCH 34/73] Don't mutate error message (#58452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 don't mutate error object in-place This avoids mutating error thrown by an expression function in-place. The error might not even be an object, in which case mutating it will throw. * test: 💍 capture in test that thrown error is not mutated Co-authored-by: Elastic Machine --- src/plugins/expressions/common/execution/execution.test.ts | 1 + src/plugins/expressions/common/execution/execution.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/expressions/common/execution/execution.test.ts b/src/plugins/expressions/common/execution/execution.test.ts index f6ff9efca848b9..4776204a8ab2ff 100644 --- a/src/plugins/expressions/common/execution/execution.test.ts +++ b/src/plugins/expressions/common/execution/execution.test.ts @@ -630,6 +630,7 @@ describe('Execution', () => { }, }); expect(node2.debug?.rawError).toBeInstanceOf(Error); + expect(node2.debug?.rawError).toEqual(new Error('foo')); }); test('sets .debug object to expected shape', async () => { diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 7e7df822724aea..272448870e8177 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -230,8 +230,8 @@ export class Execution< input = output; } catch (rawError) { const timeEnd: number = this.params.debug ? performance.now() : 0; - rawError.message = `[${fnName}] > ${rawError.message}`; const error = createError(rawError) as ExpressionValueError; + error.error.message = `[${fnName}] > ${error.error.message}`; if (this.params.debug) { (link as ExpressionAstFunction).debug = { From 418c44a47ed7c5b6807e31aa4be24f4dbc9d6b5b Mon Sep 17 00:00:00 2001 From: patrykkopycinski Date: Tue, 25 Feb 2020 15:00:50 +0100 Subject: [PATCH 35/73] [SIEM] Fix unnecessary re-renders on the Overview page (#56587) --- .../__snapshots__/barchart.test.tsx.snap | 2 - .../components/charts/areachart.test.tsx | 4 +- .../public/components/charts/areachart.tsx | 4 - .../components/charts/barchart.test.tsx | 11 +- .../siem/public/components/charts/common.tsx | 11 +- .../drag_and_drop/draggable_wrapper.tsx | 4 +- .../events_viewer/events_viewer.tsx | 10 +- .../public/components/events_viewer/index.tsx | 18 +- .../siem/public/components/flyout/index.tsx | 55 +++--- .../siem/public/components/inspect/index.tsx | 8 +- .../public/components/navigation/index.tsx | 7 +- .../hosts/authentications_table/index.tsx | 6 +- .../page/hosts/hosts_table/index.tsx | 1 + .../components/page/hosts/kpi_hosts/index.tsx | 1 + .../hosts/uncommon_process_table/index.tsx | 6 +- .../page/network/kpi_network/index.tsx | 1 + .../network/network_dns_table/columns.tsx | 3 +- .../page/network/network_dns_table/index.tsx | 10 +- .../page/network/network_http_table/index.tsx | 6 +- .../network_top_countries_table/index.tsx | 5 +- .../network_top_n_flow_table/index.tsx | 5 +- .../page/network/tls_table/index.tsx | 10 +- .../page/network/users_table/index.tsx | 13 +- .../overview/overview_host_stats/index.tsx | 2 - .../overview/overview_network_stats/index.tsx | 6 +- .../public/components/query_bar/index.tsx | 6 +- .../public/components/search_bar/index.tsx | 6 +- .../source_destination_ip.tsx | 5 +- .../__snapshots__/index.test.tsx.snap | 3 - .../__snapshots__/timeline.test.tsx.snap | 2 +- .../components/timeline/header/index.tsx | 8 +- .../siem/public/components/timeline/index.tsx | 12 +- .../components/timeline/query_bar/index.tsx | 5 +- .../timeline/search_or_filter/index.tsx | 21 ++- .../public/components/timeline/timeline.tsx | 4 - .../public/components/url_state/index.tsx | 4 +- .../components/url_state/use_url_state.tsx | 7 +- .../rules/fetch_index_patterns.tsx | 5 +- .../public/containers/global_time/index.tsx | 18 +- .../containers/query_template_paginated.tsx | 4 +- .../siem/public/containers/source/index.tsx | 1 + .../signals_histogram.tsx | 29 +-- .../rules/components/query_bar/index.tsx | 12 +- .../rules/components/rule_status/index.tsx | 4 +- .../components/step_about_rule/index.tsx | 4 +- .../components/step_define_rule/index.tsx | 13 +- .../components/step_schedule_rule/index.tsx | 4 +- .../pages/hosts/details/details_tabs.tsx | 45 ++--- .../siem/public/pages/hosts/hosts_tabs.tsx | 75 ++++---- .../network/navigation/network_routes.tsx | 171 +++++++++--------- x-pack/legacy/plugins/siem/public/routes.tsx | 8 +- .../siem/public/utils/kql/use_update_kql.tsx | 4 +- .../siem/public/utils/route/spy_routes.tsx | 3 +- x-pack/package.json | 1 + x-pack/tsconfig.json | 2 +- yarn.lock | 9 +- 56 files changed, 374 insertions(+), 330 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/components/charts/__snapshots__/barchart.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/charts/__snapshots__/barchart.test.tsx.snap index 12b9afb661da15..c330676e9219eb 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/__snapshots__/barchart.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/charts/__snapshots__/barchart.test.tsx.snap @@ -1,5 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`BarChartBaseComponent render with customized configs should 2 render BarSeries 1`] = `[Function]`; - exports[`BarChartBaseComponent render with default configs if no customized configs given should 2 render BarSeries 1`] = `[Function]`; diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx index 27f0222b96b77f..3c2de28ae423cf 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx @@ -331,7 +331,7 @@ describe('AreaChart', () => { }); it(`should render area chart`, () => { - expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(1); + expect(shallowWrapper.find('AreaChartBase')).toHaveLength(1); expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(0); }); }); @@ -344,7 +344,7 @@ describe('AreaChart', () => { }); it(`should render a chart place holder`, () => { - expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(0); + expect(shallowWrapper.find('AreaChartBase')).toHaveLength(0); expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(1); }); } diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx index b66cc77e30aad2..f3b2b736ed87de 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx @@ -146,8 +146,4 @@ export const AreaChartComponent: React.FC = ({ areaChar ); }; -AreaChartComponent.displayName = 'AreaChartComponent'; - export const AreaChart = React.memo(AreaChartComponent); - -AreaChart.displayName = 'AreaChart'; diff --git a/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx index 0b6635b04d3808..272c41833f3685 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { BarChartBaseComponent, BarChartComponent } from './barchart'; import { ChartSeriesData } from './common'; -import { BarSeries, ScaleType, Axis } from '@elastic/charts'; +import { Chart, BarSeries, Axis, ScaleType } from '@elastic/charts'; jest.mock('../../lib/kibana'); @@ -139,7 +139,7 @@ describe('BarChartBaseComponent', () => { }); it('should render two bar series', () => { - expect(shallowWrapper.find('Chart')).toHaveLength(1); + expect(shallowWrapper.find(Chart)).toHaveLength(1); }); }); @@ -167,7 +167,6 @@ describe('BarChartBaseComponent', () => { }); it(`should ${mockBarChartData.length} render BarSeries`, () => { - expect(shallow).toMatchSnapshot(); expect(shallowWrapper.find(BarSeries)).toHaveLength(mockBarChartData.length); }); @@ -265,7 +264,7 @@ describe('BarChartBaseComponent', () => { }); it('should not render without height and width', () => { - expect(shallowWrapper.find('Chart')).toHaveLength(0); + expect(shallowWrapper.find(Chart)).toHaveLength(0); }); }); }); @@ -278,7 +277,7 @@ describe.each(chartDataSets)('BarChart with valid data [%o]', data => { }); it(`should render chart`, () => { - expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(1); + expect(shallowWrapper.find('BarChartBase')).toHaveLength(1); expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(0); }); }); @@ -291,7 +290,7 @@ describe.each(chartHolderDataSets)('BarChart with invalid data [%o]', data => { }); it(`should render a ChartPlaceHolder`, () => { - expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(0); + expect(shallowWrapper.find('BarChartBase')).toHaveLength(0); expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(1); }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx index 03b412f5756466..7377bcbe7050fa 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx @@ -16,7 +16,9 @@ import { TickFormatter, Position, } from '@elastic/charts'; +import React, { useMemo } from 'react'; import styled from 'styled-components'; + import { useUiSetting } from '../../lib/kibana'; import { DEFAULT_DARK_MODE } from '../../../common/constants'; @@ -54,7 +56,7 @@ export interface ChartSeriesData { color?: string | undefined; } -export const WrappedByAutoSizer = styled.div<{ height?: string }>` +const WrappedByAutoSizerComponent = styled.div<{ height?: string }>` ${style => ` height: ${style.height != null ? style.height : defaultChartHeight}; @@ -66,7 +68,9 @@ export const WrappedByAutoSizer = styled.div<{ height?: string }>` } `; -WrappedByAutoSizer.displayName = 'WrappedByAutoSizer'; +WrappedByAutoSizerComponent.displayName = 'WrappedByAutoSizer'; + +export const WrappedByAutoSizer = React.memo(WrappedByAutoSizerComponent); export enum SeriesType { BAR = 'bar', @@ -96,8 +100,9 @@ const theme: PartialTheme = { export const useTheme = () => { const isDarkMode = useUiSetting(DEFAULT_DARK_MODE); const defaultTheme = isDarkMode ? DARK_THEME : LIGHT_THEME; + const themeValue = useMemo(() => mergeWithDefaultTheme(theme, defaultTheme), []); - return mergeWithDefaultTheme(theme, defaultTheme); + return themeValue; }; export const chartDefaultSettings = { diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx index cf958bfd75d3b2..7d84403b87f8d0 100644 --- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import React, { createContext, useContext, useEffect } from 'react'; import { Draggable, @@ -14,6 +13,7 @@ import { } from 'react-beautiful-dnd'; import { connect, ConnectedProps } from 'react-redux'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import { EuiPortal } from '@elastic/eui'; import { dragAndDropActions } from '../../store/drag_and_drop'; @@ -122,7 +122,7 @@ const DraggableWrapperComponent = React.memo( }, (prevProps, nextProps) => { return ( - isEqual(prevProps.dataProvider, nextProps.dataProvider) && + deepEqual(prevProps.dataProvider, nextProps.dataProvider) && prevProps.render !== nextProps.render && prevProps.truncate === nextProps.truncate ); diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx index 2a4d08ea214bc4..a913186d9ad3b9 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx @@ -5,10 +5,10 @@ */ import { EuiPanel } from '@elastic/eui'; -import deepEqual from 'fast-deep-equal'; -import { getOr, isEmpty, isEqual, union } from 'lodash/fp'; +import { getOr, isEmpty, union } from 'lodash/fp'; import React, { useMemo } from 'react'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import useResizeObserver from 'use-resize-observer/polyfilled'; import { BrowserFields } from '../../containers/source'; @@ -228,7 +228,7 @@ const EventsViewerComponent: React.FC = ({ export const EventsViewer = React.memo( EventsViewerComponent, (prevProps, nextProps) => - isEqual(prevProps.browserFields, nextProps.browserFields) && + deepEqual(prevProps.browserFields, nextProps.browserFields) && prevProps.columns === nextProps.columns && prevProps.dataProviders === nextProps.dataProviders && prevProps.deletedEventIds === nextProps.deletedEventIds && @@ -241,9 +241,9 @@ export const EventsViewer = React.memo( prevProps.itemsPerPage === nextProps.itemsPerPage && prevProps.itemsPerPageOptions === nextProps.itemsPerPageOptions && prevProps.kqlMode === nextProps.kqlMode && - isEqual(prevProps.query, nextProps.query) && + deepEqual(prevProps.query, nextProps.query) && prevProps.start === nextProps.start && prevProps.sort === nextProps.sort && - isEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) && + deepEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) && prevProps.utilityBar === nextProps.utilityBar ); diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx index 762ae8497dadba..9b31be40dd9557 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import React, { useCallback, useMemo, useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; import { inputsModel, inputsSelectors, State, timelineSelectors } from '../../store'; import { inputsActions, timelineActions } from '../../store/actions'; @@ -197,23 +197,23 @@ export const StatefulEventsViewer = connector( StatefulEventsViewerComponent, (prevProps, nextProps) => prevProps.id === nextProps.id && - isEqual(prevProps.columns, nextProps.columns) && - isEqual(prevProps.dataProviders, nextProps.dataProviders) && + deepEqual(prevProps.columns, nextProps.columns) && + deepEqual(prevProps.dataProviders, nextProps.dataProviders) && prevProps.deletedEventIds === nextProps.deletedEventIds && prevProps.end === nextProps.end && - isEqual(prevProps.filters, nextProps.filters) && + deepEqual(prevProps.filters, nextProps.filters) && prevProps.isLive === nextProps.isLive && prevProps.itemsPerPage === nextProps.itemsPerPage && - isEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) && + deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) && prevProps.kqlMode === nextProps.kqlMode && - isEqual(prevProps.query, nextProps.query) && - isEqual(prevProps.sort, nextProps.sort) && + deepEqual(prevProps.query, nextProps.query) && + deepEqual(prevProps.sort, nextProps.sort) && prevProps.start === nextProps.start && - isEqual(prevProps.pageFilters, nextProps.pageFilters) && + deepEqual(prevProps.pageFilters, nextProps.pageFilters) && prevProps.showCheckboxes === nextProps.showCheckboxes && prevProps.showRowRenderers === nextProps.showRowRenderers && prevProps.start === nextProps.start && - isEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) && + deepEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) && prevProps.utilityBar === nextProps.utilityBar ) ); diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx index eb41773bb21c86..22fc9f27ce26c7 100644 --- a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx @@ -6,7 +6,7 @@ import { EuiBadge } from '@elastic/eui'; import { defaultTo, getOr } from 'lodash/fp'; -import React from 'react'; +import React, { useCallback } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import styled from 'styled-components'; @@ -58,28 +58,39 @@ export const FlyoutComponent = React.memo( timelineId, usersViewing, width, - }) => ( - <> - - showTimeline({ id: timelineId, show: false })} + }) => { + const handleClose = useCallback(() => showTimeline({ id: timelineId, show: false }), [ + showTimeline, + timelineId, + ]); + const handleOpen = useCallback(() => showTimeline({ id: timelineId, show: true }), [ + showTimeline, + timelineId, + ]); + + return ( + <> + + + {children} + + + - {children} - - - showTimeline({ id: timelineId, show: true })} - /> - - ) + onOpen={handleOpen} + /> + + ); + } ); FlyoutComponent.displayName = 'FlyoutComponent'; diff --git a/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx b/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx index 405a8f060948e3..d6f8143745356f 100644 --- a/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/inspect/index.tsx @@ -5,7 +5,7 @@ */ import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; -import { getOr } from 'lodash/fp'; +import { getOr, omit } from 'lodash/fp'; import React, { useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; @@ -162,7 +162,11 @@ const makeMapStateToProps = () => { const getGlobalQuery = inputsSelectors.globalQueryByIdSelector(); const getTimelineQuery = inputsSelectors.timelineQueryByIdSelector(); const mapStateToProps = (state: State, { inputId = 'global', queryId }: OwnProps) => { - return inputId === 'global' ? getGlobalQuery(state, queryId) : getTimelineQuery(state, queryId); + const props = + inputId === 'global' ? getGlobalQuery(state, queryId) : getTimelineQuery(state, queryId); + // refetch caused unnecessary component rerender and it was even not used + const propsWithoutRefetch = omit('refetch', props); + return propsWithoutRefetch; }; return mapStateToProps; }; diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx index e40cc887ab5ff4..8a754cb47475f2 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/navigation/index.tsx @@ -4,11 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import isEqual from 'lodash/fp/isEqual'; -import deepEqual from 'fast-deep-equal'; import React, { useEffect } from 'react'; import { connect } from 'react-redux'; import { compose } from 'redux'; +import deepEqual from 'fast-deep-equal'; import { useKibana } from '../../lib/kibana'; import { RouteSpyState } from '../../utils/route/types'; @@ -81,8 +80,8 @@ export const SiemNavigationRedux = compose< (prevProps, nextProps) => prevProps.pathName === nextProps.pathName && prevProps.search === nextProps.search && - isEqual(prevProps.navTabs, nextProps.navTabs) && - isEqual(prevProps.urlState, nextProps.urlState) && + deepEqual(prevProps.navTabs, nextProps.navTabs) && + deepEqual(prevProps.urlState, nextProps.urlState) && deepEqual(prevProps.state, nextProps.state) ) ); diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx index 853ba7ae234142..678faff7654db8 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_table/index.tsx @@ -7,7 +7,7 @@ /* eslint-disable react/display-name */ import { has } from 'lodash/fp'; -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { hostsActions } from '../../../../store/hosts'; @@ -100,10 +100,12 @@ const AuthenticationTableComponent = React.memo( [type, updateTableActivePage] ); + const columns = useMemo(() => getAuthenticationColumnsCurated(type), [type]); + return ( ( [type, updateTableActivePage] ); + const columns = useMemo(() => getUncommonColumnsCurated(type), [type]); + return ( ]; -export const getNetworkDnsColumns = (type: networkModel.NetworkType): NetworkDnsColumns => [ +export const getNetworkDnsColumns = (): NetworkDnsColumns => [ { field: `node.${NetworkDnsFields.dnsName}`, name: i18n.REGISTERED_DOMAIN, diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx index f3fe98936a55de..c1dd96c5c96f91 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/network_dns_table/index.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; import { networkActions } from '../../../../store/actions'; import { @@ -93,7 +93,7 @@ export const NetworkDnsTableComponent = React.memo( field: criteria.sort.field.split('.')[1] as NetworkDnsFields, direction: criteria.sort.direction as Direction, }; - if (!isEqual(newDnsSortField, sort)) { + if (!deepEqual(newDnsSortField, sort)) { updateNetworkTable({ networkType: type, tableType, @@ -115,10 +115,12 @@ export const NetworkDnsTableComponent = React.memo( [type, updateNetworkTable, isPtrIncluded] ); + const columns = useMemo(() => getNetworkDnsColumns(), []); + return ( = ({ const sorting = { field: `node.${NetworkHttpFields.requestCount}`, direction: sort.direction }; + const columns = useMemo(() => getNetworkHttpColumns(tableType), [tableType]); + return ( = ({ field: field as NetworkTopTablesFields, direction: newSortDirection as Direction, }; - if (!isEqual(newTopNFlowSort, sort)) { + if (!deepEqual(newTopNFlowSort, sort)) { updateNetworkTable({ networkType: type, tableType, diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx index 77abae68b76bfe..d1512699cc709c 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/network/tls_table/index.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; -import React, { useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; import { networkActions } from '../../../../store/network'; import { TlsEdges, TlsSortField, TlsFields, Direction } from '../../../../graphql/types'; @@ -91,7 +91,7 @@ const TlsTableComponent = React.memo( field: getSortFromString(splitField[splitField.length - 1]), direction: criteria.sort.direction as Direction, }; - if (!isEqual(newTlsSort, sort)) { + if (!deepEqual(newTlsSort, sort)) { updateNetworkTable({ networkType: type, tableType, @@ -103,10 +103,12 @@ const TlsTableComponent = React.memo( [sort, type, tableType, updateNetworkTable] ); + const columns = useMemo(() => getTlsColumns(tlsTableId), [tlsTableId]); + return ( ( field: getSortFromString(splitField[splitField.length - 1]), direction: criteria.sort.direction as Direction, }; - if (!isEqual(newUsersSort, sort)) { + if (!deepEqual(newUsersSort, sort)) { updateNetworkTable({ networkType: type, tableType, @@ -109,10 +109,15 @@ const UsersTableComponent = React.memo( [sort, type, updateNetworkTable] ); + const columns = useMemo(() => getUsersColumns(flowTarget, usersTableId), [ + flowTarget, + usersTableId, + ]); + return ( = ({ data, loading ); }; -OverviewHostStatsComponent.displayName = 'OverviewHostStatsComponent'; - export const OverviewHostStats = React.memo(OverviewHostStatsComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network_stats/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network_stats/index.tsx index 260b1d6895140d..ca947c29bc3822 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network_stats/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/overview/overview_network_stats/index.tsx @@ -130,7 +130,7 @@ const AccordionContent = styled.div` margin-top: 8px; `; -export const OverviewNetworkStats = React.memo(({ data, loading }) => { +const OverviewNetworkStatsComponent: React.FC = ({ data, loading }) => { const allNetworkStats = getOverviewNetworkStats(data); const allNetworkStatsCount = allNetworkStats.reduce((total, stat) => total + stat.count, 0); @@ -190,6 +190,6 @@ export const OverviewNetworkStats = React.memo(({ data, lo })} ); -}); +}; -OverviewNetworkStats.displayName = 'OverviewNetworkStats'; +export const OverviewNetworkStats = React.memo(OverviewNetworkStatsComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/query_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/query_bar/index.tsx index 03a8143c89517f..557d389aefee92 100644 --- a/x-pack/legacy/plugins/siem/public/components/query_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/query_bar/index.tsx @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import React, { memo, useState, useEffect, useMemo, useCallback } from 'react'; +import deepEqual from 'fast-deep-equal'; import { Filter, @@ -64,7 +64,7 @@ export const QueryBar = memo( const onQuerySubmit = useCallback( (payload: { dateRange: TimeRange; query?: Query }) => { - if (payload.query != null && !isEqual(payload.query, filterQuery)) { + if (payload.query != null && !deepEqual(payload.query, filterQuery)) { onSubmitQuery(payload.query); } }, @@ -73,7 +73,7 @@ export const QueryBar = memo( const onQueryChange = useCallback( (payload: { dateRange: TimeRange; query?: Query }) => { - if (payload.query != null && !isEqual(payload.query, draftQuery)) { + if (payload.query != null && !deepEqual(payload.query, draftQuery)) { setDraftQuery(payload.query); onChangedQuery(payload.query); } diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx index cb5729ad8e26e5..2513004af84dd6 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getOr, isEqual, set } from 'lodash/fp'; +import { getOr, set } from 'lodash/fp'; import React, { memo, useEffect, useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Dispatch } from 'redux'; import { Subscription } from 'rxjs'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import { FilterManager, IIndexPattern, TimeRange, Query, Filter } from 'src/plugins/data/public'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; @@ -60,7 +61,6 @@ const SearchBarComponent = memo( setSavedQuery, setSearchBarFilter, start, - timelineId, toStr, updateSearch, dataTestSubj, @@ -108,7 +108,7 @@ const SearchBarComponent = memo( updateSearchBar.start = payload.dateRange.from; } - if (payload.query != null && !isEqual(payload.query, filterQuery)) { + if (payload.query != null && !deepEqual(payload.query, filterQuery)) { isStateUpdated = true; updateSearchBar = set('query', payload.query, updateSearchBar); } diff --git a/x-pack/legacy/plugins/siem/public/components/source_destination/source_destination_ip.tsx b/x-pack/legacy/plugins/siem/public/components/source_destination/source_destination_ip.tsx index 33159387214e43..b8192cce11e5aa 100644 --- a/x-pack/legacy/plugins/siem/public/components/source_destination/source_destination_ip.tsx +++ b/x-pack/legacy/plugins/siem/public/components/source_destination/source_destination_ip.tsx @@ -5,8 +5,9 @@ */ import { EuiBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { isEmpty, isEqual, uniqWith } from 'lodash/fp'; +import { isEmpty, uniqWith } from 'lodash/fp'; import React from 'react'; +import deepEqual from 'fast-deep-equal'; import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip'; import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, Port } from '../port'; @@ -115,7 +116,7 @@ const IpAdressesWithPorts = React.memo<{ return ( - {uniqWith(isEqual, ipPortPairs).map( + {uniqWith(deepEqual, ipPortPairs).map( ipPortPair => ipPortPair.ip != null && ( diff --git a/x-pack/legacy/plugins/siem/public/components/stat_items/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/stat_items/__snapshots__/index.test.tsx.snap index 69596ba8f33250..ef077ece19f923 100644 --- a/x-pack/legacy/plugins/siem/public/components/stat_items/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/stat_items/__snapshots__/index.test.tsx.snap @@ -94,7 +94,6 @@ exports[`Stat Items Component disable charts it renders the default widget 1`] = isInspected={false} loading={false} queryId="statItems" - refetch={null} selectedInspectIndex={0} setIsInspected={[Function]} title="KPI HOSTS" @@ -328,7 +327,6 @@ exports[`Stat Items Component disable charts it renders the default widget 2`] = isInspected={false} loading={false} queryId="statItems" - refetch={null} selectedInspectIndex={0} setIsInspected={[Function]} title="KPI HOSTS" @@ -632,7 +630,6 @@ exports[`Stat Items Component rendering kpis with charts it renders the default isInspected={false} loading={false} queryId="statItems" - refetch={null} selectedInspectIndex={0} setIsInspected={[Function]} title="KPI UNIQUE_PRIVATE_IPS" diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/__snapshots__/timeline.test.tsx.snap b/x-pack/legacy/plugins/siem/public/components/timeline/__snapshots__/timeline.test.tsx.snap index 3fcd258b79147c..372930ee3167df 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/__snapshots__/timeline.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/components/timeline/__snapshots__/timeline.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Timeline rendering renders correctly against snapshot 1`] = ` justifyContent="flexStart" > - = ({ browserFields, id, indexPattern, @@ -60,7 +60,7 @@ export const TimelineHeaderComponent = ({ onToggleDataProviderExcluded, show, showCallOutUnauthorizedMsg, -}: Props) => ( +}) => ( {showCallOutUnauthorizedMsg && ( ); -TimelineHeaderComponent.displayName = 'TimelineHeaderComponent'; - export const TimelineHeader = React.memo(TimelineHeaderComponent); - -TimelineHeader.displayName = 'TimelineHeader'; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx index d782d0366f041c..0ce6bc16f1325a 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/index.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import React, { useEffect, useCallback, useMemo } from 'react'; import { connect, ConnectedProps } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; import { WithSource } from '../../containers/source'; import { useSignalIndex } from '../../containers/detection_engine/signals/use_signal_index'; @@ -215,11 +215,11 @@ const StatefulTimelineComponent = React.memo( prevProps.show === nextProps.show && prevProps.showCallOutUnauthorizedMsg === nextProps.showCallOutUnauthorizedMsg && prevProps.start === nextProps.start && - isEqual(prevProps.columns, nextProps.columns) && - isEqual(prevProps.dataProviders, nextProps.dataProviders) && - isEqual(prevProps.filters, nextProps.filters) && - isEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) && - isEqual(prevProps.sort, nextProps.sort) + deepEqual(prevProps.columns, nextProps.columns) && + deepEqual(prevProps.dataProviders, nextProps.dataProviders) && + deepEqual(prevProps.filters, nextProps.filters) && + deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) && + deepEqual(prevProps.sort, nextProps.sort) ); } ); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/query_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/query_bar/index.tsx index 96b8df6d8ada70..7f662cdb2f1b44 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/query_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/query_bar/index.tsx @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual, isEmpty } from 'lodash/fp'; +import { isEmpty } from 'lodash/fp'; import React, { memo, useCallback, useState, useEffect } from 'react'; import { Subscription } from 'rxjs'; +import deepEqual from 'fast-deep-equal'; import { IIndexPattern, @@ -127,7 +128,7 @@ export const QueryBarTimeline = memo( const filterWithoutDropArea = filterManager .getFilters() .filter((f: Filter) => f.meta.controlledBy !== timelineFilterDropArea); - if (!isEqual(filters, filterWithoutDropArea)) { + if (!deepEqual(filters, filterWithoutDropArea)) { filterManager.setFilters(filters); } }, [filters]); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx index d1904fd5d9aac2..87061bdbb5d02a 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/search_or_filter/index.tsx @@ -4,10 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getOr, isEqual } from 'lodash/fp'; +import { getOr } from 'lodash/fp'; import React, { useCallback } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { Dispatch } from 'redux'; +import deepEqual from 'fast-deep-equal'; import { Filter, IIndexPattern } from '../../../../../../../../src/plugins/data/public'; import { BrowserFields } from '../../../containers/source'; @@ -152,15 +153,15 @@ const StatefulSearchOrFilterComponent = React.memo( prevProps.isRefreshPaused === nextProps.isRefreshPaused && prevProps.refreshInterval === nextProps.refreshInterval && prevProps.timelineId === nextProps.timelineId && - isEqual(prevProps.browserFields, nextProps.browserFields) && - isEqual(prevProps.dataProviders, nextProps.dataProviders) && - isEqual(prevProps.filters, nextProps.filters) && - isEqual(prevProps.filterQuery, nextProps.filterQuery) && - isEqual(prevProps.filterQueryDraft, nextProps.filterQueryDraft) && - isEqual(prevProps.indexPattern, nextProps.indexPattern) && - isEqual(prevProps.kqlMode, nextProps.kqlMode) && - isEqual(prevProps.savedQueryId, nextProps.savedQueryId) && - isEqual(prevProps.timelineId, nextProps.timelineId) + deepEqual(prevProps.browserFields, nextProps.browserFields) && + deepEqual(prevProps.dataProviders, nextProps.dataProviders) && + deepEqual(prevProps.filters, nextProps.filters) && + deepEqual(prevProps.filterQuery, nextProps.filterQuery) && + deepEqual(prevProps.filterQueryDraft, nextProps.filterQueryDraft) && + deepEqual(prevProps.indexPattern, nextProps.indexPattern) && + deepEqual(prevProps.kqlMode, nextProps.kqlMode) && + deepEqual(prevProps.savedQueryId, nextProps.savedQueryId) && + deepEqual(prevProps.timelineId, nextProps.timelineId) ); } ); diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx index c9ff0296a40e27..58bbbef328ddf9 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx @@ -229,8 +229,4 @@ export const TimelineComponent: React.FC = ({ ); }; -TimelineComponent.displayName = 'TimelineComponent'; - export const Timeline = React.memo(TimelineComponent); - -Timeline.displayName = 'Timeline'; diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx index e656ec3496d8dc..294e41a1faa7b4 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/index.tsx @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import React from 'react'; import { compose, Dispatch } from 'redux'; import { connect } from 'react-redux'; +import deepEqual from 'fast-deep-equal'; import { timelineActions } from '../../store/actions'; import { RouteSpyState } from '../../utils/route/types'; @@ -39,7 +39,7 @@ export const UrlStateRedux = compose - prevProps.pathName === nextProps.pathName && isEqual(prevProps.urlState, nextProps.urlState) + prevProps.pathName === nextProps.pathName && deepEqual(prevProps.urlState, nextProps.urlState) ) ); diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx index deaf9bbf5011d8..a7704e0e86970a 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx +++ b/x-pack/legacy/plugins/siem/public/components/url_state/use_url_state.tsx @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual, difference, isEmpty } from 'lodash/fp'; +import { difference, isEmpty } from 'lodash/fp'; import { useEffect, useRef, useState } from 'react'; +import deepEqual from 'fast-deep-equal'; import { useKibana } from '../../lib/kibana'; import { useApolloClient } from '../../utils/apollo_context'; @@ -77,7 +78,7 @@ export const useUrlStateHooks = ({ const updatedUrlStateString = getParamFromQueryString(getQueryStringFromLocation(mySearch), urlKey) ?? newUrlStateString; - if (isInitializing || !isEqual(updatedUrlStateString, newUrlStateString)) { + if (isInitializing || !deepEqual(updatedUrlStateString, newUrlStateString)) { urlStateToUpdate = [ ...urlStateToUpdate, { @@ -157,7 +158,7 @@ export const useUrlStateHooks = ({ if (isInitializing && pageName != null && pageName !== '') { handleInitialize(type); setIsInitializing(false); - } else if (!isEqual(urlState, prevProps.urlState) && !isInitializing) { + } else if (!deepEqual(urlState, prevProps.urlState) && !isInitializing) { let mySearch = search; URL_STATE_KEYS[type].forEach((urlKey: KeyUrlState) => { if ( diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/fetch_index_patterns.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/fetch_index_patterns.tsx index b7ad41b8ba1bb2..06c4d1054bca4f 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/fetch_index_patterns.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/fetch_index_patterns.tsx @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEmpty, isEqual, get } from 'lodash/fp'; +import { isEmpty, get } from 'lodash/fp'; import { useEffect, useState, Dispatch, SetStateAction } from 'react'; +import deepEqual from 'fast-deep-equal'; import { IIndexPattern } from '../../../../../../../../src/plugins/data/public'; import { @@ -41,7 +42,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return => const [, dispatchToaster] = useStateToaster(); useEffect(() => { - if (!isEqual(defaultIndices, indices)) { + if (!deepEqual(defaultIndices, indices)) { setIndices(defaultIndices); } }, [defaultIndices, indices]); diff --git a/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx index caf597d02c835f..4632e9aee3fdd1 100644 --- a/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/global_time/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useState, useEffect } from 'react'; +import React, { useCallback, useState, useEffect } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { inputsModel, inputsSelectors, State } from '../../store'; @@ -41,6 +41,17 @@ export const GlobalTimeComponent: React.FC = ({ }) => { const [isInitializing, setIsInitializing] = useState(true); + const setQuery = useCallback( + ({ id, inspect, loading, refetch }: SetQuery) => + setGlobalQuery({ inputId: 'global', id, inspect, loading, refetch }), + [setGlobalQuery] + ); + + const deleteQuery = useCallback( + ({ id }: { id: string }) => deleteOneQuery({ inputId: 'global', id }), + [deleteOneQuery] + ); + useEffect(() => { if (isInitializing) { setIsInitializing(false); @@ -56,9 +67,8 @@ export const GlobalTimeComponent: React.FC = ({ isInitializing, from, to, - setQuery: ({ id, inspect, loading, refetch }: SetQuery) => - setGlobalQuery({ inputId: 'global', id, inspect, loading, refetch }), - deleteQuery: ({ id }: { id: string }) => deleteOneQuery({ inputId: 'global', id }), + setQuery, + deleteQuery, })} ); diff --git a/x-pack/legacy/plugins/siem/public/containers/query_template_paginated.tsx b/x-pack/legacy/plugins/siem/public/containers/query_template_paginated.tsx index 4d6ab757fdea7a..db618f216d83e7 100644 --- a/x-pack/legacy/plugins/siem/public/containers/query_template_paginated.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/query_template_paginated.tsx @@ -5,10 +5,10 @@ */ import { ApolloQueryResult, NetworkStatus } from 'apollo-client'; -import { isEqual } from 'lodash/fp'; import memoizeOne from 'memoize-one'; import React from 'react'; import { FetchMoreOptions, FetchMoreQueryOptions, OperationVariables } from 'react-apollo'; +import deepEqual from 'fast-deep-equal'; import { ESQuery } from '../../common/typed_json'; import { inputsModel } from '../store/model'; @@ -85,7 +85,7 @@ export class QueryTemplatePaginated< public isItAValidLoading(loading: boolean, variables: TVariables, networkStatus: NetworkStatus) { if ( !this.myLoading && - (!isEqual(variables, this.queryVariables) || networkStatus === NetworkStatus.refetch) && + (!deepEqual(variables, this.queryVariables) || networkStatus === NetworkStatus.refetch) && loading ) { this.myLoading = true; diff --git a/x-pack/legacy/plugins/siem/public/containers/source/index.tsx b/x-pack/legacy/plugins/siem/public/containers/source/index.tsx index 0336e4a9a977b9..e454421ca955d6 100644 --- a/x-pack/legacy/plugins/siem/public/containers/source/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/source/index.tsx @@ -10,6 +10,7 @@ import { Query } from 'react-apollo'; import React, { useEffect, useMemo, useState } from 'react'; import memoizeOne from 'memoize-one'; import { IIndexPattern } from 'src/plugins/data/public'; + import { useUiSetting$ } from '../../lib/kibana'; import { DEFAULT_INDEX_KEY } from '../../../common/constants'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.tsx index 92f6740e4d767a..2d9b1ee844b4ba 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/components/signals_histogram_panel/signals_histogram.tsx @@ -12,9 +12,11 @@ import { HistogramBarSeries, Position, Settings, + ChartSizeArray, } from '@elastic/charts'; -import React from 'react'; +import React, { useMemo } from 'react'; import { EuiProgress } from '@elastic/eui'; + import { useTheme } from '../../../../components/charts/common'; import { histogramDateTimeFormatter } from '../../../../components/utils'; import { HistogramData } from './types'; @@ -43,6 +45,14 @@ export const SignalsHistogram = React.memo( }) => { const theme = useTheme(); + const chartSize: ChartSizeArray = useMemo(() => ['100%', chartHeight], [chartHeight]); + const xAxisId = useMemo(() => getAxisId('signalsHistogramAxisX'), []); + const yAxisId = useMemo(() => getAxisId('signalsHistogramAxisY'), []); + const id = useMemo(() => getSpecId('signalsHistogram'), []); + const yAccessors = useMemo(() => ['y'], []); + const splitSeriesAccessors = useMemo(() => ['g'], []); + const tickFormat = useMemo(() => histogramDateTimeFormatter([from, to]), [from, to]); + return ( <> {loading && ( @@ -54,7 +64,7 @@ export const SignalsHistogram = React.memo( /> )} - + ( theme={theme} /> - + - + @@ -84,4 +90,5 @@ export const SignalsHistogram = React.memo( ); } ); + SignalsHistogram.displayName = 'SignalsHistogram'; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.tsx index 88795f9195e68d..fbe854c1ee346f 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/query_bar/index.tsx @@ -5,10 +5,10 @@ */ import { EuiFormRow, EuiMutationObserver } from '@elastic/eui'; -import { isEqual } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Subscription } from 'rxjs'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import { Filter, @@ -99,7 +99,7 @@ export const QueryBarDefineRule = ({ const newFilters = filterManager.getFilters(); const { filters } = field.value as FieldValueQueryBar; - if (!isEqual(filters, newFilters)) { + if (!deepEqual(filters, newFilters)) { field.setValue({ ...(field.value as FieldValueQueryBar), filters: newFilters }); } } @@ -117,10 +117,10 @@ export const QueryBarDefineRule = ({ let isSubscribed = true; async function updateFilterQueryFromValue() { const { filters, query, saved_id: savedId } = field.value as FieldValueQueryBar; - if (!isEqual(query, queryDraft)) { + if (!deepEqual(query, queryDraft)) { setQueryDraft(query); } - if (!isEqual(filters, filterManager.getFilters())) { + if (!deepEqual(filters, filterManager.getFilters())) { filterManager.setFilters(filters); } if ( @@ -148,7 +148,7 @@ export const QueryBarDefineRule = ({ const onSubmitQuery = useCallback( (newQuery: Query, timefilter?: SavedQueryTimeFilter) => { const { query } = field.value as FieldValueQueryBar; - if (!isEqual(query, newQuery)) { + if (!deepEqual(query, newQuery)) { field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery }); } }, @@ -158,7 +158,7 @@ export const QueryBarDefineRule = ({ const onChangedQuery = useCallback( (newQuery: Query) => { const { query } = field.value as FieldValueQueryBar; - if (!isEqual(query, newQuery)) { + if (!deepEqual(query, newQuery)) { field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery }); } }, diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.tsx index 2c9173cbeb694a..ac457d7345c29e 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_status/index.tsx @@ -12,8 +12,8 @@ import { EuiLoadingSpinner, EuiText, } from '@elastic/eui'; -import { isEqual } from 'lodash/fp'; import React, { memo, useCallback, useEffect, useState } from 'react'; +import deepEqual from 'fast-deep-equal'; import { useRuleStatus, RuleInfoStatus } from '../../../../../containers/detection_engine/rules'; import { FormattedDate } from '../../../../../components/formatted_date'; @@ -43,7 +43,7 @@ const RuleStatusComponent: React.FC = ({ ruleId, ruleEnabled }) }, [fetchRuleStatus, myRuleEnabled, ruleId, ruleEnabled, setMyRuleEnabled]); useEffect(() => { - if (!isEqual(currentStatus, ruleStatus?.current_status)) { + if (!deepEqual(currentStatus, ruleStatus?.current_status)) { setCurrentStatus(ruleStatus?.current_status ?? null); } }, [currentStatus, ruleStatus, setCurrentStatus]); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_about_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_about_rule/index.tsx index 45da7d081333e9..431d793d6e68a5 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_about_rule/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_about_rule/index.tsx @@ -13,9 +13,9 @@ import { EuiSpacer, EuiButtonEmpty, } from '@elastic/eui'; -import { isEqual } from 'lodash/fp'; import React, { FC, memo, useCallback, useEffect, useState } from 'react'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import { setFieldValue } from '../../helpers'; import { RuleStepProps, RuleStep, AboutStepRule } from '../../types'; @@ -103,7 +103,7 @@ const StepAboutRuleComponent: FC = ({ useEffect(() => { const { isNew, ...initDefaultValue } = myStepData; - if (defaultValues != null && !isEqual(initDefaultValue, defaultValues)) { + if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) { const myDefaultValues = { ...defaultValues, isNew: false, diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.tsx index 920a9f2dfe56ca..773eb44efb26c5 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_define_rule/index.tsx @@ -11,9 +11,10 @@ import { EuiFlexItem, EuiButton, } from '@elastic/eui'; -import { isEmpty, isEqual } from 'lodash/fp'; +import { isEmpty } from 'lodash/fp'; import React, { FC, memo, useCallback, useState, useEffect } from 'react'; import styled from 'styled-components'; +import deepEqual from 'fast-deep-equal'; import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/public'; import { useFetchIndexPatterns } from '../../../../../containers/detection_engine/rules'; @@ -126,9 +127,9 @@ const StepDefineRuleComponent: FC = ({ useEffect(() => { if (indicesConfig != null && defaultValues != null) { const myDefaultValues = getStepDefaultValue(indicesConfig, defaultValues); - if (!isEqual(myDefaultValues, myStepData)) { + if (!deepEqual(myDefaultValues, myStepData)) { setMyStepData(myDefaultValues); - setLocalUseIndicesConfig(isEqual(myDefaultValues.index, indicesConfig)); + setLocalUseIndicesConfig(deepEqual(myDefaultValues.index, indicesConfig)); setFieldValue(form, schema, myDefaultValues); } } @@ -212,13 +213,13 @@ const StepDefineRuleComponent: FC = ({ {({ index }) => { if (index != null) { - if (isEqual(index, indicesConfig) && !localUseIndicesConfig) { + if (deepEqual(index, indicesConfig) && !localUseIndicesConfig) { setLocalUseIndicesConfig(true); } - if (!isEqual(index, indicesConfig) && localUseIndicesConfig) { + if (!deepEqual(index, indicesConfig) && localUseIndicesConfig) { setLocalUseIndicesConfig(false); } - if (index != null && !isEmpty(index) && !isEqual(index, mylocalIndicesConfig)) { + if (index != null && !isEmpty(index) && !deepEqual(index, mylocalIndicesConfig)) { setMyLocalIndicesConfig(index); } } diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.tsx index cfbb0a622c7219..2e2c7e068dd857 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/step_schedule_rule/index.tsx @@ -5,8 +5,8 @@ */ import { EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui'; -import { isEqual } from 'lodash/fp'; import React, { FC, memo, useCallback, useEffect, useState } from 'react'; +import deepEqual from 'fast-deep-equal'; import { setFieldValue } from '../../helpers'; import { RuleStep, RuleStepProps, ScheduleStepRule } from '../../types'; @@ -62,7 +62,7 @@ const StepScheduleRuleComponent: FC = ({ useEffect(() => { const { isNew, ...initDefaultValue } = myStepData; - if (defaultValues != null && !isEqual(initDefaultValue, defaultValues)) { + if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) { const myDefaultValues = { ...defaultValues, isNew: false, diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx index 41eb620850a7fd..f5efd9248029da 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/details_tabs.tsx @@ -73,32 +73,25 @@ export const HostDetailsTabs = React.memo( return ( - } - /> - } - /> - } - /> - ( - - )} - /> - } - /> - } - /> + + + + + + + + + + + + + + + + + + + ); } diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx index 0b83710a132935..80c35e5563c1db 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts_tabs.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { memo } from 'react'; +import React, { memo, useCallback } from 'react'; import { Route, Switch } from 'react-router-dom'; import { HostsTabsProps } from './types'; @@ -22,7 +22,7 @@ import { } from './navigation'; import { HostAlertsQueryTabBody } from './navigation/alerts_query_tab_body'; -const HostsTabs = memo( +export const HostsTabs = memo( ({ deleteQuery, filterQuery, @@ -44,49 +44,48 @@ const HostsTabs = memo( startDate: from, type, indexPattern, - narrowDateRange: (score: Anomaly, interval: string) => { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }, + narrowDateRange: useCallback( + (score: Anomaly, interval: string) => { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }, + [setAbsoluteRangeDatePicker] + ), + updateDateRange: useCallback( + (min: number, max: number) => { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }, + [setAbsoluteRangeDatePicker] + ), }; return ( - } - /> - } - /> - } - /> - ( - - )} - /> - } - /> - } - /> + + + + + + + + + + + + + + + + + + ); } ); HostsTabs.displayName = 'HostsTabs'; - -export { HostsTabs }; diff --git a/x-pack/legacy/plugins/siem/public/pages/network/navigation/network_routes.tsx b/x-pack/legacy/plugins/siem/public/pages/network/navigation/network_routes.tsx index 23a619db97ee4c..b6b54b68ac06a0 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/navigation/network_routes.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/navigation/network_routes.tsx @@ -23,77 +23,82 @@ import { TlsQueryTabBody } from './tls_query_tab_body'; import { Anomaly } from '../../../components/ml/types'; import { NetworkAlertsQueryTabBody } from './alerts_query_tab_body'; -export const NetworkRoutes = ({ - networkPagePath, - type, - to, - filterQuery, - isInitializing, - from, - indexPattern, - setQuery, - setAbsoluteRangeDatePicker, -}: NetworkRoutesProps) => { - const narrowDateRange = useCallback( - (score: Anomaly, interval: string) => { - const fromTo = scoreIntervalToDateTime(score, interval); - setAbsoluteRangeDatePicker({ - id: 'global', - from: fromTo.from, - to: fromTo.to, - }); - }, - [setAbsoluteRangeDatePicker] - ); +export const NetworkRoutes = React.memo( + ({ + networkPagePath, + type, + to, + filterQuery, + isInitializing, + from, + indexPattern, + setQuery, + setAbsoluteRangeDatePicker, + }) => { + const narrowDateRange = useCallback( + (score: Anomaly, interval: string) => { + const fromTo = scoreIntervalToDateTime(score, interval); + setAbsoluteRangeDatePicker({ + id: 'global', + from: fromTo.from, + to: fromTo.to, + }); + }, + [setAbsoluteRangeDatePicker] + ); + const updateDateRange = useCallback( + (min: number, max: number) => { + setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max }); + }, + [setAbsoluteRangeDatePicker] + ); - const networkAnomaliesFilterQuery = { - bool: { - should: [ - { - exists: { - field: 'source.ip', + const networkAnomaliesFilterQuery = { + bool: { + should: [ + { + exists: { + field: 'source.ip', + }, }, - }, - { - exists: { - field: 'destination.ip', + { + exists: { + field: 'destination.ip', + }, }, - }, - ], - minimum_should_match: 1, - }, - }; + ], + minimum_should_match: 1, + }, + }; - const commonProps = { - startDate: from, - endDate: to, - skip: isInitializing, - type, - narrowDateRange, - setQuery, - filterQuery, - }; + const commonProps = { + startDate: from, + endDate: to, + skip: isInitializing, + type, + narrowDateRange, + setQuery, + filterQuery, + }; - const tabProps = { - ...commonProps, - indexPattern, - }; + const tabProps = { + ...commonProps, + indexPattern, + updateDateRange, + }; - const anomaliesProps = { - ...commonProps, - anomaliesFilterQuery: networkAnomaliesFilterQuery, - AnomaliesTableComponent: AnomaliesNetworkTable, - }; + const anomaliesProps = { + ...commonProps, + anomaliesFilterQuery: networkAnomaliesFilterQuery, + AnomaliesTableComponent: AnomaliesNetworkTable, + }; - return ( - - } - /> - ( + return ( + + + + + <> @@ -118,31 +123,25 @@ export const NetworkRoutes = ({ - )} - /> - } - /> - } - /> - ( + + + + + + + + - )} - /> - } - /> - - ); -}; + + + + + + ); + } +); NetworkRoutes.displayName = 'NetworkRoutes'; diff --git a/x-pack/legacy/plugins/siem/public/routes.tsx b/x-pack/legacy/plugins/siem/public/routes.tsx index cbb58a473e8ea0..a989fa9873435e 100644 --- a/x-pack/legacy/plugins/siem/public/routes.tsx +++ b/x-pack/legacy/plugins/siem/public/routes.tsx @@ -20,8 +20,12 @@ const PageRouterComponent: FC = ({ history }) => ( - } /> - } /> + + + + + + diff --git a/x-pack/legacy/plugins/siem/public/utils/kql/use_update_kql.tsx b/x-pack/legacy/plugins/siem/public/utils/kql/use_update_kql.tsx index 213b881bd20843..af993588f7e0dc 100644 --- a/x-pack/legacy/plugins/siem/public/utils/kql/use_update_kql.tsx +++ b/x-pack/legacy/plugins/siem/public/utils/kql/use_update_kql.tsx @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual } from 'lodash/fp'; import { Dispatch } from 'redux'; import { IIndexPattern } from 'src/plugins/data/public'; +import deepEqual from 'fast-deep-equal'; import { KueryFilterQuery } from '../../store'; import { applyKqlFilterQuery as dispatchApplyTimelineFilterQuery } from '../../store/timeline/actions'; @@ -29,7 +29,7 @@ export const useUpdateKql = ({ timelineId, }: UseUpdateKqlProps): RefetchKql => { const updateKql: RefetchKql = (dispatch: Dispatch) => { - if (kueryFilterQueryDraft != null && !isEqual(kueryFilterQuery, kueryFilterQueryDraft)) { + if (kueryFilterQueryDraft != null && !deepEqual(kueryFilterQuery, kueryFilterQueryDraft)) { if (storeType === 'timelineType' && timelineId != null) { dispatch( dispatchApplyTimelineFilterQuery({ diff --git a/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx b/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx index c88562abef6ae0..ddee2359b28ba4 100644 --- a/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx +++ b/x-pack/legacy/plugins/siem/public/utils/route/spy_routes.tsx @@ -5,7 +5,6 @@ */ import * as H from 'history'; -import { isEqual } from 'lodash/fp'; import { memo, useEffect, useState } from 'react'; import { withRouter } from 'react-router-dom'; import deepEqual from 'fast-deep-equal'; @@ -35,7 +34,7 @@ export const SpyRouteComponent = memo( } }, [search]); useEffect(() => { - if (pageName && !isEqual(route.pathName, pathname)) { + if (pageName && !deepEqual(route.pathName, pathname)) { if (isInitializing && detailName == null) { dispatch({ type: 'updateRouteWithOutSearch', diff --git a/x-pack/package.json b/x-pack/package.json index f76b0182ea228d..b8fe0326903b66 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -106,6 +106,7 @@ "@types/uuid": "^3.4.4", "@types/xml-crypto": "^1.4.0", "@types/xml2js": "^0.4.5", + "@welldone-software/why-did-you-render": "^4.0.0", "abab": "^1.0.4", "axios": "^0.19.0", "babel-jest": "^24.9.0", diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index 978271166cc058..723da7cef6a777 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -36,7 +36,7 @@ "x-pack/test_utils/*" ], "plugins/*": ["src/legacy/core_plugins/*/public/"], - "fixtures/*": ["src/fixtures/*"] + "fixtures/*": ["src/fixtures/*"], }, "types": [ "node", diff --git a/yarn.lock b/yarn.lock index f46e869909e2e5..7906f363813b8d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5684,6 +5684,13 @@ text-table "^0.2.0" webpack-log "^1.1.2" +"@welldone-software/why-did-you-render@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@welldone-software/why-did-you-render/-/why-did-you-render-4.0.0.tgz#cc98c996f5a06ea55bd07dc99ba4b4d68af93332" + integrity sha512-PjqriZ8Ak9biP2+kOcIrg+NwsFwWVhGV03Hm+ns84YBCArn+hWBKM9rMBEU6e62I1qyrYF2/G9yktNpEmfWfJA== + dependencies: + lodash "^4" + "@wry/context@^0.4.0": version "0.4.1" resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.4.1.tgz#b3e23ca036035cbad0bd9711269352dd03a6fe3c" @@ -19767,7 +19774,7 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: +lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== From d339740c2de9f61d7140cd9bc983383f2843df67 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 25 Feb 2020 09:27:18 -0500 Subject: [PATCH 36/73] [Uptime] Migrate server to new platform (#53939) * Move uptime legacy server to plugins directory. * Re-add feature registration code. * Move feature registration back to kibana bootstrap file. * Delete obsolete test file. * Remove i18n call from untracked file. * Implement feedback. Co-authored-by: Elastic Machine --- .../plugins/uptime/common/constants/plugin.ts | 7 ++- x-pack/legacy/plugins/uptime/index.ts | 19 -------- .../plugins/uptime/scripts/graphql_schemas.ts | 15 ------ .../__tests__/find_potential_matches_test.ts | 5 -- x-pack/legacy/plugins/uptime/server/plugin.ts | 19 -------- x-pack/plugins/uptime/kibana.json | 9 ++++ .../uptime/server/graphql/constants.ts | 0 .../plugins/uptime/server/graphql/index.ts | 0 .../server/graphql/monitor_states/index.ts | 0 .../graphql/monitor_states/resolvers.ts | 6 +-- .../graphql/monitor_states/schema.gql.ts | 0 .../uptime/server/graphql/monitors/index.ts | 0 .../server/graphql/monitors/resolvers.ts | 10 +++- .../server/graphql/monitors/schema.gql.ts | 0 .../uptime/server/graphql/pings/index.ts | 0 .../uptime/server/graphql/pings/resolvers.ts | 7 ++- .../uptime/server/graphql/pings/schema.gql.ts | 0 .../plugins/uptime/server/graphql/types.ts | 0 .../__tests__/parse_literal.test.ts | 0 .../__tests__/parse_value.test.ts | 0 .../__tests__/serialize.test.ts | 0 .../graphql/unsigned_int_scalar/index.ts | 0 .../graphql/unsigned_int_scalar/resolvers.ts | 0 .../graphql/unsigned_int_scalar/schema.gql.ts | 0 .../plugins/uptime/server/index.ts | 6 ++- .../plugins/uptime/server/kibana.index.ts | 17 +++---- .../lib/adapters/framework/adapter_types.ts | 11 ++--- .../server/lib/adapters/framework/index.ts | 0 .../framework/kibana_framework_adapter.ts | 0 .../uptime/server/lib/adapters/index.ts | 0 .../kibana_telemetry_adapter.test.ts.snap | 0 .../kibana_telemetry_adapter.test.ts | 0 .../server/lib/adapters/telemetry/index.ts | 0 .../telemetry/kibana_telemetry_adapter.ts | 0 .../uptime/server/lib/compose/kibana.ts | 4 +- .../__snapshots__/license.test.ts.snap | 0 .../lib/domains/__tests__/license.test.ts | 2 +- .../uptime/server/lib/domains/index.ts | 0 .../uptime/server/lib/domains/license.ts | 2 +- .../assert_close_to.test.ts.snap | 0 .../get_filter_clause.test.ts.snap | 0 .../helper/__test__/assert_close_to.test.ts | 0 .../helper/__test__/get_filter_clause.test.ts | 0 .../__test__/get_histogram_interval.test.ts | 0 .../get_histogram_interval_formatted.test.ts | 0 .../__test__/parse_relative_date.test.ts | 0 .../server/lib/helper/assert_close_to.ts | 0 .../server/lib/helper/get_filter_clause.ts | 0 .../lib/helper/get_histogram_interval.ts | 2 +- .../get_histogram_interval_formatted.ts | 0 .../plugins/uptime/server/lib/helper/index.ts | 0 .../lib/helper/make_date_rate_filter.ts | 0 .../server/lib/helper/object_to_array.ts | 0 .../plugins/uptime/server/lib/lib.ts | 0 .../extract_filter_aggs_results.test.ts.snap | 0 .../generate_filter_aggs.test.ts.snap | 0 .../get_monitor_charts.test.ts.snap | 0 .../get_ping_histogram.test.ts.snap | 0 .../combine_range_with_filters.test.ts | 0 .../extract_filter_aggs_results.test.ts | 0 .../__tests__/generate_filter_aggs.test.ts | 0 .../__tests__/get_latest_monitor.test.ts | 0 .../__tests__/get_monitor_charts.test.ts | 0 .../__tests__/get_ping_histogram.test.ts | 0 .../lib/requests/__tests__/get_pings.test.ts | 0 .../__tests__/monitor_charts_mock.json | 0 .../lib/requests/generate_filter_aggs.ts | 0 .../server/lib/requests/get_filter_bar.ts | 4 +- .../server/lib/requests/get_index_pattern.ts | 4 +- .../server/lib/requests/get_index_status.ts | 4 +- .../server/lib/requests/get_latest_monitor.ts | 4 +- .../uptime/server/lib/requests/get_monitor.ts | 4 +- .../server/lib/requests/get_monitor_charts.ts | 7 ++- .../lib/requests/get_monitor_details.ts | 7 ++- .../lib/requests/get_monitor_locations.ts | 10 +++- .../server/lib/requests/get_monitor_states.ts | 8 +++- .../server/lib/requests/get_ping_histogram.ts | 4 +- .../uptime/server/lib/requests/get_pings.ts | 8 +++- .../lib/requests/get_snapshot_counts.ts | 7 ++- .../uptime/server/lib/requests/index.ts | 0 .../search/__tests__/fetch_page.test.ts | 2 +- .../__tests__/monitor_group_iterator.test.ts | 0 .../search/__tests__/query_context.test.ts | 5 +- .../requests/search/__tests__/test_helpers.ts | 5 +- .../requests/search/enrich_monitor_groups.ts | 4 +- .../server/lib/requests/search/fetch_chunk.ts | 0 .../server/lib/requests/search/fetch_page.ts | 8 +++- .../requests/search/find_potential_matches.ts | 4 +- .../server/lib/requests/search/index.ts | 0 .../requests/search/monitor_group_iterator.ts | 2 +- .../lib/requests/search/query_context.ts | 2 +- .../search/refine_potential_matches.ts | 4 +- .../server/lib/requests/search/types.ts | 5 +- .../uptime/server/lib/requests/types.ts | 7 ++- .../server/lib/requests/uptime_requests.ts | 11 +++-- x-pack/plugins/uptime/server/plugin.ts | 17 +++++++ .../server/rest_api/create_route_with_auth.ts | 0 .../plugins/uptime/server/rest_api/index.ts | 0 .../index_pattern/get_index_pattern.ts | 0 .../server/rest_api/index_pattern/index.ts | 0 .../uptime/server/rest_api/monitors/index.ts | 0 .../rest_api/monitors/monitor_locations.ts | 0 .../rest_api/monitors/monitors_details.ts | 0 .../uptime/server/rest_api/monitors/status.ts | 0 .../overview_filters/get_overview_filters.ts | 0 .../server/rest_api/overview_filters/index.ts | 0 .../uptime/server/rest_api/pings/get_all.ts | 48 +++++++++++++++++++ .../rest_api/pings/get_ping_histogram.ts | 0 .../uptime/server/rest_api/pings/get_pings.ts | 0 .../uptime/server/rest_api/pings/index.ts | 0 .../rest_api/snapshot/get_snapshot_count.ts | 0 .../uptime/server/rest_api/snapshot/index.ts | 0 .../uptime/server/rest_api/telemetry/index.ts | 0 .../rest_api/telemetry/log_monitor_page.ts | 0 .../rest_api/telemetry/log_overview_page.ts | 0 .../plugins/uptime/server/rest_api/types.ts | 0 .../server/rest_api/uptime_route_wrapper.ts | 0 .../plugins/uptime/server/uptime_server.ts | 0 .../apis/uptime/rest/ping_histogram.ts | 2 +- 119 files changed, 204 insertions(+), 134 deletions(-) delete mode 100644 x-pack/legacy/plugins/uptime/scripts/graphql_schemas.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/find_potential_matches_test.ts delete mode 100644 x-pack/legacy/plugins/uptime/server/plugin.ts create mode 100644 x-pack/plugins/uptime/kibana.json rename x-pack/{legacy => }/plugins/uptime/server/graphql/constants.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitor_states/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitor_states/resolvers.ts (89%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitor_states/schema.gql.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitors/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitors/resolvers.ts (71%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/monitors/schema.gql.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/pings/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/pings/resolvers.ts (84%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/pings/schema.gql.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/types.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_literal.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_value.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/serialize.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/resolvers.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/graphql/unsigned_int_scalar/schema.gql.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/index.ts (59%) rename x-pack/{legacy => }/plugins/uptime/server/kibana.index.ts (82%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/framework/adapter_types.ts (85%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/framework/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/telemetry/__tests__/__snapshots__/kibana_telemetry_adapter.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/telemetry/__tests__/kibana_telemetry_adapter.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/telemetry/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/compose/kibana.ts (80%) rename x-pack/{legacy => }/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/domains/__tests__/license.test.ts (93%) rename x-pack/{legacy => }/plugins/uptime/server/lib/domains/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/domains/license.ts (93%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/__snapshots__/assert_close_to.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/__snapshots__/get_filter_clause.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/assert_close_to.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/get_filter_clause.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/assert_close_to.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/get_filter_clause.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/get_histogram_interval.ts (95%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/make_date_rate_filter.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/helper/object_to_array.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/lib.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/__snapshots__/generate_filter_aggs.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_monitor_charts.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_ping_histogram.test.ts.snap (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/combine_range_with_filters.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/generate_filter_aggs.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/__tests__/monitor_charts_mock.json (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/generate_filter_aggs.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_filter_bar.ts (94%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_index_pattern.ts (92%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_index_status.ts (76%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_latest_monitor.ts (91%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_monitor.ts (87%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_monitor_charts.ts (96%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_monitor_details.ts (88%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_monitor_locations.ts (92%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_monitor_states.ts (89%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_ping_histogram.ts (93%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_pings.ts (93%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/get_snapshot_counts.ts (96%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts (96%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/__tests__/monitor_group_iterator.test.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts (95%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts (88%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts (98%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/fetch_chunk.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/fetch_page.ts (96%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/find_potential_matches.ts (95%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts (98%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/query_context.ts (97%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts (96%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/search/types.ts (76%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/types.ts (89%) rename x-pack/{legacy => }/plugins/uptime/server/lib/requests/uptime_requests.ts (83%) create mode 100644 x-pack/plugins/uptime/server/plugin.ts rename x-pack/{legacy => }/plugins/uptime/server/rest_api/create_route_with_auth.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/index_pattern/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/monitors/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/monitors/monitor_locations.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/monitors/monitors_details.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/monitors/status.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/overview_filters/index.ts (100%) create mode 100644 x-pack/plugins/uptime/server/rest_api/pings/get_all.ts rename x-pack/{legacy => }/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/pings/get_pings.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/pings/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/snapshot/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/telemetry/index.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/types.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/rest_api/uptime_route_wrapper.ts (100%) rename x-pack/{legacy => }/plugins/uptime/server/uptime_server.ts (100%) diff --git a/x-pack/legacy/plugins/uptime/common/constants/plugin.ts b/x-pack/legacy/plugins/uptime/common/constants/plugin.ts index f6fa569a503150..00781726941d5c 100644 --- a/x-pack/legacy/plugins/uptime/common/constants/plugin.ts +++ b/x-pack/legacy/plugins/uptime/common/constants/plugin.ts @@ -4,11 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ +import { i18n } from '@kbn/i18n'; + export const PLUGIN = { APP_ROOT_ID: 'react-uptime-root', DESCRIPTION: 'Uptime monitoring', ID: 'uptime', - ROUTER_BASE_NAME: '/app/uptime#', LOCAL_STORAGE_KEY: 'xpack.uptime', + NAME: i18n.translate('xpack.uptime.featureRegistry.uptimeFeatureName', { + defaultMessage: 'Uptime', + }), + ROUTER_BASE_NAME: '/app/uptime#', TITLE: 'uptime', }; diff --git a/x-pack/legacy/plugins/uptime/index.ts b/x-pack/legacy/plugins/uptime/index.ts index cf7332f97d466b..feecef58578950 100644 --- a/x-pack/legacy/plugins/uptime/index.ts +++ b/x-pack/legacy/plugins/uptime/index.ts @@ -6,9 +6,7 @@ import { i18n } from '@kbn/i18n'; import { resolve } from 'path'; -import { PluginInitializerContext } from 'src/core/server'; import { PLUGIN } from './common/constants'; -import { KibanaServer, plugin } from './server'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils'; export const uptime = (kibana: any) => @@ -35,21 +33,4 @@ export const uptime = (kibana: any) => }, home: ['plugins/uptime/register_feature'], }, - init(server: KibanaServer) { - const initializerContext = {} as PluginInitializerContext; - const { savedObjects } = server; - const { xpack_main } = server.plugins; - const { usageCollection } = server.newPlatform.setup.plugins; - - plugin(initializerContext).setup( - { - route: server.newPlatform.setup.core.http.createRouter(), - }, - { - savedObjects, - usageCollection, - xpack: xpack_main, - } - ); - }, }); diff --git a/x-pack/legacy/plugins/uptime/scripts/graphql_schemas.ts b/x-pack/legacy/plugins/uptime/scripts/graphql_schemas.ts deleted file mode 100644 index c337cf098e48dd..00000000000000 --- a/x-pack/legacy/plugins/uptime/scripts/graphql_schemas.ts +++ /dev/null @@ -1,15 +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 { buildSchemaFromTypeDefinitions } from 'graphql-tools'; -import { typeDefs } from '../server/graphql'; - -export const schemas = [...typeDefs]; - -// this default export is used to feed the combined types to the gql-gen tool -// which generates the corresponding typescript types -// eslint-disable-next-line import/no-default-export -export default buildSchemaFromTypeDefinitions(schemas); diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/find_potential_matches_test.ts b/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/find_potential_matches_test.ts deleted file mode 100644 index 41bc2aa2588073..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/find_potential_matches_test.ts +++ /dev/null @@ -1,5 +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. - */ diff --git a/x-pack/legacy/plugins/uptime/server/plugin.ts b/x-pack/legacy/plugins/uptime/server/plugin.ts deleted file mode 100644 index acecce305e7cb9..00000000000000 --- a/x-pack/legacy/plugins/uptime/server/plugin.ts +++ /dev/null @@ -1,19 +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 { PluginInitializerContext } from 'src/core/server'; -import { initServerWithKibana } from './kibana.index'; -import { UptimeCoreSetup, UptimeCorePlugins } from './lib/adapters/framework'; - -export function plugin(initializerContext: PluginInitializerContext) { - return new Plugin(); -} - -export class Plugin { - public setup(core: UptimeCoreSetup, plugins: UptimeCorePlugins) { - initServerWithKibana(core, plugins); - } -} diff --git a/x-pack/plugins/uptime/kibana.json b/x-pack/plugins/uptime/kibana.json new file mode 100644 index 00000000000000..dd61716325afc8 --- /dev/null +++ b/x-pack/plugins/uptime/kibana.json @@ -0,0 +1,9 @@ +{ + "configPath": ["xpack"], + "id": "uptime", + "kibanaVersion": "kibana", + "requiredPlugins": ["features", "licensing", "usageCollection"], + "server": true, + "ui": false, + "version": "8.0.0" +} diff --git a/x-pack/legacy/plugins/uptime/server/graphql/constants.ts b/x-pack/plugins/uptime/server/graphql/constants.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/constants.ts rename to x-pack/plugins/uptime/server/graphql/constants.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/index.ts b/x-pack/plugins/uptime/server/graphql/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/index.ts rename to x-pack/plugins/uptime/server/graphql/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/index.ts b/x-pack/plugins/uptime/server/graphql/monitor_states/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/monitor_states/index.ts rename to x-pack/plugins/uptime/server/graphql/monitor_states/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts b/x-pack/plugins/uptime/server/graphql/monitor_states/resolvers.ts similarity index 89% rename from x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts rename to x-pack/plugins/uptime/server/graphql/monitor_states/resolvers.ts index e2b076d5708432..6ac42f77172599 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/resolvers.ts +++ b/x-pack/plugins/uptime/server/graphql/monitor_states/resolvers.ts @@ -6,13 +6,13 @@ import { CreateUMGraphQLResolvers, UMContext } from '../types'; import { UMServerLibs } from '../../lib/lib'; -import { UMResolver } from '../../../common/graphql/resolver_types'; +import { UMResolver } from '../../../../../legacy/plugins/uptime/common/graphql/resolver_types'; import { GetMonitorStatesQueryArgs, MonitorSummaryResult, StatesIndexStatus, -} from '../../../common/graphql/types'; -import { CONTEXT_DEFAULTS } from '../../../common/constants/context_defaults'; +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; +import { CONTEXT_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants/context_defaults'; export type UMGetMonitorStatesResolver = UMResolver< MonitorSummaryResult | Promise, diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitor_states/schema.gql.ts b/x-pack/plugins/uptime/server/graphql/monitor_states/schema.gql.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/monitor_states/schema.gql.ts rename to x-pack/plugins/uptime/server/graphql/monitor_states/schema.gql.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/index.ts b/x-pack/plugins/uptime/server/graphql/monitors/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/monitors/index.ts rename to x-pack/plugins/uptime/server/graphql/monitors/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/plugins/uptime/server/graphql/monitors/resolvers.ts similarity index 71% rename from x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts rename to x-pack/plugins/uptime/server/graphql/monitors/resolvers.ts index 19f23fa1bb9347..b39c5f42bfd756 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -4,11 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMResolver } from '../../../common/graphql/resolver_types'; -import { GetMonitorChartsDataQueryArgs, MonitorChart } from '../../../common/graphql/types'; +import { UMGqlRange } from '../../../../../legacy/plugins/uptime/common/domain_types'; +import { UMResolver } from '../../../../../legacy/plugins/uptime/common/graphql/resolver_types'; +import { + GetMonitorChartsDataQueryArgs, + MonitorChart, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; import { UMServerLibs } from '../../lib/lib'; import { CreateUMGraphQLResolvers, UMContext } from '../types'; +export type UMMonitorsResolver = UMResolver, any, UMGqlRange, UMContext>; + export type UMGetMonitorChartsResolver = UMResolver< any | Promise, any, diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts b/x-pack/plugins/uptime/server/graphql/monitors/schema.gql.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/monitors/schema.gql.ts rename to x-pack/plugins/uptime/server/graphql/monitors/schema.gql.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/index.ts b/x-pack/plugins/uptime/server/graphql/pings/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/pings/index.ts rename to x-pack/plugins/uptime/server/graphql/pings/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts b/x-pack/plugins/uptime/server/graphql/pings/resolvers.ts similarity index 84% rename from x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts rename to x-pack/plugins/uptime/server/graphql/pings/resolvers.ts index de83a9ced16b2d..b383fc5d5fb154 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/pings/resolvers.ts +++ b/x-pack/plugins/uptime/server/graphql/pings/resolvers.ts @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UMResolver } from '../../../common/graphql/resolver_types'; -import { AllPingsQueryArgs, PingResults } from '../../../common/graphql/types'; +import { UMResolver } from '../../../../../legacy/plugins/uptime/common/graphql/resolver_types'; +import { + AllPingsQueryArgs, + PingResults, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; import { UMServerLibs } from '../../lib/lib'; import { UMContext } from '../types'; import { CreateUMGraphQLResolvers } from '../types'; diff --git a/x-pack/legacy/plugins/uptime/server/graphql/pings/schema.gql.ts b/x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/pings/schema.gql.ts rename to x-pack/plugins/uptime/server/graphql/pings/schema.gql.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/types.ts b/x-pack/plugins/uptime/server/graphql/types.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/types.ts rename to x-pack/plugins/uptime/server/graphql/types.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_literal.test.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_literal.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_literal.test.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_literal.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_value.test.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_value.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_value.test.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/parse_value.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/serialize.test.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/serialize.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/serialize.test.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/__tests__/serialize.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/index.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/index.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/resolvers.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/resolvers.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/resolvers.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/resolvers.ts diff --git a/x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/schema.gql.ts b/x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/schema.gql.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/graphql/unsigned_int_scalar/schema.gql.ts rename to x-pack/plugins/uptime/server/graphql/unsigned_int_scalar/schema.gql.ts diff --git a/x-pack/legacy/plugins/uptime/server/index.ts b/x-pack/plugins/uptime/server/index.ts similarity index 59% rename from x-pack/legacy/plugins/uptime/server/index.ts rename to x-pack/plugins/uptime/server/index.ts index d063f0d8c2288d..bec47fa9db4cf5 100644 --- a/x-pack/legacy/plugins/uptime/server/index.ts +++ b/x-pack/plugins/uptime/server/index.ts @@ -4,5 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import { PluginInitializerContext } from '../../../../src/core/server'; +import { Plugin } from './plugin'; + export { initServerWithKibana, KibanaServer } from './kibana.index'; -export { plugin } from './plugin'; +export const plugin = (initializerContext: PluginInitializerContext) => + new Plugin(initializerContext); diff --git a/x-pack/legacy/plugins/uptime/server/kibana.index.ts b/x-pack/plugins/uptime/server/kibana.index.ts similarity index 82% rename from x-pack/legacy/plugins/uptime/server/kibana.index.ts rename to x-pack/plugins/uptime/server/kibana.index.ts index 73fabc629946b6..c7ac3a70c0494c 100644 --- a/x-pack/legacy/plugins/uptime/server/kibana.index.ts +++ b/x-pack/plugins/uptime/server/kibana.index.ts @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { Request, Server } from 'hapi'; -import { PLUGIN } from '../common/constants'; +import { PLUGIN } from '../../../legacy/plugins/uptime/common/constants'; import { KibanaTelemetryAdapter } from './lib/adapters/telemetry'; import { compose } from './lib/compose/kibana'; import { initUptimeServer } from './uptime_server'; @@ -25,17 +24,13 @@ export interface KibanaServer extends Server { } export const initServerWithKibana = (server: UptimeCoreSetup, plugins: UptimeCorePlugins) => { - const { usageCollection, xpack } = plugins; - const libs = compose(server, plugins); + const { features, usageCollection } = plugins; + const libs = compose(server); KibanaTelemetryAdapter.registerUsageCollector(usageCollection); - initUptimeServer(libs); - - xpack.registerFeature({ + features.registerFeature({ id: PLUGIN.ID, - name: i18n.translate('xpack.uptime.featureRegistry.uptimeFeatureName', { - defaultMessage: 'Uptime', - }), + name: PLUGIN.NAME, navLinkId: PLUGIN.ID, icon: 'uptimeApp', app: ['uptime', 'kibana'], @@ -59,4 +54,6 @@ export const initServerWithKibana = (server: UptimeCoreSetup, plugins: UptimeCor }, }, }); + + initUptimeServer(libs); }; diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts similarity index 85% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts rename to x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index fb2052bb4c87f1..8dde6050d5d36c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -6,13 +6,9 @@ import { GraphQLSchema } from 'graphql'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { - SavedObjectsLegacyService, - IRouter, - CallAPIOptions, - SavedObjectsClientContract, -} from 'src/core/server'; +import { IRouter, CallAPIOptions, SavedObjectsClientContract } from 'src/core/server'; import { UMKibanaRoute } from '../../../rest_api'; +import { PluginSetupContract } from '../../../../../features/server'; type APICaller = ( endpoint: string, @@ -34,9 +30,8 @@ export interface UptimeCoreSetup { } export interface UptimeCorePlugins { - savedObjects: SavedObjectsLegacyService; + features: PluginSetupContract; usageCollection: UsageCollectionSetup; - xpack: any; } export interface UMBackendFrameworkAdapter { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/index.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/framework/index.ts rename to x-pack/plugins/uptime/server/lib/adapters/framework/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts rename to x-pack/plugins/uptime/server/lib/adapters/framework/kibana_framework_adapter.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts b/x-pack/plugins/uptime/server/lib/adapters/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/index.ts rename to x-pack/plugins/uptime/server/lib/adapters/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/__tests__/__snapshots__/kibana_telemetry_adapter.test.ts.snap b/x-pack/plugins/uptime/server/lib/adapters/telemetry/__tests__/__snapshots__/kibana_telemetry_adapter.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/__tests__/__snapshots__/kibana_telemetry_adapter.test.ts.snap rename to x-pack/plugins/uptime/server/lib/adapters/telemetry/__tests__/__snapshots__/kibana_telemetry_adapter.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/__tests__/kibana_telemetry_adapter.test.ts b/x-pack/plugins/uptime/server/lib/adapters/telemetry/__tests__/kibana_telemetry_adapter.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/__tests__/kibana_telemetry_adapter.test.ts rename to x-pack/plugins/uptime/server/lib/adapters/telemetry/__tests__/kibana_telemetry_adapter.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/index.ts b/x-pack/plugins/uptime/server/lib/adapters/telemetry/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/index.ts rename to x-pack/plugins/uptime/server/lib/adapters/telemetry/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts b/x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts rename to x-pack/plugins/uptime/server/lib/adapters/telemetry/kibana_telemetry_adapter.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts b/x-pack/plugins/uptime/server/lib/compose/kibana.ts similarity index 80% rename from x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts rename to x-pack/plugins/uptime/server/lib/compose/kibana.ts index 875a5d9dc8c5c1..edda5cb283323f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/compose/kibana.ts +++ b/x-pack/plugins/uptime/server/lib/compose/kibana.ts @@ -8,9 +8,9 @@ import { UMKibanaBackendFrameworkAdapter } from '../adapters/framework'; import * as requests from '../requests'; import { licenseCheck } from '../domains'; import { UMDomainLibs, UMServerLibs } from '../lib'; -import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters/framework'; +import { UptimeCoreSetup } from '../adapters/framework'; -export function compose(server: UptimeCoreSetup, plugins: UptimeCorePlugins): UMServerLibs { +export function compose(server: UptimeCoreSetup): UMServerLibs { const framework = new UMKibanaBackendFrameworkAdapter(server); const domainLibs: UMDomainLibs = { diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap b/x-pack/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap rename to x-pack/plugins/uptime/server/lib/domains/__tests__/__snapshots__/license.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts b/x-pack/plugins/uptime/server/lib/domains/__tests__/license.test.ts similarity index 93% rename from x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts rename to x-pack/plugins/uptime/server/lib/domains/__tests__/license.test.ts index 8c47b318da9bdc..b842f55fc75792 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/__tests__/license.test.ts +++ b/x-pack/plugins/uptime/server/lib/domains/__tests__/license.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ILicense } from '../../../../../../../plugins/licensing/server'; +import { ILicense } from '../../../../../licensing/server'; import { licenseCheck } from '../license'; describe('license check', () => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/index.ts b/x-pack/plugins/uptime/server/lib/domains/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/domains/index.ts rename to x-pack/plugins/uptime/server/lib/domains/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts b/x-pack/plugins/uptime/server/lib/domains/license.ts similarity index 93% rename from x-pack/legacy/plugins/uptime/server/lib/domains/license.ts rename to x-pack/plugins/uptime/server/lib/domains/license.ts index b8b5722d798777..d272424379e48c 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/license.ts +++ b/x-pack/plugins/uptime/server/lib/domains/license.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ILicense } from '../../../../../../plugins/licensing/server'; +import { ILicense } from '../../../../licensing/server'; export interface UMLicenseStatusResponse { statusCode: number; diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/assert_close_to.test.ts.snap b/x-pack/plugins/uptime/server/lib/helper/__test__/__snapshots__/assert_close_to.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/assert_close_to.test.ts.snap rename to x-pack/plugins/uptime/server/lib/helper/__test__/__snapshots__/assert_close_to.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/get_filter_clause.test.ts.snap b/x-pack/plugins/uptime/server/lib/helper/__test__/__snapshots__/get_filter_clause.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/__snapshots__/get_filter_clause.test.ts.snap rename to x-pack/plugins/uptime/server/lib/helper/__test__/__snapshots__/get_filter_clause.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/assert_close_to.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/assert_close_to.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/assert_close_to.test.ts rename to x-pack/plugins/uptime/server/lib/helper/__test__/assert_close_to.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_filter_clause.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/get_filter_clause.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_filter_clause.test.ts rename to x-pack/plugins/uptime/server/lib/helper/__test__/get_filter_clause.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts rename to x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts rename to x-pack/plugins/uptime/server/lib/helper/__test__/get_histogram_interval_formatted.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts b/x-pack/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts rename to x-pack/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/assert_close_to.ts b/x-pack/plugins/uptime/server/lib/helper/assert_close_to.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/assert_close_to.ts rename to x-pack/plugins/uptime/server/lib/helper/assert_close_to.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_filter_clause.ts b/x-pack/plugins/uptime/server/lib/helper/get_filter_clause.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/get_filter_clause.ts rename to x-pack/plugins/uptime/server/lib/helper/get_filter_clause.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts b/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts rename to x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts index 26515fb4b4c63b..fb44f5727aab38 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts +++ b/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval.ts @@ -5,7 +5,7 @@ */ import DateMath from '@elastic/datemath'; -import { QUERY } from '../../../common/constants'; +import { QUERY } from '../../../../../legacy/plugins/uptime/common/constants'; export const parseRelativeDate = (dateStr: string, options = {}) => { // We need this this parsing because if user selects This week or this date diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts b/x-pack/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts rename to x-pack/plugins/uptime/server/lib/helper/get_histogram_interval_formatted.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/index.ts b/x-pack/plugins/uptime/server/lib/helper/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/index.ts rename to x-pack/plugins/uptime/server/lib/helper/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/make_date_rate_filter.ts b/x-pack/plugins/uptime/server/lib/helper/make_date_rate_filter.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/make_date_rate_filter.ts rename to x-pack/plugins/uptime/server/lib/helper/make_date_rate_filter.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/object_to_array.ts b/x-pack/plugins/uptime/server/lib/helper/object_to_array.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/helper/object_to_array.ts rename to x-pack/plugins/uptime/server/lib/helper/object_to_array.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/lib.ts b/x-pack/plugins/uptime/server/lib/lib.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/lib.ts rename to x-pack/plugins/uptime/server/lib/lib.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap rename to x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/extract_filter_aggs_results.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/generate_filter_aggs.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/generate_filter_aggs.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/generate_filter_aggs.test.ts.snap rename to x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/generate_filter_aggs.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_monitor_charts.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_monitor_charts.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_monitor_charts.test.ts.snap rename to x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_monitor_charts.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_ping_histogram.test.ts.snap b/x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_ping_histogram.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_ping_histogram.test.ts.snap rename to x-pack/plugins/uptime/server/lib/requests/__tests__/__snapshots__/get_ping_histogram.test.ts.snap diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/combine_range_with_filters.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/combine_range_with_filters.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/combine_range_with_filters.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/combine_range_with_filters.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/extract_filter_aggs_results.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/generate_filter_aggs.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/generate_filter_aggs.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/generate_filter_aggs.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/generate_filter_aggs.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/get_latest_monitor.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/get_monitor_charts.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/get_ping_histogram.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts b/x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts rename to x-pack/plugins/uptime/server/lib/requests/__tests__/get_pings.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/monitor_charts_mock.json b/x-pack/plugins/uptime/server/lib/requests/__tests__/monitor_charts_mock.json similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/__tests__/monitor_charts_mock.json rename to x-pack/plugins/uptime/server/lib/requests/__tests__/monitor_charts_mock.json diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/generate_filter_aggs.ts b/x-pack/plugins/uptime/server/lib/requests/generate_filter_aggs.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/generate_filter_aggs.ts rename to x-pack/plugins/uptime/server/lib/requests/generate_filter_aggs.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_filter_bar.ts b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts similarity index 94% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_filter_bar.ts rename to x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts index 79259afe2b9eb3..affe205a46844e 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_filter_bar.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_filter_bar.ts @@ -5,9 +5,9 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { OverviewFilters } from '../../../common/runtime_types'; +import { OverviewFilters } from '../../../../../legacy/plugins/uptime/common/runtime_types'; import { generateFilterAggs } from './generate_filter_aggs'; -import { INDEX_NAMES } from '../../../common/constants'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export interface GetFilterBarParams { /** @param dateRangeStart timestamp bounds */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_index_pattern.ts b/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts similarity index 92% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_index_pattern.ts rename to x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts index 4b40f800b6779c..1ba1eb62e8439a 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_index_pattern.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_index_pattern.ts @@ -6,8 +6,8 @@ import { APICaller } from 'src/core/server'; import { UMElasticsearchQueryFn } from '../adapters'; -import { IndexPatternsFetcher, IIndexPattern } from '../../../../../../../src/plugins/data/server'; -import { INDEX_NAMES } from '../../../common/constants'; +import { IndexPatternsFetcher, IIndexPattern } from '../../../../../../src/plugins/data/server'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export const getUptimeIndexPattern: UMElasticsearchQueryFn = async callES => { const indexPatternsFetcher = new IndexPatternsFetcher((...rest: Parameters) => diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_index_status.ts b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts similarity index 76% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_index_status.ts rename to x-pack/plugins/uptime/server/lib/requests/get_index_status.ts index e801b05d057f47..95aa7eeef88e19 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_index_status.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_index_status.ts @@ -5,8 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { StatesIndexStatus } from '../../../common/graphql/types'; -import { INDEX_NAMES } from '../../../common/constants'; +import { StatesIndexStatus } from '../../../../../legacy/plugins/uptime/common/graphql/types'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export const getIndexStatus: UMElasticsearchQueryFn<{}, StatesIndexStatus> = async ({ callES }) => { const { diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_latest_monitor.ts b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts similarity index 91% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_latest_monitor.ts rename to x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts index bfaee3f2bf7eea..2d549fce06884f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_latest_monitor.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_latest_monitor.ts @@ -5,8 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Ping } from '../../../common/graphql/types'; -import { INDEX_NAMES } from '../../../common/constants'; +import { Ping } from '../../../../../legacy/plugins/uptime/common/graphql/types'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export interface GetLatestMonitorParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor.ts similarity index 87% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor.ts rename to x-pack/plugins/uptime/server/lib/requests/get_monitor.ts index 94175616f374e2..20103042f19abf 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor.ts @@ -5,8 +5,8 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Ping } from '../../../common/graphql/types'; -import { INDEX_NAMES } from '../../../common/constants'; +import { Ping } from '../../../../../legacy/plugins/uptime/common/graphql/types'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export interface GetMonitorParams { /** @member monitorId optional limit to monitorId */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_charts.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.ts similarity index 96% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_charts.ts rename to x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.ts index b97cc7287e921f..7dd17ef9aa80f1 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_charts.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_charts.ts @@ -5,9 +5,12 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { INDEX_NAMES } from '../../../common/constants'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; import { getHistogramIntervalFormatted } from '../helper'; -import { MonitorChart, LocationDurationLine } from '../../../common/graphql/types'; +import { + MonitorChart, + LocationDurationLine, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; export interface GetMonitorChartsParams { /** @member monitorId ID value for the selected monitor */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_details.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts similarity index 88% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_details.ts rename to x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts index b516fde1ce844b..eb3657e60a7bbb 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_details.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_details.ts @@ -5,8 +5,11 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { MonitorDetails, MonitorError } from '../../../common/runtime_types'; -import { INDEX_NAMES } from '../../../common/constants'; +import { + MonitorDetails, + MonitorError, +} from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export interface GetMonitorDetailsParams { monitorId: string; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_locations.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts similarity index 92% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_locations.ts rename to x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts index e1a0e14fe951d5..328ef54c404d37 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_locations.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_locations.ts @@ -5,8 +5,14 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { INDEX_NAMES, UNNAMED_LOCATION } from '../../../common/constants'; -import { MonitorLocations, MonitorLocation } from '../../../common/runtime_types'; +import { + INDEX_NAMES, + UNNAMED_LOCATION, +} from '../../../../../legacy/plugins/uptime/common/constants'; +import { + MonitorLocations, + MonitorLocation, +} from '../../../../../legacy/plugins/uptime/common/runtime_types'; /** * Fetch data for the monitor page title. diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_states.ts b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts similarity index 89% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_states.ts rename to x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts index 32c82b1fa2098d..5b02e2502a27e1 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_monitor_states.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_monitor_states.ts @@ -4,10 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CONTEXT_DEFAULTS } from '../../../common/constants'; +import { CONTEXT_DEFAULTS } from '../../../../../legacy/plugins/uptime/common/constants'; import { fetchPage } from './search'; import { UMElasticsearchQueryFn } from '../adapters'; -import { MonitorSummary, SortOrder, CursorDirection } from '../../../common/graphql/types'; +import { + MonitorSummary, + SortOrder, + CursorDirection, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; import { QueryContext } from './search'; export interface CursorPagination { diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts similarity index 93% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts rename to x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts index 7b8ca4708255c8..339409b63a4f6f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -5,10 +5,10 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; +import { INDEX_NAMES, QUERY } from '../../../../../legacy/plugins/uptime/common/constants'; import { getFilterClause } from '../helper'; -import { INDEX_NAMES, QUERY } from '../../../common/constants'; import { HistogramQueryResult } from './types'; -import { HistogramResult } from '../../../common/types'; +import { HistogramResult } from '../../../../../legacy/plugins/uptime/common/types'; export interface GetPingHistogramParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_pings.ts b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts similarity index 93% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_pings.ts rename to x-pack/plugins/uptime/server/lib/requests/get_pings.ts index 381aca720dc1d9..ddca27d7820663 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_pings.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_pings.ts @@ -5,8 +5,12 @@ */ import { UMElasticsearchQueryFn } from '../adapters/framework'; -import { PingResults, Ping, HttpBody } from '../../../common/graphql/types'; -import { INDEX_NAMES } from '../../../common/constants'; +import { + PingResults, + Ping, + HttpBody, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; +import { INDEX_NAMES } from '../../../../../legacy/plugins/uptime/common/constants'; export interface GetPingsParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts similarity index 96% rename from x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts rename to x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts index 8d84c0f4d6769f..050e906f01c621 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/get_snapshot_counts.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_snapshot_counts.ts @@ -5,9 +5,12 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Snapshot } from '../../../common/runtime_types'; +import { Snapshot } from '../../../../../legacy/plugins/uptime/common/runtime_types'; +import { + CONTEXT_DEFAULTS, + INDEX_NAMES, +} from '../../../../../legacy/plugins/uptime/common/constants'; import { QueryContext } from './search'; -import { CONTEXT_DEFAULTS, INDEX_NAMES } from '../../../common/constants'; export interface GetSnapshotCountParams { dateRangeStart: string; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/index.ts b/x-pack/plugins/uptime/server/lib/requests/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/index.ts rename to x-pack/plugins/uptime/server/lib/requests/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts similarity index 96% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts rename to x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts index d519a4e75463f2..f542773f32796e 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/fetch_page.test.ts @@ -12,7 +12,7 @@ import { MonitorGroupsPage, } from '../fetch_page'; import { QueryContext } from '../query_context'; -import { MonitorSummary } from '../../../../../common/graphql/types'; +import { MonitorSummary } from '../../../../../../../legacy/plugins/uptime/common/graphql/types'; import { nextPagination, prevPagination, simpleQueryContext } from './test_helpers'; const simpleFixture: MonitorGroups[] = [ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/monitor_group_iterator.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/monitor_group_iterator.test.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/monitor_group_iterator.test.ts rename to x-pack/plugins/uptime/server/lib/requests/search/__tests__/monitor_group_iterator.test.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts rename to x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts index 86506c2c4c044d..ea81ec623e01c7 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/query_context.test.ts @@ -6,7 +6,10 @@ import { QueryContext } from '../query_context'; import { CursorPagination } from '../types'; -import { CursorDirection, SortOrder } from '../../../../../common/graphql/types'; +import { + CursorDirection, + SortOrder, +} from '../../../../../../../legacy/plugins/uptime/common/graphql/types'; describe(QueryContext, () => { // 10 minute range diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts similarity index 88% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts rename to x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts index 98b192d14f91a6..d96f8dc95aa722 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/test_helpers.ts @@ -5,7 +5,10 @@ */ import { CursorPagination } from '../types'; -import { CursorDirection, SortOrder } from '../../../../../common/graphql/types'; +import { + CursorDirection, + SortOrder, +} from '../../../../../../../legacy/plugins/uptime/common/graphql/types'; import { QueryContext } from '../query_context'; export const prevPagination = (key: any): CursorPagination => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts similarity index 98% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts rename to x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts index e37c749e63566f..9ad3928a3b1b22 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts @@ -7,14 +7,14 @@ import { get, sortBy } from 'lodash'; import { QueryContext } from './query_context'; import { getHistogramIntervalFormatted } from '../../helper'; -import { INDEX_NAMES, STATES } from '../../../../common/constants'; +import { INDEX_NAMES, STATES } from '../../../../../../legacy/plugins/uptime/common/constants'; import { MonitorSummary, SummaryHistogram, Check, CursorDirection, SortOrder, -} from '../../../../common/graphql/types'; +} from '../../../../../../legacy/plugins/uptime/common/graphql/types'; import { MonitorEnricher } from './fetch_page'; export const enrichMonitorGroups: MonitorEnricher = async ( diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/fetch_chunk.ts b/x-pack/plugins/uptime/server/lib/requests/search/fetch_chunk.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/fetch_chunk.ts rename to x-pack/plugins/uptime/server/lib/requests/search/fetch_chunk.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/fetch_page.ts b/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts similarity index 96% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/fetch_page.ts rename to x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts index 6440850dc0ffc0..62144dacbd3777 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/fetch_page.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/fetch_page.ts @@ -7,8 +7,12 @@ import { flatten } from 'lodash'; import { CursorPagination } from './types'; import { QueryContext } from './query_context'; -import { QUERY } from '../../../../common/constants'; -import { CursorDirection, MonitorSummary, SortOrder } from '../../../../common/graphql/types'; +import { QUERY } from '../../../../../../legacy/plugins/uptime/common/constants'; +import { + CursorDirection, + MonitorSummary, + SortOrder, +} from '../../../../../../legacy/plugins/uptime/common/graphql/types'; import { enrichMonitorGroups } from './enrich_monitor_groups'; import { MonitorGroupIterator } from './monitor_group_iterator'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/find_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts similarity index 95% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/find_potential_matches.ts rename to x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts index fc0e35b279e0b0..9b3b1186472be8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/find_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/find_potential_matches.ts @@ -5,8 +5,8 @@ */ import { get, set } from 'lodash'; -import { CursorDirection } from '../../../../common/graphql/types'; -import { INDEX_NAMES } from '../../../../common/constants'; +import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/graphql/types'; +import { INDEX_NAMES } from '../../../../../../legacy/plugins/uptime/common/constants'; import { QueryContext } from './query_context'; // This is the first phase of the query. In it, we find the most recent check groups that matched the given query. diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/index.ts b/x-pack/plugins/uptime/server/lib/requests/search/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/index.ts rename to x-pack/plugins/uptime/server/lib/requests/search/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts b/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts similarity index 98% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts rename to x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts index ced557dbf62e08..267551907c5e8f 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/monitor_group_iterator.ts @@ -6,7 +6,7 @@ import { QueryContext } from './query_context'; import { fetchChunk } from './fetch_chunk'; -import { CursorDirection } from '../../../../common/graphql/types'; +import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/graphql/types'; import { MonitorGroups } from './fetch_page'; import { CursorPagination } from './types'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/query_context.ts b/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts similarity index 97% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/query_context.ts rename to x-pack/plugins/uptime/server/lib/requests/search/query_context.ts index f5b13c165d87d9..c1f5d89ec1a388 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/query_context.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/query_context.ts @@ -6,7 +6,7 @@ import moment from 'moment'; import { APICaller } from 'src/core/server'; -import { INDEX_NAMES } from '../../../../common/constants'; +import { INDEX_NAMES } from '../../../../../../legacy/plugins/uptime/common/constants'; import { CursorPagination } from './types'; import { parseRelativeDate } from '../../helper'; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts similarity index 96% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts rename to x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts index a55301555c8bf1..c55aff3e8c4cd4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/refine_potential_matches.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { INDEX_NAMES } from '../../../../common/constants'; +import { INDEX_NAMES } from '../../../../../../legacy/plugins/uptime/common/constants'; import { QueryContext } from './query_context'; -import { CursorDirection } from '../../../../common/graphql/types'; +import { CursorDirection } from '../../../../../../legacy/plugins/uptime/common/graphql/types'; import { MonitorGroups, MonitorLocCheckGroup } from './fetch_page'; /** diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/search/types.ts b/x-pack/plugins/uptime/server/lib/requests/search/types.ts similarity index 76% rename from x-pack/legacy/plugins/uptime/server/lib/requests/search/types.ts rename to x-pack/plugins/uptime/server/lib/requests/search/types.ts index dc6021a91146af..42c98ace6e8f5e 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/search/types.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/types.ts @@ -4,7 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CursorDirection, SortOrder } from '../../../../common/graphql/types'; +import { + CursorDirection, + SortOrder, +} from '../../../../../../legacy/plugins/uptime/common/graphql/types'; export interface CursorPagination { cursorKey?: any; diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/types.ts b/x-pack/plugins/uptime/server/lib/requests/types.ts similarity index 89% rename from x-pack/legacy/plugins/uptime/server/lib/requests/types.ts rename to x-pack/plugins/uptime/server/lib/requests/types.ts index e17eb546712a94..53a4e989e37893 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/types.ts +++ b/x-pack/plugins/uptime/server/lib/requests/types.ts @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Ping, PingResults } from '../../../common/graphql/types'; +import { Ping, PingResults } from '../../../../../legacy/plugins/uptime/common/graphql/types'; import { UMElasticsearchQueryFn } from '../adapters'; -import { GetPingHistogramParams, HistogramResult } from '../../../common/types'; +import { + GetPingHistogramParams, + HistogramResult, +} from '../../../../../legacy/plugins/uptime/common/types'; export interface GetAllParams { /** @member dateRangeStart timestamp bounds */ diff --git a/x-pack/legacy/plugins/uptime/server/lib/requests/uptime_requests.ts b/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts similarity index 83% rename from x-pack/legacy/plugins/uptime/server/lib/requests/uptime_requests.ts rename to x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts index 73be850306202e..8a411368c228f4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/requests/uptime_requests.ts +++ b/x-pack/plugins/uptime/server/lib/requests/uptime_requests.ts @@ -5,7 +5,12 @@ */ import { UMElasticsearchQueryFn } from '../adapters'; -import { Ping, MonitorChart, PingResults, StatesIndexStatus } from '../../../common/graphql/types'; +import { + Ping, + MonitorChart, + PingResults, + StatesIndexStatus, +} from '../../../../../legacy/plugins/uptime/common/graphql/types'; import { GetFilterBarParams, GetLatestMonitorParams, @@ -22,10 +27,10 @@ import { MonitorDetails, MonitorLocations, Snapshot, -} from '../../../common/runtime_types'; +} from '../../../../../legacy/plugins/uptime/common/runtime_types'; import { GetMonitorStatesResult } from './get_monitor_states'; import { GetSnapshotCountParams } from './get_snapshot_counts'; -import { HistogramResult } from '../../../common/types'; +import { HistogramResult } from '../../../../../legacy/plugins/uptime/common/types'; type ESQ = UMElasticsearchQueryFn; diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts new file mode 100644 index 00000000000000..e217b0e2f1ad8d --- /dev/null +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PluginInitializerContext, CoreStart, CoreSetup } from '../../../../src/core/server'; +import { initServerWithKibana } from './kibana.index'; +import { UptimeCorePlugins } from './lib/adapters'; + +export class Plugin { + constructor(_initializerContext: PluginInitializerContext) {} + public setup(core: CoreSetup, plugins: UptimeCorePlugins) { + initServerWithKibana({ route: core.http.createRouter() }, plugins); + } + public start(_core: CoreStart, _plugins: any) {} +} diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/create_route_with_auth.ts rename to x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index.ts b/x-pack/plugins/uptime/server/rest_api/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/index.ts rename to x-pack/plugins/uptime/server/rest_api/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts b/x-pack/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts rename to x-pack/plugins/uptime/server/rest_api/index_pattern/get_index_pattern.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/index.ts b/x-pack/plugins/uptime/server/rest_api/index_pattern/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/index_pattern/index.ts rename to x-pack/plugins/uptime/server/rest_api/index_pattern/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts b/x-pack/plugins/uptime/server/rest_api/monitors/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/monitors/index.ts rename to x-pack/plugins/uptime/server/rest_api/monitors/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitor_locations.ts rename to x-pack/plugins/uptime/server/rest_api/monitors/monitor_locations.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts b/x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/monitors/monitors_details.ts rename to x-pack/plugins/uptime/server/rest_api/monitors/monitors_details.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/monitors/status.ts b/x-pack/plugins/uptime/server/rest_api/monitors/status.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/monitors/status.ts rename to x-pack/plugins/uptime/server/rest_api/monitors/status.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts b/x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts rename to x-pack/plugins/uptime/server/rest_api/overview_filters/get_overview_filters.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/overview_filters/index.ts b/x-pack/plugins/uptime/server/rest_api/overview_filters/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/overview_filters/index.ts rename to x-pack/plugins/uptime/server/rest_api/overview_filters/index.ts diff --git a/x-pack/plugins/uptime/server/rest_api/pings/get_all.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_all.ts new file mode 100644 index 00000000000000..21168edfc97445 --- /dev/null +++ b/x-pack/plugins/uptime/server/rest_api/pings/get_all.ts @@ -0,0 +1,48 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { UMServerLibs } from '../../lib/lib'; +import { UMRestApiRouteFactory } from '../types'; + +export const createGetAllRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ + method: 'GET', + path: '/api/uptime/pings', + validate: { + query: schema.object({ + dateRangeStart: schema.string(), + dateRangeEnd: schema.string(), + location: schema.maybe(schema.string()), + monitorId: schema.maybe(schema.string()), + size: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + status: schema.maybe(schema.string()), + }), + }, + options: { + tags: ['access:uptime'], + }, + handler: async ({ callES }, _context, request, response): Promise => { + const { dateRangeStart, dateRangeEnd, location, monitorId, size, sort, status } = request.query; + + const result = await libs.requests.getPings({ + callES, + dateRangeStart, + dateRangeEnd, + monitorId, + status, + sort, + size, + location, + }); + + return response.ok({ + body: { + ...result, + }, + }); + }, +}); diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts rename to x-pack/plugins/uptime/server/rest_api/pings/get_ping_histogram.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/get_pings.ts b/x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/pings/get_pings.ts rename to x-pack/plugins/uptime/server/rest_api/pings/get_pings.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/pings/index.ts b/x-pack/plugins/uptime/server/rest_api/pings/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/pings/index.ts rename to x-pack/plugins/uptime/server/rest_api/pings/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts b/x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts rename to x-pack/plugins/uptime/server/rest_api/snapshot/get_snapshot_count.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/snapshot/index.ts b/x-pack/plugins/uptime/server/rest_api/snapshot/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/snapshot/index.ts rename to x-pack/plugins/uptime/server/rest_api/snapshot/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/index.ts b/x-pack/plugins/uptime/server/rest_api/telemetry/index.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/telemetry/index.ts rename to x-pack/plugins/uptime/server/rest_api/telemetry/index.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts b/x-pack/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts rename to x-pack/plugins/uptime/server/rest_api/telemetry/log_monitor_page.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts b/x-pack/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts rename to x-pack/plugins/uptime/server/rest_api/telemetry/log_overview_page.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/types.ts b/x-pack/plugins/uptime/server/rest_api/types.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/types.ts rename to x-pack/plugins/uptime/server/rest_api/types.ts diff --git a/x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts b/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/rest_api/uptime_route_wrapper.ts rename to x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts diff --git a/x-pack/legacy/plugins/uptime/server/uptime_server.ts b/x-pack/plugins/uptime/server/uptime_server.ts similarity index 100% rename from x-pack/legacy/plugins/uptime/server/uptime_server.ts rename to x-pack/plugins/uptime/server/uptime_server.ts diff --git a/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts b/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts index 429f50ec0aa5bf..0982d5fef7cb44 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/ping_histogram.ts @@ -6,7 +6,7 @@ import { expectFixtureEql } from '../graphql/helpers/expect_fixture_eql'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { assertCloseTo } from '../../../../../legacy/plugins/uptime/server/lib/helper'; +import { assertCloseTo } from '../../../../../plugins/uptime/server/lib/helper'; export default function({ getService }: FtrProviderContext) { describe('pingHistogram', () => { From 899270a108c5e47f5602c0f5c3b67a8502e47173 Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Tue, 25 Feb 2020 15:31:04 +0100 Subject: [PATCH 37/73] [Upgrade Assistant] Move out of legacy folder (#58034) * Create x-pack/plugins skeleton for upgrade assistant * Move public folder contents Move the public folder of Upgrade Assistant and migrate public to use HttpSetup (remove axios) * Include stylesheets in public * Move server side out of legacy Begin migration of Reindex worker to new platform Move imports around so that it satsifies new platform constraints like not importing server side code (even types) in client. * Updated the routes with new dependencies and removed server shim * Fix router unit tests * Fix server lib tests After changing function signatures for the reindex server factory (and others) all of the tests needed to be revisited and brought in line with the new APIs. Also used core/server mocks where appropriate * Clean up types issues * Fix setting credentials on request header * Removed the security plugin from Upgrade Assistant The security plugin is a potential future consumer of the Upgrade Assistant's deprecation feature and we would therefore not want to create a circular depedency here. We pull in the licensing plugin rather (as it is less likely that we will depend on that) and use it to determine whether security is available and enabled. * Migrate to config to new platform config xpack.upgrade_assistant.enabled * Remove unused types * Fix import issue * Move upgrade assistant back to Elasticsearch management section * Update dotfiles Added elasticsearch ui team as upgrade assistant code owner Updated i18nrc.json path * Alphabetical ordering in xpack/i18nrc.json * Implemented PR feedback Renamed callCluster -> callAsUser to be more consistent with platform naming. Added comment about why we are not using security plugin directly inside of Upgrade Assistant. Fixed long path imports and use 'src/core/..' throughout. Fixed import ordering. Renamed variables inside of telemetry lib. * Revert to longer import path In plugin.ts importing from 'kibana/server' or 'src/core/server' results in a module not found error. Co-authored-by: Elastic Machine --- .github/CODEOWNERS | 2 + x-pack/.i18nrc.json | 2 +- .../legacy/plugins/upgrade_assistant/index.ts | 44 +--- .../plugins/upgrade_assistant/public/index.ts | 7 - .../upgrade_assistant/public/legacy.ts | 106 --------- .../public/np_ready/application/app.tsx | 40 ---- .../reindex/polling_service.test.mocks.ts | 24 -- .../public/np_ready/plugin.ts | 24 -- .../plugins/upgrade_assistant/server/index.ts | 7 - .../np_ready/lib/telemetry/es_ui_open_apis.ts | 47 ---- .../lib/telemetry/es_ui_reindex_apis.ts | 58 ----- .../server/np_ready/plugin.ts | 49 ---- .../server/np_ready/routes/cluster_checkup.ts | 46 ---- .../np_ready/routes/create_request_shim.ts | 16 -- .../np_ready/routes/deprecation_logging.ts | 57 ----- .../server/np_ready/routes/reindex_indices.ts | 207 ----------------- .../server/np_ready/types.ts | 29 --- .../upgrade_assistant/common/config.ts} | 10 +- .../plugins/upgrade_assistant/common/types.ts | 13 ++ .../upgrade_assistant/common/version.ts | 0 x-pack/plugins/upgrade_assistant/kibana.json | 9 + .../public/application/_index.scss} | 0 .../public/application/app.tsx | 44 ++++ .../public}/application/app_context.tsx | 1 - .../application/components/_index.scss | 0 .../application/components/error_banner.tsx | 0 .../components/latest_minor_banner.tsx | 2 +- .../application/components/tabs.test.tsx | 28 +-- .../public}/application/components/tabs.tsx | 9 +- .../__fixtures__/checkup_api_response.json | 0 .../__snapshots__/checkup_tab.test.tsx.snap | 0 .../__snapshots__/filter_bar.test.tsx.snap | 0 .../__snapshots__/group_by_bar.test.tsx.snap | 0 .../components/tabs/checkup/_index.scss | 0 .../tabs/checkup/checkup_tab.test.tsx | 0 .../components/tabs/checkup/checkup_tab.tsx | 2 +- .../components/tabs/checkup/constants.tsx | 0 .../components/tabs/checkup/controls.tsx | 0 .../tabs/checkup/deprecations/_cell.scss | 0 .../checkup/deprecations/_deprecations.scss | 0 .../tabs/checkup/deprecations/_index.scss | 0 .../tabs/checkup/deprecations/cell.tsx | 4 +- .../checkup/deprecations/count_summary.tsx | 2 +- .../checkup/deprecations/grouped.test.tsx | 2 +- .../tabs/checkup/deprecations/grouped.tsx | 2 +- .../tabs/checkup/deprecations/health.tsx | 0 .../tabs/checkup/deprecations/index.tsx | 0 .../checkup/deprecations/index_table.test.tsx | 0 .../tabs/checkup/deprecations/index_table.tsx | 4 +- .../tabs/checkup/deprecations/list.test.tsx | 2 +- .../tabs/checkup/deprecations/list.tsx | 2 +- .../checkup/deprecations/reindex/_button.scss | 0 .../checkup/deprecations/reindex/_index.scss | 0 .../checkup/deprecations/reindex/button.tsx | 7 +- .../checklist_step.test.tsx.snap | 0 .../__snapshots__/warning_step.test.tsx.snap | 0 .../deprecations/reindex/flyout/_index.scss | 0 .../reindex/flyout/_step_progress.scss | 0 .../reindex/flyout/_warnings_step.scss | 0 .../reindex/flyout/checklist_step.test.tsx | 2 +- .../reindex/flyout/checklist_step.tsx | 2 +- .../deprecations/reindex/flyout/container.tsx | 0 .../deprecations/reindex/flyout/index.tsx | 0 .../reindex/flyout/progress.test.tsx | 2 +- .../deprecations/reindex/flyout/progress.tsx | 2 +- .../reindex/flyout/step_progress.tsx | 0 .../reindex/flyout/warning_step.test.tsx | 2 +- .../reindex/flyout/warnings_step.tsx | 2 +- .../checkup/deprecations/reindex/index.tsx | 0 .../reindex/polling_service.test.ts | 67 ++---- .../deprecations/reindex/polling_service.ts | 29 +-- .../tabs/checkup/filter_bar.test.tsx | 0 .../components/tabs/checkup/filter_bar.tsx | 0 .../tabs/checkup/group_by_bar.test.tsx | 0 .../components/tabs/checkup/group_by_bar.tsx | 0 .../components/tabs/checkup/index.tsx | 0 .../components/tabs/overview/_index.scss | 0 .../components/tabs/overview/_steps.scss | 0 .../overview/deprecation_logging_toggle.tsx | 25 +- .../components/tabs/overview/index.tsx | 2 +- .../components/tabs/overview/steps.tsx | 6 +- .../public}/application/components/types.ts | 5 +- .../public/application/render_app.tsx | 20 ++ .../public}/application/utils.test.ts | 0 .../public}/application/utils.ts | 0 .../upgrade_assistant/public/index.scss | 1 + .../upgrade_assistant/public}/index.ts | 7 +- .../upgrade_assistant/public/plugin.ts | 48 ++++ .../plugins/upgrade_assistant/server/index.ts | 19 ++ .../lib/__fixtures__/fake_deprecations.json | 0 .../lib/__mocks__/es_version_precheck.ts | 0 .../es_migration_apis.test.ts.snap | 0 .../lib/es_deprecation_logging_apis.test.ts | 20 +- .../lib/es_deprecation_logging_apis.ts | 14 +- .../server}/lib/es_migration_apis.test.ts | 26 ++- .../server}/lib/es_migration_apis.ts | 27 +-- .../server}/lib/es_version_precheck.test.ts | 2 +- .../server}/lib/es_version_precheck.ts | 2 +- .../lib/reindexing/credential_store.test.ts | 2 +- .../lib/reindexing/credential_store.ts | 5 +- .../server}/lib/reindexing/index.ts | 0 .../lib/reindexing/index_settings.test.ts | 2 +- .../server}/lib/reindexing/index_settings.ts | 4 +- .../lib/reindexing/reindex_actions.test.ts | 4 +- .../server}/lib/reindexing/reindex_actions.ts | 9 +- .../lib/reindexing/reindex_service.test.ts | 93 ++++---- .../server}/lib/reindexing/reindex_service.ts | 70 +++--- .../server}/lib/reindexing/types.ts | 0 .../server}/lib/reindexing/worker.ts | 61 +++-- .../lib/telemetry/es_ui_open_apis.test.ts | 50 ++-- .../server/lib/telemetry/es_ui_open_apis.ts | 58 +++++ .../lib/telemetry/es_ui_reindex_apis.test.ts | 56 ++--- .../lib/telemetry/es_ui_reindex_apis.ts | 64 ++++++ .../server}/lib/telemetry/index.ts | 0 .../lib/telemetry/usage_collector.test.ts | 37 +-- .../server}/lib/telemetry/usage_collector.ts | 44 ++-- .../upgrade_assistant/server/plugin.ts | 125 ++++++++++ .../server}/routes/__mocks__/request.mock.ts | 2 +- .../server}/routes/__mocks__/routes.mock.ts | 16 +- .../server}/routes/cluster_checkup.test.ts | 44 ++-- .../server/routes/cluster_checkup.ts | 43 ++++ .../routes/deprecation_logging.test.ts | 52 +++-- .../server/routes/deprecation_logging.ts | 72 ++++++ .../server}/routes/reindex_indices.test.ts | 93 ++++---- .../server/routes/reindex_indices.ts | 217 ++++++++++++++++++ .../server}/routes/telemetry.test.ts | 58 +++-- .../server}/routes/telemetry.ts | 32 ++- .../plugins/upgrade_assistant/server/types.ts | 19 ++ .../upgrade_assistant/reindexing.js | 5 +- 129 files changed, 1234 insertions(+), 1343 deletions(-) delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/public/index.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/public/legacy.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app.tsx delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.mocks.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/public/np_ready/plugin.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/index.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/plugin.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/create_request_shim.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.ts delete mode 100644 x-pack/legacy/plugins/upgrade_assistant/server/np_ready/types.ts rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready/index.ts => plugins/upgrade_assistant/common/config.ts} (54%) rename x-pack/{legacy => }/plugins/upgrade_assistant/common/types.ts (88%) rename x-pack/{legacy => }/plugins/upgrade_assistant/common/version.ts (100%) create mode 100644 x-pack/plugins/upgrade_assistant/kibana.json rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready/application/index.scss => plugins/upgrade_assistant/public/application/_index.scss} (100%) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/app.tsx rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/app_context.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/error_banner.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/latest_minor_banner.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs.test.tsx (82%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs.tsx (96%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/__fixtures__/checkup_api_response.json (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/__snapshots__/filter_bar.test.tsx.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/__snapshots__/group_by_bar.test.tsx.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/checkup_tab.test.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/checkup_tab.tsx (99%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/constants.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/controls.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/_cell.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/_deprecations.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/cell.tsx (94%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/count_summary.tsx (93%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/grouped.test.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/grouped.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/health.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/index.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/index_table.test.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/index_table.tsx (96%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/list.test.tsx (96%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/list.tsx (97%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/_button.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/button.tsx (97%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/__snapshots__/checklist_step.test.tsx.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/__snapshots__/warning_step.test.tsx.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/_step_progress.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/_warnings_step.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.test.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/checklist_step.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/container.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/index.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/progress.test.tsx (99%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/progress.tsx (99%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/step_progress.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/warning_step.test.tsx (95%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx (99%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/index.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts (63%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/deprecations/reindex/polling_service.ts (82%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/filter_bar.test.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/filter_bar.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/group_by_bar.test.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/group_by_bar.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/checkup/index.tsx (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/overview/_index.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/overview/_steps.scss (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/overview/deprecation_logging_toggle.tsx (86%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/overview/index.tsx (96%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/tabs/overview/steps.tsx (98%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/components/types.ts (89%) create mode 100644 x-pack/plugins/upgrade_assistant/public/application/render_app.tsx rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/utils.test.ts (100%) rename x-pack/{legacy/plugins/upgrade_assistant/public/np_ready => plugins/upgrade_assistant/public}/application/utils.ts (100%) create mode 100644 x-pack/plugins/upgrade_assistant/public/index.scss rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/public}/index.ts (62%) create mode 100644 x-pack/plugins/upgrade_assistant/public/plugin.ts create mode 100644 x-pack/plugins/upgrade_assistant/server/index.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/__fixtures__/fake_deprecations.json (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/__mocks__/es_version_precheck.ts (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/__snapshots__/es_migration_apis.test.ts.snap (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_deprecation_logging_apis.test.ts (75%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_deprecation_logging_apis.ts (75%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_migration_apis.test.ts (73%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_migration_apis.ts (75%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_version_precheck.test.ts (98%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/es_version_precheck.ts (98%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/credential_store.test.ts (95%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/credential_store.ts (91%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/index.ts (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/index_settings.test.ts (99%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/index_settings.ts (97%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/reindex_actions.test.ts (99%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/reindex_actions.ts (97%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/reindex_service.test.ts (95%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/reindex_service.ts (90%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/types.ts (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/reindexing/worker.ts (76%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/telemetry/es_ui_open_apis.test.ts (51%) create mode 100644 x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/telemetry/es_ui_reindex_apis.test.ts (52%) create mode 100644 x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/telemetry/index.ts (100%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/telemetry/usage_collector.test.ts (78%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/lib/telemetry/usage_collector.ts (72%) create mode 100644 x-pack/plugins/upgrade_assistant/server/plugin.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/__mocks__/request.mock.ts (92%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/__mocks__/routes.mock.ts (72%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/cluster_checkup.test.ts (73%) create mode 100644 x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/deprecation_logging.test.ts (56%) create mode 100644 x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/reindex_indices.test.ts (80%) create mode 100644 x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/telemetry.test.ts (79%) rename x-pack/{legacy/plugins/upgrade_assistant/server/np_ready => plugins/upgrade_assistant/server}/routes/telemetry.ts (66%) create mode 100644 x-pack/plugins/upgrade_assistant/server/types.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 51433f598ac16e..b924c7a1a2c297 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -179,6 +179,8 @@ /x-pack/legacy/plugins/rollup/ @elastic/es-ui /x-pack/plugins/searchprofiler/ @elastic/es-ui /x-pack/legacy/plugins/snapshot_restore/ @elastic/es-ui +/x-pack/legacy/plugins/upgrade_assistant/ @elastic/es-ui +/x-pack/plugins/upgrade_assistant/ @elastic/es-ui /x-pack/plugins/watcher/ @elastic/es-ui # Endpoint diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index b1cb9075434e87..bb084b3bb72a18 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -40,7 +40,7 @@ "xpack.taskManager": "legacy/plugins/task_manager", "xpack.transform": "legacy/plugins/transform", "xpack.triggersActionsUI": "plugins/triggers_actions_ui", - "xpack.upgradeAssistant": "legacy/plugins/upgrade_assistant", + "xpack.upgradeAssistant": "plugins/upgrade_assistant", "xpack.uptime": "legacy/plugins/uptime", "xpack.watcher": "plugins/watcher" }, diff --git a/x-pack/legacy/plugins/upgrade_assistant/index.ts b/x-pack/legacy/plugins/upgrade_assistant/index.ts index 3f98ff60a91ce1..b5e8ce47502155 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/index.ts +++ b/x-pack/legacy/plugins/upgrade_assistant/index.ts @@ -3,25 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; -import Joi from 'joi'; import { Legacy } from 'kibana'; -import { resolve } from 'path'; import mappings from './mappings.json'; -import { plugin } from './server/np_ready'; -import { CloudSetup } from '../../../plugins/cloud/server'; export function upgradeAssistant(kibana: any) { - const publicSrc = resolve(__dirname, 'public'); - const npSrc = resolve(publicSrc, 'np_ready'); - const config: Legacy.PluginSpecOptions = { id: 'upgrade_assistant', - configPrefix: 'xpack.upgrade_assistant', - require: ['elasticsearch'], uiExports: { // @ts-ignore - managementSections: ['plugins/upgrade_assistant'], savedObjectSchemas: { 'upgrade-assistant-reindex-operation': { isNamespaceAgnostic: true, @@ -30,41 +19,10 @@ export function upgradeAssistant(kibana: any) { isNamespaceAgnostic: true, }, }, - styleSheetPaths: resolve(npSrc, 'application/index.scss'), mappings, }, - publicDir: publicSrc, - - config() { - return Joi.object({ - enabled: Joi.boolean().default(true), - }).default(); - }, - - init(server: Legacy.Server) { - // Add server routes and initialize the plugin here - const instance = plugin({} as any); - const { usageCollection, cloud } = server.newPlatform.setup.plugins; - instance.setup(server.newPlatform.setup.core, { - usageCollection, - cloud: cloud as CloudSetup, - __LEGACY: { - // Legacy objects - events: server.events, - savedObjects: server.savedObjects, - - // Legacy functions - log: server.log.bind(server), - - // Legacy plugins - plugins: { - elasticsearch: server.plugins.elasticsearch, - xpack_main: server.plugins.xpack_main, - }, - }, - }); - }, + init() {}, }; return new kibana.Plugin(config); } diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/index.ts b/x-pack/legacy/plugins/upgrade_assistant/public/index.ts deleted file mode 100644 index d22b5d64b6b469..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/public/index.ts +++ /dev/null @@ -1,7 +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. - */ - -export * from './legacy'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/legacy.ts b/x-pack/legacy/plugins/upgrade_assistant/public/legacy.ts deleted file mode 100644 index b6bc6a14de2246..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/public/legacy.ts +++ /dev/null @@ -1,106 +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 { ComponentType } from 'react'; -import { i18n } from '@kbn/i18n'; - -/* LEGACY IMPORTS */ -import { npSetup } from 'ui/new_platform'; -import { wrapInI18nContext } from 'ui/i18n'; -import { management } from 'ui/management'; -// @ts-ignore -import { uiModules } from 'ui/modules'; -import routes from 'ui/routes'; -import chrome from 'ui/chrome'; -/* LEGACY IMPORTS */ - -import { NEXT_MAJOR_VERSION } from '../common/version'; -import { plugin } from './np_ready'; -import { CloudSetup } from '../../../../plugins/cloud/public'; - -const BASE_PATH = `/management/elasticsearch/upgrade_assistant`; - -export interface LegacyAppMountParameters { - __LEGACY: { renderToElement: (RootComponent: ComponentType) => void }; -} - -export interface LegacyApp { - mount(ctx: any, params: LegacyAppMountParameters): void; -} - -export interface LegacyManagementPlugin { - sections: { - get( - name: string - ): { - registerApp(app: LegacyApp): void; - }; - }; -} - -// Based on /rfcs/text/0006_management_section_service.md -export interface LegacyPlugins { - cloud?: CloudSetup; - management: LegacyManagementPlugin; - __LEGACY: { - XSRF: string; - }; -} - -function startApp() { - routes.when(`${BASE_PATH}/:view?`, { - template: - '', - }); - const { cloud } = npSetup.plugins as any; - const legacyPluginsShim: LegacyPlugins = { - cloud: cloud as CloudSetup, - __LEGACY: { - XSRF: chrome.getXsrfToken(), - }, - management: { - sections: { - get(_: string) { - return { - registerApp(app) { - management.getSection('elasticsearch').register('upgrade_assistant', { - visible: true, - display: i18n.translate('xpack.upgradeAssistant.appTitle', { - defaultMessage: '{version} Upgrade Assistant', - values: { version: `${NEXT_MAJOR_VERSION}.0` }, - }), - order: 100, - url: `#${BASE_PATH}`, - }); - - app.mount( - {}, - { - __LEGACY: { - // While there is not an NP API for registering management section apps yet - renderToElement: RootComponent => { - uiModules - .get('kibana') - .directive('upgradeAssistant', (reactDirective: any) => { - return reactDirective(wrapInI18nContext(RootComponent)); - }); - }, - }, - } - ); - }, - }; - }, - }, - }, - }; - - const pluginInstance = plugin(); - - pluginInstance.setup(npSetup.core, legacyPluginsShim); -} - -startApp(); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app.tsx b/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app.tsx deleted file mode 100644 index 571967ab114c90..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app.tsx +++ /dev/null @@ -1,40 +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 from 'react'; - -import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { NEXT_MAJOR_VERSION } from '../../../common/version'; -import { UpgradeAssistantTabs } from './components/tabs'; -import { AppContextProvider, ContextValue, AppContext } from './app_context'; - -type AppDependencies = ContextValue; - -export const RootComponent = (deps: AppDependencies) => { - return ( - -
- - - -

- -

-
-
-
- - {({ http }) => } - -
-
- ); -}; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.mocks.ts b/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.mocks.ts deleted file mode 100644 index dc7a758839fe56..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.mocks.ts +++ /dev/null @@ -1,24 +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 { ReindexStatus, ReindexStep } from '../../../../../../../../common/types'; - -export const mockClient = { - post: jest.fn().mockResolvedValue({ - lastCompletedStep: ReindexStep.created, - status: ReindexStatus.inProgress, - }), - get: jest.fn().mockResolvedValue({ - status: 200, - data: { - warnings: [], - reindexOp: null, - }, - }), -}; -jest.mock('axios', () => ({ - create: jest.fn().mockReturnValue(mockClient), -})); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/plugin.ts b/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/plugin.ts deleted file mode 100644 index ed85b988c25d63..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/plugin.ts +++ /dev/null @@ -1,24 +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 { Plugin, CoreSetup } from 'src/core/public'; -import { RootComponent } from './application/app'; -import { LegacyPlugins } from '../legacy'; - -export class UpgradeAssistantUIPlugin implements Plugin { - async setup({ http }: CoreSetup, { cloud, management, __LEGACY: { XSRF } }: LegacyPlugins) { - const appRegistrar = management.sections.get('kibana'); - const isCloudEnabled = !!(cloud && cloud.isCloudEnabled); - - return appRegistrar.registerApp({ - mount(__, { __LEGACY: { renderToElement } }) { - return renderToElement(() => RootComponent({ http, XSRF, isCloudEnabled })); - }, - }); - } - async start() {} - async stop() {} -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/index.ts b/x-pack/legacy/plugins/upgrade_assistant/server/index.ts deleted file mode 100644 index 8b0704283509d2..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/index.ts +++ /dev/null @@ -1,7 +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. - */ - -export { plugin } from './np_ready'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.ts deleted file mode 100644 index b52b3b812b7f9b..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.ts +++ /dev/null @@ -1,47 +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 { - UIOpen, - UIOpenOption, - UPGRADE_ASSISTANT_DOC_ID, - UPGRADE_ASSISTANT_TYPE, -} from '../../../../common/types'; -import { RequestShim, ServerShim } from '../../types'; - -async function incrementUIOpenOptionCounter(server: ServerShim, uiOpenOptionCounter: UIOpenOption) { - const { getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - - await internalRepository.incrementCounter( - UPGRADE_ASSISTANT_TYPE, - UPGRADE_ASSISTANT_DOC_ID, - `ui_open.${uiOpenOptionCounter}` - ); -} - -export async function upsertUIOpenOption(server: ServerShim, req: RequestShim): Promise { - const { overview, cluster, indices } = req.payload as UIOpen; - - if (overview) { - await incrementUIOpenOptionCounter(server, 'overview'); - } - - if (cluster) { - await incrementUIOpenOptionCounter(server, 'cluster'); - } - - if (indices) { - await incrementUIOpenOptionCounter(server, 'indices'); - } - - return { - overview, - cluster, - indices, - }; -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.ts deleted file mode 100644 index 626d51b298e72a..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.ts +++ /dev/null @@ -1,58 +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 { - UIReindex, - UIReindexOption, - UPGRADE_ASSISTANT_DOC_ID, - UPGRADE_ASSISTANT_TYPE, -} from '../../../../common/types'; -import { RequestShim, ServerShim } from '../../types'; - -async function incrementUIReindexOptionCounter( - server: ServerShim, - uiOpenOptionCounter: UIReindexOption -) { - const { getSavedObjectsRepository } = server.savedObjects; - const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); - const internalRepository = getSavedObjectsRepository(callWithInternalUser); - - await internalRepository.incrementCounter( - UPGRADE_ASSISTANT_TYPE, - UPGRADE_ASSISTANT_DOC_ID, - `ui_reindex.${uiOpenOptionCounter}` - ); -} - -export async function upsertUIReindexOption( - server: ServerShim, - req: RequestShim -): Promise { - const { close, open, start, stop } = req.payload as UIReindex; - - if (close) { - await incrementUIReindexOptionCounter(server, 'close'); - } - - if (open) { - await incrementUIReindexOptionCounter(server, 'open'); - } - - if (start) { - await incrementUIReindexOptionCounter(server, 'start'); - } - - if (stop) { - await incrementUIReindexOptionCounter(server, 'stop'); - } - - return { - close, - open, - start, - stop, - }; -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/plugin.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/plugin.ts deleted file mode 100644 index fae369fa59394f..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/plugin.ts +++ /dev/null @@ -1,49 +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 { Plugin, CoreSetup, CoreStart } from 'src/core/server'; -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { ServerShim, ServerShimWithRouter } from './types'; -import { credentialStoreFactory } from './lib/reindexing/credential_store'; -import { registerUpgradeAssistantUsageCollector } from './lib/telemetry'; -import { registerClusterCheckupRoutes } from './routes/cluster_checkup'; -import { registerDeprecationLoggingRoutes } from './routes/deprecation_logging'; -import { registerReindexIndicesRoutes, registerReindexWorker } from './routes/reindex_indices'; -import { CloudSetup } from '../../../../../plugins/cloud/server'; -import { registerTelemetryRoutes } from './routes/telemetry'; - -interface PluginsSetup { - __LEGACY: ServerShim; - usageCollection: UsageCollectionSetup; - cloud?: CloudSetup; -} - -export class UpgradeAssistantServerPlugin implements Plugin { - setup({ http }: CoreSetup, { __LEGACY, usageCollection, cloud }: PluginsSetup) { - const router = http.createRouter(); - const shimWithRouter: ServerShimWithRouter = { ...__LEGACY, router }; - registerClusterCheckupRoutes(shimWithRouter, { cloud }); - registerDeprecationLoggingRoutes(shimWithRouter); - - // The ReindexWorker uses a map of request headers that contain the authentication credentials - // for a given reindex. We cannot currently store these in an the .kibana index b/c we do not - // want to expose these credentials to any unauthenticated users. We also want to avoid any need - // to add a user for a special index just for upgrading. This in-memory cache allows us to - // process jobs without the browser staying on the page, but will require that jobs go into - // a paused state if no Kibana nodes have the required credentials. - const credentialStore = credentialStoreFactory(); - - const worker = registerReindexWorker(__LEGACY, credentialStore); - registerReindexIndicesRoutes(shimWithRouter, worker, credentialStore); - - // Bootstrap the needed routes and the collector for the telemetry - registerTelemetryRoutes(shimWithRouter); - registerUpgradeAssistantUsageCollector(usageCollection, __LEGACY); - } - - start(core: CoreStart, plugins: any) {} - - stop(): void {} -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.ts deleted file mode 100644 index 81cf690d813ada..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.ts +++ /dev/null @@ -1,46 +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 _ from 'lodash'; -import { ServerShimWithRouter } from '../types'; -import { getUpgradeAssistantStatus } from '../lib/es_migration_apis'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; -import { CloudSetup } from '../../../../../../plugins/cloud/server'; -import { createRequestShim } from './create_request_shim'; - -interface PluginsSetup { - cloud?: CloudSetup; -} - -export function registerClusterCheckupRoutes( - server: ServerShimWithRouter, - pluginsSetup: PluginsSetup -) { - const { cloud } = pluginsSetup; - const isCloudEnabled = !!(cloud && cloud.isCloudEnabled); - const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin'); - - server.router.get( - { - path: '/api/upgrade_assistant/status', - validate: false, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - try { - return response.ok({ - body: await getUpgradeAssistantStatus(callWithRequest, reqShim, isCloudEnabled), - }); - } catch (e) { - if (e.status === 403) { - return response.forbidden(e.message); - } - - return response.internalError({ body: e }); - } - }) - ); -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/create_request_shim.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/create_request_shim.ts deleted file mode 100644 index b1a5c8b72d0e0a..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/create_request_shim.ts +++ /dev/null @@ -1,16 +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 { KibanaRequest } from 'kibana/server'; -import { RequestShim } from '../types'; - -export const createRequestShim = (req: KibanaRequest): RequestShim => { - return { - headers: req.headers as Record, - payload: req.body || (req as any).payload, - params: req.params, - }; -}; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.ts deleted file mode 100644 index 7e19ef3fb60472..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.ts +++ /dev/null @@ -1,57 +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 { schema } from '@kbn/config-schema'; - -import { - getDeprecationLoggingStatus, - setDeprecationLogging, -} from '../lib/es_deprecation_logging_apis'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; -import { ServerShimWithRouter } from '../types'; -import { createRequestShim } from './create_request_shim'; - -export function registerDeprecationLoggingRoutes(server: ServerShimWithRouter) { - const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin'); - - server.router.get( - { - path: '/api/upgrade_assistant/deprecation_logging', - validate: false, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - try { - const result = await getDeprecationLoggingStatus(callWithRequest, reqShim); - return response.ok({ body: result }); - } catch (e) { - return response.internalError({ body: e }); - } - }) - ); - - server.router.put( - { - path: '/api/upgrade_assistant/deprecation_logging', - validate: { - body: schema.object({ - isEnabled: schema.boolean(), - }), - }, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - try { - const { isEnabled } = reqShim.payload as { isEnabled: boolean }; - return response.ok({ - body: await setDeprecationLogging(callWithRequest, reqShim, isEnabled), - }); - } catch (e) { - return response.internalError({ body: e }); - } - }) - ); -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.ts deleted file mode 100644 index c22f12316bd027..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.ts +++ /dev/null @@ -1,207 +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 { schema } from '@kbn/config-schema'; -import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; -import { SavedObjectsClientContract } from 'kibana/server'; -import { ReindexStatus } from '../../../common/types'; -import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; -import { reindexServiceFactory, ReindexWorker } from '../lib/reindexing'; -import { CredentialStore } from '../lib/reindexing/credential_store'; -import { reindexActionsFactory } from '../lib/reindexing/reindex_actions'; -import { ServerShim, ServerShimWithRouter } from '../types'; -import { createRequestShim } from './create_request_shim'; - -export function registerReindexWorker(server: ServerShim, credentialStore: CredentialStore) { - const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster( - 'admin' - ); - const xpackInfo = server.plugins.xpack_main.info; - const savedObjectsRepository = server.savedObjects.getSavedObjectsRepository( - callWithInternalUser - ); - const savedObjectsClient = new server.savedObjects.SavedObjectsClient( - savedObjectsRepository - ) as SavedObjectsClientContract; - - // Cannot pass server.log directly because it's value changes during startup (?). - // Use this function to proxy through. - const log = (tags: string | string[], data?: string | object | (() => any), timestamp?: number) => - server.log(tags, data, timestamp); - - const worker = new ReindexWorker( - savedObjectsClient, - credentialStore, - callWithRequest, - callWithInternalUser, - xpackInfo, - log - ); - - // Wait for ES connection before starting the polling loop. - server.plugins.elasticsearch.waitUntilReady().then(() => { - worker.start(); - server.events.on('stop', () => worker.stop()); - }); - - return worker; -} - -export function registerReindexIndicesRoutes( - server: ServerShimWithRouter, - worker: ReindexWorker, - credentialStore: CredentialStore -) { - const { callWithRequest } = server.plugins.elasticsearch.getCluster('admin'); - const xpackInfo = server.plugins.xpack_main.info; - const BASE_PATH = '/api/upgrade_assistant/reindex'; - - // Start reindex for an index - server.router.post( - { - path: `${BASE_PATH}/{indexName}`, - validate: { - params: schema.object({ - indexName: schema.string(), - }), - }, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - const { indexName } = reqShim.params; - const { client } = ctx.core.savedObjects; - const callCluster = callWithRequest.bind(null, reqShim) as CallCluster; - const reindexActions = reindexActionsFactory(client, callCluster); - const reindexService = reindexServiceFactory( - callCluster, - xpackInfo, - reindexActions, - server.log - ); - - try { - if (!(await reindexService.hasRequiredPrivileges(indexName))) { - return response.forbidden({ - body: `You do not have adequate privileges to reindex this index.`, - }); - } - - const existingOp = await reindexService.findReindexOperation(indexName); - - // If the reindexOp already exists and it's paused, resume it. Otherwise create a new one. - const reindexOp = - existingOp && existingOp.attributes.status === ReindexStatus.paused - ? await reindexService.resumeReindexOperation(indexName) - : await reindexService.createReindexOperation(indexName); - - // Add users credentials for the worker to use - credentialStore.set(reindexOp, reqShim.headers); - - // Kick the worker on this node to immediately pickup the new reindex operation. - worker.forceRefresh(); - - return response.ok({ body: reindexOp.attributes }); - } catch (e) { - return response.internalError({ body: e }); - } - }) - ); - - // Get status - server.router.get( - { - path: `${BASE_PATH}/{indexName}`, - validate: { - params: schema.object({ - indexName: schema.string(), - }), - }, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - const { client } = ctx.core.savedObjects; - const { indexName } = reqShim.params; - const callCluster = callWithRequest.bind(null, reqShim) as CallCluster; - const reindexActions = reindexActionsFactory(client, callCluster); - const reindexService = reindexServiceFactory( - callCluster, - xpackInfo, - reindexActions, - server.log - ); - - try { - const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); - const reindexOp = await reindexService.findReindexOperation(indexName); - // If the user doesn't have privileges than querying for warnings is going to fail. - const warnings = hasRequiredPrivileges - ? await reindexService.detectReindexWarnings(indexName) - : []; - const indexGroup = reindexService.getIndexGroup(indexName); - - return response.ok({ - body: { - reindexOp: reindexOp ? reindexOp.attributes : null, - warnings, - indexGroup, - hasRequiredPrivileges, - }, - }); - } catch (e) { - if (!e.isBoom) { - return response.internalError({ body: e }); - } - return response.customError({ - body: { - message: e.message, - }, - statusCode: e.statusCode, - }); - } - }) - ); - - // Cancel reindex - server.router.post( - { - path: `${BASE_PATH}/{indexName}/cancel`, - validate: { - params: schema.object({ - indexName: schema.string(), - }), - }, - }, - versionCheckHandlerWrapper(async (ctx, request, response) => { - const reqShim = createRequestShim(request); - const { indexName } = reqShim.params; - const { client } = ctx.core.savedObjects; - const callCluster = callWithRequest.bind(null, reqShim) as CallCluster; - const reindexActions = reindexActionsFactory(client, callCluster); - const reindexService = reindexServiceFactory( - callCluster, - xpackInfo, - reindexActions, - server.log - ); - - try { - await reindexService.cancelReindexing(indexName); - - return response.ok({ body: { acknowledged: true } }); - } catch (e) { - if (!e.isBoom) { - return response.internalError({ body: e }); - } - return response.customError({ - body: { - message: e.message, - }, - statusCode: e.statusCode, - }); - } - }) - ); -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/types.ts b/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/types.ts deleted file mode 100644 index 77ba97529c32f4..00000000000000 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/types.ts +++ /dev/null @@ -1,29 +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 { Legacy } from 'kibana'; -import { IRouter } from 'src/core/server'; -import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch'; -import { XPackMainPlugin } from '../../../xpack_main/server/xpack_main'; - -export interface ServerShim { - plugins: { - elasticsearch: ElasticsearchPlugin; - xpack_main: XPackMainPlugin; - }; - log: any; - events: any; - savedObjects: Legacy.SavedObjectsService; -} - -export interface ServerShimWithRouter extends ServerShim { - router: IRouter; -} - -export interface RequestShim { - headers: Record; - payload: any; - params: any; -} diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/index.ts b/x-pack/plugins/upgrade_assistant/common/config.ts similarity index 54% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/index.ts rename to x-pack/plugins/upgrade_assistant/common/config.ts index 020d6972f8280c..8a13aedd5fdd85 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/index.ts +++ b/x-pack/plugins/upgrade_assistant/common/config.ts @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UpgradeAssistantUIPlugin } from './plugin'; +import { schema, TypeOf } from '@kbn/config-schema'; -export const plugin = () => { - return new UpgradeAssistantUIPlugin(); -}; +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), +}); + +export type Config = TypeOf; diff --git a/x-pack/legacy/plugins/upgrade_assistant/common/types.ts b/x-pack/plugins/upgrade_assistant/common/types.ts similarity index 88% rename from x-pack/legacy/plugins/upgrade_assistant/common/types.ts rename to x-pack/plugins/upgrade_assistant/common/types.ts index 0e65506bb584d8..a0c12154988a1e 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/common/types.ts +++ b/x-pack/plugins/upgrade_assistant/common/types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch'; import { SavedObject, SavedObjectAttributes } from 'src/core/public'; export enum ReindexStep { @@ -114,3 +115,15 @@ export interface UpgradeAssistantTelemetry { export interface UpgradeAssistantTelemetrySavedObjectAttributes { [key: string]: any; } + +export interface EnrichedDeprecationInfo extends DeprecationInfo { + index?: string; + node?: string; + reindex?: boolean; +} + +export interface UpgradeAssistantStatus { + readyForUpgrade: boolean; + cluster: EnrichedDeprecationInfo[]; + indices: EnrichedDeprecationInfo[]; +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/common/version.ts b/x-pack/plugins/upgrade_assistant/common/version.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/common/version.ts rename to x-pack/plugins/upgrade_assistant/common/version.ts diff --git a/x-pack/plugins/upgrade_assistant/kibana.json b/x-pack/plugins/upgrade_assistant/kibana.json new file mode 100644 index 00000000000000..273036a653aeb8 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/kibana.json @@ -0,0 +1,9 @@ +{ + "id": "upgradeAssistant", + "version": "kibana", + "server": true, + "ui": true, + "configPath": ["xpack", "upgrade_assistant"], + "requiredPlugins": ["management", "licensing"], + "optionalPlugins": ["cloud", "usageCollection"] +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/index.scss b/x-pack/plugins/upgrade_assistant/public/application/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/index.scss rename to x-pack/plugins/upgrade_assistant/public/application/_index.scss diff --git a/x-pack/plugins/upgrade_assistant/public/application/app.tsx b/x-pack/plugins/upgrade_assistant/public/application/app.tsx new file mode 100644 index 00000000000000..17eff71f1039ba --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/app.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { I18nStart } from 'src/core/public'; +import { EuiPageHeader, EuiPageHeaderSection, EuiTitle } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { NEXT_MAJOR_VERSION } from '../../common/version'; +import { UpgradeAssistantTabs } from './components/tabs'; +import { AppContextProvider, ContextValue, AppContext } from './app_context'; + +export interface AppDependencies extends ContextValue { + i18n: I18nStart; +} + +export const RootComponent = ({ i18n, ...contexValue }: AppDependencies) => { + return ( + + +
+ + + +

+ +

+
+
+
+ + {({ http }) => } + +
+
+
+ ); +}; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app_context.tsx b/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app_context.tsx rename to x-pack/plugins/upgrade_assistant/public/application/app_context.tsx index a48a4efa3bbdfb..1ae9dabd69481b 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/app_context.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/app_context.tsx @@ -9,7 +9,6 @@ import React, { createContext, useContext } from 'react'; export interface ContextValue { http: HttpSetup; isCloudEnabled: boolean; - XSRF: string; } export const AppContext = createContext({} as any); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/_index.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/_index.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/error_banner.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/error_banner.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/error_banner.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/error_banner.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/latest_minor_banner.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/latest_minor_banner.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx index 864df292fbffef..43d0364425cbb3 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/latest_minor_banner.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/latest_minor_banner.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { EuiCallOut, EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../../../common/version'; +import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../../common/version'; export const LatestMinorBanner: React.FunctionComponent = () => ( ({ - get: jest.fn(), - create: jest.fn(), -})); - +import { httpServiceMock } from 'src/core/public/mocks'; import { UpgradeAssistantTabs } from './tabs'; import { LoadingState } from './types'; -import axios from 'axios'; import { OverviewTab } from './tabs/overview'; // Used to wait for promises to resolve and renders to finish before reading updates const promisesToResolve = () => new Promise(resolve => setTimeout(resolve, 0)); -const mockHttp = { - basePath: { - prepend: () => 'test', - }, - fetch() {}, -}; +const mockHttp = httpServiceMock.createSetupContract(); describe('UpgradeAssistantTabs', () => { test('renders loading state', async () => { - // @ts-ignore - axios.get.mockReturnValue( + mockHttp.get.mockReturnValue( new Promise(resolve => { /* never resolve */ }) ); - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); // Should pass down loading status to child component expect(wrapper.find(OverviewTab).prop('loadingState')).toEqual(LoadingState.Loading); }); test('successful data fetch', async () => { // @ts-ignore - axios.get.mockResolvedValue({ + mockHttp.get.mockResolvedValue({ data: { cluster: [], indices: [], }, }); const wrapper = mountWithIntl(); - expect(axios.get).toHaveBeenCalled(); + expect(mockHttp.get).toHaveBeenCalled(); await promisesToResolve(); wrapper.update(); // Should pass down success status to child component @@ -59,7 +47,7 @@ describe('UpgradeAssistantTabs', () => { test('network failure', async () => { // @ts-ignore - axios.get.mockRejectedValue(new Error(`oh no!`)); + mockHttp.get.mockRejectedValue(new Error(`oh no!`)); const wrapper = mountWithIntl(); await promisesToResolve(); wrapper.update(); @@ -69,7 +57,7 @@ describe('UpgradeAssistantTabs', () => { it('upgrade error', async () => { // @ts-ignore - axios.get.mockRejectedValue({ response: { status: 426 } }); + mockHttp.get.mockRejectedValue({ response: { status: 426 } }); const wrapper = mountWithIntl(); await promisesToResolve(); wrapper.update(); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx similarity index 96% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx index 0b154fb20404dc..43ec5554aaaeef 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import axios from 'axios'; import { findIndex, get, set } from 'lodash'; import React from 'react'; @@ -18,7 +17,7 @@ import { import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; import { HttpSetup } from 'src/core/public'; -import { UpgradeAssistantStatus } from '../../../../server/np_ready/lib/es_migration_apis'; +import { UpgradeAssistantStatus } from '../../../common/types'; import { LatestMinorBanner } from './latest_minor_banner'; import { CheckupTab } from './tabs/checkup'; import { OverviewTab } from './tabs/overview'; @@ -153,12 +152,10 @@ export class UpgradeAssistantTabsUI extends React.Component { private loadData = async () => { try { this.setState({ loadingState: LoadingState.Loading }); - const resp = await axios.get( - this.props.http.basePath.prepend('/api/upgrade_assistant/status') - ); + const resp = await this.props.http.get('/api/upgrade_assistant/status'); this.setState({ loadingState: LoadingState.Success, - checkupData: resp.data, + checkupData: resp, }); } catch (e) { if (get(e, 'response.status') === 426) { diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/__fixtures__/checkup_api_response.json b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/__fixtures__/checkup_api_response.json similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/__fixtures__/checkup_api_response.json rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/__fixtures__/checkup_api_response.json diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/checkup_tab.test.tsx.snap diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/filter_bar.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/filter_bar.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/filter_bar.test.tsx.snap rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/filter_bar.test.tsx.snap diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/group_by_bar.test.tsx.snap b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/group_by_bar.test.tsx.snap similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/__snapshots__/group_by_bar.test.tsx.snap rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/__snapshots__/group_by_bar.test.tsx.snap diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/_index.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/_index.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/checkup_tab.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/checkup_tab.test.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/checkup_tab.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/checkup_tab.test.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/checkup_tab.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/checkup_tab.tsx similarity index 99% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/checkup_tab.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/checkup_tab.tsx index 7e862a846290b0..b047427174e083 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/checkup_tab.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/checkup_tab.tsx @@ -18,7 +18,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { NEXT_MAJOR_VERSION } from '../../../../../../common/version'; +import { NEXT_MAJOR_VERSION } from '../../../../../common/version'; import { LoadingErrorBanner } from '../../error_banner'; import { GroupByOption, diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/constants.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/controls.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/controls.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/controls.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_cell.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_cell.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_cell.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_cell.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_deprecations.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_deprecations.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_deprecations.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_deprecations.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/_index.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/_index.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/cell.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx similarity index 94% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/cell.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx index 4bd2f7c4bf62c3..879bb695ca60af 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/cell.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/cell.tsx @@ -79,9 +79,7 @@ export const DeprecationCell: FunctionComponent = ({ {reindexIndexName && ( - {({ http, XSRF }) => ( - - )} + {({ http }) => } )} diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/count_summary.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/count_summary.tsx similarity index 93% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/count_summary.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/count_summary.tsx index a0e55dc55c8656..7e5172a361a563 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/count_summary.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/count_summary.tsx @@ -8,7 +8,7 @@ import React, { Fragment, FunctionComponent } from 'react'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EnrichedDeprecationInfo } from '../../../../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; export const DeprecationCountSummary: FunctionComponent<{ deprecations: EnrichedDeprecationInfo[]; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx index 28f5f6894b78f2..c6309fb57d786e 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.test.tsx @@ -11,7 +11,7 @@ import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { EuiBadge, EuiPagination } from '@elastic/eui'; import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch'; -import { EnrichedDeprecationInfo } from '../../../../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption, LevelFilterOption } from '../../../types'; import { DeprecationAccordion, filterDeps, GroupedDeprecations } from './grouped'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx index 74f66b6c4fb35b..8fa78639c39d3b 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/grouped.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/grouped.tsx @@ -19,7 +19,7 @@ import { import { FormattedMessage } from '@kbn/i18n/react'; import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch'; -import { EnrichedDeprecationInfo } from '../../../../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption, LevelFilterOption } from '../../../types'; import { DeprecationCountSummary } from './count_summary'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/health.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/health.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/health.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index_table.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.test.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index_table.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.test.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index_table.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx similarity index 96% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index_table.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx index 835affce590708..5506528a3ded09 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/index_table.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/index_table.tsx @@ -148,9 +148,7 @@ export class IndexDeprecationTableUI extends React.Component< render(indexDep: IndexDeprecationDetails) { return ( - {({ XSRF, http }) => ( - - )} + {({ http }) => } ); }, diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx similarity index 96% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx index 78ded735934641..a1e173737bab06 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.test.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.test.tsx @@ -7,7 +7,7 @@ import { shallow } from 'enzyme'; import React from 'react'; -import { EnrichedDeprecationInfo } from '../../../../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption } from '../../../types'; import { DeprecationList } from './list'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx similarity index 97% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx index 15a3d94974dcd4..a46bc0d12fad41 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/list.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/list.tsx @@ -7,7 +7,7 @@ import React, { FunctionComponent } from 'react'; import { DeprecationInfo } from 'src/legacy/core_plugins/elasticsearch'; -import { EnrichedDeprecationInfo } from '../../../../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo } from '../../../../../../common/types'; import { GroupByOption } from '../../../types'; import { COLOR_MAP, LEVEL_MAP } from '../constants'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/_button.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/_button.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/_button.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/_button.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/_index.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/_index.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/button.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx similarity index 97% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/button.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx index 2a28018a3ae81e..30b46e0c15213e 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/button.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/button.tsx @@ -11,14 +11,13 @@ import { Subscription } from 'rxjs'; import { EuiButton, EuiLoadingSpinner } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { HttpSetup } from 'src/core/public'; -import { ReindexStatus, UIReindexOption } from '../../../../../../../../common/types'; +import { ReindexStatus, UIReindexOption } from '../../../../../../../common/types'; import { LoadingState } from '../../../../types'; import { ReindexFlyout } from './flyout'; import { ReindexPollingService, ReindexState } from './polling_service'; interface ReindexButtonProps { indexName: string; - xsrf: string; http: HttpSetup; } @@ -154,8 +153,8 @@ export class ReindexButton extends React.Component { diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx similarity index 99% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx index 91e35c0bd7dc0d..643dd2e9b6efc6 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/flyout/warnings_step.tsx @@ -21,7 +21,7 @@ import { EuiText, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ReindexWarning } from '../../../../../../../../../common/types'; +import { ReindexWarning } from '../../../../../../../../common/types'; interface CheckedIds { [id: string]: boolean; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/index.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/index.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/index.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts similarity index 63% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts index cb2a0856f0f2e9..4228426d621597 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.test.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { mockClient } from './polling_service.test.mocks'; - -import { ReindexStatus, ReindexStep } from '../../../../../../../../common/types'; +import { ReindexStatus, ReindexStep } from '../../../../../../../common/types'; import { ReindexPollingService } from './polling_service'; import { httpServiceMock } from 'src/core/public/http/http_service.mock'; +const mockClient = httpServiceMock.createSetupContract(); + describe('ReindexPollingService', () => { beforeEach(() => { mockClient.post.mockReset(); @@ -18,18 +18,11 @@ describe('ReindexPollingService', () => { it('does not poll when reindexOp is null', async () => { mockClient.get.mockResolvedValueOnce({ - status: 200, - data: { - warnings: [], - reindexOp: null, - }, + warnings: [], + reindexOp: null, }); - const service = new ReindexPollingService( - 'myIndex', - 'myXsrf', - httpServiceMock.createSetupContract() - ); + const service = new ReindexPollingService('myIndex', mockClient); service.updateStatus(); await new Promise(resolve => setTimeout(resolve, 1200)); // wait for poll interval @@ -39,22 +32,15 @@ describe('ReindexPollingService', () => { it('does not poll when first check is a 200 and status is failed', async () => { mockClient.get.mockResolvedValue({ - status: 200, - data: { - warnings: [], - reindexOp: { - lastCompletedStep: ReindexStep.created, - status: ReindexStatus.failed, - errorMessage: `Oh no!`, - }, + warnings: [], + reindexOp: { + lastCompletedStep: ReindexStep.created, + status: ReindexStatus.failed, + errorMessage: `Oh no!`, }, }); - const service = new ReindexPollingService( - 'myIndex', - 'myXsrf', - httpServiceMock.createSetupContract() - ); + const service = new ReindexPollingService('myIndex', mockClient); service.updateStatus(); await new Promise(resolve => setTimeout(resolve, 1200)); // wait for poll interval @@ -65,21 +51,14 @@ describe('ReindexPollingService', () => { it('begins to poll when first check is a 200 and status is inProgress', async () => { mockClient.get.mockResolvedValue({ - status: 200, - data: { - warnings: [], - reindexOp: { - lastCompletedStep: ReindexStep.created, - status: ReindexStatus.inProgress, - }, + warnings: [], + reindexOp: { + lastCompletedStep: ReindexStep.created, + status: ReindexStatus.inProgress, }, }); - const service = new ReindexPollingService( - 'myIndex', - 'myXsrf', - httpServiceMock.createSetupContract() - ); + const service = new ReindexPollingService('myIndex', mockClient); service.updateStatus(); await new Promise(resolve => setTimeout(resolve, 1200)); // wait for poll interval @@ -89,11 +68,7 @@ describe('ReindexPollingService', () => { describe('startReindex', () => { it('posts to endpoint', async () => { - const service = new ReindexPollingService( - 'myIndex', - 'myXsrf', - httpServiceMock.createSetupContract() - ); + const service = new ReindexPollingService('myIndex', mockClient); await service.startReindex(); expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex'); @@ -102,11 +77,7 @@ describe('ReindexPollingService', () => { describe('cancelReindex', () => { it('posts to cancel endpoint', async () => { - const service = new ReindexPollingService( - 'myIndex', - 'myXsrf', - httpServiceMock.createSetupContract() - ); + const service = new ReindexPollingService('myIndex', mockClient); await service.cancelReindex(); expect(mockClient.post).toHaveBeenCalledWith('/api/upgrade_assistant/reindex/myIndex/cancel'); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.ts b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts similarity index 82% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.ts rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts index 879fafe610982b..6fe6a859057062 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/deprecations/reindex/polling_service.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/deprecations/reindex/polling_service.ts @@ -3,8 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import axios, { AxiosInstance } from 'axios'; - import { BehaviorSubject } from 'rxjs'; import { HttpSetup } from 'src/core/public'; @@ -14,7 +12,7 @@ import { ReindexStatus, ReindexStep, ReindexWarning, -} from '../../../../../../../../common/types'; +} from '../../../../../../../common/types'; import { LoadingState } from '../../../../types'; const POLL_INTERVAL = 1000; @@ -45,24 +43,13 @@ interface StatusResponse { export class ReindexPollingService { public status$: BehaviorSubject; private pollTimeout?: NodeJS.Timeout; - private APIClient: AxiosInstance; - constructor(private indexName: string, private xsrf: string, private http: HttpSetup) { + constructor(private indexName: string, private http: HttpSetup) { this.status$ = new BehaviorSubject({ loadingState: LoadingState.Loading, errorMessage: null, reindexTaskPercComplete: null, }); - - this.APIClient = axios.create({ - headers: { - Accept: 'application/json', - credentials: 'same-origin', - 'Content-Type': 'application/json', - 'kbn-version': this.xsrf, - 'kbn-xsrf': this.xsrf, - }, - }); } public updateStatus = async () => { @@ -70,8 +57,8 @@ export class ReindexPollingService { this.stopPolling(); try { - const { data } = await this.APIClient.get( - this.http.basePath.prepend(`/api/upgrade_assistant/reindex/${this.indexName}`) + const data = await this.http.get( + `/api/upgrade_assistant/reindex/${this.indexName}` ); this.updateWithResponse(data); @@ -107,8 +94,8 @@ export class ReindexPollingService { errorMessage: null, cancelLoadingState: undefined, }); - const { data } = await this.APIClient.post( - this.http.basePath.prepend(`/api/upgrade_assistant/reindex/${this.indexName}`) + const data = await this.http.post( + `/api/upgrade_assistant/reindex/${this.indexName}` ); this.updateWithResponse({ reindexOp: data }); @@ -125,9 +112,7 @@ export class ReindexPollingService { cancelLoadingState: LoadingState.Loading, }); - await this.APIClient.post( - this.http.basePath.prepend(`/api/upgrade_assistant/reindex/${this.indexName}/cancel`) - ); + await this.http.post(`/api/upgrade_assistant/reindex/${this.indexName}/cancel`); } catch (e) { this.status$.next({ ...this.status$.value, diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/filter_bar.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/filter_bar.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.test.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/filter_bar.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/filter_bar.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/filter_bar.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/group_by_bar.test.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/group_by_bar.test.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/group_by_bar.test.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/group_by_bar.test.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/group_by_bar.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/group_by_bar.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/group_by_bar.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/group_by_bar.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/index.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/index.tsx similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/checkup/index.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/index.tsx diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/_index.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/_index.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/_index.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/_index.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/_steps.scss b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/_steps.scss similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/_steps.scss rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/_steps.scss diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/deprecation_logging_toggle.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/deprecation_logging_toggle.tsx similarity index 86% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/deprecation_logging_toggle.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/deprecation_logging_toggle.tsx index db37bc58904ec9..0e6c79dc47b537 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/deprecation_logging_toggle.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/deprecation_logging_toggle.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import axios from 'axios'; import React from 'react'; import { EuiLoadingSpinner, EuiSwitch } from '@elastic/eui'; @@ -15,7 +14,6 @@ import { HttpSetup } from 'src/core/public'; import { LoadingState } from '../../types'; interface DeprecationLoggingTabProps extends ReactIntl.InjectedIntlProps { - xsrf: string; http: HttpSetup; } @@ -88,12 +86,10 @@ export class DeprecationLoggingToggleUI extends React.Component< private loadData = async () => { try { this.setState({ loadingState: LoadingState.Loading }); - const resp = await axios.get( - this.props.http.basePath.prepend('/api/upgrade_assistant/deprecation_logging') - ); + const resp = await this.props.http.get('/api/upgrade_assistant/deprecation_logging'); this.setState({ loadingState: LoadingState.Success, - loggingEnabled: resp.data.isEnabled, + loggingEnabled: resp.isEnabled, }); } catch (e) { this.setState({ loadingState: LoadingState.Error }); @@ -102,26 +98,19 @@ export class DeprecationLoggingToggleUI extends React.Component< private toggleLogging = async () => { try { - const { http, xsrf } = this.props; // Optimistically toggle the UI const newEnabled = !this.state.loggingEnabled; this.setState({ loadingState: LoadingState.Loading, loggingEnabled: newEnabled }); - const resp = await axios.put( - http.basePath.prepend('/api/upgrade_assistant/deprecation_logging'), - { + const resp = await this.props.http.put('/api/upgrade_assistant/deprecation_logging', { + body: JSON.stringify({ isEnabled: newEnabled, - }, - { - headers: { - 'kbn-xsrf': xsrf, - }, - } - ); + }), + }); this.setState({ loadingState: LoadingState.Success, - loggingEnabled: resp.data.isEnabled, + loggingEnabled: resp.isEnabled, }); } catch (e) { this.setState({ loadingState: LoadingState.Error }); diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/index.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/index.tsx similarity index 96% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/index.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/index.tsx index 284265bb31f142..aede377fa8d45d 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/index.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/index.tsx @@ -17,7 +17,7 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { NEXT_MAJOR_VERSION } from '../../../../../../common/version'; +import { NEXT_MAJOR_VERSION } from '../../../../../common/version'; import { LoadingErrorBanner } from '../../error_banner'; import { LoadingState, UpgradeAssistantTabProps } from '../../types'; import { Steps } from './steps'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/steps.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/steps.tsx similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/steps.tsx rename to x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/steps.tsx index ccba51c73c1362..85d275b080e138 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/tabs/overview/steps.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/overview/steps.tsx @@ -19,7 +19,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; -import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../../../../../common/version'; +import { CURRENT_MAJOR_VERSION, NEXT_MAJOR_VERSION } from '../../../../../common/version'; import { UpgradeAssistantTabProps } from '../../types'; import { DeprecationLoggingToggle } from './deprecation_logging_toggle'; import { useAppContext } from '../../../app_context'; @@ -104,7 +104,7 @@ export const StepsUI: FunctionComponent - + ), diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/types.ts b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts similarity index 89% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/types.ts rename to x-pack/plugins/upgrade_assistant/public/application/components/types.ts index 2d9a373f20b7e9..86d1486543596a 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/components/types.ts +++ b/x-pack/plugins/upgrade_assistant/public/application/components/types.ts @@ -6,10 +6,7 @@ import React from 'react'; -import { - EnrichedDeprecationInfo, - UpgradeAssistantStatus, -} from '../../../../server/np_ready/lib/es_migration_apis'; +import { EnrichedDeprecationInfo, UpgradeAssistantStatus } from '../../../common/types'; export interface UpgradeAssistantTabProps { alertBanner?: React.ReactNode; diff --git a/x-pack/plugins/upgrade_assistant/public/application/render_app.tsx b/x-pack/plugins/upgrade_assistant/public/application/render_app.tsx new file mode 100644 index 00000000000000..97120cfc3333a0 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/application/render_app.tsx @@ -0,0 +1,20 @@ +/* + * 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 { render, unmountComponentAtNode } from 'react-dom'; +import { AppDependencies, RootComponent } from './app'; + +interface BootDependencies extends AppDependencies { + element: HTMLElement; +} + +export const renderApp = (deps: BootDependencies) => { + const { element, ...appDependencies } = deps; + render(, element); + return () => { + unmountComponentAtNode(element); + }; +}; diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/utils.test.ts b/x-pack/plugins/upgrade_assistant/public/application/utils.test.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/utils.test.ts rename to x-pack/plugins/upgrade_assistant/public/application/utils.test.ts diff --git a/x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/utils.ts b/x-pack/plugins/upgrade_assistant/public/application/utils.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/public/np_ready/application/utils.ts rename to x-pack/plugins/upgrade_assistant/public/application/utils.ts diff --git a/x-pack/plugins/upgrade_assistant/public/index.scss b/x-pack/plugins/upgrade_assistant/public/index.scss new file mode 100644 index 00000000000000..9bd47b64733721 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/index.scss @@ -0,0 +1 @@ +@import './application/index'; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/index.ts b/x-pack/plugins/upgrade_assistant/public/index.ts similarity index 62% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/index.ts rename to x-pack/plugins/upgrade_assistant/public/index.ts index cf1b78e1e3920f..2b1860167ef5df 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/index.ts +++ b/x-pack/plugins/upgrade_assistant/public/index.ts @@ -3,9 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext } from 'src/core/server'; -import { UpgradeAssistantServerPlugin } from './plugin'; +import './index.scss'; +import { PluginInitializerContext } from 'src/core/public'; +import { UpgradeAssistantUIPlugin } from './plugin'; export const plugin = (ctx: PluginInitializerContext) => { - return new UpgradeAssistantServerPlugin(); + return new UpgradeAssistantUIPlugin(ctx); }; diff --git a/x-pack/plugins/upgrade_assistant/public/plugin.ts b/x-pack/plugins/upgrade_assistant/public/plugin.ts new file mode 100644 index 00000000000000..614221272dd5c4 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/public/plugin.ts @@ -0,0 +1,48 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { Plugin, CoreSetup, PluginInitializerContext } from 'src/core/public'; + +import { CloudSetup } from '../../cloud/public'; +import { ManagementSetup } from '../../../../src/plugins/management/public'; + +import { NEXT_MAJOR_VERSION } from '../common/version'; +import { Config } from '../common/config'; + +import { renderApp } from './application/render_app'; + +interface Dependencies { + cloud: CloudSetup; + management: ManagementSetup; +} + +export class UpgradeAssistantUIPlugin implements Plugin { + constructor(private ctx: PluginInitializerContext) {} + setup({ http, getStartServices }: CoreSetup, { cloud, management }: Dependencies) { + const { enabled } = this.ctx.config.get(); + if (!enabled) { + return; + } + const appRegistrar = management.sections.getSection('elasticsearch')!; + const isCloudEnabled = Boolean(cloud?.isCloudEnabled); + + appRegistrar.registerApp({ + id: 'upgrade_assistant', + title: i18n.translate('xpack.upgradeAssistant.appTitle', { + defaultMessage: '{version} Upgrade Assistant', + values: { version: `${NEXT_MAJOR_VERSION}.0` }, + }), + order: 1000, + async mount({ element }) { + const [{ i18n: i18nDep }] = await getStartServices(); + return renderApp({ element, isCloudEnabled, http, i18n: i18nDep }); + }, + }); + } + + start() {} + stop() {} +} diff --git a/x-pack/plugins/upgrade_assistant/server/index.ts b/x-pack/plugins/upgrade_assistant/server/index.ts new file mode 100644 index 00000000000000..cab7eb613f74cf --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/index.ts @@ -0,0 +1,19 @@ +/* + * 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 { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; +import { UpgradeAssistantServerPlugin } from './plugin'; +import { configSchema } from '../common/config'; + +export const plugin = (ctx: PluginInitializerContext) => { + return new UpgradeAssistantServerPlugin(ctx); +}; + +export const config: PluginConfigDescriptor = { + schema: configSchema, + exposeToBrowser: { + enabled: true, + }, +}; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__fixtures__/fake_deprecations.json b/x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__fixtures__/fake_deprecations.json rename to x-pack/plugins/upgrade_assistant/server/lib/__fixtures__/fake_deprecations.json diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__mocks__/es_version_precheck.ts b/x-pack/plugins/upgrade_assistant/server/lib/__mocks__/es_version_precheck.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__mocks__/es_version_precheck.ts rename to x-pack/plugins/upgrade_assistant/server/lib/__mocks__/es_version_precheck.ts diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__snapshots__/es_migration_apis.test.ts.snap b/x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/__snapshots__/es_migration_apis.test.ts.snap rename to x-pack/plugins/upgrade_assistant/server/lib/__snapshots__/es_migration_apis.test.ts.snap diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts similarity index 75% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts index 317e2a7554e038..862f64e2323700 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { getDeprecationLoggingStatus, isDeprecationLoggingEnabled, @@ -12,9 +12,9 @@ import { describe('getDeprecationLoggingStatus', () => { it('calls cluster.getSettings', async () => { - const callWithRequest = jest.fn(); - await getDeprecationLoggingStatus(callWithRequest, {} as any); - expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.getSettings', { + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); + await getDeprecationLoggingStatus(dataClient); + expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.getSettings', { includeDefaults: true, }); }); @@ -23,9 +23,9 @@ describe('getDeprecationLoggingStatus', () => { describe('setDeprecationLogging', () => { describe('isEnabled = true', () => { it('calls cluster.putSettings with logger.deprecation = WARN', async () => { - const callWithRequest = jest.fn(); - await setDeprecationLogging(callWithRequest, {} as any, true); - expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.putSettings', { + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); + await setDeprecationLogging(dataClient, true); + expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.putSettings', { body: { transient: { 'logger.deprecation': 'WARN' } }, }); }); @@ -33,9 +33,9 @@ describe('setDeprecationLogging', () => { describe('isEnabled = false', () => { it('calls cluster.putSettings with logger.deprecation = ERROR', async () => { - const callWithRequest = jest.fn(); - await setDeprecationLogging(callWithRequest, {} as any, false); - expect(callWithRequest).toHaveBeenCalledWith({}, 'cluster.putSettings', { + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); + await setDeprecationLogging(dataClient, false); + expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('cluster.putSettings', { body: { transient: { 'logger.deprecation': 'ERROR' } }, }); }); diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts similarity index 75% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts index 199d3894084427..8f25533c0afb1e 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_deprecation_logging_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_deprecation_logging_apis.ts @@ -4,19 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ import { get } from 'lodash'; - -import { CallClusterWithRequest } from 'src/legacy/core_plugins/elasticsearch'; -import { RequestShim } from '../types'; +import { IScopedClusterClient } from 'src/core/server'; interface DeprecationLoggingStatus { isEnabled: boolean; } export async function getDeprecationLoggingStatus( - callWithRequest: CallClusterWithRequest, - req: RequestShim + dataClient: IScopedClusterClient ): Promise { - const response = await callWithRequest(req, 'cluster.getSettings', { + const response = await dataClient.callAsCurrentUser('cluster.getSettings', { includeDefaults: true, }); @@ -26,11 +23,10 @@ export async function getDeprecationLoggingStatus( } export async function setDeprecationLogging( - callWithRequest: CallClusterWithRequest, - req: RequestShim, + dataClient: IScopedClusterClient, isEnabled: boolean ): Promise { - const response = await callWithRequest(req, 'cluster.putSettings', { + const response = await dataClient.callAsCurrentUser('cluster.putSettings', { body: { transient: { 'logger.deprecation': isEnabled ? 'WARN' : 'ERROR', diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts similarity index 73% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts index a1d7049e4171f2..4ab4227ba3e919 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.test.ts @@ -5,6 +5,7 @@ */ import _ from 'lodash'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { getUpgradeAssistantStatus } from './es_migration_apis'; import { DeprecationAPIResponse } from 'src/legacy/core_plugins/elasticsearch'; @@ -13,7 +14,8 @@ import fakeDeprecations from './__fixtures__/fake_deprecations.json'; describe('getUpgradeAssistantStatus', () => { let deprecationsResponse: DeprecationAPIResponse; - const callWithRequest = jest.fn().mockImplementation(async (req, api, { path }) => { + const dataClient = elasticsearchServiceMock.createScopedClusterClient(); + (dataClient.callAsCurrentUser as jest.Mock).mockImplementation(async (api, { path }) => { if (path === '/_migration/deprecations') { return deprecationsResponse; } else if (api === 'indices.getMapping') { @@ -28,15 +30,15 @@ describe('getUpgradeAssistantStatus', () => { }); it('calls /_migration/deprecations', async () => { - await getUpgradeAssistantStatus(callWithRequest, {} as any, false); - expect(callWithRequest).toHaveBeenCalledWith({}, 'transport.request', { + await getUpgradeAssistantStatus(dataClient, false); + expect(dataClient.callAsCurrentUser).toHaveBeenCalledWith('transport.request', { path: '/_migration/deprecations', method: 'GET', }); }); it('returns the correct shape of data', async () => { - const resp = await getUpgradeAssistantStatus(callWithRequest, {} as any, false); + const resp = await getUpgradeAssistantStatus(dataClient, false); expect(resp).toMatchSnapshot(); }); @@ -48,9 +50,10 @@ describe('getUpgradeAssistantStatus', () => { index_settings: {}, }; - await expect( - getUpgradeAssistantStatus(callWithRequest, {} as any, false) - ).resolves.toHaveProperty('readyForUpgrade', false); + await expect(getUpgradeAssistantStatus(dataClient, false)).resolves.toHaveProperty( + 'readyForUpgrade', + false + ); }); it('returns readyForUpgrade === true when no critical issues found', async () => { @@ -61,9 +64,10 @@ describe('getUpgradeAssistantStatus', () => { index_settings: {}, }; - await expect( - getUpgradeAssistantStatus(callWithRequest, {} as any, false) - ).resolves.toHaveProperty('readyForUpgrade', true); + await expect(getUpgradeAssistantStatus(dataClient, false)).resolves.toHaveProperty( + 'readyForUpgrade', + true + ); }); it('filters out security realm deprecation on Cloud', async () => { @@ -80,7 +84,7 @@ describe('getUpgradeAssistantStatus', () => { index_settings: {}, }; - const result = await getUpgradeAssistantStatus(callWithRequest, {} as any, true); + const result = await getUpgradeAssistantStatus(dataClient, true); expect(result).toHaveProperty('readyForUpgrade', true); expect(result).toHaveProperty('cluster', []); diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts similarity index 75% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts index b52c4c374266f7..68f21c1fd93b56 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_migration_apis.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_migration_apis.ts @@ -4,32 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - CallClusterWithRequest, - DeprecationAPIResponse, - DeprecationInfo, -} from 'src/legacy/core_plugins/elasticsearch'; - -import { RequestShim } from '../types'; - -export interface EnrichedDeprecationInfo extends DeprecationInfo { - index?: string; - node?: string; - reindex?: boolean; -} - -export interface UpgradeAssistantStatus { - readyForUpgrade: boolean; - cluster: EnrichedDeprecationInfo[]; - indices: EnrichedDeprecationInfo[]; -} +import { IScopedClusterClient } from 'src/core/server'; +import { DeprecationAPIResponse } from 'src/legacy/core_plugins/elasticsearch'; +import { EnrichedDeprecationInfo, UpgradeAssistantStatus } from '../../common/types'; export async function getUpgradeAssistantStatus( - callWithRequest: CallClusterWithRequest, - req: RequestShim, + dataClient: IScopedClusterClient, isCloudEnabled: boolean ): Promise { - const deprecations = await callWithRequest(req, 'transport.request', { + const deprecations = await dataClient.callAsCurrentUser('transport.request', { path: '/_migration/deprecations', method: 'GET', }); diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts index bbabe557df4d4a..51cb776ef4e0ba 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.test.ts @@ -6,7 +6,7 @@ import { SemVer } from 'semver'; import { IScopedClusterClient, kibanaResponseFactory } from 'src/core/server'; -import { CURRENT_VERSION } from '../../../common/version'; +import { CURRENT_VERSION } from '../../common/version'; import { esVersionCheck, getAllNodeVersions, diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.ts b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts similarity index 98% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.ts rename to x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts index 2fb3effe437938..e7636eea664791 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/es_version_precheck.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/es_version_precheck.ts @@ -13,7 +13,7 @@ import { RequestHandler, RequestHandlerContext, } from 'src/core/server'; -import { CURRENT_VERSION } from '../../../common/version'; +import { CURRENT_VERSION } from '../../common/version'; /** * Returns an array of all the unique Elasticsearch Node Versions in the Elasticsearch cluster. diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.test.ts similarity index 95% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.test.ts index 06fa755472238f..ce892df0de9469 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReindexSavedObject } from '../../../../common/types'; +import { ReindexSavedObject } from '../../../common/types'; import { Credential, credentialStoreFactory } from './credential_store'; describe('credentialStore', () => { diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.ts similarity index 91% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.ts index a051d16b5779f8..0958559910be6c 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/credential_store.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/credential_store.ts @@ -5,12 +5,11 @@ */ import { createHash } from 'crypto'; -import { Request } from 'hapi'; import stringify from 'json-stable-stringify'; -import { ReindexSavedObject } from '../../../../common/types'; +import { ReindexSavedObject } from '../../../common/types'; -export type Credential = Request['headers']; +export type Credential = Record; /** * An in-memory cache for user credentials to be used for reindexing operations. When looking up diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/index.ts diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts similarity index 99% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts index 7b346cc87edf6d..9ec06b72f02e2c 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../../common/version'; +import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../common/version'; import { generateNewIndexName, getReindexWarnings, diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts similarity index 97% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts index 0b95bc628fbb41..f6dc471d0945d3 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/index_settings.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts @@ -5,8 +5,8 @@ */ import { flow, omit } from 'lodash'; -import { ReindexWarning } from '../../../../common/types'; -import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../../common/version'; +import { ReindexWarning } from '../../../common/types'; +import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../common/version'; import { FlatSettings } from './types'; export interface ParsedIndexName { diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts similarity index 99% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts index 3fb855958a5d08..4569fdfa33a83b 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.test.ts @@ -13,8 +13,8 @@ import { ReindexSavedObject, ReindexStatus, ReindexStep, -} from '../../../../common/types'; -import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../../common/version'; +} from '../../../common/types'; +import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../common/version'; import { LOCK_WINDOW, ReindexActions, reindexActionsFactory } from './reindex_actions'; describe('ReindexActions', () => { diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts similarity index 97% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts index 6683f80c8e7791..2ae340f12d80cb 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_actions.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_actions.ts @@ -6,8 +6,7 @@ import moment from 'moment'; -import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; -import { SavedObjectsFindResponse, SavedObjectsClientContract } from 'kibana/server'; +import { SavedObjectsFindResponse, SavedObjectsClientContract, APICaller } from 'src/core/server'; import { IndexGroup, REINDEX_OP_TYPE, @@ -15,7 +14,7 @@ import { ReindexSavedObject, ReindexStatus, ReindexStep, -} from '../../../../common/types'; +} from '../../../common/types'; import { generateNewIndexName } from './index_settings'; import { FlatSettings } from './types'; @@ -111,7 +110,7 @@ export interface ReindexActions { export const reindexActionsFactory = ( client: SavedObjectsClientContract, - callCluster: CallCluster + callAsUser: APICaller ): ReindexActions => { // ----- Internal functions const isLocked = (reindexOp: ReindexSavedObject) => { @@ -230,7 +229,7 @@ export const reindexActionsFactory = ( }, async getFlatSettings(indexName: string) { - const flatSettings = (await callCluster('transport.request', { + const flatSettings = (await callAsUser('transport.request', { path: `/${encodeURIComponent(indexName)}?flat_settings=true`, })) as { [indexName: string]: FlatSettings }; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts similarity index 95% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts index 9cd41c8cbe8264..6c3b2c869dc7f9 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.test.ts @@ -4,14 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ +import { BehaviorSubject } from 'rxjs'; +import { Logger } from 'src/core/server'; +import { loggingServiceMock } from 'src/core/server/mocks'; + import { IndexGroup, ReindexOperation, ReindexSavedObject, ReindexStatus, ReindexStep, -} from '../../../../common/types'; -import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../../common/version'; +} from '../../../common/types'; +import { CURRENT_MAJOR_VERSION, PREV_MAJOR_VERSION } from '../../../common/version'; +import { licensingMock } from '../../../../licensing/server/mocks'; +import { LicensingPluginSetup } from '../../../../licensing/server'; + import { isMlIndex, isWatcherIndex, @@ -22,9 +29,9 @@ import { describe('reindexService', () => { let actions: jest.Mocked; let callCluster: jest.Mock; - let log: jest.Mock; - let xpackInfo: { feature: jest.Mocked }; + let log: Logger; let service: ReindexService; + let licensingPluginSetup: LicensingPluginSetup; const updateMockImpl = (reindexOp: ReindexSavedObject, attrs: Partial = {}) => Promise.resolve({ @@ -50,32 +57,24 @@ describe('reindexService', () => { runWhileIndexGroupLocked: jest.fn(async (group: string, f: any) => f({ attributes: {} })), }; callCluster = jest.fn(); - log = jest.fn(); - xpackInfo = { - feature: jest.fn(() => ({ - isAvailable() { - return true; - }, - isEnabled() { - return true; - }, - })), - }; - - service = reindexServiceFactory(callCluster as any, xpackInfo as any, actions, log); + log = loggingServiceMock.create().get(); + licensingPluginSetup = licensingMock.createSetup(); + licensingPluginSetup.license$ = new BehaviorSubject( + licensingMock.createLicense({ + features: { security: { isAvailable: true, isEnabled: true } }, + }) + ); + + service = reindexServiceFactory(callCluster as any, actions, log, licensingPluginSetup); }); describe('hasRequiredPrivileges', () => { it('returns true if security is disabled', async () => { - xpackInfo.feature.mockReturnValueOnce({ - isAvailable() { - return true; - }, - isEnabled() { - return false; - }, - }); - + licensingPluginSetup.license$ = new BehaviorSubject( + licensingMock.createLicense({ + features: { security: { isAvailable: true, isEnabled: false } }, + }) + ); const hasRequired = await service.hasRequiredPrivileges('anIndex'); expect(hasRequired).toBe(true); }); @@ -584,7 +583,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=true', method: 'POST', @@ -599,7 +598,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=true', method: 'POST', @@ -623,7 +622,7 @@ describe('reindexService', () => { expect( updatedOp.attributes.errorMessage!.includes('Could not stop ML jobs') ).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=true', method: 'POST', @@ -645,7 +644,7 @@ describe('reindexService', () => { expect( updatedOp.attributes.errorMessage!.includes('Some nodes are not on minimum version') ).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); // Should not have called ML endpoint at all expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=true', @@ -698,7 +697,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_watcher/_stop', method: 'POST', @@ -713,7 +712,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.created); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_watcher/_stop', method: 'POST', @@ -735,7 +734,7 @@ describe('reindexService', () => { expect( updatedOp.attributes.errorMessage!.includes('Could not stop Watcher') ).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).toHaveBeenCalledWith('transport.request', { path: '/_watcher/_stop', method: 'POST', @@ -771,7 +770,7 @@ describe('reindexService', () => { ); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); it('fails if setting updates fail', async () => { @@ -782,7 +781,7 @@ describe('reindexService', () => { ); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); }); @@ -817,7 +816,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); it('fails if create index fails', async () => { @@ -829,7 +828,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.readonly); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); // Original index should have been set back to allow reads. expect(callCluster).toHaveBeenCalledWith('indices.putSettings', { @@ -874,7 +873,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.newIndexCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); }); @@ -931,7 +930,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexStarted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); }); @@ -1014,7 +1013,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); it('fails if switching aliases fails', async () => { @@ -1023,7 +1022,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.reindexCompleted); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage).not.toBeNull(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); }); }); @@ -1092,7 +1091,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=false', method: 'POST', @@ -1108,7 +1107,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=false', method: 'POST', @@ -1129,7 +1128,7 @@ describe('reindexService', () => { expect( updatedOp.attributes.errorMessage!.includes('Could not resume ML jobs') ).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).toHaveBeenCalledWith('transport.request', { path: '/_ml/set_upgrade_mode?enabled=false', method: 'POST', @@ -1196,7 +1195,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_watcher/_start', method: 'POST', @@ -1212,7 +1211,7 @@ describe('reindexService', () => { expect(updatedOp.attributes.lastCompletedStep).toEqual(ReindexStep.aliasCreated); expect(updatedOp.attributes.status).toEqual(ReindexStatus.failed); expect(updatedOp.attributes.errorMessage!.includes(`Can't lock!`)).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).not.toHaveBeenCalledWith('transport.request', { path: '/_watcher/_start', method: 'POST', @@ -1233,7 +1232,7 @@ describe('reindexService', () => { expect( updatedOp.attributes.errorMessage!.includes('Could not start Watcher') ).toBeTruthy(); - expect(log).toHaveBeenCalledWith(['upgrade_assistant', 'error'], expect.any(String)); + expect(log.error).toHaveBeenCalledWith(expect.any(String)); expect(callCluster).toHaveBeenCalledWith('transport.request', { path: '/_watcher/_start', method: 'POST', diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts similarity index 90% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts index 0e6095f98b6ff0..8f1df5b34372b3 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/reindex_service.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/reindex_service.ts @@ -5,17 +5,16 @@ */ import Boom from 'boom'; +import { APICaller, Logger } from 'src/core/server'; +import { first } from 'rxjs/operators'; -import { Server } from 'hapi'; -import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; -import { XPackInfo } from '../../../../../xpack_main/server/lib/xpack_info'; import { IndexGroup, ReindexSavedObject, ReindexStatus, ReindexStep, ReindexWarning, -} from '../../../../common/types'; +} from '../../../common/types'; import { generateNewIndexName, getReindexWarnings, @@ -23,6 +22,7 @@ import { transformFlatSettings, } from './index_settings'; import { ReindexActions } from './reindex_actions'; +import { LicensingPluginSetup } from '../../../../licensing/server'; const VERSION_REGEX = new RegExp(/^([1-9]+)\.([0-9]+)\.([0-9]+)/); const ML_INDICES = ['.ml-state', '.ml-anomalies', '.ml-config']; @@ -97,10 +97,10 @@ export interface ReindexService { } export const reindexServiceFactory = ( - callCluster: CallCluster, - xpackInfo: XPackInfo, + callAsUser: APICaller, actions: ReindexActions, - log: Server['log'] + log: Logger, + licensing: LicensingPluginSetup ): ReindexService => { // ------ Utility functions @@ -114,7 +114,7 @@ export const reindexServiceFactory = ( await actions.runWhileIndexGroupLocked(IndexGroup.ml, async mlDoc => { await validateNodesMinimumVersion(6, 7); - const res = await callCluster('transport.request', { + const res = await callAsUser('transport.request', { path: '/_ml/set_upgrade_mode?enabled=true', method: 'POST', }); @@ -134,7 +134,7 @@ export const reindexServiceFactory = ( await actions.decrementIndexGroupReindexes(IndexGroup.ml); await actions.runWhileIndexGroupLocked(IndexGroup.ml, async mlDoc => { if (mlDoc.attributes.runningReindexCount === 0) { - const res = await callCluster('transport.request', { + const res = await callAsUser('transport.request', { path: '/_ml/set_upgrade_mode?enabled=false', method: 'POST', }); @@ -154,7 +154,7 @@ export const reindexServiceFactory = ( const stopWatcher = async () => { await actions.incrementIndexGroupReindexes(IndexGroup.watcher); await actions.runWhileIndexGroupLocked(IndexGroup.watcher, async watcherDoc => { - const { acknowledged } = await callCluster('transport.request', { + const { acknowledged } = await callAsUser('transport.request', { path: '/_watcher/_stop', method: 'POST', }); @@ -174,7 +174,7 @@ export const reindexServiceFactory = ( await actions.decrementIndexGroupReindexes(IndexGroup.watcher); await actions.runWhileIndexGroupLocked(IndexGroup.watcher, async watcherDoc => { if (watcherDoc.attributes.runningReindexCount === 0) { - const { acknowledged } = await callCluster('transport.request', { + const { acknowledged } = await callAsUser('transport.request', { path: '/_watcher/_start', method: 'POST', }); @@ -191,14 +191,14 @@ export const reindexServiceFactory = ( const cleanupChanges = async (reindexOp: ReindexSavedObject) => { // Cancel reindex task if it was started but not completed if (reindexOp.attributes.lastCompletedStep === ReindexStep.reindexStarted) { - await callCluster('tasks.cancel', { + await callAsUser('tasks.cancel', { taskId: reindexOp.attributes.reindexTaskId, }).catch(e => undefined); // Ignore any exceptions trying to cancel (it may have already completed). } // Set index back to writable if we ever got past this point. if (reindexOp.attributes.lastCompletedStep >= ReindexStep.readonly) { - await callCluster('indices.putSettings', { + await callAsUser('indices.putSettings', { index: reindexOp.attributes.indexName, body: { 'index.blocks.write': false }, }); @@ -208,7 +208,7 @@ export const reindexServiceFactory = ( reindexOp.attributes.lastCompletedStep >= ReindexStep.newIndexCreated && reindexOp.attributes.lastCompletedStep < ReindexStep.aliasCreated ) { - await callCluster('indices.delete', { index: reindexOp.attributes.newIndexName }); + await callAsUser('indices.delete', { index: reindexOp.attributes.newIndexName }); } // Resume consumers if we ever got past this point. @@ -222,7 +222,7 @@ export const reindexServiceFactory = ( // ------ Functions used to process the state machine const validateNodesMinimumVersion = async (minMajor: number, minMinor: number) => { - const nodesResponse = await callCluster('transport.request', { + const nodesResponse = await callAsUser('transport.request', { path: '/_nodes', method: 'GET', }); @@ -263,7 +263,7 @@ export const reindexServiceFactory = ( */ const setReadonly = async (reindexOp: ReindexSavedObject) => { const { indexName } = reindexOp.attributes; - const putReadonly = await callCluster('indices.putSettings', { + const putReadonly = await callAsUser('indices.putSettings', { index: indexName, body: { 'index.blocks.write': true }, }); @@ -289,7 +289,7 @@ export const reindexServiceFactory = ( const { settings, mappings } = transformFlatSettings(flatSettings); - const createIndex = await callCluster('indices.create', { + const createIndex = await callAsUser('indices.create', { index: newIndexName, body: { settings, @@ -313,7 +313,7 @@ export const reindexServiceFactory = ( const startReindexing = async (reindexOp: ReindexSavedObject) => { const { indexName } = reindexOp.attributes; - const startReindex = (await callCluster('reindex', { + const startReindex = (await callAsUser('reindex', { refresh: true, waitForCompletion: false, body: { @@ -337,7 +337,7 @@ export const reindexServiceFactory = ( const taskId = reindexOp.attributes.reindexTaskId; // Check reindexing task progress - const taskResponse = await callCluster('tasks.get', { + const taskResponse = await callAsUser('tasks.get', { taskId, waitForCompletion: false, }); @@ -358,7 +358,7 @@ export const reindexServiceFactory = ( reindexOp = await cleanupChanges(reindexOp); } else { // Check that it reindexed all documents - const { count } = await callCluster('count', { index: reindexOp.attributes.indexName }); + const { count } = await callAsUser('count', { index: reindexOp.attributes.indexName }); if (taskResponse.task.status.created < count) { // Include the entire task result in the error message. This should be guaranteed @@ -374,7 +374,7 @@ export const reindexServiceFactory = ( } // Delete the task from ES .tasks index - const deleteTaskResp = await callCluster('delete', { + const deleteTaskResp = await callAsUser('delete', { index: '.tasks', id: taskId, }); @@ -394,7 +394,7 @@ export const reindexServiceFactory = ( const { indexName, newIndexName } = reindexOp.attributes; const existingAliases = ( - await callCluster('indices.getAlias', { + await callAsUser('indices.getAlias', { index: indexName, }) )[indexName].aliases; @@ -403,7 +403,7 @@ export const reindexServiceFactory = ( add: { index: newIndexName, alias: aliasName, ...existingAliases[aliasName] }, })); - const aliasResponse = await callCluster('indices.updateAliases', { + const aliasResponse = await callAsUser('indices.updateAliases', { body: { actions: [ { add: { index: newIndexName, alias: indexName } }, @@ -443,9 +443,18 @@ export const reindexServiceFactory = ( return { async hasRequiredPrivileges(indexName: string) { + /** + * To avoid a circular dependency on Security we use a work around + * here to detect whether Security is available and enabled + * (i.e., via the licensing plugin). This enables Security to use + * functionality exposed through Upgrade Assistant. + */ + const license = await licensing.license$.pipe(first()).toPromise(); + + const securityFeature = license.getFeature('security'); + // If security is disabled or unavailable, return true. - const security = xpackInfo.feature('security'); - if (!security.isAvailable() || !security.isEnabled()) { + if (!securityFeature || !(securityFeature.isAvailable && securityFeature.isEnabled)) { return true; } @@ -482,7 +491,7 @@ export const reindexServiceFactory = ( body.cluster = [...body.cluster, 'manage_watcher']; } - const resp = await callCluster('transport.request', { + const resp = await callAsUser('transport.request', { path: '/_security/user/_has_privileges', method: 'POST', body, @@ -509,7 +518,7 @@ export const reindexServiceFactory = ( }, async createReindexOperation(indexName: string) { - const indexExists = await callCluster('indices.exists', { index: indexName }); + const indexExists = await callAsUser('indices.exists', { index: indexName }); if (!indexExists) { throw Boom.notFound(`Index ${indexName} does not exist in this cluster.`); } @@ -579,10 +588,7 @@ export const reindexServiceFactory = ( break; } } catch (e) { - log( - ['upgrade_assistant', 'error'], - `Reindexing step failed: ${e instanceof Error ? e.stack : e.toString()}` - ); + log.error(`Reindexing step failed: ${e instanceof Error ? e.stack : e.toString()}`); // Trap the exception and add the message to the object so the UI can display it. lockedReindexOp = await actions.updateReindexOp(lockedReindexOp, { @@ -647,7 +653,7 @@ export const reindexServiceFactory = ( throw new Error(`Reindex operation is not current waiting for reindex task to complete`); } - const resp = await callCluster('tasks.cancel', { + const resp = await callAsUser('tasks.cancel', { taskId: reindexOp.attributes.reindexTaskId, }); diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/types.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/types.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/types.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/types.ts diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/worker.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts similarity index 76% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/worker.ts rename to x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts index 628a47be9f5e77..bad6db62efe41a 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/reindexing/worker.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts @@ -3,23 +3,19 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { CallCluster, CallClusterWithRequest } from 'src/legacy/core_plugins/elasticsearch'; -import { Request, Server } from 'src/legacy/server/kbn_server'; -import { SavedObjectsClientContract } from 'kibana/server'; - +import { IClusterClient, Logger, SavedObjectsClientContract, FakeRequest } from 'src/core/server'; import moment from 'moment'; -import { XPackInfo } from '../../../../../xpack_main/server/lib/xpack_info'; -import { ReindexSavedObject, ReindexStatus } from '../../../../common/types'; + +import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; import { CredentialStore } from './credential_store'; import { reindexActionsFactory } from './reindex_actions'; import { ReindexService, reindexServiceFactory } from './reindex_service'; +import { LicensingPluginSetup } from '../../../../licensing/server'; const POLL_INTERVAL = 30000; // If no nodes have been able to update this index in 2 minutes (due to missing credentials), set to paused. const PAUSE_WINDOW = POLL_INTERVAL * 4; -const LOG_TAGS = ['upgrade_assistant', 'reindex_worker']; - /** * A singleton worker that will coordinate two polling loops: * (1) A longer loop that polls for reindex operations that are in progress. If any are found, loop (2) is started. @@ -41,24 +37,27 @@ export class ReindexWorker { private timeout?: NodeJS.Timeout; private inProgressOps: ReindexSavedObject[] = []; private readonly reindexService: ReindexService; + private readonly log: Logger; constructor( private client: SavedObjectsClientContract, private credentialStore: CredentialStore, - private callWithRequest: CallClusterWithRequest, - private callWithInternalUser: CallCluster, - private xpackInfo: XPackInfo, - private readonly log: Server['log'] + private clusterClient: IClusterClient, + log: Logger, + private licensing: LicensingPluginSetup ) { + this.log = log.get('reindex_worker'); if (ReindexWorker.workerSingleton) { throw new Error(`More than one ReindexWorker cannot be created.`); } + const callAsInternalUser = this.clusterClient.callAsInternalUser.bind(this.clusterClient); + this.reindexService = reindexServiceFactory( - this.callWithInternalUser, - this.xpackInfo, - reindexActionsFactory(this.client, this.callWithInternalUser), - this.log + callAsInternalUser, + reindexActionsFactory(this.client, callAsInternalUser), + log, + this.licensing ); ReindexWorker.workerSingleton = this; @@ -68,7 +67,7 @@ export class ReindexWorker { * Begins loop (1) to begin checking for in progress reindex operations. */ public start = () => { - this.log(['debug', ...LOG_TAGS], `Starting worker...`); + this.log.debug('Starting worker...'); this.continuePolling = true; this.pollForOperations(); }; @@ -77,7 +76,7 @@ export class ReindexWorker { * Stops the worker from processing any further reindex operations. */ public stop = () => { - this.log(['debug', ...LOG_TAGS], `Stopping worker...`); + this.log.debug('Stopping worker...'); if (this.timeout) { clearTimeout(this.timeout); } @@ -107,7 +106,7 @@ export class ReindexWorker { this.updateOperationLoopRunning = true; while (this.inProgressOps.length > 0) { - this.log(['debug', ...LOG_TAGS], `Updating ${this.inProgressOps.length} reindex operations`); + this.log.debug(`Updating ${this.inProgressOps.length} reindex operations`); // Push each operation through the state machine and refresh. await Promise.all(this.inProgressOps.map(this.processNextStep)); @@ -118,7 +117,7 @@ export class ReindexWorker { }; private pollForOperations = async () => { - this.log(['debug', ...LOG_TAGS], `Polling for reindex operations`); + this.log.debug(`Polling for reindex operations`); await this.refresh(); @@ -131,7 +130,7 @@ export class ReindexWorker { try { this.inProgressOps = await this.reindexService.findAllByStatus(ReindexStatus.inProgress); } catch (e) { - this.log(['debug', ...LOG_TAGS], `Could not fetch riendex operations from Elasticsearch`); + this.log.debug(`Could not fetch reindex operations from Elasticsearch`); this.inProgressOps = []; } @@ -159,10 +158,13 @@ export class ReindexWorker { } // Setup a ReindexService specific to these credentials. - const fakeRequest = { headers: credential } as Request; - const callCluster = this.callWithRequest.bind(null, fakeRequest) as CallCluster; - const actions = reindexActionsFactory(this.client, callCluster); - const service = reindexServiceFactory(callCluster, this.xpackInfo, actions, this.log); + const fakeRequest: FakeRequest = { headers: credential }; + + const scopedClusterClient = this.clusterClient.asScoped(fakeRequest); + const callAsCurrentUser = scopedClusterClient.callAsCurrentUser.bind(scopedClusterClient); + const actions = reindexActionsFactory(this.client, callAsCurrentUser); + + const service = reindexServiceFactory(callAsCurrentUser, actions, this.log, this.licensing); reindexOp = await swallowExceptions(service.processNextStep, this.log)(reindexOp); // Update credential store with most recent state. @@ -176,18 +178,15 @@ export class ReindexWorker { */ const swallowExceptions = ( func: (reindexOp: ReindexSavedObject) => Promise, - log: Server['log'] + log: Logger ) => async (reindexOp: ReindexSavedObject) => { try { return await func(reindexOp); } catch (e) { if (reindexOp.attributes.locked) { - log(['debug', ...LOG_TAGS], `Skipping reindexOp with unexpired lock: ${reindexOp.id}`); + log.debug(`Skipping reindexOp with unexpired lock: ${reindexOp.id}`); } else { - log( - ['warning', ...LOG_TAGS], - `Error when trying to process reindexOp (${reindexOp.id}): ${e.toString()}` - ); + log.warn(`Error when trying to process reindexOp (${reindexOp.id}): ${e.toString()}`); } return reindexOp; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.test.ts similarity index 51% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.test.ts index 5f95f6e9fd5559..703351c45ba5af 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_open_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.test.ts @@ -3,8 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { savedObjectsRepositoryMock } from 'src/core/server/mocks'; +import { UPGRADE_ASSISTANT_DOC_ID, UPGRADE_ASSISTANT_TYPE } from '../../../common/types'; -import { UPGRADE_ASSISTANT_DOC_ID, UPGRADE_ASSISTANT_TYPE } from '../../../../common/types'; import { upsertUIOpenOption } from './es_ui_open_apis'; /** @@ -13,54 +14,29 @@ import { upsertUIOpenOption } from './es_ui_open_apis'; * more thoroughly in the lib/telemetry tests. */ describe('Upgrade Assistant Telemetry SavedObject UIOpen', () => { - const mockIncrementCounter = jest.fn(); - const server = jest.fn().mockReturnValue({ - savedObjects: { - getSavedObjectsRepository: jest.fn().mockImplementation(() => { - return { - incrementCounter: mockIncrementCounter, - }; - }), - }, - plugins: { - elasticsearch: { - getCluster: () => { - return { - callWithInternalUser: {}, - }; - }, - }, - }, - }); - - const request = jest.fn().mockReturnValue({ - payload: { - overview: true, - cluster: true, - indices: true, - }, - }); - describe('Upsert UIOpen Option', () => { it('call saved objects internal repository with the correct info', async () => { - const serverMock = server(); - const incCounterSORepoFunc = serverMock.savedObjects.getSavedObjectsRepository() - .incrementCounter; + const internalRepo = savedObjectsRepositoryMock.create(); - await upsertUIOpenOption(serverMock, request()); + await upsertUIOpenOption({ + overview: true, + cluster: true, + indices: true, + savedObjects: { createInternalRepository: () => internalRepo } as any, + }); - expect(incCounterSORepoFunc).toHaveBeenCalledTimes(3); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledTimes(3); + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_open.overview` ); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_open.cluster` ); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_open.indices` diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.ts new file mode 100644 index 00000000000000..64e9b0f217555b --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_open_apis.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectsServiceStart } from 'src/core/server'; +import { + UIOpen, + UIOpenOption, + UPGRADE_ASSISTANT_DOC_ID, + UPGRADE_ASSISTANT_TYPE, +} from '../../../common/types'; + +interface IncrementUIOpenDependencies { + uiOpenOptionCounter: UIOpenOption; + savedObjects: SavedObjectsServiceStart; +} + +async function incrementUIOpenOptionCounter({ + savedObjects, + uiOpenOptionCounter, +}: IncrementUIOpenDependencies) { + const internalRepository = savedObjects.createInternalRepository(); + + await internalRepository.incrementCounter( + UPGRADE_ASSISTANT_TYPE, + UPGRADE_ASSISTANT_DOC_ID, + `ui_open.${uiOpenOptionCounter}` + ); +} + +type UpsertUIOpenOptionDependencies = UIOpen & { savedObjects: SavedObjectsServiceStart }; + +export async function upsertUIOpenOption({ + overview, + cluster, + indices, + savedObjects, +}: UpsertUIOpenOptionDependencies): Promise { + if (overview) { + await incrementUIOpenOptionCounter({ savedObjects, uiOpenOptionCounter: 'overview' }); + } + + if (cluster) { + await incrementUIOpenOptionCounter({ savedObjects, uiOpenOptionCounter: 'cluster' }); + } + + if (indices) { + await incrementUIOpenOptionCounter({ savedObjects, uiOpenOptionCounter: 'indices' }); + } + + return { + overview, + cluster, + indices, + }; +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.test.ts similarity index 52% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.test.ts index 3f2c80f7d6b751..31e4e3f07b5de4 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/es_ui_reindex_apis.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.test.ts @@ -3,8 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { UPGRADE_ASSISTANT_DOC_ID, UPGRADE_ASSISTANT_TYPE } from '../../../../common/types'; +import { savedObjectsRepositoryMock } from 'src/core/server/mocks'; +import { UPGRADE_ASSISTANT_DOC_ID, UPGRADE_ASSISTANT_TYPE } from '../../../common/types'; import { upsertUIReindexOption } from './es_ui_reindex_apis'; /** @@ -13,60 +13,34 @@ import { upsertUIReindexOption } from './es_ui_reindex_apis'; * more thoroughly in the lib/telemetry tests. */ describe('Upgrade Assistant Telemetry SavedObject UIReindex', () => { - const mockIncrementCounter = jest.fn(); - const server = jest.fn().mockReturnValue({ - savedObjects: { - getSavedObjectsRepository: jest.fn().mockImplementation(() => { - return { - incrementCounter: mockIncrementCounter, - }; - }), - }, - plugins: { - elasticsearch: { - getCluster: () => { - return { - callWithInternalUser: {}, - }; - }, - }, - }, - }); - - const request = jest.fn().mockReturnValue({ - payload: { - close: true, - open: true, - start: true, - stop: true, - }, - }); - describe('Upsert UIReindex Option', () => { it('call saved objects internal repository with the correct info', async () => { - const serverMock = server(); - const incCounterSORepoFunc = serverMock.savedObjects.getSavedObjectsRepository() - .incrementCounter; - - await upsertUIReindexOption(serverMock, request()); + const internalRepo = savedObjectsRepositoryMock.create(); + await upsertUIReindexOption({ + close: true, + open: true, + start: true, + stop: true, + savedObjects: { createInternalRepository: () => internalRepo } as any, + }); - expect(incCounterSORepoFunc).toHaveBeenCalledTimes(4); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledTimes(4); + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_reindex.close` ); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_reindex.open` ); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_reindex.start` ); - expect(incCounterSORepoFunc).toHaveBeenCalledWith( + expect(internalRepo.incrementCounter).toHaveBeenCalledWith( UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID, `ui_reindex.stop` diff --git a/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.ts new file mode 100644 index 00000000000000..0aaaf63196d67f --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/es_ui_reindex_apis.ts @@ -0,0 +1,64 @@ +/* + * 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 { SavedObjectsServiceStart } from 'src/core/server'; +import { + UIReindex, + UIReindexOption, + UPGRADE_ASSISTANT_DOC_ID, + UPGRADE_ASSISTANT_TYPE, +} from '../../../common/types'; + +interface IncrementUIReindexOptionDependencies { + uiReindexOptionCounter: UIReindexOption; + savedObjects: SavedObjectsServiceStart; +} + +async function incrementUIReindexOptionCounter({ + savedObjects, + uiReindexOptionCounter, +}: IncrementUIReindexOptionDependencies) { + const internalRepository = savedObjects.createInternalRepository(); + + await internalRepository.incrementCounter( + UPGRADE_ASSISTANT_TYPE, + UPGRADE_ASSISTANT_DOC_ID, + `ui_reindex.${uiReindexOptionCounter}` + ); +} + +type UpsertUIReindexOptionDepencies = UIReindex & { savedObjects: SavedObjectsServiceStart }; + +export async function upsertUIReindexOption({ + start, + close, + open, + stop, + savedObjects, +}: UpsertUIReindexOptionDepencies): Promise { + if (close) { + await incrementUIReindexOptionCounter({ savedObjects, uiReindexOptionCounter: 'close' }); + } + + if (open) { + await incrementUIReindexOptionCounter({ savedObjects, uiReindexOptionCounter: 'open' }); + } + + if (start) { + await incrementUIReindexOptionCounter({ savedObjects, uiReindexOptionCounter: 'start' }); + } + + if (stop) { + await incrementUIReindexOptionCounter({ savedObjects, uiReindexOptionCounter: 'stop' }); + } + + return { + close, + open, + start, + stop, + }; +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/index.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/index.ts similarity index 100% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/index.ts rename to x-pack/plugins/upgrade_assistant/server/lib/telemetry/index.ts diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.test.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts similarity index 78% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.test.ts rename to x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts index 27a0eef0d16f6f..a4833d9a3d7fe8 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.test.ts @@ -3,8 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { registerUpgradeAssistantUsageCollector } from './usage_collector'; +import { IClusterClient } from 'src/core/server'; /** * Since these route callbacks are so thin, these serve simply as integration tests @@ -14,20 +15,31 @@ import { registerUpgradeAssistantUsageCollector } from './usage_collector'; describe('Upgrade Assistant Usage Collector', () => { let makeUsageCollectorStub: any; let registerStub: any; - let server: any; + let dependencies: any; let callClusterStub: any; let usageCollection: any; + let clusterClient: IClusterClient; beforeEach(() => { + clusterClient = elasticsearchServiceMock.createClusterClient(); + (clusterClient.callAsInternalUser as jest.Mock).mockResolvedValue({ + persistent: {}, + transient: { + logger: { + deprecation: 'WARN', + }, + }, + }); makeUsageCollectorStub = jest.fn(); registerStub = jest.fn(); usageCollection = { makeUsageCollector: makeUsageCollectorStub, registerCollector: registerStub, }; - server = jest.fn().mockReturnValue({ + dependencies = { + usageCollection, savedObjects: { - getSavedObjectsRepository: jest.fn().mockImplementation(() => { + createInternalRepository: jest.fn().mockImplementation(() => { return { get: () => { return { @@ -45,31 +57,26 @@ describe('Upgrade Assistant Usage Collector', () => { }; }), }, - }); - callClusterStub = jest.fn().mockResolvedValue({ - persistent: {}, - transient: { - logger: { - deprecation: 'WARN', - }, + elasticsearch: { + adminClient: clusterClient, }, - }); + }; }); describe('registerUpgradeAssistantUsageCollector', () => { it('should registerCollector', () => { - registerUpgradeAssistantUsageCollector(usageCollection, server()); + registerUpgradeAssistantUsageCollector(dependencies); expect(registerStub).toHaveBeenCalledTimes(1); }); it('should call makeUsageCollector with type = upgrade-assistant', () => { - registerUpgradeAssistantUsageCollector(usageCollection, server()); + registerUpgradeAssistantUsageCollector(dependencies); expect(makeUsageCollectorStub).toHaveBeenCalledTimes(1); expect(makeUsageCollectorStub.mock.calls[0][0].type).toBe('upgrade-assistant-telemetry'); }); it('fetchUpgradeAssistantMetrics should return correct info', async () => { - registerUpgradeAssistantUsageCollector(usageCollection, server()); + registerUpgradeAssistantUsageCollector(dependencies); const upgradeAssistantStats = await makeUsageCollectorStub.mock.calls[0][0].fetch( callClusterStub ); diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.ts b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts similarity index 72% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.ts rename to x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts index 1d24d190fa9f25..79d6e53c64ec06 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/lib/telemetry/usage_collector.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/telemetry/usage_collector.ts @@ -5,8 +5,12 @@ */ import { set } from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { SavedObjectsRepository } from 'src/core/server/saved_objects/service/lib/repository'; +import { + APICaller, + ElasticsearchServiceSetup, + ISavedObjectsRepository, + SavedObjectsServiceStart, +} from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { UPGRADE_ASSISTANT_DOC_ID, @@ -14,12 +18,11 @@ import { UpgradeAssistantTelemetry, UpgradeAssistantTelemetrySavedObject, UpgradeAssistantTelemetrySavedObjectAttributes, -} from '../../../../common/types'; -import { ServerShim } from '../../types'; +} from '../../../common/types'; import { isDeprecationLoggingEnabled } from '../es_deprecation_logging_apis'; async function getSavedObjectAttributesFromRepo( - savedObjectsRepository: SavedObjectsRepository, + savedObjectsRepository: ISavedObjectsRepository, docType: string, docID: string ) { @@ -35,9 +38,9 @@ async function getSavedObjectAttributesFromRepo( } } -async function getDeprecationLoggingStatusValue(callCluster: any): Promise { +async function getDeprecationLoggingStatusValue(callAsCurrentUser: APICaller): Promise { try { - const loggerDeprecationCallResult = await callCluster('cluster.getSettings', { + const loggerDeprecationCallResult = await callAsCurrentUser('cluster.getSettings', { includeDefaults: true, }); @@ -48,17 +51,17 @@ async function getDeprecationLoggingStatusValue(callCluster: any): Promise { - const { getSavedObjectsRepository } = server.savedObjects; - const savedObjectsRepository = getSavedObjectsRepository(callCluster); + const savedObjectsRepository = savedObjects.createInternalRepository(); const upgradeAssistantSOAttributes = await getSavedObjectAttributesFromRepo( savedObjectsRepository, UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_DOC_ID ); - const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue(callCluster); + const callAsInternalUser = adminClient.callAsInternalUser.bind(adminClient); + const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue(callAsInternalUser); const getTelemetrySavedObject = ( upgradeAssistantTelemetrySavedObjectAttrs: UpgradeAssistantTelemetrySavedObjectAttributes | null @@ -103,14 +106,21 @@ export async function fetchUpgradeAssistantMetrics( }; } -export function registerUpgradeAssistantUsageCollector( - usageCollection: UsageCollectionSetup, - server: ServerShim -) { +interface Dependencies { + elasticsearch: ElasticsearchServiceSetup; + savedObjects: SavedObjectsServiceStart; + usageCollection: UsageCollectionSetup; +} + +export function registerUpgradeAssistantUsageCollector({ + elasticsearch, + usageCollection, + savedObjects, +}: Dependencies) { const upgradeAssistantUsageCollector = usageCollection.makeUsageCollector({ type: UPGRADE_ASSISTANT_TYPE, isReady: () => true, - fetch: async (callCluster: any) => fetchUpgradeAssistantMetrics(callCluster, server), + fetch: async () => fetchUpgradeAssistantMetrics(elasticsearch, savedObjects), }); usageCollection.registerCollector(upgradeAssistantUsageCollector); diff --git a/x-pack/plugins/upgrade_assistant/server/plugin.ts b/x-pack/plugins/upgrade_assistant/server/plugin.ts new file mode 100644 index 00000000000000..6ccd073a9e0207 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/plugin.ts @@ -0,0 +1,125 @@ +/* + * 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 { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; + +import { + Plugin, + CoreSetup, + CoreStart, + PluginInitializerContext, + Logger, + ElasticsearchServiceSetup, + SavedObjectsClient, + SavedObjectsServiceStart, +} from '../../../../src/core/server'; + +import { CloudSetup } from '../../cloud/server'; +import { LicensingPluginSetup } from '../../licensing/server'; + +import { CredentialStore, credentialStoreFactory } from './lib/reindexing/credential_store'; +import { ReindexWorker } from './lib/reindexing'; +import { registerUpgradeAssistantUsageCollector } from './lib/telemetry'; +import { registerClusterCheckupRoutes } from './routes/cluster_checkup'; +import { registerDeprecationLoggingRoutes } from './routes/deprecation_logging'; +import { registerReindexIndicesRoutes, createReindexWorker } from './routes/reindex_indices'; +import { registerTelemetryRoutes } from './routes/telemetry'; +import { RouteDependencies } from './types'; + +interface PluginsSetup { + usageCollection: UsageCollectionSetup; + licensing: LicensingPluginSetup; + cloud?: CloudSetup; +} + +export class UpgradeAssistantServerPlugin implements Plugin { + private readonly logger: Logger; + private readonly credentialStore: CredentialStore; + + // Properties set at setup + private licensing?: LicensingPluginSetup; + private elasticSearchService?: ElasticsearchServiceSetup; + + // Properties set at start + private savedObjectsServiceStart?: SavedObjectsServiceStart; + private worker?: ReindexWorker; + + constructor({ logger }: PluginInitializerContext) { + this.logger = logger.get(); + this.credentialStore = credentialStoreFactory(); + } + + private getWorker() { + if (!this.worker) { + throw new Error('Worker unavailable'); + } + return this.worker; + } + + setup( + { http, elasticsearch, getStartServices, capabilities }: CoreSetup, + { usageCollection, cloud, licensing }: PluginsSetup + ) { + this.elasticSearchService = elasticsearch; + this.licensing = licensing; + + const router = http.createRouter(); + + const dependencies: RouteDependencies = { + cloud, + router, + credentialStore: this.credentialStore, + log: this.logger, + getSavedObjectsService: () => { + if (!this.savedObjectsServiceStart) { + throw new Error('Saved Objects Start service not available'); + } + return this.savedObjectsServiceStart; + }, + licensing, + }; + + registerClusterCheckupRoutes(dependencies); + registerDeprecationLoggingRoutes(dependencies); + registerReindexIndicesRoutes(dependencies, this.getWorker.bind(this)); + // Bootstrap the needed routes and the collector for the telemetry + registerTelemetryRoutes(dependencies); + + if (usageCollection) { + getStartServices().then(([{ savedObjects }]) => { + registerUpgradeAssistantUsageCollector({ elasticsearch, usageCollection, savedObjects }); + }); + } + } + + start({ savedObjects }: CoreStart) { + this.savedObjectsServiceStart = savedObjects; + + // The ReindexWorker uses a map of request headers that contain the authentication credentials + // for a given reindex. We cannot currently store these in an the .kibana index b/c we do not + // want to expose these credentials to any unauthenticated users. We also want to avoid any need + // to add a user for a special index just for upgrading. This in-memory cache allows us to + // process jobs without the browser staying on the page, but will require that jobs go into + // a paused state if no Kibana nodes have the required credentials. + + this.worker = createReindexWorker({ + credentialStore: this.credentialStore, + licensing: this.licensing!, + elasticsearchService: this.elasticSearchService!, + logger: this.logger, + savedObjects: new SavedObjectsClient( + this.savedObjectsServiceStart.createInternalRepository() + ), + }); + + this.worker.start(); + } + + stop(): void { + if (this.worker) { + this.worker.stop(); + } + } +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/request.mock.ts b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/request.mock.ts similarity index 92% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/request.mock.ts rename to x-pack/plugins/upgrade_assistant/server/routes/__mocks__/request.mock.ts index d09a66dbb43269..fb68e188bb255a 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/request.mock.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/request.mock.ts @@ -6,7 +6,7 @@ export const createRequestMock = (opts?: { headers?: any; params?: Record; - payload?: Record; + body?: Record; }) => { return Object.assign({ headers: {} }, opts || {}); }; diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/routes.mock.ts b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts similarity index 72% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/routes.mock.ts rename to x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts index 3769bc389123e2..a8be171dccd98b 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/__mocks__/routes.mock.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/__mocks__/routes.mock.ts @@ -3,7 +3,21 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandler } from 'kibana/server'; +import { RequestHandler, RequestHandlerContext } from 'src/core/server'; +import { + elasticsearchServiceMock, + savedObjectsClientMock, +} from '../../../../../../src/core/server/mocks'; + +export const routeHandlerContextMock = ({ + core: { + elasticsearch: { + adminClient: elasticsearchServiceMock.createScopedClusterClient(), + dataClient: elasticsearchServiceMock.createScopedClusterClient(), + }, + savedObjects: { client: savedObjectsClientMock.create() }, + }, +} as unknown) as RequestHandlerContext; /** * Creates a very crude mock of the new platform router implementation. This enables use to test diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts similarity index 73% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.test.ts rename to x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts index 3fe2e1797182b2..16f8001f8e1de4 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/cluster_checkup.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { kibanaResponseFactory } from 'src/core/server'; -import { createMockRouter, MockRouter } from './__mocks__/routes.mock'; +import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks__/routes.mock'; import { createRequestMock } from './__mocks__/request.mock'; jest.mock('../lib/es_version_precheck', () => ({ @@ -24,32 +24,22 @@ import { registerClusterCheckupRoutes } from './cluster_checkup'; * more thoroughly in the es_migration_apis test. */ describe('cluster checkup API', () => { - afterEach(() => jest.clearAllMocks()); - let mockRouter: MockRouter; - let serverShim: any; - let ctxMock: any; - let mockPluginsSetup: any; + let routeDependencies: any; beforeEach(() => { mockRouter = createMockRouter(); - mockPluginsSetup = { + routeDependencies = { cloud: { isCloudEnabled: true, }, - }; - ctxMock = { - core: {}, - }; - serverShim = { router: mockRouter, - plugins: { - elasticsearch: { - getCluster: () => ({ callWithRequest: jest.fn() } as any), - } as any, - }, }; - registerClusterCheckupRoutes(serverShim, mockPluginsSetup); + registerClusterCheckupRoutes(routeDependencies); + }); + + afterEach(() => { + jest.resetAllMocks(); }); describe('with cloud enabled', () => { @@ -62,11 +52,11 @@ describe('cluster checkup API', () => { nodes: [], }); - await serverShim.router.getHandler({ + await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/status', - })(ctxMock, createRequestMock(), kibanaResponseFactory); - expect(spy.mock.calls[0][2]).toBe(true); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); + expect(spy.mock.calls[0][1]).toBe(true); }); }); @@ -77,10 +67,10 @@ describe('cluster checkup API', () => { indices: [], nodes: [], }); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/status', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(200); expect(JSON.stringify(resp.payload)).toMatchInlineSnapshot( @@ -93,10 +83,10 @@ describe('cluster checkup API', () => { e.status = 403; MigrationApis.getUpgradeAssistantStatus.mockRejectedValue(e); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/status', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(403); }); @@ -104,10 +94,10 @@ describe('cluster checkup API', () => { it('returns an 500 error if it throws', async () => { MigrationApis.getUpgradeAssistantStatus.mockRejectedValue(new Error(`scary error!`)); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/status', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(500); }); diff --git a/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts new file mode 100644 index 00000000000000..22a121ab78683a --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/routes/cluster_checkup.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getUpgradeAssistantStatus } from '../lib/es_migration_apis'; +import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; +import { RouteDependencies } from '../types'; + +export function registerClusterCheckupRoutes({ cloud, router }: RouteDependencies) { + const isCloudEnabled = Boolean(cloud?.isCloudEnabled); + + router.get( + { + path: '/api/upgrade_assistant/status', + validate: false, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + try { + return response.ok({ + body: await getUpgradeAssistantStatus(dataClient, isCloudEnabled), + }); + } catch (e) { + if (e.status === 403) { + return response.forbidden(e.message); + } + + return response.internalError({ body: e }); + } + } + ) + ); +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts similarity index 56% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.test.ts rename to x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts index d6633619563743..845a0238f7918c 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/deprecation_logging.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.test.ts @@ -5,7 +5,7 @@ */ import { kibanaResponseFactory } from 'src/core/server'; -import { createMockRouter, MockRouter } from './__mocks__/routes.mock'; +import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks__/routes.mock'; import { createRequestMock } from './__mocks__/request.mock'; jest.mock('../lib/es_version_precheck', () => ({ @@ -21,42 +21,42 @@ import { registerDeprecationLoggingRoutes } from './deprecation_logging'; */ describe('deprecation logging API', () => { let mockRouter: MockRouter; - let serverShim: any; - let callWithRequest: any; - const ctxMock: any = {}; + let routeDependencies: any; beforeEach(() => { mockRouter = createMockRouter(); - callWithRequest = jest.fn(); - serverShim = { + routeDependencies = { router: mockRouter, - plugins: { - elasticsearch: { - getCluster: () => ({ callWithRequest } as any), - } as any, - }, }; - registerDeprecationLoggingRoutes(serverShim); + registerDeprecationLoggingRoutes(routeDependencies); + }); + + afterEach(() => { + jest.resetAllMocks(); }); describe('GET /api/upgrade_assistant/deprecation_logging', () => { it('returns isEnabled', async () => { - callWithRequest.mockResolvedValue({ default: { logger: { deprecation: 'WARN' } } }); - const resp = await serverShim.router.getHandler({ + (routeHandlerContextMock.core.elasticsearch.dataClient + .callAsCurrentUser as jest.Mock).mockResolvedValue({ + default: { logger: { deprecation: 'WARN' } }, + }); + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/deprecation_logging', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(200); expect(resp.payload).toEqual({ isEnabled: true }); }); it('returns an error if it throws', async () => { - callWithRequest.mockRejectedValue(new Error(`scary error!`)); - const resp = await serverShim.router.getHandler({ + (routeHandlerContextMock.core.elasticsearch.dataClient + .callAsCurrentUser as jest.Mock).mockRejectedValue(new Error(`scary error!`)); + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/deprecation_logging', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.status).toEqual(500); }); @@ -64,21 +64,25 @@ describe('deprecation logging API', () => { describe('PUT /api/upgrade_assistant/deprecation_logging', () => { it('returns isEnabled', async () => { - callWithRequest.mockResolvedValue({ default: { logger: { deprecation: 'ERROR' } } }); - const resp = await serverShim.router.getHandler({ + (routeHandlerContextMock.core.elasticsearch.dataClient + .callAsCurrentUser as jest.Mock).mockResolvedValue({ + default: { logger: { deprecation: 'ERROR' } }, + }); + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/deprecation_logging', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })(routeHandlerContextMock, createRequestMock(), kibanaResponseFactory); expect(resp.payload).toEqual({ isEnabled: false }); }); it('returns an error if it throws', async () => { - callWithRequest.mockRejectedValue(new Error(`scary error!`)); - const resp = await serverShim.router.getHandler({ + (routeHandlerContextMock.core.elasticsearch.dataClient + .callAsCurrentUser as jest.Mock).mockRejectedValue(new Error(`scary error!`)); + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/deprecation_logging', - })(ctxMock, { body: { isEnabled: false } }, kibanaResponseFactory); + })(routeHandlerContextMock, { body: { isEnabled: false } }, kibanaResponseFactory); expect(resp.status).toEqual(500); }); diff --git a/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts new file mode 100644 index 00000000000000..739a789c95ce09 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/routes/deprecation_logging.ts @@ -0,0 +1,72 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; + +import { + getDeprecationLoggingStatus, + setDeprecationLogging, +} from '../lib/es_deprecation_logging_apis'; +import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; +import { RouteDependencies } from '../types'; + +export function registerDeprecationLoggingRoutes({ router }: RouteDependencies) { + router.get( + { + path: '/api/upgrade_assistant/deprecation_logging', + validate: false, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + try { + const result = await getDeprecationLoggingStatus(dataClient); + return response.ok({ body: result }); + } catch (e) { + return response.internalError({ body: e }); + } + } + ) + ); + + router.put( + { + path: '/api/upgrade_assistant/deprecation_logging', + validate: { + body: schema.object({ + isEnabled: schema.boolean(), + }), + }, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + try { + const { isEnabled } = request.body as { isEnabled: boolean }; + return response.ok({ + body: await setDeprecationLogging(dataClient, isEnabled), + }); + } catch (e) { + return response.internalError({ body: e }); + } + } + ) + ); +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts similarity index 80% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.test.ts rename to x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts index d520324239656b..695bb6304cfdfb 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/reindex_indices.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.test.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { savedObjectsClientMock } from 'src/core/server/mocks'; import { kibanaResponseFactory } from 'src/core/server'; -import { createMockRouter, MockRouter } from './__mocks__/routes.mock'; +import { licensingMock } from '../../../licensing/server/mocks'; +import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks__/routes.mock'; import { createRequestMock } from './__mocks__/request.mock'; const mockReindexService = { @@ -31,12 +31,7 @@ jest.mock('../lib/reindexing', () => { }; }); -import { - IndexGroup, - ReindexSavedObject, - ReindexStatus, - ReindexWarning, -} from '../../../common/types'; +import { IndexGroup, ReindexSavedObject, ReindexStatus, ReindexWarning } from '../../common/types'; import { credentialStoreFactory } from '../lib/reindexing/credential_store'; import { registerReindexIndicesRoutes } from './reindex_indices'; @@ -46,9 +41,8 @@ import { registerReindexIndicesRoutes } from './reindex_indices'; * more thoroughly in the es_migration_apis test. */ describe('reindex API', () => { - let serverShim: any; + let routeDependencies: any; let mockRouter: MockRouter; - let ctxMock: any; const credentialStore = credentialStoreFactory(); const worker = { @@ -57,24 +51,13 @@ describe('reindex API', () => { } as any; beforeEach(() => { - ctxMock = { - core: { - savedObjects: savedObjectsClientMock.create(), - }, - }; mockRouter = createMockRouter(); - serverShim = { + routeDependencies = { + credentialStore, router: mockRouter, - plugins: { - xpack_main: { - info: jest.fn(), - }, - elasticsearch: { - getCluster: () => ({ callWithRequest: jest.fn() } as any), - } as any, - }, + licensing: licensingMock.createSetup(), }; - registerReindexIndicesRoutes(serverShim, worker, credentialStore); + registerReindexIndicesRoutes(routeDependencies, () => worker); mockReindexService.hasRequiredPrivileges.mockResolvedValue(true); mockReindexService.detectReindexWarnings.mockReset(); @@ -92,7 +75,9 @@ describe('reindex API', () => { credentialStore.clear(); }); - afterEach(() => jest.clearAllMocks()); + afterEach(() => { + jest.resetAllMocks(); + }); describe('GET /api/upgrade_assistant/reindex/{indexName}', () => { it('returns the attributes of the reindex operation and reindex warnings', async () => { @@ -101,10 +86,14 @@ describe('reindex API', () => { }); mockReindexService.detectReindexWarnings.mockResolvedValueOnce([ReindexWarning.allField]); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', - })(ctxMock, createRequestMock({ params: { indexName: 'wowIndex' } }), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ params: { indexName: 'wowIndex' } }), + kibanaResponseFactory + ); // It called into the service correctly expect(mockReindexService.findReindexOperation).toHaveBeenCalledWith('wowIndex'); @@ -121,10 +110,14 @@ describe('reindex API', () => { mockReindexService.findReindexOperation.mockResolvedValueOnce(null); mockReindexService.detectReindexWarnings.mockResolvedValueOnce(null); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', - })(ctxMock, createRequestMock({ params: { indexName: 'anIndex' } }), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ params: { indexName: 'anIndex' } }), + kibanaResponseFactory + ); expect(resp.status).toEqual(200); const data = resp.payload; @@ -137,10 +130,14 @@ describe('reindex API', () => { mockReindexService.detectReindexWarnings.mockResolvedValueOnce([]); mockReindexService.getIndexGroup.mockReturnValue(IndexGroup.ml); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'get', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', - })(ctxMock, createRequestMock({ params: { indexName: 'anIndex' } }), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ params: { indexName: 'anIndex' } }), + kibanaResponseFactory + ); expect(resp.status).toEqual(200); const data = resp.payload; @@ -154,10 +151,14 @@ describe('reindex API', () => { attributes: { indexName: 'theIndex' }, }); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', - })(ctxMock, createRequestMock({ params: { indexName: 'theIndex' } }), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ params: { indexName: 'theIndex' } }), + kibanaResponseFactory + ); // It called create correctly expect(mockReindexService.createReindexOperation).toHaveBeenCalledWith('theIndex'); @@ -173,10 +174,14 @@ describe('reindex API', () => { attributes: { indexName: 'theIndex' }, }); - await serverShim.router.getHandler({ + await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', - })(ctxMock, createRequestMock({ params: { indexName: 'theIndex' } }), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ params: { indexName: 'theIndex' } }), + kibanaResponseFactory + ); expect(worker.forceRefresh).toHaveBeenCalled(); }); @@ -187,11 +192,11 @@ describe('reindex API', () => { } as ReindexSavedObject; mockReindexService.createReindexOperation.mockResolvedValueOnce(reindexOp); - await serverShim.router.getHandler({ + await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ headers: { 'kbn-auth-x': 'HERE!', @@ -212,11 +217,11 @@ describe('reindex API', () => { attributes: { indexName: 'theIndex', status: ReindexStatus.inProgress }, }); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, }), @@ -235,11 +240,11 @@ describe('reindex API', () => { it('returns a 403 if required privileges fails', async () => { mockReindexService.hasRequiredPrivileges.mockResolvedValueOnce(false); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ params: { indexName: 'theIndex' }, }), @@ -254,11 +259,11 @@ describe('reindex API', () => { it('returns a 501', async () => { mockReindexService.cancelReindexing.mockResolvedValueOnce({}); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'post', pathPattern: '/api/upgrade_assistant/reindex/{indexName}/cancel', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ params: { indexName: 'cancelMe' }, }), diff --git a/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts new file mode 100644 index 00000000000000..a910145474061f --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/routes/reindex_indices.ts @@ -0,0 +1,217 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { Logger, ElasticsearchServiceSetup, SavedObjectsClient } from 'src/core/server'; +import { ReindexStatus } from '../../common/types'; +import { versionCheckHandlerWrapper } from '../lib/es_version_precheck'; +import { reindexServiceFactory, ReindexWorker } from '../lib/reindexing'; +import { CredentialStore } from '../lib/reindexing/credential_store'; +import { reindexActionsFactory } from '../lib/reindexing/reindex_actions'; +import { RouteDependencies } from '../types'; +import { LicensingPluginSetup } from '../../../licensing/server'; + +interface CreateReindexWorker { + logger: Logger; + elasticsearchService: ElasticsearchServiceSetup; + credentialStore: CredentialStore; + savedObjects: SavedObjectsClient; + licensing: LicensingPluginSetup; +} + +export function createReindexWorker({ + logger, + elasticsearchService, + credentialStore, + savedObjects, + licensing, +}: CreateReindexWorker) { + const { adminClient } = elasticsearchService; + return new ReindexWorker(savedObjects, credentialStore, adminClient, logger, licensing); +} + +export function registerReindexIndicesRoutes( + { credentialStore, router, licensing, log }: RouteDependencies, + getWorker: () => ReindexWorker +) { + const BASE_PATH = '/api/upgrade_assistant/reindex'; + + // Start reindex for an index + router.post( + { + path: `${BASE_PATH}/{indexName}`, + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + savedObjects, + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + const { indexName } = request.params as any; + const { client } = savedObjects; + const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing + ); + + try { + if (!(await reindexService.hasRequiredPrivileges(indexName))) { + return response.forbidden({ + body: `You do not have adequate privileges to reindex this index.`, + }); + } + + const existingOp = await reindexService.findReindexOperation(indexName); + + // If the reindexOp already exists and it's paused, resume it. Otherwise create a new one. + const reindexOp = + existingOp && existingOp.attributes.status === ReindexStatus.paused + ? await reindexService.resumeReindexOperation(indexName) + : await reindexService.createReindexOperation(indexName); + + // Add users credentials for the worker to use + credentialStore.set(reindexOp, request.headers); + + // Kick the worker on this node to immediately pickup the new reindex operation. + getWorker().forceRefresh(); + + return response.ok({ body: reindexOp.attributes }); + } catch (e) { + return response.internalError({ body: e }); + } + } + ) + ); + + // Get status + router.get( + { + path: `${BASE_PATH}/{indexName}`, + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + savedObjects, + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + const { client } = savedObjects; + const { indexName } = request.params as any; + const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing + ); + + try { + const hasRequiredPrivileges = await reindexService.hasRequiredPrivileges(indexName); + const reindexOp = await reindexService.findReindexOperation(indexName); + // If the user doesn't have privileges than querying for warnings is going to fail. + const warnings = hasRequiredPrivileges + ? await reindexService.detectReindexWarnings(indexName) + : []; + const indexGroup = reindexService.getIndexGroup(indexName); + + return response.ok({ + body: { + reindexOp: reindexOp ? reindexOp.attributes : null, + warnings, + indexGroup, + hasRequiredPrivileges, + }, + }); + } catch (e) { + if (!e.isBoom) { + return response.internalError({ body: e }); + } + return response.customError({ + body: { + message: e.message, + }, + statusCode: e.statusCode, + }); + } + } + ) + ); + + // Cancel reindex + router.post( + { + path: `${BASE_PATH}/{indexName}/cancel`, + validate: { + params: schema.object({ + indexName: schema.string(), + }), + }, + }, + versionCheckHandlerWrapper( + async ( + { + core: { + savedObjects, + elasticsearch: { dataClient }, + }, + }, + request, + response + ) => { + const { indexName } = request.params as any; + const { client } = savedObjects; + const callAsCurrentUser = dataClient.callAsCurrentUser.bind(dataClient); + const reindexActions = reindexActionsFactory(client, callAsCurrentUser); + const reindexService = reindexServiceFactory( + callAsCurrentUser, + reindexActions, + log, + licensing + ); + + try { + await reindexService.cancelReindexing(indexName); + + return response.ok({ body: { acknowledged: true } }); + } catch (e) { + if (!e.isBoom) { + return response.internalError({ body: e }); + } + return response.customError({ + body: { + message: e.message, + }, + statusCode: e.statusCode, + }); + } + } + ) + ); +} diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.test.ts b/x-pack/plugins/upgrade_assistant/server/routes/telemetry.test.ts similarity index 79% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.test.ts rename to x-pack/plugins/upgrade_assistant/server/routes/telemetry.test.ts index 582c75e3701b64..b2b8ccf1ca57af 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.test.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/telemetry.test.ts @@ -5,7 +5,8 @@ */ import { kibanaResponseFactory } from 'src/core/server'; -import { createMockRouter, MockRouter } from './__mocks__/routes.mock'; +import { savedObjectsServiceMock } from 'src/core/server/saved_objects/saved_objects_service.mock'; +import { createMockRouter, MockRouter, routeHandlerContextMock } from './__mocks__/routes.mock'; import { createRequestMock } from './__mocks__/request.mock'; jest.mock('../lib/telemetry/es_ui_open_apis', () => ({ @@ -26,24 +27,15 @@ import { registerTelemetryRoutes } from './telemetry'; * more thoroughly in the lib/telemetry tests. */ describe('Upgrade Assistant Telemetry API', () => { - let serverShim: any; + let routeDependencies: any; let mockRouter: MockRouter; - let ctxMock: any; beforeEach(() => { - ctxMock = {}; mockRouter = createMockRouter(); - serverShim = { + routeDependencies = { + getSavedObjectsService: () => savedObjectsServiceMock.create(), router: mockRouter, - plugins: { - xpack_main: { - info: jest.fn(), - }, - elasticsearch: { - getCluster: () => ({ callWithRequest: jest.fn() } as any), - } as any, - }, }; - registerTelemetryRoutes(serverShim); + registerTelemetryRoutes(routeDependencies); }); afterEach(() => jest.clearAllMocks()); @@ -57,10 +49,14 @@ describe('Upgrade Assistant Telemetry API', () => { (upsertUIOpenOption as jest.Mock).mockResolvedValue(returnPayload); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_open', - })(ctxMock, createRequestMock(), kibanaResponseFactory); + })( + routeHandlerContextMock, + createRequestMock({ body: returnPayload }), + kibanaResponseFactory + ); expect(resp.payload).toEqual(returnPayload); }); @@ -74,13 +70,13 @@ describe('Upgrade Assistant Telemetry API', () => { (upsertUIOpenOption as jest.Mock).mockResolvedValue(returnPayload); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_open', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ - payload: { + body: { overview: true, cluster: true, indices: true, @@ -95,13 +91,13 @@ describe('Upgrade Assistant Telemetry API', () => { it('returns an error if it throws', async () => { (upsertUIOpenOption as jest.Mock).mockRejectedValue(new Error(`scary error!`)); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_open', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ - payload: { + body: { overview: false, }, }), @@ -123,13 +119,13 @@ describe('Upgrade Assistant Telemetry API', () => { (upsertUIReindexOption as jest.Mock).mockRejectedValue(returnPayload); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_reindex', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ - payload: { + body: { overview: false, }, }), @@ -149,13 +145,13 @@ describe('Upgrade Assistant Telemetry API', () => { (upsertUIReindexOption as jest.Mock).mockRejectedValue(returnPayload); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_reindex', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ - payload: { + body: { close: true, open: true, start: true, @@ -171,13 +167,13 @@ describe('Upgrade Assistant Telemetry API', () => { it('returns an error if it throws', async () => { (upsertUIReindexOption as jest.Mock).mockRejectedValue(new Error(`scary error!`)); - const resp = await serverShim.router.getHandler({ + const resp = await routeDependencies.router.getHandler({ method: 'put', pathPattern: '/api/upgrade_assistant/telemetry/ui_reindex', })( - ctxMock, + routeHandlerContextMock, createRequestMock({ - payload: { + body: { start: false, }, }), diff --git a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.ts b/x-pack/plugins/upgrade_assistant/server/routes/telemetry.ts similarity index 66% rename from x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.ts rename to x-pack/plugins/upgrade_assistant/server/routes/telemetry.ts index f08c49809033db..900a5e64c55c3e 100644 --- a/x-pack/legacy/plugins/upgrade_assistant/server/np_ready/routes/telemetry.ts +++ b/x-pack/plugins/upgrade_assistant/server/routes/telemetry.ts @@ -7,11 +7,10 @@ import { schema } from '@kbn/config-schema'; import { upsertUIOpenOption } from '../lib/telemetry/es_ui_open_apis'; import { upsertUIReindexOption } from '../lib/telemetry/es_ui_reindex_apis'; -import { ServerShimWithRouter } from '../types'; -import { createRequestShim } from './create_request_shim'; +import { RouteDependencies } from '../types'; -export function registerTelemetryRoutes(server: ServerShimWithRouter) { - server.router.put( +export function registerTelemetryRoutes({ router, getSavedObjectsService }: RouteDependencies) { + router.put( { path: '/api/upgrade_assistant/telemetry/ui_open', validate: { @@ -23,16 +22,23 @@ export function registerTelemetryRoutes(server: ServerShimWithRouter) { }, }, async (ctx, request, response) => { - const reqShim = createRequestShim(request); + const { cluster, indices, overview } = request.body; try { - return response.ok({ body: await upsertUIOpenOption(server, reqShim) }); + return response.ok({ + body: await upsertUIOpenOption({ + savedObjects: getSavedObjectsService(), + cluster, + indices, + overview, + }), + }); } catch (e) { return response.internalError({ body: e }); } } ); - server.router.put( + router.put( { path: '/api/upgrade_assistant/telemetry/ui_reindex', validate: { @@ -45,9 +51,17 @@ export function registerTelemetryRoutes(server: ServerShimWithRouter) { }, }, async (ctx, request, response) => { - const reqShim = createRequestShim(request); + const { close, open, start, stop } = request.body; try { - return response.ok({ body: await upsertUIReindexOption(server, reqShim) }); + return response.ok({ + body: await upsertUIReindexOption({ + savedObjects: getSavedObjectsService(), + close, + open, + start, + stop, + }), + }); } catch (e) { return response.internalError({ body: e }); } diff --git a/x-pack/plugins/upgrade_assistant/server/types.ts b/x-pack/plugins/upgrade_assistant/server/types.ts new file mode 100644 index 00000000000000..3f3beadd2f3332 --- /dev/null +++ b/x-pack/plugins/upgrade_assistant/server/types.ts @@ -0,0 +1,19 @@ +/* + * 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 { IRouter, Logger, SavedObjectsServiceStart } from 'src/core/server'; +import { CloudSetup } from '../../cloud/server'; +import { CredentialStore } from './lib/reindexing/credential_store'; +import { LicensingPluginSetup } from '../../licensing/server'; + +export interface RouteDependencies { + router: IRouter; + credentialStore: CredentialStore; + log: Logger; + getSavedObjectsService: () => SavedObjectsServiceStart; + licensing: LicensingPluginSetup; + cloud?: CloudSetup; +} diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js index 9fc80781628474..38fc1f0c6356f7 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -6,10 +6,7 @@ import expect from '@kbn/expect'; -import { - ReindexStatus, - REINDEX_OP_TYPE, -} from '../../../legacy/plugins/upgrade_assistant/common/types'; +import { ReindexStatus, REINDEX_OP_TYPE } from '../../../plugins/upgrade_assistant/common/types'; export default function({ getService }) { const supertest = getService('supertest'); From 10bf90f9f57112c078db973b196974277404f745 Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Tue, 25 Feb 2020 09:34:53 -0500 Subject: [PATCH 38/73] [SIEM] [Detection Engine] Increase unit test coverage (#58274) * updates read privileges route tests * fixes test for 404 when alertsClient is not present, adds new test for catching errors at the route level for prepackaged rules route * fixes test for happy path on create rules bulk route (missing mock resulted in 200, but was still throwing an error), adds tests for covering case where a rule with a matching rule id is found to have already existed, adds a test covering the case where createRules throws an error and that error is caught in the catch block, and appears in the response * adds more jest functions to beforeEach to ensure mockImplementation state used by spyOn is not carried over between tests, increases test coverage for create rules route * updates unit test coverage for delete rules route and bulk delete * increase unit test coverage for find_rules_route * add test case to get_prepackaged_rules where findRules throws an error * adds unit test for missing alertsClient in patch_rules_bulk route * adds unit test coverage for transform error and pathRules throwing an error on patch rules route * adds unit test coverage for rule not found, transform error, and readRules throws an error on read_rules_route * adds unit test coverage for update rules (bulk) routes * increases unit test coverage for open close signals route * updates coverage for signals query route * adds unit tests for rules status route, updates utils test coverage. Removed unreachable code. * updates test coverage, removes usage of pipes from ndjson to stream conversion and returns arrays of tranformers to be used in createPromiseFromStreams so that unhandled promise rejections can be handled appropriately. * fixes type errors * fix bug on transform when rulestatus saved objects array is empty because we are no longer passing in the current status, we are passing in the whole saved object. * adds unit test for when readRules throws an error inside of get export by object ids * adds unit tests for catching errors on read rules and fixes property undefined bug in catch block * removes unused function from utils * adds the 'else' clause back to the getTupleDuplicateErrorsAndUniqueRules function and adds a test case for when an attempt to import rules with missing ruleIds is made, and the expected outcome. --- .../routes/__mocks__/request_responses.ts | 43 ++- .../routes/__mocks__/utils.ts | 37 ++ .../privileges/read_privileges_route.test.ts | 12 + .../rules/add_prepackaged_rules_route.test.ts | 23 +- .../rules/create_rules_bulk_route.test.ts | 49 ++- .../routes/rules/create_rules_route.test.ts | 48 ++- .../rules/delete_rules_bulk_route.test.ts | 10 + .../routes/rules/delete_rules_bulk_route.ts | 2 +- .../routes/rules/delete_rules_route.test.ts | 33 ++ .../routes/rules/find_rules_route.test.ts | 49 ++- .../rules/find_rules_status_route.test.ts | 96 +++++ .../routes/rules/find_rules_status_route.ts | 77 ++-- ...get_prepackaged_rules_status_route.test.ts | 17 + .../routes/rules/import_rules_route.test.ts | 38 +- .../routes/rules/import_rules_route.ts | 332 +++++++++--------- .../routes/rules/patch_rules_bulk.test.ts | 9 + .../routes/rules/patch_rules_route.test.ts | 34 ++ .../routes/rules/read_rules_route.test.ts | 41 ++- .../routes/rules/update_rules_bulk.test.ts | 4 +- .../routes/rules/update_rules_route.test.ts | 30 ++ .../routes/rules/utils.test.ts | 44 ++- .../detection_engine/routes/rules/utils.ts | 6 +- .../routes/signals/open_close_signals.test.ts | 14 + .../signals/open_close_signals_route.ts | 16 +- .../signals/query_signals_route.test.ts | 13 + .../routes/signals/query_signals_route.ts | 16 +- .../lib/detection_engine/routes/utils.test.ts | 12 + .../lib/detection_engine/routes/utils.ts | 9 + .../create_rules_stream_from_ndjson.test.ts | 64 +++- .../rules/create_rules_stream_from_ndjson.ts | 22 +- .../rules/get_export_by_object_ids.test.ts | 23 ++ .../detection_engine/rules/read_rules.test.ts | 73 ++++ .../lib/detection_engine/rules/read_rules.ts | 2 +- .../lib/detection_engine/rules/types.ts | 4 - .../security_and_spaces/tests/import_rules.ts | 11 + 35 files changed, 1038 insertions(+), 275 deletions(-) create mode 100644 x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 1578c71dddc6a9..2b50011cf4dff1 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -427,13 +427,54 @@ export const getMockPrivileges = () => ({ has_encryption_key: true, }); -export const getFindResultStatus = (): SavedObjectsFindResponse => ({ +export const getFindResultStatusEmpty = (): SavedObjectsFindResponse => ({ page: 1, per_page: 1, total: 0, saved_objects: [], }); +export const getFindResultStatus = (): SavedObjectsFindResponse => ({ + page: 1, + per_page: 6, + total: 2, + saved_objects: [ + { + type: 'my-type', + id: 'e0b86950-4e9f-11ea-bdbd-07b56aa159b3', + attributes: { + alertId: '1ea5a820-4da1-4e82-92a1-2b43a7bece08', + statusDate: '2020-02-18T15:26:49.783Z', + status: 'succeeded', + lastFailureAt: null, + lastSuccessAt: '2020-02-18T15:26:49.783Z', + lastFailureMessage: null, + lastSuccessMessage: 'succeeded', + }, + references: [], + updated_at: '2020-02-18T15:26:51.333Z', + version: 'WzQ2LDFd', + }, + { + type: 'my-type', + id: '91246bd0-5261-11ea-9650-33b954270f67', + attributes: { + alertId: '1ea5a820-4da1-4e82-92a1-2b43a7bece08', + statusDate: '2020-02-18T15:15:58.806Z', + status: 'failed', + lastFailureAt: '2020-02-18T15:15:58.806Z', + lastSuccessAt: '2020-02-13T20:31:59.855Z', + lastFailureMessage: + 'Signal rule name: "Query with a rule id Number 1", id: "1ea5a820-4da1-4e82-92a1-2b43a7bece08", rule_id: "query-rule-id-1" has a time gap of 5 days (412682928ms), and could be missing signals within that time. Consider increasing your look behind time or adding more Kibana instances.', + lastSuccessMessage: 'succeeded', + }, + references: [], + updated_at: '2020-02-18T15:15:58.860Z', + version: 'WzMyLDFd', + }, + ], +}); + export const getIndexName = () => 'index-name'; export const getEmptyIndex = (): { _shards: Partial } => ({ _shards: { total: 0 }, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts index f8c8e1f231ffa2..32226e38a1f7f7 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/utils.ts @@ -26,6 +26,20 @@ export const getSimpleRule = (ruleId = 'rule-1'): Partial = query: 'user.name: root or user.name: admin', }); +/** + * This is a typical simple rule for testing that is easy for most basic testing + * @param ruleId + */ +export const getSimpleRuleWithId = (id = 'rule-1'): Partial => ({ + name: 'Simple Rule Query', + description: 'Simple Rule Query', + risk_score: 1, + id, + severity: 'high', + type: 'query', + query: 'user.name: root or user.name: admin', +}); + /** * Given an array of rule_id strings this will return a ndjson buffer which is useful * for testing uploads. @@ -51,3 +65,26 @@ export const getSimpleRuleAsMultipartContent = (ruleIds: string[], isNdjson = tr return Buffer.from(resultingPayload); }; + +/** + * Given an array of rule_id strings this will return a ndjson buffer which is useful + * for testing uploads. + * @param count Number of rules to generate + * @param isNdjson Boolean to determine file extension + */ +export const getSimpleRuleAsMultipartContentNoRuleId = (count: number, isNdjson = true): Buffer => { + const arrayOfRules = Array(count).fill(JSON.stringify(getSimpleRuleWithId())); + const stringOfRules = arrayOfRules.join('\r\n'); + + const resultingPayload = + `--${TEST_BOUNDARY}\r\n` + + `Content-Disposition: form-data; name="file"; filename="rules.${ + isNdjson ? 'ndjson' : 'json' + }\r\n` + + 'Content-Type: application/octet-stream\r\n' + + '\r\n' + + `${stringOfRules}\r\n` + + `--${TEST_BOUNDARY}--\r\n`; + + return Buffer.from(resultingPayload); +}; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts index 308ee95a77e204..3c31658c61d6e3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/privileges/read_privileges_route.test.ts @@ -5,6 +5,7 @@ */ import { readPrivilegesRoute } from './read_privileges_route'; +import * as readPrivileges from '../../privileges/read_privileges'; import { createMockServer, createMockConfig, clientsServiceMock } from '../__mocks__'; import { getPrivilegeRequest, getMockPrivileges } from '../__mocks__/request_responses'; @@ -38,5 +39,16 @@ describe('read_privileges', () => { const { payload } = await inject(getPrivilegeRequest()); expect(JSON.parse(payload)).toEqual(getMockPrivileges()); }); + + test('returns 500 when bad response from readPrivileges', async () => { + jest.spyOn(readPrivileges, 'readPrivileges').mockImplementation(() => { + throw new Error('Test error'); + }); + const { payload } = await inject(getPrivilegeRequest()); + expect(JSON.parse(payload)).toEqual({ + message: 'Test error', + status_code: 500, + }); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts index e018ed4cc22ff4..e6a93fdadcfcaa 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts @@ -6,7 +6,6 @@ import { omit } from 'lodash/fp'; -import { createRulesRoute } from './create_rules_route'; import { getFindResult, getResult, @@ -17,6 +16,7 @@ import { getNonEmptyIndex, } from '../__mocks__/request_responses'; import { createMockServer, createMockConfig, clientsServiceMock } from '../__mocks__'; +import * as updatePrepackagedRules from '../../rules/update_prepacked_rules'; jest.mock('../../rules/get_prepackaged_rules', () => { return { @@ -54,7 +54,8 @@ describe('add_prepackaged_rules_route', () => { beforeEach(() => { jest.resetAllMocks(); - + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); config = createMockConfig(); getClients = clientsServiceMock.createGetScoped(); @@ -78,9 +79,7 @@ describe('add_prepackaged_rules_route', () => { test('returns 404 if alertClient is not available on the route', async () => { getClients.mockResolvedValue(omit('alertsClient', clients)); - const { inject, route } = createMockServer(); - createRulesRoute(route, config, getClients); - const { statusCode } = await inject(addPrepackagedRulesRequest()); + const { statusCode } = await server.inject(addPrepackagedRulesRequest()); expect(statusCode).toBe(404); }); }); @@ -126,5 +125,19 @@ describe('add_prepackaged_rules_route', () => { rules_updated: 1, }); }); + test('catches errors if payloads cause errors to be thrown', async () => { + jest.spyOn(updatePrepackagedRules, 'updatePrepackagedRules').mockImplementation(() => { + throw new Error('Test error'); + }); + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + const { payload } = await server.inject(addPrepackagedRulesRequest()); + expect(JSON.parse(payload)).toEqual({ + message: 'Test error', + status_code: 500, + }); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts index 664d27a7572ad1..931623ea6652c6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts @@ -14,12 +14,15 @@ import { typicalPayload, getReadBulkRequest, getEmptyIndex, + getNonEmptyIndex, } from '../__mocks__/request_responses'; import { createMockServer, createMockConfig, clientsServiceMock } from '../__mocks__'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { createRulesBulkRoute } from './create_rules_bulk_route'; import { BulkError } from '../utils'; import { OutputRuleAlertRest } from '../../types'; +import * as createRules from '../../rules/create_rules'; +import * as readRules from '../../rules/read_rules'; describe('create_rules_bulk', () => { let server = createMockServer(); @@ -29,10 +32,14 @@ describe('create_rules_bulk', () => { beforeEach(() => { jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); config = createMockConfig(); getClients = clientsServiceMock.createGetScoped(); clients = clientsServiceMock.createClients(); + clients.clusterClient.callAsCurrentUser.mockResolvedValue(getNonEmptyIndex()); + getClients.mockResolvedValue(clients); createRulesBulkRoute(server.route, config, getClients); @@ -44,8 +51,12 @@ describe('create_rules_bulk', () => { clients.alertsClient.get.mockResolvedValue(getResult()); clients.actionsClient.create.mockResolvedValue(createActionResult()); clients.alertsClient.create.mockResolvedValue(getResult()); - const { statusCode } = await server.inject(getReadBulkRequest()); + jest.spyOn(createRules, 'createRules').mockImplementation(async () => { + return getResult(); + }); + const { payload, statusCode } = await server.inject(getReadBulkRequest()); expect(statusCode).toBe(200); + expect(JSON.parse(payload).error).toBeUndefined(); }); test('returns 404 if alertClient is not available on the route', async () => { @@ -149,6 +160,24 @@ describe('create_rules_bulk', () => { expect(output.some(item => item.error?.status_code === 409)).toBeTruthy(); }); + test('returns 409 if duplicate rule_ids found in rule saved objects', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + jest.spyOn(readRules, 'readRules').mockImplementation(async () => { + return getResult(); + }); + const request: ServerInjectOptions = { + method: 'POST', + url: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`, + payload: [typicalPayload()], + }; + const { payload } = await server.inject(request); + const output: Array> = JSON.parse(payload); + expect(output.some(item => item.error?.status_code === 409)).toBeTruthy(); + }); + test('returns one error object in response when duplicate rule_ids found in request payload', async () => { clients.alertsClient.find.mockResolvedValue(getFindResult()); clients.alertsClient.get.mockResolvedValue(getResult()); @@ -163,4 +192,22 @@ describe('create_rules_bulk', () => { const output: Array> = JSON.parse(payload); expect(output.length).toBe(1); }); + + test('catches error if createRules throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + jest.spyOn(createRules, 'createRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const request: ServerInjectOptions = { + method: 'POST', + url: `${DETECTION_ENGINE_RULES_URL}/_bulk_create`, + payload: [typicalPayload()], + }; + const { payload } = await server.inject(request); + const output: Array> = JSON.parse(payload); + expect(output[0].error.message).toBe('Test error'); + }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts index 4f28771db8ed78..5ad43e70f2651e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_route.test.ts @@ -9,6 +9,9 @@ import { omit } from 'lodash/fp'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { createRulesRoute } from './create_rules_route'; +import * as createRules from '../../rules/create_rules'; +import * as readRules from '../../rules/read_rules'; +import * as utils from './utils'; import { getFindResult, @@ -29,8 +32,12 @@ describe('create_rules', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); - + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); config = createMockConfig(); getClients = clientsServiceMock.createGetScoped(); @@ -130,5 +137,44 @@ describe('create_rules', () => { const { statusCode } = await server.inject(request); expect(statusCode).toBe(400); }); + + test('catches error if createRules throws error', async () => { + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(createRules, 'createRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getCreateRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); + + test('catches error if transform returns null', async () => { + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(utils, 'transform').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getCreateRequest()); + expect(JSON.parse(payload).message).toBe('Internal error transforming rules'); + expect(statusCode).toBe(500); + }); + + test('returns 409 if duplicate rule_ids found in rule saved objects', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.create.mockResolvedValue(createActionResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + jest.spyOn(readRules, 'readRules').mockImplementation(async () => { + return getResult(); + }); + const { payload } = await server.inject(getCreateRequest()); + const output = JSON.parse(payload); + expect(output.status_code).toEqual(409); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts index 855bf7f634c26b..fb44f96d76859f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts @@ -48,6 +48,16 @@ describe('delete_rules', () => { expect(statusCode).toBe(200); }); + test('resturns 200 when deleting a single rule and related rule status', async () => { + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + clients.savedObjectsClient.delete.mockResolvedValue(true); + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.delete.mockResolvedValue({}); + const { statusCode } = await server.inject(getDeleteBulkRequest()); + expect(statusCode).toBe(200); + }); + test('returns 200 when deleting a single rule with a valid actionClient and alertClient by alertId using POST', async () => { clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); clients.alertsClient.get.mockResolvedValue(getResult()); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts index 6438318cb43dbb..aabf3e513bfea2 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts @@ -58,7 +58,7 @@ export const createDeleteRulesBulkRoute = (getClients: GetScopedClients): Hapi.S ruleStatuses.saved_objects.forEach(async obj => savedObjectsClient.delete(ruleStatusSavedObjectType, obj.id) ); - return transformOrBulkError(idOrRuleIdOrUnknown, rule); + return transformOrBulkError(idOrRuleIdOrUnknown, rule, ruleStatuses); } else { return getIdBulkError({ id, ruleId }); } diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts index a0a6f61223279b..57c7c859766196 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts @@ -7,6 +7,8 @@ import { ServerInjectOptions } from 'hapi'; import { omit } from 'lodash/fp'; import { deleteRulesRoute } from './delete_rules_route'; +import * as utils from './utils'; +import * as deleteRules from '../../rules/delete_rules'; import { getFindResult, @@ -25,7 +27,12 @@ describe('delete_rules', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); getClients = clientsServiceMock.createGetScoped(); clients = clientsServiceMock.createClients(); @@ -73,6 +80,32 @@ describe('delete_rules', () => { const { statusCode } = await inject(getDeleteRequest()); expect(statusCode).toBe(404); }); + + test('returns 500 when transform fails', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.delete.mockResolvedValue({}); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + clients.savedObjectsClient.delete.mockResolvedValue({}); + jest.spyOn(utils, 'transform').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getDeleteRequest()); + expect(JSON.parse(payload).message).toBe('Internal error transforming rules'); + expect(statusCode).toBe(500); + }); + + test('catches error if deleteRules throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.delete.mockResolvedValue({}); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + clients.savedObjectsClient.delete.mockResolvedValue({}); + jest.spyOn(deleteRules, 'deleteRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getDeleteRequestById()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts index 5b75f17164acf5..019424ea2420a6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_route.test.ts @@ -6,13 +6,22 @@ import { omit } from 'lodash/fp'; +import { + getFindResult, + getResult, + getFindResultWithSingleHit, + getFindResultStatus, + getFindRequest, +} from '../__mocks__/request_responses'; import { createMockServer } from '../__mocks__'; import { clientsServiceMock } from '../__mocks__/clients_service_mock'; +import * as utils from './utils'; +import * as findRules from '../../rules/find_rules'; + import { findRulesRoute } from './find_rules_route'; import { ServerInjectOptions } from 'hapi'; -import { getFindResult, getResult, getFindRequest } from '../__mocks__/request_responses'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; describe('find_rules', () => { @@ -21,7 +30,12 @@ describe('find_rules', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); getClients = clientsServiceMock.createGetScoped(); @@ -33,15 +47,10 @@ describe('find_rules', () => { }); describe('status codes with actionClient and alertClient', () => { - test('returns 200 when finding a single rule with a valid actionClient and alertClient', async () => { - clients.alertsClient.find.mockResolvedValue(getFindResult()); - clients.actionsClient.find.mockResolvedValue({ - page: 1, - perPage: 1, - total: 0, - data: [], - }); + test('returns 200 when finding a single rule with a valid alertsClient', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); const { statusCode } = await server.inject(getFindRequest()); expect(statusCode).toBe(200); }); @@ -53,6 +62,28 @@ describe('find_rules', () => { const { statusCode } = await inject(getFindRequest()); expect(statusCode).toBe(404); }); + + test('catches error when transformation fails', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(utils, 'transformFindAlerts').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getFindRequest()); + expect(statusCode).toBe(500); + expect(JSON.parse(payload).message).toBe('unknown data type, error transforming alert'); + }); + + test('catch error when findRules function throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(findRules, 'findRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getFindRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts new file mode 100644 index 00000000000000..00411c550fa2ea --- /dev/null +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.test.ts @@ -0,0 +1,96 @@ +/* + * 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 { omit } from 'lodash/fp'; + +import { getFindResultStatus } from '../__mocks__/request_responses'; +import { createMockServer } from '../__mocks__'; +import { clientsServiceMock } from '../__mocks__/clients_service_mock'; + +import { findRulesStatusesRoute } from './find_rules_status_route'; +import { ServerInjectOptions } from 'hapi'; + +import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; + +describe('find_statuses', () => { + let server = createMockServer(); + let getClients = clientsServiceMock.createGetScoped(); + let clients = clientsServiceMock.createClients(); + + beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 + jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + + server = createMockServer(); + getClients = clientsServiceMock.createGetScoped(); + clients = clientsServiceMock.createClients(); + + getClients.mockResolvedValue(clients); + + findRulesStatusesRoute(server.route, getClients); + }); + + describe('status codes with actionClient and alertClient', () => { + test('returns 200 when finding a single rule status with a valid alertsClient', async () => { + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + const request: ServerInjectOptions = { + method: 'GET', + url: `${DETECTION_ENGINE_RULES_URL}/_find_statuses?ids=["someid"]`, + }; + const { statusCode } = await server.inject(request); + expect(statusCode).toBe(200); + }); + + test('returns 404 if alertClient is not available on the route', async () => { + getClients.mockResolvedValue(omit('alertsClient', clients)); + const request: ServerInjectOptions = { + method: 'GET', + url: `${DETECTION_ENGINE_RULES_URL}/_find_statuses?ids=["someid"]`, + }; + const { statusCode } = await server.inject(request); + expect(statusCode).toBe(404); + }); + + test('catch error when savedObjectsClient find function throws error', async () => { + clients.savedObjectsClient.find.mockImplementation(async () => { + throw new Error('Test error'); + }); + const request: ServerInjectOptions = { + method: 'GET', + url: `${DETECTION_ENGINE_RULES_URL}/_find_statuses?ids=["someid"]`, + }; + const { payload, statusCode } = await server.inject(request); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); + }); + + describe('validation', () => { + test('returns 400 if id is given instead of ids', async () => { + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + const request: ServerInjectOptions = { + method: 'GET', + url: `${DETECTION_ENGINE_RULES_URL}/_find_statuses?id=["someid"]`, + }; + const { statusCode } = await server.inject(request); + expect(statusCode).toBe(400); + }); + + test('returns 200 if the set of optional query parameters are given', async () => { + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + const request: ServerInjectOptions = { + method: 'GET', + url: `${DETECTION_ENGINE_RULES_URL}/_find_statuses?ids=["someid"]`, + }; + const { statusCode } = await server.inject(request); + expect(statusCode).toBe(200); + }); + }); +}); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.ts index fe8742ff0b60cf..c496c7b7ce59cd 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/find_rules_status_route.ts @@ -5,7 +5,6 @@ */ import Hapi from 'hapi'; -import { snakeCase } from 'lodash/fp'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { LegacyServices, LegacyRequest } from '../../../../types'; @@ -18,17 +17,7 @@ import { IRuleStatusAttributes, } from '../../rules/types'; import { ruleStatusSavedObjectType } from '../../rules/saved_object_mappings'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const convertToSnakeCase = >(obj: T): Partial | null => { - if (!obj) { - return null; - } - return Object.keys(obj).reduce((acc, item) => { - const newKey = snakeCase(item); - return { ...acc, [newKey]: obj[item] }; - }, {}); -}; +import { transformError, convertToSnakeCase } from '../utils'; export const createFindRulesStatusRoute = (getClients: GetScopedClients): Hapi.ServerRoute => ({ method: 'GET', @@ -57,33 +46,43 @@ export const createFindRulesStatusRoute = (getClients: GetScopedClients): Hapi.S "anotherAlertId": ... } */ - const statuses = await query.ids.reduce>(async (acc, id) => { - const lastFiveErrorsForId = await savedObjectsClient.find< - IRuleSavedAttributesSavedObjectAttributes - >({ - type: ruleStatusSavedObjectType, - perPage: 6, - sortField: 'statusDate', - sortOrder: 'desc', - search: id, - searchFields: ['alertId'], - }); - const accumulated = await acc; - const currentStatus = convertToSnakeCase( - lastFiveErrorsForId.saved_objects[0]?.attributes - ); - const failures = lastFiveErrorsForId.saved_objects - .slice(1) - .map(errorItem => convertToSnakeCase(errorItem.attributes)); - return { - ...accumulated, - [id]: { - current_status: currentStatus, - failures, - }, - }; - }, Promise.resolve({})); - return statuses; + try { + const statuses = await query.ids.reduce>(async (acc, id) => { + const lastFiveErrorsForId = await savedObjectsClient.find< + IRuleSavedAttributesSavedObjectAttributes + >({ + type: ruleStatusSavedObjectType, + perPage: 6, + sortField: 'statusDate', + sortOrder: 'desc', + search: id, + searchFields: ['alertId'], + }); + const accumulated = await acc; + const currentStatus = convertToSnakeCase( + lastFiveErrorsForId.saved_objects[0]?.attributes + ); + const failures = lastFiveErrorsForId.saved_objects + .slice(1) + .map(errorItem => convertToSnakeCase(errorItem.attributes)); + return { + ...accumulated, + [id]: { + current_status: currentStatus, + failures, + }, + }; + }, Promise.resolve({})); + return statuses; + } catch (err) { + const error = transformError(err); + return headers + .response({ + message: error.message, + status_code: error.statusCode, + }) + .code(error.statusCode); + } }, }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts index 8f27910a7e5e2b..99157b4d15360d 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts @@ -7,6 +7,7 @@ import { omit } from 'lodash/fp'; import { getPrepackagedRulesStatusRoute } from './get_prepackaged_rules_status_route'; +import * as findRules from '../../rules/find_rules'; import { getFindResult, @@ -47,7 +48,12 @@ describe('get_prepackaged_rule_status_route', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); getClients = clientsServiceMock.createGetScoped(); @@ -76,6 +82,17 @@ describe('get_prepackaged_rule_status_route', () => { const { statusCode } = await inject(getPrepackagedRulesStatusRequest()); expect(statusCode).toBe(404); }); + + test('catch error when findRules function throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + jest.spyOn(findRules, 'findRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getPrepackagedRulesStatusRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('payload', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.test.ts index b1dd08f8ca371b..c8b77e505b5d7a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.test.ts @@ -8,6 +8,7 @@ import { omit } from 'lodash/fp'; import { getSimpleRuleAsMultipartContent, + getSimpleRuleAsMultipartContentNoRuleId, TEST_BOUNDARY, UNPARSABLE_LINE, getSimpleRule, @@ -25,6 +26,7 @@ import { import { createMockServer, createMockConfig, clientsServiceMock } from '../__mocks__'; import { importRulesRoute } from './import_rules_route'; import { DEFAULT_SIGNALS_INDEX } from '../../../../../common/constants'; +import * as createRulesStreamFromNdJson from '../../rules/create_rules_stream_from_ndjson'; describe('import_rules_route', () => { let server = createMockServer(); @@ -33,8 +35,12 @@ describe('import_rules_route', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); - + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); config = createMockConfig(); config = () => ({ @@ -94,6 +100,21 @@ describe('import_rules_route', () => { const { statusCode } = await inject(getImportRulesRequest(requestPayload)); expect(statusCode).toEqual(404); }); + + test('returns error if createPromiseFromStreams throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResult()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.alertsClient.create.mockResolvedValue(getResult()); + jest + .spyOn(createRulesStreamFromNdJson, 'createRulesStreamFromNdJson') + .mockImplementation(() => { + throw new Error('Test error'); + }); + const requestPayload = getSimpleRuleAsMultipartContent(['rule-1']); + const { payload, statusCode } = await server.inject(getImportRulesRequest(requestPayload)); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { @@ -306,6 +327,21 @@ describe('import_rules_route', () => { expect(statusCode).toEqual(200); }); + test('returns 200 with errors if all rules are missing rule_ids and import fails on validation', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResult()); + + const requestPayload = getSimpleRuleAsMultipartContentNoRuleId(2); + const { statusCode, payload } = await server.inject(getImportRulesRequest(requestPayload)); + const parsed: ImportSuccessError = JSON.parse(payload); + + expect(parsed.success).toEqual(false); + expect(parsed.errors[0].error.message).toEqual( + 'child "rule_id" fails because ["rule_id" is required]' + ); + expect(parsed.errors[0].error.status_code).toEqual(400); + expect(statusCode).toEqual(200); + }); + test('returns 200 with reported conflict if error parsing rule', async () => { const multipartPayload = `--${TEST_BOUNDARY}\r\n` + diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts index f438e0120f96ac..a9358a47f25fca 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/import_rules_route.ts @@ -7,6 +7,7 @@ import Hapi from 'hapi'; import { chunk, isEmpty } from 'lodash/fp'; import { extname } from 'path'; +import { Readable } from 'stream'; import { createPromiseFromStreams } from '../../../../../../../../../src/legacy/utils/streams'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; @@ -15,7 +16,7 @@ import { createRules } from '../../rules/create_rules'; import { ImportRulesRequest } from '../../rules/types'; import { readRules } from '../../rules/read_rules'; import { getIndexExists } from '../../index/get_index_exists'; -import { getIndex, createBulkErrorObject, ImportRuleResponse } from '../utils'; +import { getIndex, transformError, createBulkErrorObject, ImportRuleResponse } from '../utils'; import { createRulesStreamFromNdJson } from '../../rules/create_rules_stream_from_ndjson'; import { ImportRuleAlertRest } from '../../types'; import { patchRules } from '../../rules/patch_rules'; @@ -74,179 +75,192 @@ export const createImportRulesRoute = ( } const objectLimit = config().get('savedObjects.maxImportExportSize'); - const readStream = createRulesStreamFromNdJson(request.payload.file, objectLimit); - const parsedObjects = await createPromiseFromStreams([readStream]); - const [duplicateIdErrors, uniqueParsedObjects] = getTupleDuplicateErrorsAndUniqueRules( - parsedObjects, - request.query.overwrite - ); + try { + const readStream = createRulesStreamFromNdJson(objectLimit); + const parsedObjects = await createPromiseFromStreams([ + request.payload.file as Readable, + ...readStream, + ]); + const [duplicateIdErrors, uniqueParsedObjects] = getTupleDuplicateErrorsAndUniqueRules( + parsedObjects, + request.query.overwrite + ); - const chunkParseObjects = chunk(CHUNK_PARSED_OBJECT_SIZE, uniqueParsedObjects); - let importRuleResponse: ImportRuleResponse[] = []; + const chunkParseObjects = chunk(CHUNK_PARSED_OBJECT_SIZE, uniqueParsedObjects); + let importRuleResponse: ImportRuleResponse[] = []; - while (chunkParseObjects.length) { - const batchParseObjects = chunkParseObjects.shift() ?? []; - const newImportRuleResponse = await Promise.all( - batchParseObjects.reduce>>((accum, parsedRule) => { - const importsWorkerPromise = new Promise( - async (resolve, reject) => { - if (parsedRule instanceof Error) { - // If the JSON object had a validation or parse error then we return - // early with the error and an (unknown) for the ruleId - resolve( - createBulkErrorObject({ - statusCode: 400, - message: parsedRule.message, - }) - ); - return null; - } - const { - description, - enabled, - false_positives: falsePositives, - from, - immutable, - query, - language, - output_index: outputIndex, - saved_id: savedId, - meta, - filters, - rule_id: ruleId, - index, - interval, - max_signals: maxSignals, - risk_score: riskScore, - name, - severity, - tags, - threat, - to, - type, - references, - timeline_id: timelineId, - timeline_title: timelineTitle, - version, - } = parsedRule; - try { - const finalIndex = getIndex(spacesClient.getSpaceId, config); - const indexExists = await getIndexExists( - clusterClient.callAsCurrentUser, - finalIndex - ); - if (!indexExists) { + while (chunkParseObjects.length) { + const batchParseObjects = chunkParseObjects.shift() ?? []; + const newImportRuleResponse = await Promise.all( + batchParseObjects.reduce>>((accum, parsedRule) => { + const importsWorkerPromise = new Promise( + async (resolve, reject) => { + if (parsedRule instanceof Error) { + // If the JSON object had a validation or parse error then we return + // early with the error and an (unknown) for the ruleId resolve( createBulkErrorObject({ - ruleId, - statusCode: 409, - message: `To create a rule, the index must exist first. Index ${finalIndex} does not exist`, + statusCode: 400, + message: parsedRule.message, }) ); + return null; } - const rule = await readRules({ alertsClient, ruleId }); - if (rule == null) { - await createRules({ - alertsClient, - actionsClient, - description, - enabled, - falsePositives, - from, - immutable, - query, - language, - outputIndex: finalIndex, - savedId, - timelineId, - timelineTitle, - meta, - filters, - ruleId, - index, - interval, - maxSignals, - riskScore, - name, - severity, - tags, - to, - type, - threat, - references, - version, - }); - resolve({ rule_id: ruleId, status_code: 200 }); - } else if (rule != null && request.query.overwrite) { - await patchRules({ - alertsClient, - actionsClient, - savedObjectsClient, - description, - enabled, - falsePositives, - from, - immutable, - query, - language, - outputIndex, - savedId, - timelineId, - timelineTitle, - meta, - filters, - id: undefined, - ruleId, - index, - interval, - maxSignals, - riskScore, - name, - severity, - tags, - to, - type, - threat, - references, - version, - }); - resolve({ rule_id: ruleId, status_code: 200 }); - } else if (rule != null) { + const { + description, + enabled, + false_positives: falsePositives, + from, + immutable, + query, + language, + output_index: outputIndex, + saved_id: savedId, + meta, + filters, + rule_id: ruleId, + index, + interval, + max_signals: maxSignals, + risk_score: riskScore, + name, + severity, + tags, + threat, + to, + type, + references, + timeline_id: timelineId, + timeline_title: timelineTitle, + version, + } = parsedRule; + try { + const finalIndex = getIndex(spacesClient.getSpaceId, config); + const indexExists = await getIndexExists( + clusterClient.callAsCurrentUser, + finalIndex + ); + if (!indexExists) { + resolve( + createBulkErrorObject({ + ruleId, + statusCode: 409, + message: `To create a rule, the index must exist first. Index ${finalIndex} does not exist`, + }) + ); + } + const rule = await readRules({ alertsClient, ruleId }); + if (rule == null) { + await createRules({ + alertsClient, + actionsClient, + description, + enabled, + falsePositives, + from, + immutable, + query, + language, + outputIndex: finalIndex, + savedId, + timelineId, + timelineTitle, + meta, + filters, + ruleId, + index, + interval, + maxSignals, + riskScore, + name, + severity, + tags, + to, + type, + threat, + references, + version, + }); + resolve({ rule_id: ruleId, status_code: 200 }); + } else if (rule != null && request.query.overwrite) { + await patchRules({ + alertsClient, + actionsClient, + savedObjectsClient, + description, + enabled, + falsePositives, + from, + immutable, + query, + language, + outputIndex, + savedId, + timelineId, + timelineTitle, + meta, + filters, + id: undefined, + ruleId, + index, + interval, + maxSignals, + riskScore, + name, + severity, + tags, + to, + type, + threat, + references, + version, + }); + resolve({ rule_id: ruleId, status_code: 200 }); + } else if (rule != null) { + resolve( + createBulkErrorObject({ + ruleId, + statusCode: 409, + message: `rule_id: "${ruleId}" already exists`, + }) + ); + } + } catch (err) { resolve( createBulkErrorObject({ ruleId, - statusCode: 409, - message: `rule_id: "${ruleId}" already exists`, + statusCode: 400, + message: err.message, }) ); } - } catch (err) { - resolve( - createBulkErrorObject({ - ruleId, - statusCode: 400, - message: err.message, - }) - ); } - } - ); - return [...accum, importsWorkerPromise]; - }, []) - ); - importRuleResponse = [ - ...duplicateIdErrors, - ...importRuleResponse, - ...newImportRuleResponse, - ]; - } + ); + return [...accum, importsWorkerPromise]; + }, []) + ); + importRuleResponse = [ + ...duplicateIdErrors, + ...importRuleResponse, + ...newImportRuleResponse, + ]; + } - const errorsResp = importRuleResponse.filter(resp => !isEmpty(resp.error)); - return { - success: errorsResp.length === 0, - success_count: importRuleResponse.filter(resp => resp.status_code === 200).length, - errors: errorsResp, - }; + const errorsResp = importRuleResponse.filter(resp => !isEmpty(resp.error)); + return { + success: errorsResp.length === 0, + success_count: importRuleResponse.filter(resp => resp.status_code === 200).length, + errors: errorsResp, + }; + } catch (exc) { + const error = transformError(exc); + return headers + .response({ + message: error.message, + status_code: error.statusCode, + }) + .code(error.statusCode); + } }, }; }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk.test.ts index 02af4135b534fa..1cfb4ae81ab852 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_bulk.test.ts @@ -15,6 +15,7 @@ import { typicalPayload, getFindResultWithSingleHit, getPatchBulkRequest, + getFindResultStatus, } from '../__mocks__/request_responses'; import { createMockServer, clientsServiceMock } from '../__mocks__'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; @@ -43,6 +44,7 @@ describe('patch_rules_bulk', () => { clients.alertsClient.get.mockResolvedValue(getResult()); clients.actionsClient.update.mockResolvedValue(updateActionResult()); clients.alertsClient.update.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); const { statusCode } = await server.inject(getPatchBulkRequest()); expect(statusCode).toBe(200); }); @@ -56,6 +58,13 @@ describe('patch_rules_bulk', () => { expect(statusCode).toBe(200); }); + test('returns 404 as a response when missing alertsClient', async () => { + getClients.mockResolvedValue(omit('alertsClient', clients)); + clients.actionsClient.update.mockResolvedValue(updateActionResult()); + const { statusCode } = await server.inject(getPatchBulkRequest()); + expect(statusCode).toBe(404); + }); + test('returns 404 within the payload when updating a single rule that does not exist', async () => { clients.alertsClient.find.mockResolvedValue(getFindResult()); clients.alertsClient.get.mockResolvedValue(getResult()); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts index cc84b08fdef119..04cd3a026562f1 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts @@ -7,6 +7,8 @@ import { ServerInjectOptions } from 'hapi'; import { omit } from 'lodash/fp'; import { patchRulesRoute } from './patch_rules_route'; +import * as utils from './utils'; +import * as patchRules from '../../rules/patch_rules'; import { getFindResult, @@ -26,7 +28,13 @@ describe('patch_rules', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + server = createMockServer(); getClients = clientsServiceMock.createGetScoped(); clients = clientsServiceMock.createClients(); @@ -63,6 +71,32 @@ describe('patch_rules', () => { const { statusCode } = await inject(getPatchRequest()); expect(statusCode).toBe(404); }); + + test('returns 500 when transform fails', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.update.mockResolvedValue(updateActionResult()); + clients.alertsClient.update.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(utils, 'transform').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getPatchRequest()); + expect(JSON.parse(payload).message).toBe('Internal error transforming rules'); + expect(statusCode).toBe(500); + }); + + test('catches error if patchRules throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.actionsClient.update.mockResolvedValue(updateActionResult()); + clients.alertsClient.update.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(patchRules, 'patchRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getPatchRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts index 7c4653af97f214..0366d3648e1ea3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/read_rules_route.test.ts @@ -7,6 +7,9 @@ import { ServerInjectOptions } from 'hapi'; import { omit } from 'lodash/fp'; +import * as utils from './utils'; +import * as readRules from '../../rules/read_rules'; + import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; import { readRulesRoute } from './read_rules_route'; import { @@ -24,8 +27,12 @@ describe('read_signals', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); - + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); getClients = clientsServiceMock.createGetScoped(); clients = clientsServiceMock.createClients(); @@ -50,6 +57,38 @@ describe('read_signals', () => { const { statusCode } = await inject(getReadRequest()); expect(statusCode).toBe(404); }); + + test('returns error if readRules returns null', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(readRules, 'readRules').mockResolvedValue(null); + const { payload, statusCode } = await server.inject(getReadRequest()); + expect(JSON.parse(payload).message).toBe('rule_id: "rule-1" not found'); + expect(statusCode).toBe(404); + }); + + test('returns 500 when transform fails', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(utils, 'transform').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getReadRequest()); + expect(JSON.parse(payload).message).toBe('Internal error transforming rules'); + expect(statusCode).toBe(500); + }); + + test('catches error if readRules throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(readRules, 'readRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getReadRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk.test.ts index 9ff7ebc37aab12..32a633799ad441 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_bulk.test.ts @@ -75,9 +75,9 @@ describe('update_rules_bulk', () => { test('returns 404 if alertClient is not available on the route', async () => { getClients.mockResolvedValue(omit('alertsClient', clients)); - const { route, inject } = createMockServer(); + const { route } = createMockServer(); updateRulesRoute(route, config, getClients); - const { statusCode } = await inject(getUpdateBulkRequest()); + const { statusCode } = await server.inject(getUpdateBulkRequest()); expect(statusCode).toBe(404); }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts index 7cadfa94467a7e..c3a92ed9a61aeb 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/update_rules_route.test.ts @@ -7,6 +7,9 @@ import { ServerInjectOptions } from 'hapi'; import { omit } from 'lodash/fp'; +import * as utils from './utils'; +import * as updateRules from '../../rules/update_rules'; + import { updateRulesRoute } from './update_rules_route'; import { getFindResult, @@ -27,7 +30,12 @@ describe('update_rules', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); server = createMockServer(); config = createMockConfig(); @@ -66,6 +74,28 @@ describe('update_rules', () => { const { statusCode } = await inject(getUpdateRequest()); expect(statusCode).toBe(404); }); + + test('returns 500 when transform fails', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(utils, 'transform').mockReturnValue(null); + const { payload, statusCode } = await server.inject(getUpdateRequest()); + expect(JSON.parse(payload).message).toBe('Internal error transforming rules'); + expect(statusCode).toBe(500); + }); + + test('catches error if readRules throws error', async () => { + clients.alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + clients.alertsClient.get.mockResolvedValue(getResult()); + clients.savedObjectsClient.find.mockResolvedValue(getFindResultStatus()); + jest.spyOn(updateRules, 'updateRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getUpdateRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts index 593c55bcae9f21..b5b687c284b251 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts @@ -1251,9 +1251,10 @@ describe('utils', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); const parsedObjects = await createPromiseFromStreams([ - rulesObjectsStream, + ndJsonStream, + ...rulesObjectsStream, ]); const [errors, output] = getTupleDuplicateErrorsAndUniqueRules(parsedObjects, false); const isInstanceOfError = output[0] instanceof Error; @@ -1272,9 +1273,10 @@ describe('utils', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); const parsedObjects = await createPromiseFromStreams([ - rulesObjectsStream, + ndJsonStream, + ...rulesObjectsStream, ]); const [errors, output] = getTupleDuplicateErrorsAndUniqueRules(parsedObjects, false); @@ -1290,6 +1292,30 @@ describe('utils', () => { ]); }); + test('returns tuple of duplicate conflict error and single rule when rules with matching ids passed in and `overwrite` is false', async () => { + const rule = getSimpleRule('rule-1'); + delete rule.rule_id; + const rule2 = getSimpleRule('rule-1'); + delete rule2.rule_id; + const ndJsonStream = new Readable({ + read() { + this.push(`${JSON.stringify(rule)}\n`); + this.push(`${JSON.stringify(rule2)}\n`); + this.push(null); + }, + }); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const parsedObjects = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); + const [errors, output] = getTupleDuplicateErrorsAndUniqueRules(parsedObjects, false); + const isInstanceOfError = output[0] instanceof Error; + + expect(isInstanceOfError).toEqual(true); + expect(errors).toEqual([]); + }); + test('returns tuple of empty duplicate errors array and single rule when rules with matching rule-ids passed in and `overwrite` is true', async () => { const rule = getSimpleRule('rule-1'); const rule2 = getSimpleRule('rule-1'); @@ -1300,9 +1326,10 @@ describe('utils', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); const parsedObjects = await createPromiseFromStreams([ - rulesObjectsStream, + ndJsonStream, + ...rulesObjectsStream, ]); const [errors, output] = getTupleDuplicateErrorsAndUniqueRules(parsedObjects, true); @@ -1320,9 +1347,10 @@ describe('utils', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); const parsedObjects = await createPromiseFromStreams([ - rulesObjectsStream, + ndJsonStream, + ...rulesObjectsStream, ]); const [errors, output] = getTupleDuplicateErrorsAndUniqueRules(parsedObjects, false); const isInstanceOfError = output[0] instanceof Error; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts index 198cdbfb9771d7..ab80e1570c31ce 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts @@ -180,9 +180,7 @@ export const transform = ( if (!ruleStatus && isAlertType(alert)) { return transformAlertToRule(alert); } - if (isAlertType(alert) && isRuleStatusFindType(ruleStatus)) { - return transformAlertToRule(alert, ruleStatus.saved_objects[0]); - } else if (isAlertType(alert) && isRuleStatusSavedObjectType(ruleStatus)) { + if (isAlertType(alert) && isRuleStatusSavedObjectType(ruleStatus)) { return transformAlertToRule(alert, ruleStatus); } else { return null; @@ -195,7 +193,7 @@ export const transformOrBulkError = ( ruleStatus?: unknown ): Partial | BulkError => { if (isAlertType(alert)) { - if (isRuleStatusFindType(ruleStatus)) { + if (isRuleStatusFindType(ruleStatus) && ruleStatus?.saved_objects.length > 0) { return transformAlertToRule(alert, ruleStatus?.saved_objects[0] ?? ruleStatus); } else { return transformAlertToRule(alert); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals.test.ts index 3e7ed4de6d8c6f..7086c62f817119 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals.test.ts @@ -25,7 +25,12 @@ describe('set signal status', () => { let clients = clientsServiceMock.createClients(); beforeEach(() => { + // jest carries state between mocked implementations when using + // spyOn. So now we're doing all three of these. + // https://github.com/facebook/jest/issues/7136#issuecomment-565976599 jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); jest.spyOn(myUtils, 'getIndex').mockReturnValue('fakeindex'); server = createMockServer(); @@ -50,6 +55,15 @@ describe('set signal status', () => { const { statusCode } = await server.inject(getSetSignalStatusByQueryRequest()); expect(statusCode).toBe(200); }); + + test('catches error if callAsCurrentUser throws error', async () => { + clients.clusterClient.callAsCurrentUser.mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(getSetSignalStatusByQueryRequest()); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); describe('validation', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index dd3b8d3c99e0c8..ee3fd349a26eec 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -28,7 +28,7 @@ export const setSignalsStatusRouteDef = ( payload: setSignalsStatusSchema, }, }, - async handler(request: SignalsStatusRequest) { + async handler(request: SignalsStatusRequest, headers) { const { signal_ids: signalIds, query, status } = request.payload; const { clusterClient, spacesClient } = await getClients(request); const index = getIndex(spacesClient.getSpaceId, config); @@ -45,7 +45,7 @@ export const setSignalsStatusRouteDef = ( }; } try { - return clusterClient.callAsCurrentUser('updateByQuery', { + const updateByQueryResponse = await clusterClient.callAsCurrentUser('updateByQuery', { index, body: { script: { @@ -56,9 +56,15 @@ export const setSignalsStatusRouteDef = ( }, ignoreUnavailable: true, }); - } catch (exc) { - // error while getting or updating signal with id: id in signal index .siem-signals - return transformError(exc); + return updateByQueryResponse; + } catch (err) { + const error = transformError(err); + return headers + .response({ + message: error.message, + status_code: error.statusCode, + }) + .code(error.statusCode); } }, }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.test.ts index 9439adfcec3cb3..210ac9f3d7b01a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.test.ts @@ -127,5 +127,18 @@ describe('query for signal', () => { const { statusCode } = await server.inject(request); expect(statusCode).toBe(400); }); + test('catches error if deleteRules throws error', async () => { + const request: ServerInjectOptions = { + method: 'POST', + url: DETECTION_ENGINE_QUERY_SIGNALS_URL, + payload: { ...typicalSignalsQueryAggs(), ...typicalSignalsQuery() }, + }; + clients.clusterClient.callAsCurrentUser.mockImplementation(async () => { + throw new Error('Test error'); + }); + const { payload, statusCode } = await server.inject(request); + expect(JSON.parse(payload).message).toBe('Test error'); + expect(statusCode).toBe(500); + }); }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts index adb6e5f32921a0..7636329ecc306c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/signals/query_signals_route.ts @@ -28,21 +28,27 @@ export const querySignalsRouteDef = ( payload: querySignalsSchema, }, }, - async handler(request: SignalsQueryRequest) { + async handler(request: SignalsQueryRequest, headers) { const { query, aggs, _source, track_total_hits, size } = request.payload; const { clusterClient, spacesClient } = await getClients(request); const index = getIndex(spacesClient.getSpaceId, config); try { - return clusterClient.callAsCurrentUser('search', { + const searchSignalsIndexResult = await clusterClient.callAsCurrentUser('search', { index, body: { query, aggs, _source, track_total_hits, size }, ignoreUnavailable: true, }); - } catch (exc) { - // error while getting or updating signal with id: id in signal index .siem-signals - return transformError(exc); + return searchSignalsIndexResult; + } catch (err) { + const error = transformError(err); + return headers + .response({ + message: error.message, + status_code: error.statusCode, + }) + .code(error.statusCode); } }, }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.test.ts index 957ddd4ee6caac..3148083b4db267 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.test.ts @@ -15,6 +15,7 @@ import { ImportSuccessError, createImportErrorObject, transformImportError, + convertToSnakeCase, } from './utils'; import { createMockConfig } from './__mocks__'; @@ -312,4 +313,15 @@ describe('utils', () => { expect(index).toEqual('mockSignalsIndex-myspace'); }); }); + + describe('convertToSnakeCase', () => { + it('converts camelCase to snakeCase', () => { + const values = { myTestCamelCaseKey: 'something' }; + expect(convertToSnakeCase(values)).toEqual({ my_test_camel_case_key: 'something' }); + }); + it('returns empty object when object is empty', () => { + const values = {}; + expect(convertToSnakeCase(values)).toEqual({}); + }); + }); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.ts index 55832ab67dc6ba..36e1a814d8ec26 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/utils.ts @@ -5,6 +5,7 @@ */ import Boom from 'boom'; +import { snakeCase } from 'lodash/fp'; import { APP_ID, SIGNALS_INDEX_KEY } from '../../../../common/constants'; import { LegacyServices } from '../../../types'; @@ -211,3 +212,11 @@ export const getIndex = (getSpaceId: () => string, config: LegacyServices['confi return `${signalsIndex}-${spaceId}`; }; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const convertToSnakeCase = >(obj: T): Partial | null => { + return Object.keys(obj).reduce((acc, item) => { + const newKey = snakeCase(item); + return { ...acc, [newKey]: obj[item] }; + }, {}); +}; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts index d4b7c252e3e380..b1dc62f6fc90f0 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts @@ -5,12 +5,10 @@ */ import { Readable } from 'stream'; import { createRulesStreamFromNdJson } from './create_rules_stream_from_ndjson'; -import { createPromiseFromStreams, createConcatStream } from 'src/legacy/utils/streams'; +import { createPromiseFromStreams } from 'src/legacy/utils/streams'; import { ImportRuleAlertRest } from '../types'; -const readStreamToCompletion = (stream: Readable) => { - return createPromiseFromStreams([stream, createConcatStream([])]); -}; +type PromiseFromStreams = ImportRuleAlertRest | Error; export const getOutputSample = (): Partial => ({ rule_id: 'rule-1', @@ -43,8 +41,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); expect(result).toEqual([ { rule_id: 'rule-1', @@ -95,6 +96,22 @@ describe('create_rules_stream_from_ndjson', () => { ]); }); + test('returns error when ndjson stream is larger than limit', async () => { + const sample1 = getOutputSample(); + const sample2 = getOutputSample(); + sample2.rule_id = 'rule-2'; + const ndJsonStream = new Readable({ + read() { + this.push(getSampleAsNdjson(sample1)); + this.push(getSampleAsNdjson(sample2)); + }, + }); + const rulesObjectsStream = createRulesStreamFromNdJson(1); + await expect( + createPromiseFromStreams([ndJsonStream, ...rulesObjectsStream]) + ).rejects.toThrowError("Can't import more than 1 rules"); + }); + test('skips empty lines', async () => { const sample1 = getOutputSample(); const sample2 = getOutputSample(); @@ -108,8 +125,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); expect(result).toEqual([ { rule_id: 'rule-1', @@ -172,8 +192,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); expect(result).toEqual([ { rule_id: 'rule-1', @@ -236,8 +259,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); const resultOrError = result as Error[]; expect(resultOrError[0]).toEqual({ rule_id: 'rule-1', @@ -300,8 +326,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); const resultOrError = result as TypeError[]; expect(resultOrError[0]).toEqual({ rule_id: 'rule-1', @@ -366,8 +395,11 @@ describe('create_rules_stream_from_ndjson', () => { this.push(null); }, }); - const rulesObjectsStream = createRulesStreamFromNdJson(ndJsonStream, 1000); - const result = await readStreamToCompletion(rulesObjectsStream); + const rulesObjectsStream = createRulesStreamFromNdJson(1000); + const result = await createPromiseFromStreams([ + ndJsonStream, + ...rulesObjectsStream, + ]); const resultOrError = result as TypeError[]; expect(resultOrError[1] instanceof TypeError).toEqual(true); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts index 6d58171a3245dc..ae0dfa20852aa1 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { Readable, Transform } from 'stream'; +import { Transform } from 'stream'; import { has, isString } from 'lodash/fp'; import { ImportRuleAlertRest } from '../types'; import { @@ -74,15 +74,13 @@ export const createLimitStream = (limit: number): Transform => { * Inspiration and the pattern of code followed is from: * saved_objects/lib/create_saved_objects_stream_from_ndjson.ts */ -export const createRulesStreamFromNdJson = ( - ndJsonStream: Readable, - ruleLimit: number -): Transform => { - return ndJsonStream - .pipe(createSplitStream('\n')) - .pipe(parseNdjsonStrings()) - .pipe(filterExportedCounts()) - .pipe(validateRules()) - .pipe(createLimitStream(ruleLimit)) - .pipe(createConcatStream([])); +export const createRulesStreamFromNdJson = (ruleLimit: number) => { + return [ + createSplitStream('\n'), + parseNdjsonStrings(), + filterExportedCounts(), + validateRules(), + createLimitStream(ruleLimit), + createConcatStream([]), + ]; }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts index 98f5df48525300..44d3013263c656 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts @@ -10,9 +10,15 @@ import { getFindResultWithSingleHit, FindHit, } from '../routes/__mocks__/request_responses'; +import * as readRules from './read_rules'; import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; describe('get_export_by_object_ids', () => { + beforeEach(() => { + jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + }); describe('getExportByObjectIds', () => { test('it exports object ids into an expected string with new line characters', async () => { const alertsClient = alertsClientMock.create(); @@ -119,6 +125,23 @@ describe('get_export_by_object_ids', () => { expect(exports).toEqual(expected); }); + test('it returns error when readRules throws error', async () => { + const alertsClient = alertsClientMock.create(); + alertsClient.get.mockResolvedValue(getResult()); + alertsClient.find.mockResolvedValue(getFindResultWithSingleHit()); + jest.spyOn(readRules, 'readRules').mockImplementation(async () => { + throw new Error('Test error'); + }); + const objects = [{ rule_id: 'rule-1' }]; + const exports = await getRulesFromObjects(alertsClient, objects); + const expected: RulesErrors = { + exportedCount: 0, + missingRules: [{ rule_id: objects[0].rule_id }], + rules: [], + }; + expect(exports).toEqual(expected); + }); + test('it does not transform the rule if the rule is an immutable rule and designates it as a missing rule', async () => { const alertsClient = alertsClientMock.create(); const result = getResult(); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts index 45507a69f50c2f..aa1cce6f152382 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts @@ -8,7 +8,23 @@ import { readRules } from './read_rules'; import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; import { getResult, getFindResultWithSingleHit } from '../routes/__mocks__/request_responses'; +class TestError extends Error { + constructor() { + // Pass remaining arguments (including vendor specific ones) to parent constructor + super(); + + this.name = 'CustomError'; + this.output = { statusCode: 404 }; + } + public output: { statusCode: number }; +} + describe('read_rules', () => { + beforeEach(() => { + jest.resetAllMocks(); + jest.restoreAllMocks(); + jest.clearAllMocks(); + }); describe('readRules', () => { test('should return the output from alertsClient if id is set but ruleId is undefined', async () => { const alertsClient = alertsClientMock.create(); @@ -21,6 +37,49 @@ describe('read_rules', () => { }); expect(rule).toEqual(getResult()); }); + test('should return null if saved object found by alerts client given id is not alert type', async () => { + const alertsClient = alertsClientMock.create(); + const { alertTypeId, ...rest } = getResult(); + // @ts-ignore + alertsClient.get.mockImplementation(() => rest); + + const rule = await readRules({ + alertsClient, + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + ruleId: undefined, + }); + expect(rule).toEqual(null); + }); + + test('should return error if alerts client throws 404 error on get', async () => { + const alertsClient = alertsClientMock.create(); + alertsClient.get.mockImplementation(() => { + throw new TestError(); + }); + + const rule = await readRules({ + alertsClient, + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + ruleId: undefined, + }); + expect(rule).toEqual(null); + }); + + test('should return error if alerts client throws error on get', async () => { + const alertsClient = alertsClientMock.create(); + alertsClient.get.mockImplementation(() => { + throw new Error('Test error'); + }); + try { + await readRules({ + alertsClient, + id: '04128c15-0d1b-4716-a4c5-46997ac7f3bd', + ruleId: undefined, + }); + } catch (exc) { + expect(exc.message).toEqual('Test error'); + } + }); test('should return the output from alertsClient if id is set but ruleId is null', async () => { const alertsClient = alertsClientMock.create(); @@ -47,6 +106,20 @@ describe('read_rules', () => { expect(rule).toEqual(getResult()); }); + test('should return null if the output from alertsClient with ruleId set is empty', async () => { + const alertsClient = alertsClientMock.create(); + alertsClient.get.mockResolvedValue(getResult()); + // @ts-ignore + alertsClient.find.mockResolvedValue({ data: [] }); + + const rule = await readRules({ + alertsClient, + id: undefined, + ruleId: 'rule-1', + }); + expect(rule).toEqual(null); + }); + test('should return the output from alertsClient if id is null but ruleId is set', async () => { const alertsClient = alertsClientMock.create(); alertsClient.get.mockResolvedValue(getResult()); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts index cbe6dbda8449f7..94e4e6357a4a0b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts @@ -31,7 +31,7 @@ export const readRules = async ({ return null; } } catch (err) { - if (err.output.statusCode === 404) { + if (err?.output?.statusCode === 404) { return null; } else { // throw non-404 as they would be 500 or other internal errors diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts index fa22765c143e1b..3d95e9868a1d68 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts @@ -197,10 +197,6 @@ export const isAlertType = (obj: unknown): obj is RuleAlertType => { return get('alertTypeId', obj) === SIGNALS_ID; }; -export const isRuleStatusAttributes = (obj: unknown): obj is IRuleStatusAttributes => { - return get('lastSuccessMessage', obj) != null; -}; - export const isRuleStatusSavedObjectType = ( obj: unknown ): obj is SavedObject => { diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts index 79a1e667e5458b..a1cb60483c332d 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts @@ -74,6 +74,17 @@ export default ({ getService }: FtrProviderContext): void => { }); }); + it('should report that it failed to import a thousand and one (10001) simple rules', async () => { + const { body } = await supertest + .post(`${DETECTION_ENGINE_RULES_URL}/_import`) + .set('kbn-xsrf', 'true') + .attach('file', getSimpleRuleAsNdjson(new Array(10001).fill('rule-1')), 'rules.ndjson') + .query() + .expect(500); + + expect(body).to.eql({ message: "Can't import more than 10000 rules", status_code: 500 }); + }); + it('should be able to read an imported rule back out correctly', async () => { await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) From b17aa3551387bbe752b86950fb2d8b0ee600a629 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 25 Feb 2020 15:28:41 +0000 Subject: [PATCH 39/73] [Logs / Metrics UI] Handle index.scss (#58219) * Ensure our index.scss file is handled --- .../plugins/infra/public/apps/start_app.tsx | 9 ++---- x-pack/plugins/infra/public/index.scss | 29 +------------------ 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/infra/public/apps/start_app.tsx b/x-pack/plugins/infra/public/apps/start_app.tsx index 66e699abd22b41..a797e4c9d4ba79 100644 --- a/x-pack/plugins/infra/public/apps/start_app.tsx +++ b/x-pack/plugins/infra/public/apps/start_app.tsx @@ -26,6 +26,7 @@ import { KibanaContextProvider, } from '../../../../../src/plugins/kibana_react/public'; import { AppRouter } from '../routers'; +import '../index.scss'; export const CONTAINER_CLASSNAME = 'infra-container-element'; @@ -74,12 +75,8 @@ export async function startApp( ); - // Ensure the element we're handed from application mounting takes up - // the full size it can, so that our inner application styles work as - // expected. - element.style.height = '100%'; - element.style.display = 'flex'; - element.style.overflowY = 'hidden'; // Prevent having scroll within a container having scroll. It messes up with drag-n-drop elements + // Ensure the element we're handed from application mounting is assigned a class + // for our index.scss styles to apply to. element.className += ` ${CONTAINER_CLASSNAME}`; ReactDOM.render(, element); diff --git a/x-pack/plugins/infra/public/index.scss b/x-pack/plugins/infra/public/index.scss index afee4ab8b03897..05e045c1bd53be 100644 --- a/x-pack/plugins/infra/public/index.scss +++ b/x-pack/plugins/infra/public/index.scss @@ -3,22 +3,13 @@ /* Infra plugin styles */ -// Prefix all styles with "inf" to avoid conflicts. -// Examples -// infChart -// infChart__legend -// infChart__legend--small -// infChart__legend-isLoading - -.infReactRoot { +.infra-container-element { background-color: $euiColorEmptyShade; position: absolute; top: 0; left: 0; bottom: 0; right: 0; - // display: flex; - // flex-direction: column; align-items: flex-start; flex: 1 0 auto; overflow-x: hidden; @@ -27,21 +18,3 @@ flex-direction: column; } -// This is a temporary workaround for https://github.com/elastic/kibana/issues/39808 -// A real fix will most likely depend on changes in elastic-charts. - -.infrastructureChart .echTooltip { - max-width: 90vw; -} - -.infrastructureChart .echTooltip__label { - overflow-x: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -.metricsExplorerTitleAnchor { - white-space: nowrap; - text-overflow: ellipsis; - display: inline; -} From 21d98d787e4f8c0b20be89d9c12829ba6b3aeefd Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Tue, 25 Feb 2020 17:10:18 +0100 Subject: [PATCH 40/73] skips 'ResizeObserver loop limit exceeded' error (#58465) --- x-pack/legacy/plugins/siem/cypress/support/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x-pack/legacy/plugins/siem/cypress/support/index.js b/x-pack/legacy/plugins/siem/cypress/support/index.js index 9b86c2ffa94c69..37fa920a8bc31a 100644 --- a/x-pack/legacy/plugins/siem/cypress/support/index.js +++ b/x-pack/legacy/plugins/siem/cypress/support/index.js @@ -26,5 +26,11 @@ Cypress.Cookies.defaults({ whitelist: 'sid', }); +Cypress.on('uncaught:exception', err => { + if (err.message.includes('ResizeObserver loop limit exceeded')) { + return false; + } +}); + // Alternatively you can use CommonJS syntax: // require('./commands') From 712c0851a7d5b34009d948485eda797ed85d71fa Mon Sep 17 00:00:00 2001 From: MadameSheema Date: Tue, 25 Feb 2020 17:15:31 +0100 Subject: [PATCH 41/73] [SIEM] Deletes duplicated tests (#58453) * deletes duplicated test * deletes duplicated fields browser test --- .../plugins/siem/cypress/integration/events_viewer.spec.ts | 7 ------- .../siem/cypress/integration/fields_browser.spec.ts | 7 ------- 2 files changed, 14 deletions(-) diff --git a/x-pack/legacy/plugins/siem/cypress/integration/events_viewer.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/events_viewer.spec.ts index e44c8f4459ba99..446db89ec09dc0 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/events_viewer.spec.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/events_viewer.spec.ts @@ -8,7 +8,6 @@ import { FIELDS_BROWSER_CHECKBOX, FIELDS_BROWSER_CONTAINER, FIELDS_BROWSER_SELECTED_CATEGORY_TITLE, - FIELDS_BROWSER_TITLE, } from '../screens/fields_browser'; import { HEADER_SUBTITLE, @@ -61,12 +60,6 @@ describe('Events Viewer', () => { cy.get(FIELDS_BROWSER_CONTAINER).should('not.exist'); }); - it('renders the fields browser with the expected title when the Events Viewer Fields Browser button is clicked', () => { - cy.get(FIELDS_BROWSER_TITLE) - .invoke('text') - .should('eq', 'Customize Columns'); - }); - it('displays the `default ECS` category (by default)', () => { cy.get(FIELDS_BROWSER_SELECTED_CATEGORY_TITLE) .invoke('text') diff --git a/x-pack/legacy/plugins/siem/cypress/integration/fields_browser.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/fields_browser.spec.ts index 095fc30356fd45..8dddd97f2d8308 100644 --- a/x-pack/legacy/plugins/siem/cypress/integration/fields_browser.spec.ts +++ b/x-pack/legacy/plugins/siem/cypress/integration/fields_browser.spec.ts @@ -15,7 +15,6 @@ import { FIELDS_BROWSER_SELECTED_CATEGORY_TITLE, FIELDS_BROWSER_SELECTED_CATEGORY_COUNT, FIELDS_BROWSER_SYSTEM_CATEGORIES_COUNT, - FIELDS_BROWSER_TITLE, } from '../screens/fields_browser'; import { @@ -58,12 +57,6 @@ describe('Fields Browser', () => { clearFieldsBrowser(); }); - it('renders the fields browser with the expected title when the Fields button is clicked', () => { - cy.get(FIELDS_BROWSER_TITLE) - .invoke('text') - .should('eq', 'Customize Columns'); - }); - it('displays the `default ECS` category (by default)', () => { cy.get(FIELDS_BROWSER_SELECTED_CATEGORY_TITLE) .invoke('text') From c1dede78fbbee6ca1c97fb9c5f31d72f39584566 Mon Sep 17 00:00:00 2001 From: liza-mae Date: Tue, 25 Feb 2020 09:21:30 -0700 Subject: [PATCH 42/73] Add a way to disable certificate verification for FTR. (#58386) * Add a way to disable certificate verification for FTR. * Remove other options Co-authored-by: Elastic Machine --- test/functional/services/remote/webdriver.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts index 1bd6358749e11d..382543822d8ac1 100644 --- a/test/functional/services/remote/webdriver.ts +++ b/test/functional/services/remote/webdriver.ts @@ -44,6 +44,7 @@ import { Browsers } from './browsers'; const throttleOption: string = process.env.TEST_THROTTLE_NETWORK as string; const headlessBrowser: string = process.env.TEST_BROWSER_HEADLESS as string; const remoteDebug: string = process.env.TEST_REMOTE_DEBUG as string; +const certValidation: string = process.env.NODE_TLS_REJECT_UNAUTHORIZED as string; const SECOND = 1000; const MINUTE = 60 * SECOND; const NO_QUEUE_COMMANDS = ['getLog', 'getStatus', 'newSession', 'quit']; @@ -98,6 +99,9 @@ async function attemptToCreateCommand( // See: https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md chromeOptions.push('headless', 'disable-gpu'); } + if (certValidation === '0') { + chromeOptions.push('ignore-certificate-errors'); + } if (remoteDebug === '1') { // Visit chrome://inspect in chrome to remotely view/debug chromeOptions.push('headless', 'disable-gpu', 'remote-debugging-port=9222'); From a714300155fee3854777f4478fcf766bbc68c892 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Tue, 25 Feb 2020 17:48:56 +0100 Subject: [PATCH 43/73] =?UTF-8?q?fix:=20=F0=9F=90=9B=20make=20performance.?= =?UTF-8?q?now=20work=20on=20server=20(#58360)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 make performance.now work on server * fix: 🐛 change check for Node environment * fix: 🐛 simplify now() fn, remove require('perf_hohoks') --- .../expressions/common/execution/execution.ts | 8 +++--- src/plugins/kibana_utils/common/index.ts | 1 + src/plugins/kibana_utils/common/now.ts | 25 +++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/plugins/kibana_utils/common/now.ts diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 272448870e8177..f70a32f2f09c12 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -21,7 +21,7 @@ import { keys, last, mapValues, reduce, zipObject } from 'lodash'; import { Executor } from '../executor'; import { createExecutionContainer, ExecutionContainer } from './container'; import { createError } from '../util'; -import { Defer } from '../../../kibana_utils/common'; +import { Defer, now } from '../../../kibana_utils/common'; import { RequestAdapter, DataAdapter } from '../../../inspector/common'; import { isExpressionValueError, ExpressionValueError } from '../expression_types/specs/error'; import { @@ -211,11 +211,11 @@ export class Execution< // actually have a `then` function which would be treated as a `Promise`. const { resolvedArgs } = await this.resolveArgs(fn, input, fnArgs); args = resolvedArgs; - timeStart = this.params.debug ? performance.now() : 0; + timeStart = this.params.debug ? now() : 0; const output = await this.invokeFunction(fn, input, resolvedArgs); if (this.params.debug) { - const timeEnd: number = performance.now(); + const timeEnd: number = now(); (link as ExpressionAstFunction).debug = { success: true, fn, @@ -229,7 +229,7 @@ export class Execution< if (getType(output) === 'error') return output; input = output; } catch (rawError) { - const timeEnd: number = this.params.debug ? performance.now() : 0; + const timeEnd: number = this.params.debug ? now() : 0; const error = createError(rawError) as ExpressionValueError; error.error.message = `[${fnName}] > ${error.error.message}`; diff --git a/src/plugins/kibana_utils/common/index.ts b/src/plugins/kibana_utils/common/index.ts index 3b07674315dce3..50120edc0c0561 100644 --- a/src/plugins/kibana_utils/common/index.ts +++ b/src/plugins/kibana_utils/common/index.ts @@ -25,3 +25,4 @@ export * from './typed_json'; export { createGetterSetter, Get, Set } from './create_getter_setter'; export { distinctUntilChangedWithInitialValue } from './distinct_until_changed_with_initial_value'; export { url } from './url'; +export { now } from './now'; diff --git a/src/plugins/kibana_utils/common/now.ts b/src/plugins/kibana_utils/common/now.ts new file mode 100644 index 00000000000000..e6c6d745526226 --- /dev/null +++ b/src/plugins/kibana_utils/common/now.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Function that returns number in milliseconds since some undefined point in + * time. Use this function for performance measurements. + */ +export const now: () => number = + typeof performance === 'object' ? performance.now.bind(performance) : Date.now; From c8f18208ab697ea823f7029ee6ae48f87d5fa5fe Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Tue, 25 Feb 2020 17:56:02 +0100 Subject: [PATCH 44/73] Embeddable action storage (#58438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 stub out EmbeddableActionStorage class * test: 💍 add embeddable event storage .create() tests * feat: 🎸 add EmbeddableActionStorage.update() method * feat: 🎸 add .actionStorage to Embeddable class * feat: 🎸 add EmbeddableActionStorage.remove() method * feat: 🎸 add EmbeddableActionStorage.read() method * feat: 🎸 add .list() and .count() to EmbeddableActionStorage --- .../public/lib/embeddables/embeddable.tsx | 6 + .../embeddable_action_storage.test.ts | 536 ++++++++++++++++++ .../embeddables/embeddable_action_storage.ts | 126 ++++ .../public/lib/embeddables/i_embeddable.ts | 5 + 4 files changed, 673 insertions(+) create mode 100644 src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts create mode 100644 src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx index 534e1cae3f62de..a1b332bb656174 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable.tsx @@ -22,6 +22,7 @@ import { Adapters } from '../types'; import { IContainer } from '../containers'; import { IEmbeddable, EmbeddableInput, EmbeddableOutput } from './i_embeddable'; import { ViewMode } from '../types'; +import { EmbeddableActionStorage } from './embeddable_action_storage'; function getPanelTitle(input: EmbeddableInput, output: EmbeddableOutput) { return input.hidePanelTitles ? '' : input.title === undefined ? output.defaultTitle : input.title; @@ -49,6 +50,11 @@ export abstract class Embeddable< // TODO: Rename to destroyed. private destoyed: boolean = false; + private __actionStorage?: EmbeddableActionStorage; + public get actionStorage(): EmbeddableActionStorage { + return this.__actionStorage || (this.__actionStorage = new EmbeddableActionStorage(this)); + } + constructor(input: TEmbeddableInput, output: TEmbeddableOutput, parent?: IContainer) { this.id = input.id; this.output = { diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts new file mode 100644 index 00000000000000..56facc37fc6661 --- /dev/null +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.test.ts @@ -0,0 +1,536 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Embeddable } from './embeddable'; +import { EmbeddableInput } from './i_embeddable'; +import { ViewMode } from '../types'; +import { EmbeddableActionStorage, SerializedEvent } from './embeddable_action_storage'; +import { of } from '../../../../kibana_utils/common'; + +class TestEmbeddable extends Embeddable { + public readonly type = 'test'; + constructor() { + super({ id: 'test', viewMode: ViewMode.VIEW }, {}); + } + reload() {} +} + +describe('EmbeddableActionStorage', () => { + describe('.create()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.create).toBe('function'); + }); + + test('can add event to embeddable', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + const events1 = embeddable.getInput().events || []; + expect(events1).toEqual([]); + + await storage.create(event); + + const events2 = embeddable.getInput().events || []; + expect(events2).toEqual([event]); + }); + + test('can create multiple events', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + const event3: SerializedEvent = { + eventId: 'EVENT_ID3', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + const events1 = embeddable.getInput().events || []; + expect(events1).toEqual([]); + + await storage.create(event1); + + const events2 = embeddable.getInput().events || []; + expect(events2).toEqual([event1]); + + await storage.create(event2); + await storage.create(event3); + + const events3 = embeddable.getInput().events || []; + expect(events3).toEqual([event1, event2, event3]); + }); + + test('throws when creating an event with the same ID', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event); + const [, error] = await of(storage.create(event)); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[EEXIST]: Event with [eventId = EVENT_ID] already exists on [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + }); + + describe('.update()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.update).toBe('function'); + }); + + test('can update an existing event', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: { + name: 'foo', + } as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: { + name: 'bar', + } as any, + }; + + await storage.create(event1); + await storage.update(event2); + + const events = embeddable.getInput().events || []; + expect(events).toEqual([event2]); + }); + + test('updates event in place of the old event', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID', + action: { + name: 'foo', + } as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID', + action: { + name: 'bar', + } as any, + }; + const event22: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID', + action: { + name: 'baz', + } as any, + }; + const event3: SerializedEvent = { + eventId: 'EVENT_ID3', + triggerId: 'TRIGGER-ID', + action: { + name: 'qux', + } as any, + }; + + await storage.create(event1); + await storage.create(event2); + await storage.create(event3); + + const events1 = embeddable.getInput().events || []; + expect(events1).toEqual([event1, event2, event3]); + + await storage.update(event22); + + const events2 = embeddable.getInput().events || []; + expect(events2).toEqual([event1, event22, event3]); + + await storage.update(event2); + + const events3 = embeddable.getInput().events || []; + expect(events3).toEqual([event1, event2, event3]); + }); + + test('throws when updating event, but storage is empty', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + const [, error] = await of(storage.update(event)); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = EVENT_ID] could not be updated as it does not exist in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + + test('throws when updating event with ID that is not stored', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event1); + const [, error] = await of(storage.update(event2)); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = EVENT_ID2] could not be updated as it does not exist in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + }); + + describe('.remove()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.remove).toBe('function'); + }); + + test('can remove existing event', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event); + await storage.remove(event.eventId); + + const events = embeddable.getInput().events || []; + expect(events).toEqual([]); + }); + + test('removes correct events in a list of events', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID', + action: { + name: 'foo', + } as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID', + action: { + name: 'bar', + } as any, + }; + const event3: SerializedEvent = { + eventId: 'EVENT_ID3', + triggerId: 'TRIGGER-ID', + action: { + name: 'qux', + } as any, + }; + + await storage.create(event1); + await storage.create(event2); + await storage.create(event3); + + const events1 = embeddable.getInput().events || []; + expect(events1).toEqual([event1, event2, event3]); + + await storage.remove(event2.eventId); + + const events2 = embeddable.getInput().events || []; + expect(events2).toEqual([event1, event3]); + + await storage.remove(event3.eventId); + + const events3 = embeddable.getInput().events || []; + expect(events3).toEqual([event1]); + + await storage.remove(event1.eventId); + + const events4 = embeddable.getInput().events || []; + expect(events4).toEqual([]); + }); + + test('throws when removing an event from an empty storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const [, error] = await of(storage.remove('EVENT_ID')); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = EVENT_ID] could not be removed as it does not exist in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + + test('throws when removing with ID that does not exist in storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event); + const [, error] = await of(storage.remove('WRONG_ID')); + await storage.remove(event.eventId); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = WRONG_ID] could not be removed as it does not exist in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + }); + + describe('.read()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.read).toBe('function'); + }); + + test('can read an existing event out of storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event); + const event2 = await storage.read(event.eventId); + + expect(event2).toEqual(event); + }); + + test('throws when reading from empty storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const [, error] = await of(storage.read('EVENT_ID')); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = EVENT_ID] could not be found in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + + test('throws when reading event with ID not existing in storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event: SerializedEvent = { + eventId: 'EVENT_ID', + triggerId: 'TRIGGER-ID', + action: {} as any, + }; + + await storage.create(event); + const [, error] = await of(storage.read('WRONG_ID')); + + expect(error).toBeInstanceOf(Error); + expect(error.message).toMatchInlineSnapshot( + `"[ENOENT]: Event with [eventId = WRONG_ID] could not be found in [embeddable.id = test, embeddable.title = undefined]."` + ); + }); + + test('returns correct event when multiple events are stored', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID1', + action: {} as any, + }; + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID2', + action: {} as any, + }; + const event3: SerializedEvent = { + eventId: 'EVENT_ID3', + triggerId: 'TRIGGER-ID3', + action: {} as any, + }; + + await storage.create(event1); + await storage.create(event2); + await storage.create(event3); + + const event12 = await storage.read(event1.eventId); + const event22 = await storage.read(event2.eventId); + const event32 = await storage.read(event3.eventId); + + expect(event12).toEqual(event1); + expect(event22).toEqual(event2); + expect(event32).toEqual(event3); + + expect(event12).not.toEqual(event2); + }); + }); + + describe('.count()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.count).toBe('function'); + }); + + test('returns 0 when storage is empty', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const count = await storage.count(); + + expect(count).toBe(0); + }); + + test('returns correct number of events in storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + expect(await storage.count()).toBe(0); + + await storage.create({ + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID1', + action: {} as any, + }); + + expect(await storage.count()).toBe(1); + + await storage.create({ + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID1', + action: {} as any, + }); + + expect(await storage.count()).toBe(2); + + await storage.remove('EVENT_ID1'); + + expect(await storage.count()).toBe(1); + + await storage.remove('EVENT_ID2'); + + expect(await storage.count()).toBe(0); + }); + }); + + describe('.list()', () => { + test('method exists', () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + expect(typeof storage.list).toBe('function'); + }); + + test('returns empty array when storage is empty', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const list = await storage.list(); + + expect(list).toEqual([]); + }); + + test('returns correct list of events in storage', async () => { + const embeddable = new TestEmbeddable(); + const storage = new EmbeddableActionStorage(embeddable); + + const event1: SerializedEvent = { + eventId: 'EVENT_ID1', + triggerId: 'TRIGGER-ID1', + action: {} as any, + }; + + const event2: SerializedEvent = { + eventId: 'EVENT_ID2', + triggerId: 'TRIGGER-ID1', + action: {} as any, + }; + + expect(await storage.list()).toEqual([]); + + await storage.create(event1); + + expect(await storage.list()).toEqual([event1]); + + await storage.create(event2); + + expect(await storage.list()).toEqual([event1, event2]); + + await storage.remove('EVENT_ID1'); + + expect(await storage.list()).toEqual([event2]); + + await storage.remove('EVENT_ID2'); + + expect(await storage.list()).toEqual([]); + }); + }); +}); diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts new file mode 100644 index 00000000000000..520f92840c5f9c --- /dev/null +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_action_storage.ts @@ -0,0 +1,126 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Embeddable } from '..'; + +/** + * Below two interfaces are here temporarily, they will move to `ui_actions` + * plugin once #58216 is merged. + */ +export interface SerializedEvent { + eventId: string; + triggerId: string; + action: unknown; +} +export interface ActionStorage { + create(event: SerializedEvent): Promise; + update(event: SerializedEvent): Promise; + remove(eventId: string): Promise; + read(eventId: string): Promise; + count(): Promise; + list(): Promise; +} + +export class EmbeddableActionStorage implements ActionStorage { + constructor(private readonly embbeddable: Embeddable) {} + + async create(event: SerializedEvent) { + const input = this.embbeddable.getInput(); + const events = (input.events || []) as SerializedEvent[]; + const exists = !!events.find(({ eventId }) => eventId === event.eventId); + + if (exists) { + throw new Error( + `[EEXIST]: Event with [eventId = ${event.eventId}] already exists on ` + + `[embeddable.id = ${input.id}, embeddable.title = ${input.title}].` + ); + } + + this.embbeddable.updateInput({ + ...input, + events: [...events, event], + }); + } + + async update(event: SerializedEvent) { + const input = this.embbeddable.getInput(); + const events = (input.events || []) as SerializedEvent[]; + const index = events.findIndex(({ eventId }) => eventId === event.eventId); + + if (index === -1) { + throw new Error( + `[ENOENT]: Event with [eventId = ${event.eventId}] could not be ` + + `updated as it does not exist in ` + + `[embeddable.id = ${input.id}, embeddable.title = ${input.title}].` + ); + } + + this.embbeddable.updateInput({ + ...input, + events: [...events.slice(0, index), event, ...events.slice(index + 1)], + }); + } + + async remove(eventId: string) { + const input = this.embbeddable.getInput(); + const events = (input.events || []) as SerializedEvent[]; + const index = events.findIndex(event => eventId === event.eventId); + + if (index === -1) { + throw new Error( + `[ENOENT]: Event with [eventId = ${eventId}] could not be ` + + `removed as it does not exist in ` + + `[embeddable.id = ${input.id}, embeddable.title = ${input.title}].` + ); + } + + this.embbeddable.updateInput({ + ...input, + events: [...events.slice(0, index), ...events.slice(index + 1)], + }); + } + + async read(eventId: string): Promise { + const input = this.embbeddable.getInput(); + const events = (input.events || []) as SerializedEvent[]; + const event = events.find(ev => eventId === ev.eventId); + + if (!event) { + throw new Error( + `[ENOENT]: Event with [eventId = ${eventId}] could not be found in ` + + `[embeddable.id = ${input.id}, embeddable.title = ${input.title}].` + ); + } + + return event; + } + + private __list() { + const input = this.embbeddable.getInput(); + return (input.events || []) as SerializedEvent[]; + } + + async count(): Promise { + return this.__list().length; + } + + async list(): Promise { + return this.__list(); + } +} diff --git a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts index 46cffab8796846..62121cb0f23dd5 100644 --- a/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts +++ b/src/plugins/embeddable/public/lib/embeddables/i_embeddable.ts @@ -30,6 +30,11 @@ export interface EmbeddableInput { hidePanelTitles?: boolean; isEmptyState?: boolean; + /** + * Reserved key for `ui_actions` events. + */ + events?: unknown; + /** * List of action IDs that this embeddable should not render. */ From bd40f557a5e4a7cbcabe1c6f6a5cc7d4d5f52320 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Tue, 25 Feb 2020 17:57:40 +0100 Subject: [PATCH 45/73] Embeddable action storage (#58438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 stub out EmbeddableActionStorage class * test: 💍 add embeddable event storage .create() tests * feat: 🎸 add EmbeddableActionStorage.update() method * feat: 🎸 add .actionStorage to Embeddable class * feat: 🎸 add EmbeddableActionStorage.remove() method * feat: 🎸 add EmbeddableActionStorage.read() method * feat: 🎸 add .list() and .count() to EmbeddableActionStorage From 120f03dc06f7f4a64e911454d6774c1d651acef1 Mon Sep 17 00:00:00 2001 From: Vadim Dalecky Date: Tue, 25 Feb 2020 18:02:25 +0100 Subject: [PATCH 46/73] Add component (#58335) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 use .story for Storybook and standartize dir struct * feat: 🎸 add component * feat: 🎸 add component * refactor: 💡 improve FlyoutCreateDrilldownAction * test: 💍 add tests * docs: ✏️ add @todo for * feat: 🎸 make name editable in * test: 💍 add name field tests * chore: 🤖 change drilldown translation keys --- .../index.tsx | 22 ++-- .../drilldowns/public/actions/index.ts | 2 +- ...ples.tsx => drilldown_hello_bar.story.tsx} | 2 +- .../drilldown_hello_bar.tsx | 26 +++++ .../components/drilldown_hello_bar/index.tsx | 22 +--- ...xamples.tsx => drilldown_picker.story.tsx} | 2 +- .../drilldown_picker/drilldown_picker.tsx | 21 ++++ .../components/drilldown_picker/index.tsx | 16 +-- .../flyout_create_drilldown.story.tsx | 24 +++++ .../flyout_create_drilldown.tsx | 34 ++++++ .../flyout_create_drilldown/i18n.ts | 14 +++ .../flyout_create_drilldown/index.ts | 7 ++ .../flyout_frame/flyout_frame.story.tsx | 39 +++++++ .../flyout_frame/flyout_frame.test.tsx | 102 ++++++++++++++++++ .../components/flyout_frame/flyout_frame.tsx | 71 ++++++++++++ .../i18n.ts} | 8 +- .../public/components/flyout_frame/index.tsx | 7 ++ .../form_create_drilldown.story.tsx | 34 ++++++ .../form_create_drilldown.test.tsx | 68 ++++++++++++ .../form_create_drilldown.tsx | 52 +++++++++ .../components/form_create_drilldown/i18n.ts | 6 +- .../form_create_drilldown/index.tsx | 25 +---- .../public/service/drilldown_service.ts | 8 +- .../plugins/drilldowns/scripts/storybook.js | 2 +- 24 files changed, 528 insertions(+), 86 deletions(-) rename x-pack/plugins/drilldowns/public/actions/{open_flyout_add_drilldown => flyout_create_drilldown}/index.tsx (61%) rename x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/{__examples__/drilldown_hello_bar.examples.tsx => drilldown_hello_bar.story.tsx} (91%) create mode 100644 x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx rename x-pack/plugins/drilldowns/public/components/drilldown_picker/{__examples__/drilldown_picker.examples.tsx => drilldown_picker.story.tsx} (91%) create mode 100644 x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.story.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/i18n.ts create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/index.ts create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx rename x-pack/plugins/drilldowns/public/components/{form_create_drilldown/__examples__/form_create_drilldown.examples.tsx => flyout_frame/i18n.ts} (51%) create mode 100644 x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.story.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.test.tsx create mode 100644 x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.tsx diff --git a/x-pack/plugins/drilldowns/public/actions/open_flyout_add_drilldown/index.tsx b/x-pack/plugins/drilldowns/public/actions/flyout_create_drilldown/index.tsx similarity index 61% rename from x-pack/plugins/drilldowns/public/actions/open_flyout_add_drilldown/index.tsx rename to x-pack/plugins/drilldowns/public/actions/flyout_create_drilldown/index.tsx index 06f134b10a4b7d..0b9f54f51f61e4 100644 --- a/x-pack/plugins/drilldowns/public/actions/open_flyout_add_drilldown/index.tsx +++ b/x-pack/plugins/drilldowns/public/actions/flyout_create_drilldown/index.tsx @@ -10,11 +10,11 @@ import { CoreStart } from 'src/core/public'; import { Action } from '../../../../../../src/plugins/ui_actions/public'; import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public'; import { IEmbeddable } from '../../../../../../src/plugins/embeddable/public'; -import { FormCreateDrilldown } from '../../components/form_create_drilldown'; +import { FlyoutCreateDrilldown } from '../../components/flyout_create_drilldown'; export const OPEN_FLYOUT_ADD_DRILLDOWN = 'OPEN_FLYOUT_ADD_DRILLDOWN'; -interface ActionContext { +export interface FlyoutCreateDrilldownActionContext { embeddable: IEmbeddable; } @@ -22,29 +22,31 @@ export interface OpenFlyoutAddDrilldownParams { overlays: () => Promise; } -export class OpenFlyoutAddDrilldown implements Action { +export class FlyoutCreateDrilldownAction implements Action { public readonly type = OPEN_FLYOUT_ADD_DRILLDOWN; public readonly id = OPEN_FLYOUT_ADD_DRILLDOWN; - public order = 100; + public order = 5; constructor(protected readonly params: OpenFlyoutAddDrilldownParams) {} public getDisplayName() { - return i18n.translate('xpack.drilldowns.panel.openFlyoutAddDrilldown.displayName', { - defaultMessage: 'Add drilldown', + return i18n.translate('xpack.drilldowns.FlyoutCreateDrilldownAction.displayName', { + defaultMessage: 'Create Drilldown', }); } public getIconType() { - return 'empty'; + return 'plusInCircle'; } - public async isCompatible({ embeddable }: ActionContext) { + public async isCompatible({ embeddable }: FlyoutCreateDrilldownActionContext) { return true; } - public async execute({ embeddable }: ActionContext) { + public async execute(context: FlyoutCreateDrilldownActionContext) { const overlays = await this.params.overlays(); - overlays.openFlyout(toMountPoint()); + const handle = overlays.openFlyout( + toMountPoint( handle.close()} />) + ); } } diff --git a/x-pack/plugins/drilldowns/public/actions/index.ts b/x-pack/plugins/drilldowns/public/actions/index.ts index c0ca7fac22049b..ce235043b4ef6e 100644 --- a/x-pack/plugins/drilldowns/public/actions/index.ts +++ b/x-pack/plugins/drilldowns/public/actions/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './open_flyout_add_drilldown'; +export * from './flyout_create_drilldown'; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/__examples__/drilldown_hello_bar.examples.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx similarity index 91% rename from x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/__examples__/drilldown_hello_bar.examples.tsx rename to x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx index afa82f5e74c16b..7a9e19342f27ce 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/__examples__/drilldown_hello_bar.examples.tsx +++ b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.story.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { storiesOf } from '@storybook/react'; -import { DrilldownHelloBar } from '..'; +import { DrilldownHelloBar } from '.'; storiesOf('components/DrilldownHelloBar', module).add('default', () => { return ; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx new file mode 100644 index 00000000000000..1ef714f7b86e2e --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/drilldown_hello_bar.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +export interface DrilldownHelloBarProps { + docsLink?: string; +} + +/** + * @todo https://github.com/elastic/kibana/issues/55311 + */ +export const DrilldownHelloBar: React.FC = ({ docsLink }) => { + return ( +
+

+ Drilldowns provide the ability to define a new behavior when interacting with a panel. You + can add multiple options or simply override the default filtering behavior. +

+ View docs +
+ ); +}; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx index 895a100df3ac50..f28c8cfa3a0595 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx +++ b/x-pack/plugins/drilldowns/public/components/drilldown_hello_bar/index.tsx @@ -4,24 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; - -export interface DrilldownHelloBarProps { - docsLink?: string; -} - -export const DrilldownHelloBar: React.FC = ({ docsLink }) => { - return ( -
-

- Drilldowns provide the ability to define a new behavior when interacting with a panel. You - can add multiple options or simply override the default filtering behavior. -

- View docs - -
- ); -}; +export * from './drilldown_hello_bar'; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_picker/__examples__/drilldown_picker.examples.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.story.tsx similarity index 91% rename from x-pack/plugins/drilldowns/public/components/drilldown_picker/__examples__/drilldown_picker.examples.tsx rename to x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.story.tsx index dfdd9627ab5cd4..5627a5d6f4522b 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_picker/__examples__/drilldown_picker.examples.tsx +++ b/x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.story.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { storiesOf } from '@storybook/react'; -import { DrilldownPicker } from '..'; +import { DrilldownPicker } from '.'; storiesOf('components/DrilldownPicker', module).add('default', () => { return ; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.tsx new file mode 100644 index 00000000000000..3748fc666c81c5 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/drilldown_picker/drilldown_picker.tsx @@ -0,0 +1,21 @@ +/* + * 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'; + +// eslint-disable-next-line +export interface DrilldownPickerProps {} + +export const DrilldownPicker: React.FC = () => { + return ( + + ); +}; diff --git a/x-pack/plugins/drilldowns/public/components/drilldown_picker/index.tsx b/x-pack/plugins/drilldowns/public/components/drilldown_picker/index.tsx index 3748fc666c81c5..3be289fe6d46e8 100644 --- a/x-pack/plugins/drilldowns/public/components/drilldown_picker/index.tsx +++ b/x-pack/plugins/drilldowns/public/components/drilldown_picker/index.tsx @@ -4,18 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; - -// eslint-disable-next-line -export interface DrilldownPickerProps {} - -export const DrilldownPicker: React.FC = () => { - return ( - - ); -}; +export * from './drilldown_picker'; diff --git a/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.story.tsx b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.story.tsx new file mode 100644 index 00000000000000..4f024b7d9cd6a2 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.story.tsx @@ -0,0 +1,24 @@ +/* + * 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. + */ + +/* eslint-disable no-console */ + +import * as React from 'react'; +import { EuiFlyout } from '@elastic/eui'; +import { storiesOf } from '@storybook/react'; +import { FlyoutCreateDrilldown } from '.'; + +storiesOf('components/FlyoutCreateDrilldown', module) + .add('default', () => { + return ; + }) + .add('open in flyout', () => { + return ( + + + + ); + }); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.tsx b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.tsx new file mode 100644 index 00000000000000..b45ac9197c7e06 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/flyout_create_drilldown.tsx @@ -0,0 +1,34 @@ +/* + * 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 { EuiButton } from '@elastic/eui'; +import { FormCreateDrilldown } from '../form_create_drilldown'; +import { FlyoutFrame } from '../flyout_frame'; +import { txtCreateDrilldown } from './i18n'; +import { FlyoutCreateDrilldownActionContext } from '../../actions'; + +export interface FlyoutCreateDrilldownProps { + context: FlyoutCreateDrilldownActionContext; + onClose?: () => void; +} + +export const FlyoutCreateDrilldown: React.FC = ({ + context, + onClose, +}) => { + const footer = ( + {}} fill> + {txtCreateDrilldown} + + ); + + return ( + + + + ); +}; diff --git a/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/i18n.ts b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/i18n.ts new file mode 100644 index 00000000000000..ceabc6d3a9aa51 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/i18n.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const txtCreateDrilldown = i18n.translate( + 'xpack.drilldowns.components.FlyoutCreateDrilldown.CreateDrilldown', + { + defaultMessage: 'Create drilldown', + } +); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/index.ts b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/index.ts new file mode 100644 index 00000000000000..ce235043b4ef6e --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_create_drilldown/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export * from './flyout_create_drilldown'; diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx new file mode 100644 index 00000000000000..2715637f6392fe --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.story.tsx @@ -0,0 +1,39 @@ +/* + * 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. + */ + +/* eslint-disable no-console */ + +import * as React from 'react'; +import { EuiFlyout, EuiButton } from '@elastic/eui'; +import { storiesOf } from '@storybook/react'; +import { FlyoutFrame } from '.'; + +storiesOf('components/FlyoutFrame', module) + .add('default', () => { + return test; + }) + .add('with title', () => { + return test; + }) + .add('with onClose', () => { + return console.log('onClose')}>test; + }) + .add('custom footer', () => { + return click me!}>test; + }) + .add('open in flyout', () => { + return ( + + Save} + onClose={() => console.log('onClose')} + > + test + + + ); + }); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx new file mode 100644 index 00000000000000..b5fb52fcf5c18a --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.test.tsx @@ -0,0 +1,102 @@ +/* + * 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 { render } from 'react-dom'; +import { render as renderTestingLibrary, fireEvent } from '@testing-library/react'; +import { FlyoutFrame } from '.'; + +describe('', () => { + test('renders without crashing', () => { + const div = document.createElement('div'); + render(, div); + }); + + describe('[title=]', () => { + test('renders title in

tag', () => { + const div = document.createElement('div'); + render(, div); + + const title = div.querySelector('h1'); + expect(title?.textContent).toBe('foobar'); + }); + + test('title can be any react node', () => { + const div = document.createElement('div'); + render( + + foo bar + + } + />, + div + ); + + const title = div.querySelector('h1'); + expect(title?.innerHTML).toBe('foo bar'); + }); + }); + + describe('[footer=]', () => { + test('if [footer=] prop not provided, does not render footer', () => { + const div = document.createElement('div'); + render(, div); + + const footer = div.querySelector('[data-test-subj="flyoutFooter"]'); + expect(footer).toBe(null); + }); + + test('can render anything in footer', () => { + const div = document.createElement('div'); + render( + + a b + + } + />, + div + ); + + const footer = div.querySelector('[data-test-subj="flyoutFooter"]'); + expect(footer?.innerHTML).toBe('a b'); + }); + }); + + describe('[onClose=]', () => { + test('does not render close button if "onClose" prop is missing', () => { + const div = document.createElement('div'); + render(, div); + + const closeButton = div.querySelector('[data-test-subj="flyoutCloseButton"]'); + expect(closeButton).toBe(null); + }); + + test('renders close button if "onClose" prop is provided', () => { + const div = document.createElement('div'); + render( {}} />, div); + + const closeButton = div.querySelector('[data-test-subj="flyoutCloseButton"]'); + expect(closeButton).not.toBe(null); + }); + + test('calls onClose prop when close button clicked', async () => { + const onClose = jest.fn(); + const el = renderTestingLibrary(); + + const closeButton = el.queryByText('Close'); + + expect(onClose).toHaveBeenCalledTimes(0); + + fireEvent.click(closeButton!); + + expect(onClose).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx new file mode 100644 index 00000000000000..2945cfd739482d --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_frame/flyout_frame.tsx @@ -0,0 +1,71 @@ +/* + * 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 { + EuiFlyoutHeader, + EuiTitle, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, +} from '@elastic/eui'; +import { txtClose } from './i18n'; + +export interface FlyoutFrameProps { + title?: React.ReactNode; + footer?: React.ReactNode; + onClose?: () => void; +} + +/** + * @todo This component can be moved to `kibana_react`. + */ +export const FlyoutFrame: React.FC = ({ + title = '', + footer, + onClose, + children, +}) => { + const headerFragment = title && ( + + +

{title}

+
+
+ ); + + const footerFragment = (onClose || footer) && ( + + + + {onClose && ( + + {txtClose} + + )} + + + {footer} + + + + ); + + return ( + <> + {headerFragment} + {children} + {footerFragment} + + ); +}; diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/__examples__/form_create_drilldown.examples.tsx b/x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts similarity index 51% rename from x-pack/plugins/drilldowns/public/components/form_create_drilldown/__examples__/form_create_drilldown.examples.tsx rename to x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts index 34f6932b41dacf..257d7d36dbee19 100644 --- a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/__examples__/form_create_drilldown.examples.tsx +++ b/x-pack/plugins/drilldowns/public/components/flyout_frame/i18n.ts @@ -4,10 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as React from 'react'; -import { storiesOf } from '@storybook/react'; -import { FormCreateDrilldown } from '..'; +import { i18n } from '@kbn/i18n'; -storiesOf('components/FormCreateDrilldown', module).add('default', () => { - return ; +export const txtClose = i18n.translate('xpack.drilldowns.components.FlyoutFrame.Close', { + defaultMessage: 'Close', }); diff --git a/x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx b/x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx new file mode 100644 index 00000000000000..040b4b6b5e2439 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/flyout_frame/index.tsx @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export * from './flyout_frame'; diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.story.tsx b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.story.tsx new file mode 100644 index 00000000000000..e7e1d67473e8c7 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.story.tsx @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/* eslint-disable no-console */ + +import * as React from 'react'; +import { EuiFlyout } from '@elastic/eui'; +import { storiesOf } from '@storybook/react'; +import { FormCreateDrilldown } from '.'; + +const DemoEditName: React.FC = () => { + const [name, setName] = React.useState(''); + + return ; +}; + +storiesOf('components/FormCreateDrilldown', module) + .add('default', () => { + return ; + }) + .add('[name=foobar]', () => { + return ; + }) + .add('can edit name', () => ) + .add('open in flyout', () => { + return ( + + + + ); + }); diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.test.tsx b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.test.tsx new file mode 100644 index 00000000000000..6691966e47e647 --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.test.tsx @@ -0,0 +1,68 @@ +/* + * 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 { render } from 'react-dom'; +import { FormCreateDrilldown } from '.'; +import { render as renderTestingLibrary, fireEvent } from '@testing-library/react'; +import { txtNameOfDrilldown } from './i18n'; + +describe('', () => { + test('renders without crashing', () => { + const div = document.createElement('div'); + render( {}} />, div); + }); + + describe('[name=]', () => { + test('if name not provided, uses to empty string', () => { + const div = document.createElement('div'); + + render(, div); + + const input = div.querySelector( + '[data-test-subj="dynamicActionNameInput"]' + ) as HTMLInputElement; + + expect(input?.value).toBe(''); + }); + + test('can set name input field value', () => { + const div = document.createElement('div'); + + render(, div); + + const input = div.querySelector( + '[data-test-subj="dynamicActionNameInput"]' + ) as HTMLInputElement; + + expect(input?.value).toBe('foo'); + + render(, div); + + expect(input?.value).toBe('bar'); + }); + + test('fires onNameChange callback on name change', () => { + const onNameChange = jest.fn(); + const utils = renderTestingLibrary( + + ); + const input = utils.getByLabelText(txtNameOfDrilldown); + + expect(onNameChange).toHaveBeenCalledTimes(0); + + fireEvent.change(input, { target: { value: 'qux' } }); + + expect(onNameChange).toHaveBeenCalledTimes(1); + expect(onNameChange).toHaveBeenCalledWith('qux'); + + fireEvent.change(input, { target: { value: 'quxx' } }); + + expect(onNameChange).toHaveBeenCalledTimes(2); + expect(onNameChange).toHaveBeenCalledWith('quxx'); + }); + }); +}); diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.tsx b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.tsx new file mode 100644 index 00000000000000..4422de604092bb --- /dev/null +++ b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/form_create_drilldown.tsx @@ -0,0 +1,52 @@ +/* + * 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 { EuiForm, EuiFormRow, EuiFieldText } from '@elastic/eui'; +import { DrilldownHelloBar } from '../drilldown_hello_bar'; +import { txtNameOfDrilldown, txtUntitledDrilldown, txtDrilldownAction } from './i18n'; +import { DrilldownPicker } from '../drilldown_picker'; + +const noop = () => {}; + +export interface FormCreateDrilldownProps { + name?: string; + onNameChange?: (name: string) => void; +} + +export const FormCreateDrilldown: React.FC = ({ + name = '', + onNameChange = noop, +}) => { + const nameFragment = ( + + onNameChange(event.target.value)} + data-test-subj="dynamicActionNameInput" + /> + + ); + + const triggerPicker =
Trigger Picker will be here
; + const actionPicker = ( + + + + ); + + return ( + <> + + {nameFragment} + {triggerPicker} + {actionPicker} + + ); +}; diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/i18n.ts b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/i18n.ts index 922131ba4b9012..4c0e287935edd7 100644 --- a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/i18n.ts +++ b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/i18n.ts @@ -7,21 +7,21 @@ import { i18n } from '@kbn/i18n'; export const txtNameOfDrilldown = i18n.translate( - 'xpack.drilldowns.components.form_create_drilldown.nameOfDrilldown', + 'xpack.drilldowns.components.FormCreateDrilldown.nameOfDrilldown', { defaultMessage: 'Name of drilldown', } ); export const txtUntitledDrilldown = i18n.translate( - 'xpack.drilldowns.components.form_create_drilldown.untitledDrilldown', + 'xpack.drilldowns.components.FormCreateDrilldown.untitledDrilldown', { defaultMessage: 'Untitled drilldown', } ); export const txtDrilldownAction = i18n.translate( - 'xpack.drilldowns.components.form_create_drilldown.drilldownAction', + 'xpack.drilldowns.components.FormCreateDrilldown.drilldownAction', { defaultMessage: 'Drilldown action', } diff --git a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/index.tsx b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/index.tsx index 40cd4cf2b210b8..c2c5a7e435b391 100644 --- a/x-pack/plugins/drilldowns/public/components/form_create_drilldown/index.tsx +++ b/x-pack/plugins/drilldowns/public/components/form_create_drilldown/index.tsx @@ -4,27 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import { EuiForm, EuiFormRow, EuiFieldText } from '@elastic/eui'; -import { DrilldownHelloBar } from '../drilldown_hello_bar'; -import { txtNameOfDrilldown, txtUntitledDrilldown, txtDrilldownAction } from './i18n'; -import { DrilldownPicker } from '../drilldown_picker'; - -// eslint-disable-next-line -export interface FormCreateDrilldownProps {} - -export const FormCreateDrilldown: React.FC = () => { - return ( -
- - - - - - - - - -
- ); -}; +export * from './form_create_drilldown'; diff --git a/x-pack/plugins/drilldowns/public/service/drilldown_service.ts b/x-pack/plugins/drilldowns/public/service/drilldown_service.ts index f22f4521816480..b1310ba003ff7a 100644 --- a/x-pack/plugins/drilldowns/public/service/drilldown_service.ts +++ b/x-pack/plugins/drilldowns/public/service/drilldown_service.ts @@ -5,17 +5,17 @@ */ import { CoreSetup } from 'src/core/public'; -import { OpenFlyoutAddDrilldown } from '../actions/open_flyout_add_drilldown'; +import { FlyoutCreateDrilldownAction } from '../actions'; import { DrilldownsSetupDependencies } from '../plugin'; export class DrilldownService { bootstrap(core: CoreSetup, { uiActions }: DrilldownsSetupDependencies) { - const actionOpenFlyoutAddDrilldown = new OpenFlyoutAddDrilldown({ + const actionFlyoutCreateDrilldown = new FlyoutCreateDrilldownAction({ overlays: async () => (await core.getStartServices())[0].overlays, }); - uiActions.registerAction(actionOpenFlyoutAddDrilldown); - uiActions.attachAction('CONTEXT_MENU_TRIGGER', actionOpenFlyoutAddDrilldown.id); + uiActions.registerAction(actionFlyoutCreateDrilldown); + uiActions.attachAction('CONTEXT_MENU_TRIGGER', actionFlyoutCreateDrilldown.id); } /** diff --git a/x-pack/plugins/drilldowns/scripts/storybook.js b/x-pack/plugins/drilldowns/scripts/storybook.js index 9b0f57746e5849..2bfd0eb1a8f19c 100644 --- a/x-pack/plugins/drilldowns/scripts/storybook.js +++ b/x-pack/plugins/drilldowns/scripts/storybook.js @@ -9,5 +9,5 @@ import { join } from 'path'; // eslint-disable-next-line require('@kbn/storybook').runStorybookCli({ name: 'drilldowns', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.examples.tsx')], + storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.story.tsx')], }); From fac57c1cca66dc3aeccb535ccf99f5dba7b76535 Mon Sep 17 00:00:00 2001 From: Matthias Wilhelm Date: Tue, 25 Feb 2020 18:25:11 +0100 Subject: [PATCH 47/73] [Visualize] Improve linked saved search functional test (#58339) * Remove redundant sleep * convert to TypeScript --- ..._linked_saved_searches.js => _linked_saved_searches.ts} | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename test/functional/apps/visualize/{_linked_saved_searches.js => _linked_saved_searches.ts} (95%) diff --git a/test/functional/apps/visualize/_linked_saved_searches.js b/test/functional/apps/visualize/_linked_saved_searches.ts similarity index 95% rename from test/functional/apps/visualize/_linked_saved_searches.js rename to test/functional/apps/visualize/_linked_saved_searches.ts index 37ec3f06f2ecd0..345987a803394a 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.js +++ b/test/functional/apps/visualize/_linked_saved_searches.ts @@ -18,8 +18,9 @@ */ import expect from '@kbn/expect'; - -export default function({ getService, getPageObjects }) { +import { FtrProviderContext } from '../../ftr_provider_context'; +// eslint-disable-next-line import/no-default-export +export default function({ getService, getPageObjects }: FtrProviderContext) { const filterBar = getService('filterBar'); const retry = getService('retry'); const PageObjects = getPageObjects([ @@ -40,8 +41,6 @@ export default function({ getService, getPageObjects }) { await filterBar.addFilter('extension.raw', 'is', 'jpg'); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.discover.saveSearch(savedSearchName); - // TODO: Remove this once https://github.com/elastic/kibana/issues/19750 is properly resolved - await PageObjects.common.sleep(500); }); it('should create a visualization from a saved search', async () => { From 93556a9bdddc671cabe218973b86ee8d7ecb5273 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Tue, 25 Feb 2020 18:31:24 +0100 Subject: [PATCH 48/73] Visualizations plugin np_ready (#57983) Partially addresses #50897 updates visualizations plugin makes visualizations/saved_visualizations np_ready makes visualizations/embeddable np_ready remove DefaultVisEditor dependency from visualizations import AggConfigs directly instead of ui/public Clean up imports from root. use relative imports Remove bind directive import --- src/legacy/core_plugins/data/public/index.ts | 2 + .../public/visualize/kibana_services.ts | 2 + .../kibana/public/visualize/legacy_imports.ts | 3 +- .../np_ready/editor/visualization_editor.js | 2 +- .../kibana/public/visualize/plugin.ts | 4 +- .../public/default_editor.tsx | 6 +- .../public/default_editor_controller.tsx | 2 +- .../public/embeddable/query_geohash_bounds.ts | 103 ------------------ .../visualizations/public/index.scss | 2 - .../visualizations/public/legacy_imports.ts | 8 +- .../public/np_ready/kibana.json | 5 +- .../public/np_ready/public/_index.scss | 1 + .../public}/embeddable/_embeddables.scss | 0 .../public}/embeddable/_index.scss | 0 .../embeddable/_visualize_lab_disabled.scss | 0 .../public}/embeddable/constants.ts | 0 .../embeddable/disabled_lab_embeddable.tsx | 2 +- .../embeddable/disabled_lab_visualization.tsx | 0 .../public}/embeddable/get_index_pattern.ts | 6 +- .../{ => np_ready/public}/embeddable/index.ts | 1 + .../embeddable/visualize_embeddable.ts | 47 ++++---- .../visualize_embeddable_factory.tsx | 37 +++---- .../expressions/visualization_function.ts | 7 +- .../public/np_ready/public/index.ts | 16 ++- .../public/np_ready/public/legacy.ts | 4 +- .../__tests__/vis_types/base_vis_type.js | 2 +- .../__tests__/vis_types/react_vis_type.js | 2 +- .../public/legacy/build_pipeline.test.ts | 5 - .../np_ready/public/legacy/build_pipeline.ts | 16 +-- .../public/np_ready/public/mocks.ts | 7 +- .../public/np_ready/public/plugin.ts | 62 ++++++----- .../saved_visualizations/_saved_vis.ts | 16 ++- .../find_list_items.test.ts} | 67 +++++++----- .../saved_visualizations/find_list_items.ts} | 33 ++++-- .../public}/saved_visualizations/index.ts | 0 .../saved_visualization_references.test.ts | 10 +- .../saved_visualization_references.ts | 4 +- .../saved_visualizations.ts | 11 +- .../public/np_ready/public/services.ts | 23 +++- .../public/np_ready/public/types.ts | 38 +++++++ .../public/np_ready/public/vis.ts | 2 +- .../public/np_ready/public/vis_impl.d.ts | 2 +- .../{types => vis_types}/base_vis_type.js | 4 +- .../public/{types => vis_types}/index.ts | 0 .../{types => vis_types}/react_vis_type.js | 0 .../{types => vis_types}/types_service.ts | 0 .../vis_type_alias_registry.ts | 2 +- .../public/wizard/new_vis_modal.test.tsx | 4 +- .../np_ready/public/wizard/new_vis_modal.tsx | 4 +- .../search_selection/search_selection.tsx | 4 +- .../wizard/type_selection/new_vis_help.tsx | 2 +- .../wizard/type_selection/type_selection.tsx | 2 +- .../save_modal/saved_object_save_modal.tsx | 6 +- .../expression_types/embeddable_types.ts | 2 +- .../functions/common/saved_visualization.ts | 2 +- .../embeddable_input_to_expression.test.ts | 1 + .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 58 files changed, 279 insertions(+), 316 deletions(-) delete mode 100644 src/legacy/core_plugins/visualizations/public/embeddable/query_geohash_bounds.ts rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/_embeddables.scss (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/_index.scss (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/_visualize_lab_disabled.scss (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/constants.ts (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/disabled_lab_embeddable.tsx (94%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/disabled_lab_visualization.tsx (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/get_index_pattern.ts (90%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/index.ts (92%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/visualize_embeddable.ts (90%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/embeddable/visualize_embeddable_factory.tsx (85%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/saved_visualizations/_saved_vis.ts (90%) rename src/legacy/core_plugins/visualizations/public/{saved_visualizations/find_list_items.test.js => np_ready/public/saved_visualizations/find_list_items.test.ts} (77%) rename src/legacy/core_plugins/visualizations/public/{saved_visualizations/find_list_items.js => np_ready/public/saved_visualizations/find_list_items.ts} (64%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/saved_visualizations/index.ts (100%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/saved_visualizations/saved_visualization_references.test.ts (96%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/saved_visualizations/saved_visualization_references.ts (95%) rename src/legacy/core_plugins/visualizations/public/{ => np_ready/public}/saved_visualizations/saved_visualizations.ts (91%) create mode 100644 src/legacy/core_plugins/visualizations/public/np_ready/public/types.ts rename src/legacy/core_plugins/visualizations/public/np_ready/public/{types => vis_types}/base_vis_type.js (95%) rename src/legacy/core_plugins/visualizations/public/np_ready/public/{types => vis_types}/index.ts (100%) rename src/legacy/core_plugins/visualizations/public/np_ready/public/{types => vis_types}/react_vis_type.js (100%) rename src/legacy/core_plugins/visualizations/public/np_ready/public/{types => vis_types}/types_service.ts (100%) rename src/legacy/core_plugins/visualizations/public/np_ready/public/{types => vis_types}/vis_type_alias_registry.ts (97%) diff --git a/src/legacy/core_plugins/data/public/index.ts b/src/legacy/core_plugins/data/public/index.ts index ce46f534141f4f..8cde5d0a1fc115 100644 --- a/src/legacy/core_plugins/data/public/index.ts +++ b/src/legacy/core_plugins/data/public/index.ts @@ -54,6 +54,7 @@ export * from '../common'; export { FilterStateManager } from './filter/filter_manager'; export { // agg_types TODO need to group these under a namespace or prefix + AggConfigs, AggParamType, AggTypeFilters, // TODO convert to interface aggTypeFilters, @@ -66,6 +67,7 @@ export { convertIPRangeToString, intervalOptions, // only used in Discover isDateHistogramBucketAggConfig, + setBounds, isStringType, isType, isValidInterval, diff --git a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts index 096877d5824c49..cfd12b32834590 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/kibana_services.ts @@ -36,6 +36,7 @@ import { VisualizationsStart } from '../../../visualizations/public'; import { SavedVisualizations } from './np_ready/types'; import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public'; import { KibanaLegacyStart } from '../../../../../plugins/kibana_legacy/public'; +import { DefaultEditorController } from '../../../vis_default_editor/public'; export interface VisualizeKibanaServices { pluginInitializerContext: PluginInitializerContext; @@ -60,6 +61,7 @@ export interface VisualizeKibanaServices { usageCollection?: UsageCollectionSetup; I18nContext: I18nStart['Context']; setActiveUrl: (newUrl: string) => void; + DefaultVisualizationEditor: typeof DefaultEditorController; } let services: VisualizeKibanaServices | null = null; diff --git a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts index 8b1bb0fda8c841..d9565938c838d8 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/legacy_imports.ts @@ -43,8 +43,7 @@ export { absoluteToParsedUrl } from 'ui/url/absolute_to_parsed_url'; export { KibanaParsedUrl } from 'ui/url/kibana_parsed_url'; export { wrapInI18nContext } from 'ui/i18n'; export { DashboardConstants } from '../dashboard/np_ready/dashboard_constants'; -export { VisSavedObject } from '../../../visualizations/public/embeddable/visualize_embeddable'; -export { VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/embeddable'; +export { VisSavedObject, VISUALIZE_EMBEDDABLE_TYPE } from '../../../visualizations/public/'; export { configureAppAngularModule, ensureDefaultIndexPattern, diff --git a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js index c40a10115ae4eb..65c25b8cf705d2 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/np_ready/editor/visualization_editor.js @@ -30,7 +30,7 @@ export function initVisEditorDirective(app, deps) { appState: '=', }, link: function($scope, element) { - const Editor = $scope.savedObj.vis.type.editor; + const Editor = $scope.savedObj.vis.type.editor || deps.DefaultVisualizationEditor; const editor = new Editor(element[0], $scope.savedObj); $scope.renderFunction = () => { diff --git a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts index 22804685db3ccd..9f2283d29c203c 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/plugin.ts +++ b/src/legacy/core_plugins/kibana/public/visualize/plugin.ts @@ -50,6 +50,7 @@ import { HomePublicPluginSetup, } from '../../../../../plugins/home/public'; import { UsageCollectionSetup } from '../../../../../plugins/usage_collection/public'; +import { DefaultEditorController } from '../../../vis_default_editor/public'; export interface VisualizePluginStartDependencies { data: DataPublicPluginStart; @@ -139,7 +140,7 @@ export class VisualizePlugin implements Plugin { localStorage: new Storage(localStorage), navigation, savedObjectsClient, - savedVisualizations: visualizations.getSavedVisualizationsLoader(), + savedVisualizations: visualizations.savedVisualizationsLoader, savedQueryService: dataStart.query.savedQueries, share, toastNotifications: coreStart.notifications.toasts, @@ -150,6 +151,7 @@ export class VisualizePlugin implements Plugin { usageCollection, I18nContext: coreStart.i18n.Context, setActiveUrl, + DefaultVisualizationEditor: DefaultEditorController, }; setServices(deps); diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx index 32ea71c0bc0052..7eee54006f6844 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor.tsx @@ -20,8 +20,10 @@ import React, { useEffect, useRef, useState, useCallback } from 'react'; import { EditorRenderProps } from '../../kibana/public/visualize/np_ready/types'; -import { VisualizeEmbeddable } from '../../visualizations/public/embeddable'; -import { VisualizeEmbeddableFactory } from '../../visualizations/public/embeddable/visualize_embeddable_factory'; +import { + VisualizeEmbeddableContract as VisualizeEmbeddable, + VisualizeEmbeddableFactoryContract as VisualizeEmbeddableFactory, +} from '../../visualizations/public/'; import { PanelsContainer, Panel } from '../../../../plugins/kibana_react/public'; import './vis_type_agg_filter'; diff --git a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx index d3090d277aef9b..db910604eddd15 100644 --- a/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/legacy/core_plugins/vis_default_editor/public/default_editor_controller.tsx @@ -23,7 +23,7 @@ import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n/react'; import { EditorRenderProps } from 'src/legacy/core_plugins/kibana/public/visualize/np_ready/types'; -import { VisSavedObject } from 'src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable'; +import { VisSavedObject } from 'src/legacy/core_plugins/visualizations/public/'; import { Storage } from '../../../../plugins/kibana_utils/public'; import { KibanaContextProvider } from '../../../../plugins/kibana_react/public'; import { DefaultEditor } from './default_editor'; diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/query_geohash_bounds.ts b/src/legacy/core_plugins/visualizations/public/embeddable/query_geohash_bounds.ts deleted file mode 100644 index f37bc858efab09..00000000000000 --- a/src/legacy/core_plugins/visualizations/public/embeddable/query_geohash_bounds.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; -import { toastNotifications } from 'ui/notify'; - -import { IAggConfig } from 'ui/agg_types'; -import { timefilter } from 'ui/timefilter'; -import { Vis } from '../np_ready/public'; -import { Filter, Query, SearchSource, ISearchSource } from '../../../../../plugins/data/public'; - -interface QueryGeohashBoundsParams { - filters?: Filter[]; - query?: Query; - searchSource?: ISearchSource; -} - -/** - * Coordinate map visualization needs to be able to query for the latest geohash - * bounds when a user clicks the "fit to data" map icon, which requires knowing - * about global filters & queries. This logic has been extracted here so we can - * keep `searchSource` out of the vis, but ultimately we need to design a - * long-term solution for situations like this. - * - * TODO: Remove this as a part of elastic/kibana#30593 - */ -export async function queryGeohashBounds(vis: Vis, params: QueryGeohashBoundsParams) { - const agg = vis.getAggConfig().aggs.find((a: IAggConfig) => { - return get(a, 'type.dslName') === 'geohash_grid'; - }); - - if (agg) { - const searchSource = params.searchSource - ? params.searchSource.createChild() - : new SearchSource(); - searchSource.setField('size', 0); - searchSource.setField('aggs', () => { - const geoBoundsAgg = vis.getAggConfig().createAggConfig( - { - type: 'geo_bounds', - enabled: true, - params: { - field: agg.getField(), - }, - schema: 'metric', - }, - { - addToAggConfigs: false, - } - ); - return { - '1': geoBoundsAgg.toDsl(), - }; - }); - - const { filters, query } = params; - if (filters) { - searchSource.setField('filter', () => { - const activeFilters = [...filters]; - const indexPattern = agg.getIndexPattern(); - const useTimeFilter = !!indexPattern.timeFieldName; - if (useTimeFilter) { - const filter = timefilter.createFilter(indexPattern); - if (filter) activeFilters.push((filter as any) as Filter); - } - return activeFilters; - }); - } - if (query) { - searchSource.setField('query', query); - } - - try { - const esResp = await searchSource.fetch(); - return get(esResp, 'aggregations.1.bounds'); - } catch (error) { - toastNotifications.addDanger({ - title: i18n.translate('visualizations.queryGeohashBounds.unableToGetBoundErrorTitle', { - defaultMessage: 'Unable to get bounds', - }), - text: `${error.message}`, - }); - return; - } - } -} diff --git a/src/legacy/core_plugins/visualizations/public/index.scss b/src/legacy/core_plugins/visualizations/public/index.scss index 748945eabd3316..238f58fbfa2955 100644 --- a/src/legacy/core_plugins/visualizations/public/index.scss +++ b/src/legacy/core_plugins/visualizations/public/index.scss @@ -1,4 +1,2 @@ @import 'src/legacy/ui/public/styles/styling_constants'; - -@import './embeddable/index'; @import './np_ready/public/index'; diff --git a/src/legacy/core_plugins/visualizations/public/legacy_imports.ts b/src/legacy/core_plugins/visualizations/public/legacy_imports.ts index 5cff588d951b04..223c130df3505f 100644 --- a/src/legacy/core_plugins/visualizations/public/legacy_imports.ts +++ b/src/legacy/core_plugins/visualizations/public/legacy_imports.ts @@ -24,9 +24,5 @@ export { IAggConfigs, isDateHistogramBucketAggConfig, setBounds, -} from '../../../ui/public/agg_types'; -export { createFormat } from '../../../ui/public/visualize/loader/pipeline_helpers/utilities'; -export { I18nContext } from '../../../ui/public/i18n'; -import chrome from '../../../ui/public/chrome'; -export { chrome as legacyChrome }; -import '../../../ui/public/directives/bind'; +} from '../../data/public'; +export { createSavedSearchesLoader } from '../../kibana/public/discover/saved_searches/'; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/kibana.json b/src/legacy/core_plugins/visualizations/public/np_ready/kibana.json index 888edde44a2611..d4f9bd327d6aca 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/kibana.json +++ b/src/legacy/core_plugins/visualizations/public/np_ready/kibana.json @@ -3,8 +3,5 @@ "version": "kibana", "server": false, "ui": true, - "requiredPlugins": [ - "data", - "search" - ] + "requiredPlugins": ["data", "search", "expressions", "uiActions"] } diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/_index.scss b/src/legacy/core_plugins/visualizations/public/np_ready/public/_index.scss index d87b6b004a5113..eada763b63c4d4 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/_index.scss +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/_index.scss @@ -1 +1,2 @@ @import 'wizard/index'; +@import 'embeddable/index'; diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/_embeddables.scss b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_embeddables.scss similarity index 100% rename from src/legacy/core_plugins/visualizations/public/embeddable/_embeddables.scss rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_embeddables.scss diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/_index.scss b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_index.scss similarity index 100% rename from src/legacy/core_plugins/visualizations/public/embeddable/_index.scss rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_index.scss diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/_visualize_lab_disabled.scss b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_visualize_lab_disabled.scss similarity index 100% rename from src/legacy/core_plugins/visualizations/public/embeddable/_visualize_lab_disabled.scss rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/_visualize_lab_disabled.scss diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/constants.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/constants.ts similarity index 100% rename from src/legacy/core_plugins/visualizations/public/embeddable/constants.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/constants.ts diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_embeddable.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/disabled_lab_embeddable.tsx similarity index 94% rename from src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_embeddable.tsx rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/disabled_lab_embeddable.tsx index f9dfd5d2b98f41..fbb2eba3afe79a 100644 --- a/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_embeddable.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/disabled_lab_embeddable.tsx @@ -19,7 +19,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Embeddable, EmbeddableOutput } from '../../../../../plugins/embeddable/public'; +import { Embeddable, EmbeddableOutput } from '../../../../../../../plugins/embeddable/public'; import { DisabledLabVisualization } from './disabled_lab_visualization'; import { VisualizeInput } from './visualize_embeddable'; diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_visualization.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/disabled_lab_visualization.tsx similarity index 100% rename from src/legacy/core_plugins/visualizations/public/embeddable/disabled_lab_visualization.tsx rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/disabled_lab_visualization.tsx diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/get_index_pattern.ts similarity index 90% rename from src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/get_index_pattern.ts index cfb2960cfbb7cd..51d839275fd27d 100644 --- a/src/legacy/core_plugins/visualizations/public/embeddable/get_index_pattern.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/get_index_pattern.ts @@ -17,13 +17,13 @@ * under the License. */ -import { VisSavedObject } from './visualize_embeddable'; +import { VisSavedObject } from '../types'; import { indexPatterns, IIndexPattern, IndexPatternAttributes, -} from '../../../../../plugins/data/public'; -import { getUISettings, getSavedObjects } from '../np_ready/public/services'; +} from '../../../../../../../plugins/data/public'; +import { getUISettings, getSavedObjects } from '../services'; export async function getIndexPattern( savedVis: VisSavedObject diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/index.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/index.ts similarity index 92% rename from src/legacy/core_plugins/visualizations/public/embeddable/index.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/index.ts index d7c0205891ec57..a1cd31eebef205 100644 --- a/src/legacy/core_plugins/visualizations/public/embeddable/index.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/index.ts @@ -18,4 +18,5 @@ */ export { DisabledLabEmbeddable } from './disabled_lab_embeddable'; export { VisualizeEmbeddable, VisualizeInput } from './visualize_embeddable'; +export { VisualizeEmbeddableFactory } from './visualize_embeddable_factory'; export { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; diff --git a/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/visualize_embeddable.ts similarity index 90% rename from src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/visualize_embeddable.ts index 32bbae13b79b85..2537caa01cd46d 100644 --- a/src/legacy/core_plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/embeddable/visualize_embeddable.ts @@ -18,13 +18,8 @@ */ import _, { get } from 'lodash'; -import { PersistedState } from 'ui/persisted_state'; import { Subscription } from 'rxjs'; import * as Rx from 'rxjs'; -import { buildPipeline } from 'ui/visualize/loader/pipeline_helpers'; -import { npStart } from 'ui/new_platform'; -import { IExpressionLoaderParams } from 'src/plugins/expressions/public'; -import { EmbeddableVisTriggerContext } from 'src/plugins/embeddable/public'; import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; import { IIndexPattern, @@ -32,9 +27,8 @@ import { Query, esFilters, Filter, - ISearchSource, TimefilterContract, -} from '../../../../../plugins/data/public'; +} from '../../../../../../../plugins/data/public'; import { EmbeddableInput, EmbeddableOutput, @@ -42,27 +36,21 @@ import { Container, selectRangeTrigger, valueClickTrigger, -} from '../../../../../plugins/embeddable/public'; -import { dispatchRenderComplete } from '../../../../../plugins/kibana_utils/public'; -import { SavedObject } from '../../../../../plugins/saved_objects/public'; -import { SavedSearch } from '../../../kibana/public/discover/np_ready/types'; -import { Vis } from '../np_ready/public'; + EmbeddableVisTriggerContext, +} from '../../../../../../../plugins/embeddable/public'; +import { dispatchRenderComplete } from '../../../../../../../plugins/kibana_utils/public'; +import { + IExpressionLoaderParams, + ExpressionsStart, +} from '../../../../../../../plugins/expressions/public'; +import { buildPipeline } from '../legacy/build_pipeline'; +import { Vis } from '../vis'; +import { getExpressions, getUiActions } from '../services'; +import { PersistedState } from '../../../legacy_imports'; +import { VisSavedObject } from '../types'; const getKeys = (o: T): Array => Object.keys(o) as Array; -export interface VisSavedObject extends SavedObject { - vis: Vis; - description?: string; - searchSource: ISearchSource; - title: string; - uiStateJSON?: string; - destroy: () => void; - savedSearchRefName?: string; - savedSearchId?: string; - savedSearch?: SavedSearch; - visState: any; -} - export interface VisualizeEmbeddableConfiguration { savedVisualization: VisSavedObject; indexPatterns?: IIndexPattern[]; @@ -90,7 +78,7 @@ export interface VisualizeOutput extends EmbeddableOutput { visTypeName: string; } -type ExpressionLoader = InstanceType; +type ExpressionLoader = InstanceType; export class VisualizeEmbeddable extends Embeddable { private handler?: ExpressionLoader; @@ -281,7 +269,8 @@ export class VisualizeEmbeddable extends Embeddable { @@ -309,7 +298,9 @@ export class VisualizeEmbeddable extends Embeddable { public readonly type = VISUALIZE_EMBEDDABLE_TYPE; - constructor( - private timefilter: TimefilterContract, - private getSavedVisualizationsLoader: () => SavedVisualizations - ) { + constructor() { super({ savedObjectMetaData: { name: i18n.translate('visualizations.savedObjectName', { defaultMessage: 'Visualization' }), @@ -101,7 +98,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< input: Partial & { id: string }, parent?: Container ): Promise { - const savedVisualizations = this.getSavedVisualizationsLoader(); + const savedVisualizations = getSavedVisualizationsLoader(); try { const visId = savedObject.id as string; @@ -118,7 +115,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< const indexPattern = await getIndexPattern(savedObject); const indexPatterns = indexPattern ? [indexPattern] : []; return new VisualizeEmbeddable( - this.timefilter, + getTimeFilter(), { savedVisualization: savedObject, indexPatterns, @@ -141,7 +138,7 @@ export class VisualizeEmbeddableFactory extends EmbeddableFactory< input: Partial & { id: string }, parent?: Container ): Promise { - const savedVisualizations = this.getSavedVisualizationsLoader(); + const savedVisualizations = getSavedVisualizationsLoader(); try { const savedObject = await savedVisualizations.get(savedObjectId); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/visualization_function.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/visualization_function.ts index f1c1677a60f260..4ac0931c5d8655 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/visualization_function.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/expressions/visualization_function.ts @@ -19,8 +19,11 @@ import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { VisResponseValue } from 'src/plugins/visualizations/public'; -import { ExpressionFunctionDefinition, Render } from 'src/plugins/expressions/public'; +import { VisResponseValue } from '../../../../../../../plugins/visualizations/public'; +import { + ExpressionFunctionDefinition, + Render, +} from '../../../../../../../plugins/expressions/public'; import { PersistedState } from '../../../legacy_imports'; import { getTypes, getIndexPatterns, getFilterManager } from '../services'; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/index.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/index.ts index 3c4a1c1449d475..34ffb698e5f8c7 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/index.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/index.ts @@ -29,22 +29,28 @@ * either types, or static code. */ -import { PluginInitializerContext } from 'src/core/public'; +import { PublicContract } from '@kbn/utility-types'; +import { PluginInitializerContext } from '../../../../../../core/public'; import { VisualizationsPlugin, VisualizationsSetup, VisualizationsStart } from './plugin'; /** @public */ export { VisualizationsSetup, VisualizationsStart }; /** @public types */ -export { VisTypeAlias, VisType } from './types'; +export { VisTypeAlias, VisType } from './vis_types'; +export { VisSavedObject } from './types'; +export { Vis, VisParams, VisState } from './vis'; +import { VisualizeEmbeddableFactory, VisualizeEmbeddable } from './embeddable'; +export type VisualizeEmbeddableFactoryContract = PublicContract; +export type VisualizeEmbeddableContract = PublicContract; export function plugin(initializerContext: PluginInitializerContext) { return new VisualizationsPlugin(initializerContext); } /** @public static code */ -export { Vis, VisParams, VisState } from './vis'; -export { TypesService } from './types/types_service'; +export { TypesService } from './vis_types/types_service'; +export { VISUALIZE_EMBEDDABLE_TYPE, VisualizeInput } from './embeddable'; export { Status } from './legacy/update_status'; export { buildPipeline, buildVislibDimensions, SchemaConfig } from './legacy/build_pipeline'; @@ -52,4 +58,4 @@ export { buildPipeline, buildVislibDimensions, SchemaConfig } from './legacy/bui // @ts-ignore export { updateOldState } from './legacy/vis_update_state'; export { calculateObjectHash } from './legacy/calculate_object_hash'; -export { createSavedVisLoader } from '../../saved_visualizations/saved_visualizations'; +export { createSavedVisLoader } from './saved_visualizations/saved_visualizations'; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts index 41b23b276e88d7..57c686b6e9cb04 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy.ts @@ -17,12 +17,12 @@ * under the License. */ -import { PluginInitializerContext } from 'src/core/public'; - /* eslint-disable @kbn/eslint/no-restricted-paths */ import { npSetup, npStart } from 'ui/new_platform'; /* eslint-enable @kbn/eslint/no-restricted-paths */ +import { PluginInitializerContext } from '../../../../../../core/public'; + import { plugin } from '.'; const pluginInstance = plugin({} as PluginInitializerContext); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/base_vis_type.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/base_vis_type.js index b8aa33d0a5abe8..9c1dfd9780255b 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/base_vis_type.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/base_vis_type.js @@ -19,7 +19,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { BaseVisType } from '../../../types/base_vis_type'; +import { BaseVisType } from '../../../vis_types/base_vis_type'; describe('Base Vis Type', function() { beforeEach(ngMock.module('kibana')); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/react_vis_type.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/react_vis_type.js index c85557ea1b0b09..2474a588704245 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/react_vis_type.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/__tests__/vis_types/react_vis_type.js @@ -19,7 +19,7 @@ import expect from '@kbn/expect'; import ngMock from 'ng_mock'; -import { ReactVisType } from '../../../types/react_vis_type'; +import { ReactVisType } from '../../../vis_types/react_vis_type'; describe('React Vis Type', function() { const visConfig = { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.test.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.test.ts index f73dc3e19d0ef3..1adf6fd23f5a50 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.test.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.test.ts @@ -31,11 +31,6 @@ import { IAggConfig } from '../../../legacy_imports'; import { searchSourceMock } from '../../../legacy_mocks'; jest.mock('ui/new_platform'); -jest.mock('ui/agg_types', () => ({ - setBounds: () => {}, - dateHistogramBucketAgg: () => {}, - isDateHistogramBucketAggConfig: () => true, -})); describe('visualize loader pipeline helpers: build pipeline', () => { describe('prepareJson', () => { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.ts index 025eef834ca86b..155213b4103b03 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/legacy/build_pipeline.ts @@ -18,17 +18,11 @@ */ import { cloneDeep, get } from 'lodash'; -// @ts-ignore import moment from 'moment'; -import { SerializedFieldFormat } from 'src/plugins/expressions/public'; -import { ISearchSource } from 'src/plugins/data/public'; -import { - IAggConfig, - setBounds, - isDateHistogramBucketAggConfig, - createFormat, -} from '../../../legacy_imports'; -import { Vis, VisParams } from '..'; +import { SerializedFieldFormat } from '../../../../../../../plugins/expressions/public'; +import { fieldFormats, ISearchSource } from '../../../../../../../plugins/data/public'; +import { IAggConfig, setBounds, isDateHistogramBucketAggConfig } from '../../../legacy_imports'; +import { Vis, VisParams } from '../types'; interface SchemaConfigParams { precision?: number; @@ -102,7 +96,7 @@ export const getSchemas = (vis: Vis, timeRange?: any): Schemas => { 'max_bucket', ].includes(agg.type.name); - const format = createFormat( + const format = fieldFormats.serialize( hasSubAgg ? agg.params.customMetric || agg.aggConfigs.getRequestAggById(agg.params.metricAgg) : agg diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts index 9fb87cadb29838..b3dd22f62f81f1 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/mocks.ts @@ -23,7 +23,7 @@ jest.mock('ui/vis/vis_factory'); jest.mock('ui/registry/vis_types'); jest.mock('./types/vis_type_alias_registry'); -import { PluginInitializerContext } from 'src/core/public'; +import { PluginInitializerContext } from '../../../../../../core/public'; import { VisualizationsSetup, VisualizationsStart } from './'; import { VisualizationsPlugin } from './plugin'; import { coreMock } from '../../../../../../core/public/mocks'; @@ -31,6 +31,7 @@ import { embeddablePluginMock } from '../../../../../../plugins/embeddable/publi import { expressionsPluginMock } from '../../../../../../plugins/expressions/public/mocks'; import { dataPluginMock } from '../../../../../../plugins/data/public/mocks'; import { usageCollectionPluginMock } from '../../../../../../plugins/usage_collection/public/mocks'; +import { uiActionsPluginMock } from '../../../../../../plugins/ui_actions/public/mocks'; const createSetupContract = (): VisualizationsSetup => ({ types: { @@ -47,7 +48,7 @@ const createStartContract = (): VisualizationsStart => ({ all: jest.fn(), getAliases: jest.fn(), }, - getSavedVisualizationsLoader: jest.fn(), + savedVisualizationsLoader: {} as any, showNewVisModal: jest.fn(), Vis: jest.fn(), }); @@ -64,6 +65,8 @@ const createInstance = async () => { const doStart = () => plugin.start(coreMock.createStart(), { data: dataPluginMock.createStartContract(), + expressions: expressionsPluginMock.createStartContract(), + uiActions: uiActionsPluginMock.createStartContract(), }); return { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts index 20bed59faad88b..e1d87d414d398d 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/plugin.ts @@ -17,8 +17,13 @@ * under the License. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core/public'; -import { TypesService, TypesSetup, TypesStart } from './types'; +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, +} from '../../../../../../core/public'; +import { TypesService, TypesSetup, TypesStart } from './vis_types'; import { setUISettings, setTypes, @@ -29,10 +34,13 @@ import { setSavedObjects, setUsageCollector, setFilterManager, + setExpressions, + setUiActions, + setSavedVisualizationsLoader, + setTimeFilter, } from './services'; -import { VisualizeEmbeddableFactory } from '../../embeddable/visualize_embeddable_factory'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '../../embeddable'; -import { ExpressionsSetup } from '../../../../../../plugins/expressions/public'; +import { VISUALIZE_EMBEDDABLE_TYPE, VisualizeEmbeddableFactory } from './embeddable'; +import { ExpressionsSetup, ExpressionsStart } from '../../../../../../plugins/expressions/public'; import { IEmbeddableSetup } from '../../../../../../plugins/embeddable/public'; import { visualization as visualizationFunction } from './expressions/visualization_function'; import { visualization as visualizationRenderer } from './expressions/visualization_renderer'; @@ -41,13 +49,11 @@ import { DataPublicPluginStart, } from '../../../../../../plugins/data/public'; import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/public'; -import { - createSavedVisLoader, - SavedObjectKibanaServicesWithVisualizations, -} from '../../saved_visualizations'; -import { SavedVisualizations } from '../../../../kibana/public/visualize/np_ready/types'; +import { createSavedVisLoader, SavedVisualizationsLoader } from './saved_visualizations'; import { VisImpl, VisImplConstructor } from './vis_impl'; import { showNewVisModal } from './wizard'; +import { UiActionsStart } from '../../../../../../plugins/ui_actions/public'; + /** * Interface for this plugin's returned setup/start contracts. * @@ -59,9 +65,9 @@ export interface VisualizationsSetup { export interface VisualizationsStart { types: TypesStart; - getSavedVisualizationsLoader: () => SavedVisualizations; - showNewVisModal: typeof showNewVisModal; + savedVisualizationsLoader: SavedVisualizationsLoader; Vis: VisImplConstructor; + showNewVisModal: typeof showNewVisModal; } export interface VisualizationsSetupDeps { @@ -73,6 +79,8 @@ export interface VisualizationsSetupDeps { export interface VisualizationsStartDeps { data: DataPublicPluginStart; + expressions: ExpressionsStart; + uiActions: UiActionsStart; } /** @@ -92,8 +100,6 @@ export class VisualizationsPlugin VisualizationsStartDeps > { private readonly types: TypesService = new TypesService(); - private savedVisualizations?: SavedVisualizations; - private savedVisualizationDependencies?: SavedObjectKibanaServicesWithVisualizations; constructor(initializerContext: PluginInitializerContext) {} @@ -107,10 +113,7 @@ export class VisualizationsPlugin expressions.registerFunction(visualizationFunction); expressions.registerRenderer(visualizationRenderer); - const embeddableFactory = new VisualizeEmbeddableFactory( - data.query.timefilter.timefilter, - this.getSavedVisualizationsLoader - ); + const embeddableFactory = new VisualizeEmbeddableFactory(); embeddable.registerEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, embeddableFactory); return { @@ -118,7 +121,10 @@ export class VisualizationsPlugin }; } - public start(core: CoreStart, { data }: VisualizationsStartDeps): VisualizationsStart { + public start( + core: CoreStart, + { data, expressions, uiActions }: VisualizationsStartDeps + ): VisualizationsStart { const types = this.types.start(); setI18n(core.i18n); setTypes(types); @@ -127,31 +133,27 @@ export class VisualizationsPlugin setSavedObjects(core.savedObjects); setIndexPatterns(data.indexPatterns); setFilterManager(data.query.filterManager); - - this.savedVisualizationDependencies = { + setExpressions(expressions); + setUiActions(uiActions); + setTimeFilter(data.query.timefilter.timefilter); + const savedVisualizationsLoader = createSavedVisLoader({ savedObjectsClient: core.savedObjects.client, indexPatterns: data.indexPatterns, chrome: core.chrome, overlays: core.overlays, visualizationTypes: types, - }; + }); + setSavedVisualizationsLoader(savedVisualizationsLoader); return { types, - getSavedVisualizationsLoader: () => this.getSavedVisualizationsLoader(), showNewVisModal, Vis: VisImpl, + savedVisualizationsLoader, }; } public stop() { this.types.stop(); } - - private getSavedVisualizationsLoader = () => { - if (!this.savedVisualizations) { - this.savedVisualizations = createSavedVisLoader(this.savedVisualizationDependencies!); - } - return this.savedVisualizations; - }; } diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/_saved_vis.ts similarity index 90% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/_saved_vis.ts index f4548da3752165..f3539b3564c563 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/_saved_vis.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/_saved_vis.ts @@ -28,15 +28,13 @@ import { createSavedObjectClass, SavedObject, SavedObjectKibanaServices, -} from '../../../../../plugins/saved_objects/public'; -import { updateOldState } from '../index'; +} from '../../../../../../../plugins/saved_objects/public'; +import { updateOldState } from '../../../index'; import { extractReferences, injectReferences } from './saved_visualization_references'; -import { IIndexPattern } from '../../../../../plugins/data/public'; -import { VisSavedObject } from '../embeddable/visualize_embeddable'; - -import { createSavedSearchesLoader } from '../../../kibana/public/discover'; -import { VisualizeConstants } from '../../../kibana/public/visualize'; -import { VisImpl } from '../np_ready/public/vis_impl'; +import { IIndexPattern } from '../../../../../../../plugins/data/public'; +import { VisSavedObject } from '../types'; +import { VisImpl } from '../vis_impl'; +import { createSavedSearchesLoader } from '../../../legacy_imports'; async function _afterEsResp(savedVis: VisSavedObject, services: any) { await _getLinkedSavedSearch(savedVis, services); @@ -138,7 +136,7 @@ export function createSavedVisClass(services: SavedObjectKibanaServices) { }); this.showInRecentlyAccessed = true; this.getFullPath = () => { - return `/app/kibana#${VisualizeConstants.EDIT_PATH}/${this.id}`; + return `/app/kibana#/visualize/edit/${this.id}`; }; } } diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.test.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.test.ts similarity index 77% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.test.js rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.test.ts index ed0f6dc429ef45..d1def09978dbb7 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.test.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.test.ts @@ -18,19 +18,24 @@ */ import { findListItems } from './find_list_items'; +import { coreMock } from '../../../../../../../core/public/mocks'; +import { SavedObjectsClientContract } from '../../../../../../../core/public'; +import { VisTypeAlias } from '../vis_types'; describe('saved_visualizations', () => { function testProps() { + const savedObjects = coreMock.createStart().savedObjects.client as jest.Mocked< + SavedObjectsClientContract + >; + (savedObjects.find as jest.Mock).mockImplementation(() => ({ + total: 0, + savedObjects: [], + })); return { visTypes: [], search: '', size: 10, - savedObjectsClient: { - find: jest.fn(async () => ({ - total: 0, - savedObjects: [], - })), - }, + savedObjectsClient: savedObjects, mapSavedObjectApiHits: jest.fn(), }; } @@ -60,7 +65,7 @@ describe('saved_visualizations', () => { searchFields: ['baz', 'bing'], }, }, - }, + } as VisTypeAlias, ], }; const { find } = props.savedObjectsClient; @@ -86,7 +91,7 @@ describe('saved_visualizations', () => { searchFields: ['baz', 'bing', 'barfield'], }, }, - }, + } as VisTypeAlias, { appExtensions: { visualizations: { @@ -94,7 +99,7 @@ describe('saved_visualizations', () => { searchFields: ['baz', 'bing', 'foofield'], }, }, - }, + } as VisTypeAlias, ], }; const { find } = props.savedObjectsClient; @@ -128,24 +133,11 @@ describe('saved_visualizations', () => { it('uses type-specific toListItem function, if available', async () => { const props = { ...testProps(), - savedObjectsClient: { - find: jest.fn(async () => ({ - total: 2, - savedObjects: [ - { - id: 'lotr', - type: 'wizard', - attributes: { label: 'Gandalf' }, - }, - { - id: 'wat', - type: 'visualization', - attributes: { title: 'WATEVER' }, - }, - ], - })), - }, - mapSavedObjectApiHits(savedObject) { + mapSavedObjectApiHits(savedObject: { + id: string; + type: string; + attributes: { title: string }; + }) { return { id: savedObject.id, title: `DEFAULT ${savedObject.attributes.title}`, @@ -159,14 +151,31 @@ describe('saved_visualizations', () => { toListItem(savedObject) { return { id: savedObject.id, - title: `${savedObject.attributes.label} THE GRAY`, + title: `${(savedObject.attributes as { label: string }).label} THE GRAY`, }; }, }, }, - }, + } as VisTypeAlias, ], }; + + (props.savedObjectsClient.find as jest.Mock).mockImplementationOnce(async () => ({ + total: 2, + savedObjects: [ + { + id: 'lotr', + type: 'wizard', + attributes: { label: 'Gandalf' }, + }, + { + id: 'wat', + type: 'visualization', + attributes: { title: 'WATEVER' }, + }, + ], + })); + const items = await findListItems(props); expect(items).toEqual({ total: 2, diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.ts similarity index 64% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.js rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.ts index a7fcee67adf722..02db90a762e89f 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/find_list_items.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/find_list_items.ts @@ -18,6 +18,13 @@ */ import _ from 'lodash'; +import { + SavedObjectAttributes, + SavedObjectsClientContract, +} from '../../../../../../../core/public'; +import { SavedObjectLoader } from '../../../../../../../plugins/saved_objects/public'; +import { VisTypeAlias } from '../vis_types'; +import { VisualizationsAppExtension } from '../vis_types/vis_type_alias_registry'; /** * Search for visualizations and convert them into a list display-friendly format. @@ -28,34 +35,42 @@ export async function findListItems({ size, savedObjectsClient, mapSavedObjectApiHits, +}: { + search: string; + size: number; + visTypes: VisTypeAlias[]; + savedObjectsClient: SavedObjectsClientContract; + mapSavedObjectApiHits: SavedObjectLoader['mapSavedObjectApiHits']; }) { - const extensions = _.compact( - visTypes.map(v => v.appExtensions && v.appExtensions.visualizations) - ); + const extensions = visTypes + .map(v => v.appExtensions?.visualizations) + .filter(Boolean) as VisualizationsAppExtension[]; const extensionByType = extensions.reduce((acc, m) => { - return m.docTypes.reduce((_acc, type) => { + return m!.docTypes.reduce((_acc, type) => { acc[type] = m; return acc; }, acc); - }, {}); - const searchOption = (field, ...defaults) => + }, {} as { [visType: string]: VisualizationsAppExtension }); + const searchOption = (field: string, ...defaults: string[]) => _(extensions) .pluck(field) .concat(defaults) .compact() .flatten() .uniq() - .value(); + .value() as string[]; const searchOptions = { type: searchOption('docTypes', 'visualization'), searchFields: searchOption('searchFields', 'title^3', 'description'), search: search ? `${search}*` : undefined, perPage: size, page: 1, - defaultSearchOperator: 'AND', + defaultSearchOperator: 'AND' as 'AND', }; - const { total, savedObjects } = await savedObjectsClient.find(searchOptions); + const { total, savedObjects } = await savedObjectsClient.find( + searchOptions + ); return { total, diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/index.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/index.ts similarity index 100% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/index.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/index.ts diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.test.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.test.ts similarity index 96% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.test.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.test.ts index 6549b317d16346..98af6d99025c21 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.test.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.test.ts @@ -18,7 +18,7 @@ */ import { extractReferences, injectReferences } from './saved_visualization_references'; -import { VisSavedObject } from '../embeddable/visualize_embeddable'; +import { VisSavedObject, VisState } from '../types'; describe('extractReferences', () => { test('extracts nothing if savedSearchId is empty', () => { @@ -128,7 +128,7 @@ Object { id: '1', title: 'test', savedSearchRefName: 'search_0', - visState: { + visState: ({ params: { controls: [ { @@ -140,7 +140,7 @@ Object { }, ], }, - }, + } as unknown) as VisState, } as VisSavedObject; const references = [ { @@ -192,7 +192,7 @@ Object { const context = { id: '1', title: 'test', - visState: { + visState: ({ params: { controls: [ { @@ -201,7 +201,7 @@ Object { }, ], }, - }, + } as unknown) as VisState, } as VisSavedObject; expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( `"Could not find index pattern reference \\"control_0_index_pattern\\""` diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.ts similarity index 95% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.ts index 330f5e2dacd10a..b995d340d44d9e 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualization_references.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualization_references.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { SavedObjectAttributes, SavedObjectReference } from 'kibana/public'; -import { VisSavedObject } from '../embeddable/visualize_embeddable'; +import { SavedObjectAttributes, SavedObjectReference } from '../../../../../../../core/public'; +import { VisSavedObject } from '../types'; export function extractReferences({ attributes, diff --git a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualizations.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualizations.ts similarity index 91% rename from src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualizations.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualizations.ts index 7d0d6a10ff66f3..fc0f77d54059c0 100644 --- a/src/legacy/core_plugins/visualizations/public/saved_visualizations/saved_visualizations.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/saved_visualizations/saved_visualizations.ts @@ -19,18 +19,15 @@ import { SavedObjectLoader, SavedObjectKibanaServices, -} from '../../../../../plugins/saved_objects/public'; - -// @ts-ignore +} from '../../../../../../../plugins/saved_objects/public'; import { findListItems } from './find_list_items'; import { createSavedVisClass } from './_saved_vis'; -import { createVisualizeEditUrl } from '../../../kibana/public/visualize'; -import { TypesStart } from '../np_ready/public/types'; +import { TypesStart } from '../vis_types'; export interface SavedObjectKibanaServicesWithVisualizations extends SavedObjectKibanaServices { visualizationTypes: TypesStart; } - +export type SavedVisualizationsLoader = ReturnType; export function createSavedVisLoader(services: SavedObjectKibanaServicesWithVisualizations) { const { savedObjectsClient, visualizationTypes } = services; @@ -59,7 +56,7 @@ export function createSavedVisLoader(services: SavedObjectKibanaServicesWithVisu source.icon = source.type.icon; source.image = source.type.image; source.typeTitle = source.type.title; - source.editUrl = `#${createVisualizeEditUrl(id)}`; + source.editUrl = `#/visualize/edit/${id}`; return source; }; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts index 433c5c7b6df0dc..a977a4b452bf7f 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/services.ts @@ -23,11 +23,18 @@ import { I18nStart, IUiSettingsClient, SavedObjectsStart, -} from 'src/core/public'; -import { TypesStart } from './types'; +} from '../../../../../../core/public'; +import { TypesStart } from './vis_types'; import { createGetterSetter } from '../../../../../../plugins/kibana_utils/public'; -import { FilterManager, IndexPatternsContract } from '../../../../../../plugins/data/public'; +import { + FilterManager, + IndexPatternsContract, + TimefilterContract, +} from '../../../../../../plugins/data/public'; import { UsageCollectionSetup } from '../../../../../../plugins/usage_collection/public'; +import { ExpressionsStart } from '../../../../../../plugins/expressions/public'; +import { UiActionsStart } from '../../../../../../plugins/ui_actions/public'; +import { SavedVisualizationsLoader } from './saved_visualizations'; export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); @@ -47,6 +54,8 @@ export const [getFilterManager, setFilterManager] = createGetterSetter('TimeFilter'); + export const [getIndexPatterns, setIndexPatterns] = createGetterSetter( 'IndexPatterns' ); @@ -54,3 +63,11 @@ export const [getIndexPatterns, setIndexPatterns] = createGetterSetter( 'UsageCollection' ); + +export const [getExpressions, setExpressions] = createGetterSetter('Expressions'); + +export const [getUiActions, setUiActions] = createGetterSetter('UiActions'); + +export const [getSavedVisualizationsLoader, setSavedVisualizationsLoader] = createGetterSetter< + SavedVisualizationsLoader +>('SavedVisualisationsLoader'); diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/types.ts new file mode 100644 index 00000000000000..d2ca4ffb92eb2b --- /dev/null +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/types.ts @@ -0,0 +1,38 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { SavedObject } from '../../../../../../plugins/saved_objects/public'; +import { Vis, VisState, VisParams, VisualizationController } from './vis'; +import { ISearchSource } from '../../../../../../plugins/data/public/'; +import { SavedSearch } from '../../../../kibana/public/discover/np_ready/types'; + +export { Vis, VisState, VisParams, VisualizationController }; + +export interface VisSavedObject extends SavedObject { + vis: Vis; + description?: string; + searchSource: ISearchSource; + title: string; + uiStateJSON?: string; + destroy: () => void; + savedSearchRefName?: string; + savedSearchId?: string; + savedSearch?: SavedSearch; + visState: VisState; +} diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts index 19375e25a9fb72..990f27dca7556c 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis.ts @@ -17,7 +17,7 @@ * under the License. */ -import { VisType } from './types'; +import { VisType } from './vis_types'; import { IAggConfigs } from '../../legacy_imports'; import { Status } from './legacy/update_status'; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts index f9b7db5c02d937..62b68082e21f87 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_impl.d.ts @@ -18,7 +18,7 @@ */ import { Vis, VisState, VisParams } from './vis'; -import { VisType } from './types'; +import { VisType } from './vis_types'; import { IIndexPattern } from '../../../../../../plugins/data/common'; type InitVisStateType = diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/base_vis_type.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/base_vis_type.js similarity index 95% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/types/base_vis_type.js rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/base_vis_type.js index 351acc48e26766..50ff74cfe9dd35 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/base_vis_type.js +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/base_vis_type.js @@ -19,8 +19,6 @@ import _ from 'lodash'; -import { DefaultEditorController } from '../../../../../vis_default_editor/public'; - export class BaseVisType { constructor(opts = {}) { if (!opts.name) { @@ -47,7 +45,7 @@ export class BaseVisType { }, requestHandler: 'courier', // select one from registry or pass a function responseHandler: 'none', - editor: DefaultEditorController, + editor: null, // no default is provided editorConfig: { collections: {}, // collections used for configuration (list of positions, ...) }, diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/index.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/index.ts similarity index 100% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/types/index.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/index.ts diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/react_vis_type.js b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/react_vis_type.js similarity index 100% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/types/react_vis_type.js rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/react_vis_type.js diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/types_service.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/types_service.ts similarity index 100% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/types/types_service.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/types_service.ts diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/vis_type_alias_registry.ts b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/vis_type_alias_registry.ts similarity index 97% rename from src/legacy/core_plugins/visualizations/public/np_ready/public/types/vis_type_alias_registry.ts rename to src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/vis_type_alias_registry.ts index 97f4798c296d42..12b02ee9e6b32a 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/types/vis_type_alias_registry.ts +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/vis_types/vis_type_alias_registry.ts @@ -27,7 +27,7 @@ interface VisualizationListItem { typeTitle: string; } -interface VisualizationsAppExtension { +export interface VisualizationsAppExtension { docTypes: string[]; searchFields?: string[]; toListItem: (savedObject: { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.test.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.test.tsx index 58f7bc49d1cdb8..2712019e426095 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.test.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.test.tsx @@ -19,9 +19,9 @@ import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { TypesStart, VisType } from '../types'; +import { TypesStart, VisType } from '../vis_types'; import { NewVisModal } from './new_vis_modal'; -import { SavedObjectsStart } from 'kibana/public'; +import { SavedObjectsStart } from '../../../../../../../core/public'; describe('NewVisModal', () => { const { location } = window; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.tsx index b39e8e8926707f..7c10001eddb504 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/new_vis_modal.tsx @@ -23,10 +23,10 @@ import { EuiModal, EuiOverlayMask } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { METRIC_TYPE, UiStatsMetricType } from '@kbn/analytics'; -import { IUiSettingsClient, SavedObjectsStart } from 'kibana/public'; +import { IUiSettingsClient, SavedObjectsStart } from '../../../../../../../core/public'; import { SearchSelection } from './search_selection'; import { TypeSelection } from './type_selection'; -import { TypesStart, VisType, VisTypeAlias } from '../types'; +import { TypesStart, VisType, VisTypeAlias } from '../vis_types'; import { UsageCollectionSetup } from '../../../../../../../plugins/usage_collection/public'; interface TypeSelectionProps { diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/search_selection/search_selection.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/search_selection/search_selection.tsx index 9b3b8a6425e523..f8eb191dd5f925 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/search_selection/search_selection.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/search_selection/search_selection.tsx @@ -21,10 +21,10 @@ import { EuiModalBody, EuiModalHeader, EuiModalHeaderTitle } from '@elastic/eui' import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; -import { IUiSettingsClient, SavedObjectsStart } from 'kibana/public'; +import { IUiSettingsClient, SavedObjectsStart } from '../../../../../../../../core/public'; import { SavedObjectFinderUi } from '../../../../../../../../plugins/saved_objects/public'; -import { VisType } from '../../types'; +import { VisType } from '../../vis_types'; interface SearchSelectionProps { onSearchSelected: (searchId: string, searchType: string) => void; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/new_vis_help.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/new_vis_help.tsx index 5068f43952c4ef..e84314853ba4c7 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/new_vis_help.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/new_vis_help.tsx @@ -21,7 +21,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React, { Fragment } from 'react'; import { EuiText, EuiButton } from '@elastic/eui'; import { VisTypeAliasListEntry } from './type_selection'; -import { VisTypeAlias } from '../../types'; +import { VisTypeAlias } from '../../vis_types'; interface Props { promotedTypes: VisTypeAliasListEntry[]; diff --git a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/type_selection.tsx b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/type_selection.tsx index 574f5b3cccc99a..81dcecfee26131 100644 --- a/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/type_selection.tsx +++ b/src/legacy/core_plugins/visualizations/public/np_ready/public/wizard/type_selection/type_selection.tsx @@ -40,7 +40,7 @@ import { VisTypeAlias } from '../../../../../../visualizations/public'; import { NewVisHelp } from './new_vis_help'; import { VisHelpText } from './vis_help_text'; import { VisTypeIcon } from './vis_type_icon'; -import { VisType, TypesStart } from '../../types'; +import { VisType, TypesStart } from '../../vis_types'; export interface VisTypeListEntry extends VisType { highlighted: boolean; diff --git a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx index da70d9fe895255..275a9da96a2c4d 100644 --- a/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/saved_object_save_modal.tsx @@ -39,7 +39,11 @@ import { FormattedMessage } from '@kbn/i18n/react'; import React from 'react'; import { EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../legacy/core_plugins/visualizations/public/embeddable/constants'; + +// TODO: can't import from '../../../../legacy/core_plugins/visualizations/public/' directly, +// because yarn build:types fails after trying to emit type declarations for whole visualizations plugin +// Bunch of errors like this: 'Return type of exported function has or is using private name 'SavedVis'' +import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../legacy/core_plugins/visualizations/public/np_ready/public/embeddable/constants'; export interface OnSaveProps { newTitle: string; diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts index cc92d864282e74..d9e841092be56b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/expression_types/embeddable_types.ts @@ -6,7 +6,7 @@ // @ts-ignore import { MAP_SAVED_OBJECT_TYPE } from '../../../maps/common/constants'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/visualizations/public/embeddable/constants'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/visualizations/public'; import { SEARCH_EMBEDDABLE_TYPE } from '../../../../../../src/legacy/core_plugins/kibana/public/discover/np_ready/embeddable/constants'; export const EmbeddableTypes: { map: string; search: string; visualization: string } = { diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts index 6ac0d84bc9a731..0315a1f480911b 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/functions/common/saved_visualization.ts @@ -5,7 +5,7 @@ */ import { ExpressionFunctionDefinition } from 'src/plugins/expressions'; -import { VisualizeInput } from 'src/legacy/core_plugins/visualizations/public/embeddable'; +import { VisualizeInput } from 'src/legacy/core_plugins/visualizations/public'; import { EmbeddableTypes, EmbeddableExpressionType, diff --git a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.test.ts b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.test.ts index 93d747537c34c1..8694c0e2c7f9f3 100644 --- a/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.test.ts +++ b/x-pack/legacy/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable_input_to_expression.test.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +jest.mock('ui/new_platform'); import { embeddableInputToExpression } from './embeddable_input_to_expression'; import { SavedMapInput } from '../../functions/common/saved_map'; import { EmbeddableTypes } from '../../expression_types'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index dc97a96d4fcbab..dc8d6343007b84 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2872,7 +2872,6 @@ "visualizations.newVisWizard.title": "新規ビジュアライゼーション", "visualizations.newVisWizard.visTypeAliasDescription": "Visualize外でKibanaアプリケーションを開きます。", "visualizations.newVisWizard.visTypeAliasTitle": "Kibanaアプリケーション", - "visualizations.queryGeohashBounds.unableToGetBoundErrorTitle": "バウンドを取得できませんでした", "visDefaultEditor.aggSelect.aggregationLabel": "集約", "visDefaultEditor.aggSelect.helpLinkLabel": "{aggTitle} のヘルプ", "visDefaultEditor.aggSelect.noCompatibleAggsDescription": "インデックスパターン{indexPatternTitle}には集約可能なフィールドが含まれていません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2532cdb0c4d074..f6ef0140e385e6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2873,7 +2873,6 @@ "visualizations.newVisWizard.title": "新建可视化", "visualizations.newVisWizard.visTypeAliasDescription": "打开 Visualize 外部的 Kibana 应用程序。", "visualizations.newVisWizard.visTypeAliasTitle": "Kibana 应用程序", - "visualizations.queryGeohashBounds.unableToGetBoundErrorTitle": "无法获取边界", "visDefaultEditor.aggSelect.aggregationLabel": "聚合", "visDefaultEditor.aggSelect.helpLinkLabel": "{aggTitle} 帮助", "visDefaultEditor.aggSelect.noCompatibleAggsDescription": "索引模式“{indexPatternTitle}”不包含任何聚合。", From d50031e7215ea66eb1b7e2ee20b2897ae3b9a5b7 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 25 Feb 2020 18:02:40 +0000 Subject: [PATCH 49/73] [ML] Global calendars (#57890) * [ML] Global calendars * updating snapshots * changes based on review * larger spacer * updating jest snapshot --- .../plugins/ml/common/constants/calendars.ts | 7 ++ .../calendars/calendars_selection.tsx | 5 +- .../__snapshots__/new_calendar.test.js.snap | 2 + .../__snapshots__/calendar_form.test.js.snap | 56 ++---------- .../edit/calendar_form/calendar_form.js | 85 ++++++++++++------- .../settings/calendars/edit/new_calendar.js | 42 ++++++--- .../settings/calendars/edit/utils.js | 17 ++-- .../table/__snapshots__/table.test.js.snap | 1 + .../settings/calendars/list/table/table.js | 14 +++ .../server/models/calendar/event_manager.ts | 4 +- .../ml/server/models/job_service/groups.js | 18 ++-- 11 files changed, 148 insertions(+), 103 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/common/constants/calendars.ts diff --git a/x-pack/legacy/plugins/ml/common/constants/calendars.ts b/x-pack/legacy/plugins/ml/common/constants/calendars.ts new file mode 100644 index 00000000000000..1a56257ca13049 --- /dev/null +++ b/x-pack/legacy/plugins/ml/common/constants/calendars.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export const GLOBAL_CALENDAR = '_all'; diff --git a/x-pack/legacy/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx b/x-pack/legacy/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx index 919972186761ac..1e7327552623e5 100644 --- a/x-pack/legacy/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx +++ b/x-pack/legacy/plugins/ml/public/application/jobs/new_job/pages/components/job_details_step/components/additional_section/components/calendars/calendars_selection.tsx @@ -23,6 +23,7 @@ import { JobCreatorContext } from '../../../../../job_creator_context'; import { Description } from './description'; import { ml } from '../../../../../../../../../services/ml_api_service'; import { Calendar } from '../../../../../../../../../../../common/types/calendars'; +import { GLOBAL_CALENDAR } from '../../../../../../../../../../../common/constants/calendars'; export const CalendarsSelection: FC = () => { const { jobCreator, jobCreatorUpdate } = useContext(JobCreatorContext); @@ -35,7 +36,9 @@ export const CalendarsSelection: FC = () => { async function loadCalendars() { setIsLoading(true); - const calendars = await ml.calendars(); + const calendars = (await ml.calendars()).filter( + c => c.job_ids.includes(GLOBAL_CALENDAR) === false + ); setOptions(calendars.map(c => ({ label: c.calendar_id, value: c }))); setSelectedOptions(selectedCalendars.map(c => ({ label: c.calendar_id, value: c }))); setIsLoading(false); diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/__snapshots__/new_calendar.test.js.snap b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/__snapshots__/new_calendar.test.js.snap index 2f5eb596a157b4..21f505cff9aec6 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/__snapshots__/new_calendar.test.js.snap +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/__snapshots__/new_calendar.test.js.snap @@ -22,6 +22,7 @@ exports[`NewCalendar Renders new calendar form 1`] = ` eventsList={Array []} groupIds={Array []} isEdit={false} + isGlobalCalendar={false} isNewCalendarIdValid={true} jobIds={Array []} onCalendarIdChange={[Function]} @@ -30,6 +31,7 @@ exports[`NewCalendar Renders new calendar form 1`] = ` onDescriptionChange={[Function]} onEdit={[Function]} onEventDelete={[Function]} + onGlobalCalendarChange={[Function]} onGroupSelection={[Function]} onJobSelection={[Function]} saving={false} diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap index 0e7db62e44b51b..acce01f1994db2 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/__snapshots__/calendar_form.test.js.snap @@ -84,59 +84,19 @@ exports[`CalendarForm Renders calendar form 1`] = ` value="" /> - - } - labelType="label" - > - - - + } - labelType="label" - > - - + name="switch" + /> diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/calendar_form.js b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/calendar_form.js index fffcdf4c516f8a..62daced72ceb25 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/calendar_form.js +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/calendar_form/calendar_form.js @@ -18,6 +18,7 @@ import { EuiSpacer, EuiText, EuiTitle, + EuiSwitch, } from '@elastic/eui'; import { EventsTable } from '../events_table'; @@ -68,6 +69,8 @@ export const CalendarForm = ({ selectedGroupOptions, selectedJobOptions, showNewEventModal, + isGlobalCalendar, + onGlobalCalendarChange, }) => { const msg = i18n.translate('xpack.ml.calendarsEdit.calendarForm.allowedCharactersDescription', { defaultMessage: @@ -81,7 +84,9 @@ export const CalendarForm = ({ return ( - {!isEdit && ( + {isEdit === true ? ( + + ) : (

@@ -128,39 +133,59 @@ export const CalendarForm = ({ )} - {isEdit && } - - } - > - - - + + } - > - - + checked={isGlobalCalendar} + onChange={onGlobalCalendarChange} + /> + + {isGlobalCalendar === false && ( + <> + + + + } + > + + + + + } + > + + + + )} @@ -240,4 +265,6 @@ CalendarForm.propTypes = { selectedGroupOptions: PropTypes.array.isRequired, selectedJobOptions: PropTypes.array.isRequired, showNewEventModal: PropTypes.func.isRequired, + isGlobalCalendar: PropTypes.bool.isRequired, + onGlobalCalendarChange: PropTypes.func.isRequired, }; diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/new_calendar.js b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/new_calendar.js index 935e67ec05eff1..815d1565d5bc45 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/new_calendar.js +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/new_calendar.js @@ -19,6 +19,7 @@ import { NewEventModal } from './new_event_modal'; import { ImportModal } from './import_modal'; import { ml } from '../../../services/ml_api_service'; import { withKibana } from '../../../../../../../../../src/plugins/kibana_react/public'; +import { GLOBAL_CALENDAR } from '../../../../../common/constants/calendars'; class NewCalendarUI extends Component { static propTypes = { @@ -46,6 +47,7 @@ class NewCalendarUI extends Component { events: [], saving: false, selectedCalendar: undefined, + isGlobalCalendar: false, }; } @@ -65,6 +67,7 @@ class NewCalendarUI extends Component { let eventsList = []; let selectedCalendar; let formCalendarId = ''; + let isGlobalCalendar = false; // Editing existing calendar. if (this.props.calendarId !== undefined) { @@ -74,13 +77,17 @@ class NewCalendarUI extends Component { formCalendarId = selectedCalendar.calendar_id; eventsList = selectedCalendar.events; - selectedCalendar.job_ids.forEach(id => { - if (jobIds.find(jobId => jobId === id)) { - selectedJobOptions.push({ label: id }); - } else if (groupIds.find(groupId => groupId === id)) { - selectedGroupOptions.push({ label: id }); - } - }); + if (selectedCalendar.job_ids.includes(GLOBAL_CALENDAR)) { + isGlobalCalendar = true; + } else { + selectedCalendar.job_ids.forEach(id => { + if (jobIds.find(jobId => jobId === id)) { + selectedJobOptions.push({ label: id }); + } else if (groupIds.find(groupId => groupId === id)) { + selectedGroupOptions.push({ label: id }); + } + }); + } } } @@ -96,6 +103,7 @@ class NewCalendarUI extends Component { selectedJobOptions, selectedGroupOptions, selectedCalendar, + isGlobalCalendar, }); } catch (error) { console.log(error); @@ -181,10 +189,15 @@ class NewCalendarUI extends Component { events, selectedGroupOptions, selectedJobOptions, + isGlobalCalendar, } = this.state; - const jobIds = selectedJobOptions.map(option => option.label); - const groupIds = selectedGroupOptions.map(option => option.label); + const allIds = isGlobalCalendar + ? [GLOBAL_CALENDAR] + : [ + ...selectedJobOptions.map(option => option.label), + ...selectedGroupOptions.map(option => option.label), + ]; // Reduce events to fields expected by api const eventsToSave = events.map(event => ({ @@ -198,7 +211,7 @@ class NewCalendarUI extends Component { calendarId: formCalendarId, description, events: eventsToSave, - job_ids: [...jobIds, ...groupIds], + job_ids: allIds, }; return calendar; @@ -214,6 +227,12 @@ class NewCalendarUI extends Component { })); }; + onGlobalCalendarChange = ({ currentTarget }) => { + this.setState({ + isGlobalCalendar: currentTarget.checked, + }); + }; + onJobSelection = selectedJobOptions => { this.setState({ selectedJobOptions, @@ -295,6 +314,7 @@ class NewCalendarUI extends Component { selectedCalendar, selectedJobOptions, selectedGroupOptions, + isGlobalCalendar, } = this.state; let modal = ''; @@ -351,6 +371,8 @@ class NewCalendarUI extends Component { selectedJobOptions={selectedJobOptions} onCreateGroupOption={this.onCreateGroupOption} showNewEventModal={this.showNewEventModal} + isGlobalCalendar={isGlobalCalendar} + onGlobalCalendarChange={this.onGlobalCalendarChange} /> {modal} diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/utils.js b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/utils.js index e4ab6677accf5b..efc54c181fdc1c 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/utils.js +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/edit/utils.js @@ -73,14 +73,17 @@ function getCalendars() { export function getCalendarSettingsData() { return new Promise(async (resolve, reject) => { try { - const data = await Promise.all([getJobIds(), getGroupIds(), getCalendars()]); + const [jobIds, groupIds, calendars] = await Promise.all([ + getJobIds(), + getGroupIds(), + getCalendars(), + ]); - const formattedData = { - jobIds: data[0], - groupIds: data[1], - calendars: data[2], - }; - resolve(formattedData); + resolve({ + jobIds, + groupIds, + calendars, + }); } catch (error) { console.log(error); reject(error); diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/__snapshots__/table.test.js.snap b/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/__snapshots__/table.test.js.snap index ff74c592b2b0f6..14b65a04ce599d 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/__snapshots__/table.test.js.snap +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/__snapshots__/table.test.js.snap @@ -16,6 +16,7 @@ exports[`CalendarsListTable renders the table with all calendars 1`] = ` Object { "field": "job_ids_string", "name": "Jobs", + "render": [Function], "sortable": true, "truncateText": true, }, diff --git a/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/table.js b/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/table.js index bd1dafcd6c0aaf..be41eabd5ae2d1 100644 --- a/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/table.js +++ b/x-pack/legacy/plugins/ml/public/application/settings/calendars/list/table/table.js @@ -12,6 +12,8 @@ import { EuiButton, EuiLink, EuiInMemoryTable } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { GLOBAL_CALENDAR } from '../../../../../../common/constants/calendars'; + export const CalendarsListTable = ({ calendarsList, onDeleteClick, @@ -52,6 +54,18 @@ export const CalendarsListTable = ({ }), sortable: true, truncateText: true, + render: jobList => { + return jobList === GLOBAL_CALENDAR ? ( + + + + ) : ( + jobList + ); + }, }, { field: 'events_length', diff --git a/x-pack/legacy/plugins/ml/server/models/calendar/event_manager.ts b/x-pack/legacy/plugins/ml/server/models/calendar/event_manager.ts index 19f2eda4661796..488839f68b3fe2 100644 --- a/x-pack/legacy/plugins/ml/server/models/calendar/event_manager.ts +++ b/x-pack/legacy/plugins/ml/server/models/calendar/event_manager.ts @@ -6,6 +6,8 @@ import Boom from 'boom'; +import { GLOBAL_CALENDAR } from '../../../common/constants/calendars'; + export interface CalendarEvent { calendar_id?: string; event_id?: string; @@ -32,7 +34,7 @@ export class EventManager { // jobId is optional async getAllEvents(jobId?: string) { - const calendarId = '_all'; + const calendarId = GLOBAL_CALENDAR; try { const resp = await this._client('ml.events', { calendarId, diff --git a/x-pack/legacy/plugins/ml/server/models/job_service/groups.js b/x-pack/legacy/plugins/ml/server/models/job_service/groups.js index 91f82f04a9a0c4..6fbc071ef9854f 100644 --- a/x-pack/legacy/plugins/ml/server/models/job_service/groups.js +++ b/x-pack/legacy/plugins/ml/server/models/job_service/groups.js @@ -5,6 +5,7 @@ */ import { CalendarManager } from '../calendar'; +import { GLOBAL_CALENDAR } from '../../../common/constants/calendars'; export function groupsProvider(callWithRequest) { const calMngr = new CalendarManager(callWithRequest); @@ -12,11 +13,13 @@ export function groupsProvider(callWithRequest) { async function getAllGroups() { const groups = {}; const jobIds = {}; - const [JOBS, CALENDARS] = [0, 1]; - const results = await Promise.all([callWithRequest('ml.jobs'), calMngr.getAllCalendars()]); + const [{ jobs }, calendars] = await Promise.all([ + callWithRequest('ml.jobs'), + calMngr.getAllCalendars(), + ]); - if (results[JOBS] && results[JOBS].jobs) { - results[JOBS].jobs.forEach(job => { + if (jobs) { + jobs.forEach(job => { jobIds[job.job_id] = null; if (job.groups !== undefined) { job.groups.forEach(g => { @@ -33,10 +36,11 @@ export function groupsProvider(callWithRequest) { } }); } - if (results[CALENDARS]) { - results[CALENDARS].forEach(cal => { + if (calendars) { + calendars.forEach(cal => { cal.job_ids.forEach(jId => { - if (jobIds[jId] === undefined) { + // don't include _all in the calendar groups list + if (jId !== GLOBAL_CALENDAR && jobIds[jId] === undefined) { if (groups[jId] === undefined) { groups[jId] = { id: jId, From 30fb4eb6945a463aeec1211d04854735c3c75281 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 25 Feb 2020 11:50:54 -0700 Subject: [PATCH 50/73] [Maps] remove duplicated pagintation text in locked tooltips (#58383) --- .../__snapshots__/tooltip_header.test.js.snap | 38 ------------------- .../map/features_tooltip/tooltip_header.js | 2 +- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap index 486a830d21b65e..b5fe334f8415e7 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/__snapshots__/tooltip_header.test.js.snap @@ -17,25 +17,6 @@ exports[`TooltipHeader multiple features, multiple layers: locked should show pa pageCount={3} /> - - - - - @@ -139,25 +120,6 @@ exports[`TooltipHeader multiple features, single layer: locked should show pagin pageCount={2} /> - - - - - 1) { + if (!isLocked && filteredFeatures.length > 1) { headerItems.push( From d9e3d744ba83554139c0c4383b2167a577577b29 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 25 Feb 2020 14:21:25 -0500 Subject: [PATCH 51/73] [Maps] Add EPSG-code to docs (#58378) --- docs/setup/settings.asciidoc | 2 +- .../file_upload/public/components/json_index_file_picker.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index c1f06aff722b52..2d4d00b7301099 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -231,7 +231,7 @@ This setting does not impact <> and <> visualizations. Supported on {ece}. Each layer object points to an external vector file that contains a geojson FeatureCollection. The file must use the -https://en.wikipedia.org/wiki/World_Geodetic_System[WGS84 coordinate reference system] +https://en.wikipedia.org/wiki/World_Geodetic_System[WGS84 coordinate reference system (ESPG:4326)] and only include polygons. If the file is hosted on a separate domain from Kibana, the server needs to be CORS-enabled so Kibana can download the file. The following example shows a valid regionmap configuration. diff --git a/x-pack/legacy/plugins/file_upload/public/components/json_index_file_picker.js b/x-pack/legacy/plugins/file_upload/public/components/json_index_file_picker.js index 0ee4f76ebf9d0c..67086883a9a326 100644 --- a/x-pack/legacy/plugins/file_upload/public/components/json_index_file_picker.js +++ b/x-pack/legacy/plugins/file_upload/public/components/json_index_file_picker.js @@ -268,6 +268,10 @@ export class JsonIndexFilePicker extends Component { maxFileSize: bytesToSize(MAX_FILE_SIZE), }} /> +
+ {i18n.translate('xpack.fileUpload.jsonIndexFilePicker.coordinateSystemAccepted', { + defaultMessage: 'Coordinates must be in EPSG:4326 coordinate reference system.', + })}{' '} ) } From 7b4c809fc7b29ffead03daac0363d3701d2f016a Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 25 Feb 2020 13:51:02 -0700 Subject: [PATCH 52/73] Abort cancelled search requests to Elasticsearch (#56788) * Update abort controller library * Bootstrap * Abort when the request is aborted * Add utility and update value suggestions route * Remove bad merge * Revert switching abort controller libraries * Revert package.json in lib * Move to previous abort controller * Fix test to use fake timers to run debounced handlers * Fix loading bar not going away when cancelling * Add test for loading count * Fix test * Fix failing test Co-authored-by: Elastic Machine --- .../search/sync_search_strategy.test.ts | 52 ++++++++++++++++--- .../public/search/sync_search_strategy.ts | 21 ++++---- .../autocomplete/value_suggestions_route.ts | 4 +- .../lib/get_request_aborted_signal.test.ts | 45 ++++++++++++++++ .../server/lib/get_request_aborted_signal.ts | 33 ++++++++++++ src/plugins/data/server/lib/index.ts | 20 +++++++ src/plugins/data/server/search/routes.ts | 5 +- 7 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 src/plugins/data/server/lib/get_request_aborted_signal.test.ts create mode 100644 src/plugins/data/server/lib/get_request_aborted_signal.ts create mode 100644 src/plugins/data/server/lib/index.ts diff --git a/src/plugins/data/public/search/sync_search_strategy.test.ts b/src/plugins/data/public/search/sync_search_strategy.test.ts index 9378e5833f8d73..31a1adfa01c754 100644 --- a/src/plugins/data/public/search/sync_search_strategy.test.ts +++ b/src/plugins/data/public/search/sync_search_strategy.test.ts @@ -35,12 +35,9 @@ describe('Sync search strategy', () => { core: mockCoreStart, getSearchStrategy: jest.fn(), }); - syncSearch.search( - { - serverStrategy: SYNC_SEARCH_STRATEGY, - }, - {} - ); + const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; + syncSearch.search(request, {}); + expect(mockCoreStart.http.fetch.mock.calls[0][0]).toEqual({ path: `/internal/search/${SYNC_SEARCH_STRATEGY}`, body: JSON.stringify({ @@ -50,4 +47,47 @@ describe('Sync search strategy', () => { signal: undefined, }); }); + + it('increments and decrements loading count on success', async () => { + const expectedLoadingCountValues = [0, 1, 0]; + const receivedLoadingCountValues: number[] = []; + + mockCoreStart.http.fetch.mockResolvedValueOnce('response'); + + const syncSearch = syncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn(), + }); + const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; + + const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0]; + loadingCount$.subscribe(value => receivedLoadingCountValues.push(value)); + + await syncSearch.search(request, {}).toPromise(); + + expect(receivedLoadingCountValues).toEqual(expectedLoadingCountValues); + }); + + it('increments and decrements loading count on failure', async () => { + expect.assertions(1); + const expectedLoadingCountValues = [0, 1, 0]; + const receivedLoadingCountValues: number[] = []; + + mockCoreStart.http.fetch.mockRejectedValueOnce('error'); + + const syncSearch = syncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn(), + }); + const request = { serverStrategy: SYNC_SEARCH_STRATEGY }; + + const loadingCount$ = mockCoreStart.http.addLoadingCountSource.mock.calls[0][0]; + loadingCount$.subscribe(value => receivedLoadingCountValues.push(value)); + + try { + await syncSearch.search(request, {}).toPromise(); + } catch (e) { + expect(receivedLoadingCountValues).toEqual(expectedLoadingCountValues); + } + }); }); diff --git a/src/plugins/data/public/search/sync_search_strategy.ts b/src/plugins/data/public/search/sync_search_strategy.ts index c2cc180af546ec..860ce593ae217a 100644 --- a/src/plugins/data/public/search/sync_search_strategy.ts +++ b/src/plugins/data/public/search/sync_search_strategy.ts @@ -18,7 +18,8 @@ */ import { BehaviorSubject, from } from 'rxjs'; -import { IKibanaSearchRequest, IKibanaSearchResponse } from '../../common/search'; +import { finalize } from 'rxjs/operators'; +import { IKibanaSearchRequest } from '../../common/search'; import { ISearch, ISearchOptions } from './i_search'; import { TSearchStrategyProvider, ISearchStrategy, ISearchContext } from './types'; @@ -40,16 +41,14 @@ export const syncSearchStrategyProvider: TSearchStrategyProvider { loadingCount$.next(loadingCount$.getValue() + 1); - const response: Promise = context.core.http.fetch({ - path: `/internal/search/${request.serverStrategy}`, - method: 'POST', - body: JSON.stringify(request), - signal: options.signal, - }); - - response.then(() => loadingCount$.next(loadingCount$.getValue() - 1)); - - return from(response); + return from( + context.core.http.fetch({ + path: `/internal/search/${request.serverStrategy}`, + method: 'POST', + body: JSON.stringify(request), + signal: options.signal, + }) + ).pipe(finalize(() => loadingCount$.next(loadingCount$.getValue() - 1))); }; return { search }; diff --git a/src/plugins/data/server/autocomplete/value_suggestions_route.ts b/src/plugins/data/server/autocomplete/value_suggestions_route.ts index f032890e98901b..02a5e0921fe4f3 100644 --- a/src/plugins/data/server/autocomplete/value_suggestions_route.ts +++ b/src/plugins/data/server/autocomplete/value_suggestions_route.ts @@ -23,6 +23,7 @@ import { IRouter } from 'kibana/server'; import { IFieldType, Filter } from '../index'; import { findIndexPatternById, getFieldByName } from '../index_patterns'; +import { getRequestAbortedSignal } from '../lib'; export function registerValueSuggestionsRoute(router: IRouter) { router.post( @@ -50,6 +51,7 @@ export function registerValueSuggestionsRoute(router: IRouter) { const { field: fieldName, query, boolFilter } = request.body; const { index } = request.params; const { dataClient } = context.core.elasticsearch; + const signal = getRequestAbortedSignal(request.events.aborted$); const autocompleteSearchOptions = { timeout: await uiSettings.get('kibana.autocompleteTimeout'), @@ -62,7 +64,7 @@ export function registerValueSuggestionsRoute(router: IRouter) { const body = await getBody(autocompleteSearchOptions, field || fieldName, query, boolFilter); try { - const result = await dataClient.callAsCurrentUser('search', { index, body }); + const result = await dataClient.callAsCurrentUser('search', { index, body }, { signal }); const buckets: any[] = get(result, 'aggregations.suggestions.buckets') || diff --git a/src/plugins/data/server/lib/get_request_aborted_signal.test.ts b/src/plugins/data/server/lib/get_request_aborted_signal.test.ts new file mode 100644 index 00000000000000..3c1e20dbcb1581 --- /dev/null +++ b/src/plugins/data/server/lib/get_request_aborted_signal.test.ts @@ -0,0 +1,45 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Subject } from 'rxjs'; +import { getRequestAbortedSignal } from './get_request_aborted_signal'; + +describe('abortableRequestHandler', () => { + jest.useFakeTimers(); + + it('should call abort if disconnected', () => { + const abortedSubject = new Subject(); + const aborted$ = abortedSubject.asObservable(); + const onAborted = jest.fn(); + + const signal = getRequestAbortedSignal(aborted$); + signal.addEventListener('abort', onAborted); + + // Shouldn't be aborted or call onAborted prior to disconnecting + expect(signal.aborted).toBe(false); + expect(onAborted).not.toBeCalled(); + + abortedSubject.next(); + jest.runAllTimers(); + + // Should be aborted and call onAborted after disconnecting + expect(signal.aborted).toBe(true); + expect(onAborted).toBeCalled(); + }); +}); diff --git a/src/plugins/data/server/lib/get_request_aborted_signal.ts b/src/plugins/data/server/lib/get_request_aborted_signal.ts new file mode 100644 index 00000000000000..d1541f1df93846 --- /dev/null +++ b/src/plugins/data/server/lib/get_request_aborted_signal.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Observable } from 'rxjs'; +// @ts-ignore not typed +import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill'; + +/** + * A simple utility function that returns an `AbortSignal` corresponding to an `AbortController` + * which aborts when the given request is aborted. + * @param aborted$ The observable of abort events (usually `request.events.aborted$`) + */ +export function getRequestAbortedSignal(aborted$: Observable): AbortSignal { + const controller = new AbortController(); + aborted$.subscribe(() => controller.abort()); + return controller.signal; +} diff --git a/src/plugins/data/server/lib/index.ts b/src/plugins/data/server/lib/index.ts new file mode 100644 index 00000000000000..a2af456846e146 --- /dev/null +++ b/src/plugins/data/server/lib/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { getRequestAbortedSignal } from './get_request_aborted_signal'; diff --git a/src/plugins/data/server/search/routes.ts b/src/plugins/data/server/search/routes.ts index 6f726771c41b2f..11879d14931ae8 100644 --- a/src/plugins/data/server/search/routes.ts +++ b/src/plugins/data/server/search/routes.ts @@ -19,6 +19,7 @@ import { schema } from '@kbn/config-schema'; import { IRouter } from '../../../../core/server'; +import { getRequestAbortedSignal } from '../lib'; export function registerSearchRoute(router: IRouter): void { router.post( @@ -35,8 +36,10 @@ export function registerSearchRoute(router: IRouter): void { async (context, request, res) => { const searchRequest = request.body; const strategy = request.params.strategy; + const signal = getRequestAbortedSignal(request.events.aborted$); + try { - const response = await context.search!.search(searchRequest, {}, strategy); + const response = await context.search!.search(searchRequest, { signal }, strategy); return res.ok({ body: response }); } catch (err) { return res.customError({ From ca5fb7fb01256861cca9d897e628f11a17bc68fb Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Tue, 25 Feb 2020 15:56:28 -0500 Subject: [PATCH 53/73] Use links instead of click handlers when switching spaces (#57730) * use links instead of click handlers when switching spaces * remove unused imports * remove use of deprecated injectedMetadata service * simplify SpacesManager constructor Co-authored-by: Elastic Machine --- x-pack/plugins/spaces/common/index.ts | 2 +- .../nav_control/components/spaces_menu.tsx | 6 ++--- .../spaces/public/nav_control/nav_control.tsx | 1 + .../nav_control/nav_control_popover.test.tsx | 2 ++ .../nav_control/nav_control_popover.tsx | 7 ++--- x-pack/plugins/spaces/public/plugin.tsx | 3 +-- .../components/space_card.test.tsx | 27 ++++++++++++++----- .../space_selector/components/space_card.tsx | 9 ++++--- .../components/space_cards.test.tsx | 2 +- .../space_selector/components/space_cards.tsx | 12 +++------ .../space_selector/space_selector.test.tsx | 8 ++++-- .../public/space_selector/space_selector.tsx | 7 ++--- .../space_selector/space_selector_app.tsx | 5 +++- .../spaces_manager/spaces_manager.mock.ts | 1 - .../spaces_manager/spaces_manager.test.ts | 12 ++++----- .../public/spaces_manager/spaces_manager.ts | 12 ++++----- 16 files changed, 62 insertions(+), 54 deletions(-) diff --git a/x-pack/plugins/spaces/common/index.ts b/x-pack/plugins/spaces/common/index.ts index c1f0f8bd3ece41..703722fcf8f52c 100644 --- a/x-pack/plugins/spaces/common/index.ts +++ b/x-pack/plugins/spaces/common/index.ts @@ -5,5 +5,5 @@ */ export { isReservedSpace } from './is_reserved_space'; -export { MAX_SPACE_INITIALS, SPACE_SEARCH_COUNT_THRESHOLD } from './constants'; +export { MAX_SPACE_INITIALS, SPACE_SEARCH_COUNT_THRESHOLD, ENTER_SPACE_PATH } from './constants'; export { addSpaceIdToPath, getSpaceIdFromPath } from './lib/spaces_url_parser'; diff --git a/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx b/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx index 59656333f865ef..cdfbc9bbe2683b 100644 --- a/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx +++ b/x-pack/plugins/spaces/public/nav_control/components/spaces_menu.tsx @@ -14,7 +14,7 @@ import { import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React, { Component, ReactElement } from 'react'; import { Capabilities, ApplicationStart } from 'src/core/public'; -import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../common/constants'; +import { addSpaceIdToPath, SPACE_SEARCH_COUNT_THRESHOLD, ENTER_SPACE_PATH } from '../../../common'; import { Space } from '../../../common/model/space'; import { ManageSpacesButton } from './manage_spaces_button'; import { SpaceAvatar } from '../../space_avatar'; @@ -23,7 +23,7 @@ interface Props { id: string; spaces: Space[]; isLoading: boolean; - onSelectSpace: (space: Space) => void; + serverBasePath: string; onManageSpacesClick: () => void; intl: InjectedIntl; capabilities: Capabilities; @@ -184,7 +184,7 @@ class SpacesMenuUI extends Component { diff --git a/x-pack/plugins/spaces/public/nav_control/nav_control.tsx b/x-pack/plugins/spaces/public/nav_control/nav_control.tsx index 53d7038cec4d57..4d7af256822c83 100644 --- a/x-pack/plugins/spaces/public/nav_control/nav_control.tsx +++ b/x-pack/plugins/spaces/public/nav_control/nav_control.tsx @@ -23,6 +23,7 @@ export function initSpacesNavControl(spacesManager: SpacesManager, core: CoreSta { const wrapper = shallow( { const wrapper = mountWithIntl( { id={popoutContentId} spaces={this.state.spaces} isLoading={this.state.loading} - onSelectSpace={this.onSelectSpace} + serverBasePath={this.props.serverBasePath} onManageSpacesClick={this.toggleSpaceSelector} capabilities={this.props.capabilities} navigateToApp={this.props.navigateToApp} @@ -175,8 +176,4 @@ export class NavControlPopover extends Component { showSpaceSelector: false, }); }; - - private onSelectSpace = (space: Space) => { - this.props.spacesManager.changeSelectedSpace(space); - }; } diff --git a/x-pack/plugins/spaces/public/plugin.tsx b/x-pack/plugins/spaces/public/plugin.tsx index 73dae84c1873bd..44215ec5380025 100644 --- a/x-pack/plugins/spaces/public/plugin.tsx +++ b/x-pack/plugins/spaces/public/plugin.tsx @@ -43,8 +43,7 @@ export class SpacesPlugin implements Plugin { const space = { @@ -16,21 +17,33 @@ test('it renders without crashing', () => { disabledFeatures: [], }; - shallow(); + shallow(); }); -test('it is clickable', () => { +test('links to the indicated space', () => { const space = { - id: '', + id: 'some-space', name: 'space name', description: 'space description', disabledFeatures: [], }; - const clickHandler = jest.fn(); + const wrapper = mount(); + expect(wrapper.find(EuiCard).props()).toMatchObject({ + href: '/server-base-path/s/some-space/spaces/enter', + }); +}); - const wrapper = mount(); - wrapper.find('button').simulate('click'); +test('links to the default space too', () => { + const space = { + id: 'default', + name: 'default space', + description: 'space description', + disabledFeatures: [], + }; - expect(clickHandler).toHaveBeenCalledTimes(1); + const wrapper = mount(); + expect(wrapper.find(EuiCard).props()).toMatchObject({ + href: '/server-base-path/spaces/enter', + }); }); diff --git a/x-pack/plugins/spaces/public/space_selector/components/space_card.tsx b/x-pack/plugins/spaces/public/space_selector/components/space_card.tsx index f898ba87c60bd6..7a056427fb166e 100644 --- a/x-pack/plugins/spaces/public/space_selector/components/space_card.tsx +++ b/x-pack/plugins/spaces/public/space_selector/components/space_card.tsx @@ -6,15 +6,16 @@ import { EuiCard } from '@elastic/eui'; import React from 'react'; -import { Space } from '../../../common/model/space'; +import { addSpaceIdToPath, ENTER_SPACE_PATH } from '../../../common'; import { SpaceAvatar } from '../../space_avatar'; +import { Space } from '../..'; interface Props { space: Space; - onClick: () => void; + serverBasePath: string; } export const SpaceCard = (props: Props) => { - const { space, onClick } = props; + const { serverBasePath, space } = props; return ( { icon={renderSpaceAvatar(space)} title={space.name} description={renderSpaceDescription(space)} - onClick={onClick} + href={addSpaceIdToPath(serverBasePath, space.id, ENTER_SPACE_PATH)} /> ); }; diff --git a/x-pack/plugins/spaces/public/space_selector/components/space_cards.test.tsx b/x-pack/plugins/spaces/public/space_selector/components/space_cards.test.tsx index 07b85114e3c8f2..8de22bcbe235f9 100644 --- a/x-pack/plugins/spaces/public/space_selector/components/space_cards.test.tsx +++ b/x-pack/plugins/spaces/public/space_selector/components/space_cards.test.tsx @@ -16,5 +16,5 @@ test('it renders without crashing', () => { disabledFeatures: [], }; - shallow(); + shallow(); }); diff --git a/x-pack/plugins/spaces/public/space_selector/components/space_cards.tsx b/x-pack/plugins/spaces/public/space_selector/components/space_cards.tsx index 7c4084d36b21dc..b480cf524304f5 100644 --- a/x-pack/plugins/spaces/public/space_selector/components/space_cards.tsx +++ b/x-pack/plugins/spaces/public/space_selector/components/space_cards.tsx @@ -11,7 +11,7 @@ import { SpaceCard } from './space_card'; interface Props { spaces: Space[]; - onSpaceSelect: (space: Space) => void; + serverBasePath: string; } export class SpaceCards extends Component { @@ -25,15 +25,9 @@ export class SpaceCards extends Component { ); } - public renderSpace = (space: Space) => ( + private renderSpace = (space: Space) => ( - + ); - - public createSpaceClickHandler = (space: Space) => { - return () => { - this.props.onSpaceSelect(space); - }; - }; } diff --git a/x-pack/plugins/spaces/public/space_selector/space_selector.test.tsx b/x-pack/plugins/spaces/public/space_selector/space_selector.test.tsx index c8173de1661be7..112a8a9a0a6857 100644 --- a/x-pack/plugins/spaces/public/space_selector/space_selector.test.tsx +++ b/x-pack/plugins/spaces/public/space_selector/space_selector.test.tsx @@ -18,7 +18,9 @@ function getSpacesManager(spaces: Space[] = []) { test('it renders without crashing', () => { const spacesManager = getSpacesManager(); - const component = shallowWithIntl(); + const component = shallowWithIntl( + + ); expect(component).toMatchSnapshot(); }); @@ -34,7 +36,9 @@ test('it queries for spaces when loaded', () => { const spacesManager = getSpacesManager(spaces); - shallowWithIntl(); + shallowWithIntl( + + ); return Promise.resolve().then(() => { expect(spacesManager.getSpaces).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/spaces/public/space_selector/space_selector.tsx b/x-pack/plugins/spaces/public/space_selector/space_selector.tsx index b63de399b95c99..9289784b9f95f0 100644 --- a/x-pack/plugins/spaces/public/space_selector/space_selector.tsx +++ b/x-pack/plugins/spaces/public/space_selector/space_selector.tsx @@ -30,6 +30,7 @@ import { SpacesManager } from '../spaces_manager'; interface Props { spacesManager: SpacesManager; + serverBasePath: string; } interface State { @@ -129,7 +130,7 @@ export class SpaceSelector extends Component { {this.state.loading && } {!this.state.loading && ( - + )} {!this.state.loading && filteredSpaces.length === 0 && ( @@ -179,10 +180,6 @@ export class SpaceSelector extends Component { searchTerm: searchTerm.trim().toLowerCase(), }); }; - - public onSelectSpace = (space: Space) => { - this.props.spacesManager.changeSelectedSpace(space); - }; } export const renderSpaceSelectorApp = (i18nStart: CoreStart['i18n'], el: Element, props: Props) => { diff --git a/x-pack/plugins/spaces/public/space_selector/space_selector_app.tsx b/x-pack/plugins/spaces/public/space_selector/space_selector_app.tsx index 29ead8d34994de..6fab1767e4b6d3 100644 --- a/x-pack/plugins/spaces/public/space_selector/space_selector_app.tsx +++ b/x-pack/plugins/spaces/public/space_selector/space_selector_app.tsx @@ -29,7 +29,10 @@ export const spaceSelectorApp = Object.freeze({ getStartServices(), import('./space_selector'), ]); - return renderSpaceSelectorApp(coreStart.i18n, params.element, { spacesManager }); + return renderSpaceSelectorApp(coreStart.i18n, params.element, { + spacesManager, + serverBasePath: coreStart.http.basePath.serverBasePath, + }); }, }); }, diff --git a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.mock.ts b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.mock.ts index 56879af33916fc..6186ac7fd93be6 100644 --- a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.mock.ts +++ b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.mock.ts @@ -20,7 +20,6 @@ function createSpacesManagerMock() { copySavedObjects: jest.fn().mockResolvedValue(undefined), resolveCopySavedObjectsErrors: jest.fn().mockResolvedValue(undefined), redirectToSpaceSelector: jest.fn().mockResolvedValue(undefined), - changeSelectedSpace: jest.fn(), } as unknown) as jest.Mocked; } diff --git a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.test.ts b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.test.ts index f89bfc32a69e63..508669361c23ff 100644 --- a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.test.ts +++ b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.test.ts @@ -12,14 +12,14 @@ describe('SpacesManager', () => { describe('#constructor', () => { it('attempts to retrieve the active space', () => { const coreStart = coreMock.createStart(); - new SpacesManager('/server-base-path', coreStart.http); + new SpacesManager(coreStart.http); expect(coreStart.http.get).toHaveBeenCalledWith('/internal/spaces/_active_space'); }); it('does not retrieve the active space if on an anonymous path', () => { const coreStart = coreMock.createStart(); coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); - new SpacesManager('/server-base-path', coreStart.http); + new SpacesManager(coreStart.http); expect(coreStart.http.get).not.toHaveBeenCalled(); }); }); @@ -31,7 +31,7 @@ describe('SpacesManager', () => { id: 'my-space', name: 'my space', }); - const spacesManager = new SpacesManager('/server-base-path', coreStart.http); + const spacesManager = new SpacesManager(coreStart.http); expect(coreStart.http.get).toHaveBeenCalledWith('/internal/spaces/_active_space'); await nextTick(); @@ -47,7 +47,7 @@ describe('SpacesManager', () => { it('throws if on an anonymous path', () => { const coreStart = coreMock.createStart(); coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true); - const spacesManager = new SpacesManager('/server-base-path', coreStart.http); + const spacesManager = new SpacesManager(coreStart.http); expect(coreStart.http.get).not.toHaveBeenCalled(); expect(() => spacesManager.getActiveSpace()).toThrowErrorMatchingInlineSnapshot( @@ -67,7 +67,7 @@ describe('SpacesManager', () => { name: 'my other space', }); - const spacesManager = new SpacesManager('/server-base-path', coreStart.http); + const spacesManager = new SpacesManager(coreStart.http); expect(coreStart.http.get).toHaveBeenCalledWith('/internal/spaces/_active_space'); await nextTick(); @@ -95,7 +95,7 @@ describe('SpacesManager', () => { name: 'my space', }); - const spacesManager = new SpacesManager('/server-base-path', coreStart.http); + const spacesManager = new SpacesManager(coreStart.http); expect(() => spacesManager.getActiveSpace({ forceRefresh: true }) diff --git a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.ts b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.ts index e151dcd4f9368d..cc3f51b1850def 100644 --- a/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.ts +++ b/x-pack/plugins/spaces/public/spaces_manager/spaces_manager.ts @@ -9,16 +9,18 @@ import { HttpSetup } from 'src/core/public'; import { SavedObjectsManagementRecord } from 'src/legacy/core_plugins/management/public'; import { Space } from '../../common/model/space'; import { GetSpacePurpose } from '../../common/model/types'; -import { ENTER_SPACE_PATH } from '../../common/constants'; import { CopySavedObjectsToSpaceResponse } from '../copy_saved_objects_to_space/types'; -import { addSpaceIdToPath } from '../../common'; export class SpacesManager { private activeSpace$: BehaviorSubject = new BehaviorSubject(null); + private readonly serverBasePath: string; + public readonly onActiveSpaceChange$: Observable; - constructor(private readonly serverBasePath: string, private readonly http: HttpSetup) { + constructor(private readonly http: HttpSetup) { + this.serverBasePath = http.basePath.serverBasePath; + this.onActiveSpaceChange$ = this.activeSpace$ .asObservable() .pipe(skipWhile((v: Space | null) => v == null)) as Observable; @@ -99,10 +101,6 @@ export class SpacesManager { }); } - public async changeSelectedSpace(space: Space) { - window.location.href = addSpaceIdToPath(this.serverBasePath, space.id, ENTER_SPACE_PATH); - } - public redirectToSpaceSelector() { window.location.href = `${this.serverBasePath}/spaces/space_selector`; } From 0e2363615d62e0e27cf8bcce053a5ea80b6acf2e Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 25 Feb 2020 13:59:04 -0700 Subject: [PATCH 54/73] Fix flaky jest test (#58402) * Revert "Temporarily removes kbn-optimizer cache key tests (#58318)" This reverts commit e64eff0a3d5fde205256ab74b731a63766822f9a. * [kbn-optmizer] avoid mocking fs exports * overwrite ciGroup script to support jest in flaky testing job * limit jest workers to 3 so that concurrent runners have space to operate * Revert "limit jest workers to 3 so that concurrent runners have space to operate" This reverts commit 1a2f882f6d0b37366b0accc6dbb8bc2b42a5fc3f. * Revert "overwrite ciGroup script to support jest in flaky testing job" This reverts commit 548db6172213858691c3b93dc77cb8fd48d4fc3c. --- .../src/optimizer/cache_keys.test.ts | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 packages/kbn-optimizer/src/optimizer/cache_keys.test.ts diff --git a/packages/kbn-optimizer/src/optimizer/cache_keys.test.ts b/packages/kbn-optimizer/src/optimizer/cache_keys.test.ts new file mode 100644 index 00000000000000..7750f9145667e9 --- /dev/null +++ b/packages/kbn-optimizer/src/optimizer/cache_keys.test.ts @@ -0,0 +1,208 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Path from 'path'; + +import jestDiff from 'jest-diff'; +import { REPO_ROOT, createAbsolutePathSerializer } from '@kbn/dev-utils'; + +import { reformatJestDiff, getOptimizerCacheKey, diffCacheKey } from './cache_keys'; +import { OptimizerConfig } from './optimizer_config'; + +jest.mock('./get_changes.ts', () => ({ + getChanges: async () => + new Map([ + ['/foo/bar/a', 'modified'], + ['/foo/bar/b', 'modified'], + ['/foo/bar/c', 'deleted'], + ]), +})); + +jest.mock('./get_mtimes.ts', () => ({ + getMtimes: async (paths: string[]) => new Map(paths.map(path => [path, 12345])), +})); + +jest.mock('execa'); + +jest.mock('fs', () => { + const realFs = jest.requireActual('fs'); + return { + ...realFs, + readFile: jest.fn(realFs.readFile), + }; +}); + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +jest.requireMock('execa').mockImplementation(async (cmd: string, args: string[], opts: object) => { + expect(cmd).toBe('git'); + expect(args).toEqual([ + 'log', + '-n', + '1', + '--pretty=format:%H', + '--', + expect.stringContaining('kbn-optimizer'), + ]); + expect(opts).toEqual({ + cwd: REPO_ROOT, + }); + + return { + stdout: '', + }; +}); + +describe('getOptimizerCacheKey()', () => { + it('uses latest commit, bootstrap cache, and changed files to create unique value', async () => { + jest + .requireMock('fs') + .readFile.mockImplementation( + (path: string, enc: string, cb: (err: null, file: string) => void) => { + expect(path).toBe( + Path.resolve(REPO_ROOT, 'packages/kbn-optimizer/target/.bootstrap-cache') + ); + expect(enc).toBe('utf8'); + cb(null, ''); + } + ); + + const config = OptimizerConfig.create({ + repoRoot: REPO_ROOT, + }); + + await expect(getOptimizerCacheKey(config)).resolves.toMatchInlineSnapshot(` + Object { + "bootstrap": "", + "deletedPaths": Array [ + "/foo/bar/c", + ], + "lastCommit": "", + "modifiedTimes": Object { + "/foo/bar/a": 12345, + "/foo/bar/b": 12345, + }, + "workerConfig": Object { + "browserslistEnv": "dev", + "cache": true, + "dist": false, + "optimizerCacheKey": "♻", + "profileWebpack": false, + "repoRoot": , + "watch": false, + }, + } + `); + }); +}); + +describe('diffCacheKey()', () => { + it('returns undefined if values are equal', () => { + expect(diffCacheKey('1', '1')).toBe(undefined); + expect(diffCacheKey(1, 1)).toBe(undefined); + expect(diffCacheKey(['1', '2', { a: 'b' }], ['1', '2', { a: 'b' }])).toBe(undefined); + expect( + diffCacheKey( + { + a: '1', + b: '2', + }, + { + b: '2', + a: '1', + } + ) + ).toBe(undefined); + }); + + it('returns a diff if the values are different', () => { + expect(diffCacheKey(['1', '2', { a: 'b' }], ['1', '2', { b: 'a' }])).toMatchInlineSnapshot(` + "- Expected + + Received + +  Array [ +  \\"1\\", +  \\"2\\", +  Object { + - \\"a\\": \\"b\\", + + \\"b\\": \\"a\\", +  }, +  ]" + `); + expect( + diffCacheKey( + { + a: '1', + b: '1', + }, + { + b: '2', + a: '2', + } + ) + ).toMatchInlineSnapshot(` + "- Expected + + Received + +  Object { + - \\"a\\": \\"1\\", + - \\"b\\": \\"1\\", + + \\"a\\": \\"2\\", + + \\"b\\": \\"2\\", +  }" + `); + }); +}); + +describe('reformatJestDiff()', () => { + it('reformats large jestDiff output to focus on the changed lines', () => { + const diff = jestDiff( + { + a: ['1', '1', '1', '1', '1', '1', '1', '2', '1', '1', '1', '1', '1', '1', '1', '1', '1'], + }, + { + b: ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '1', '1', '1', '1'], + } + ); + + expect(reformatJestDiff(diff)).toMatchInlineSnapshot(` + "- Expected + + Received + +  Object { + - \\"a\\": Array [ + + \\"b\\": Array [ +  \\"1\\", +  \\"1\\", +  ... +  \\"1\\", +  \\"1\\", + - \\"2\\", +  \\"1\\", +  \\"1\\", +  ... +  \\"1\\", +  \\"1\\", + + \\"2\\", +  \\"1\\", +  \\"1\\", +  ..." + `); + }); +}); From 2501919a8a191cc127973b3789bf588229e2071c Mon Sep 17 00:00:00 2001 From: Ryland Herrick Date: Tue, 25 Feb 2020 15:33:49 -0600 Subject: [PATCH 55/73] Remove support of HEAD request in signals index route (#58489) Until these are officially supported in new platform, it's best to not rely on this behavior. We can achieve roughly the same functionality with a GET request. Modifies the existing script accordingly, in case anyone's still using it. Co-authored-by: Elastic Machine --- .../routes/index/read_index_route.ts | 25 ++++++------------- .../scripts/signal_index_exists.sh | 4 +-- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/index/read_index_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/index/read_index_route.ts index 41be42f7c0fe1a..26a6c790ceef93 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/index/read_index_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/index/read_index_route.ts @@ -36,25 +36,14 @@ export const createReadIndexRoute = ( const indexExists = await getIndexExists(callCluster, index); if (indexExists) { - // head request is used for if you want to get if the index exists - // or not and it will return a content-length: 0 along with either a 200 or 404 - // depending on if the index exists or not. - if (request.method.toLowerCase() === 'head') { - return headers.response().code(200); - } else { - return headers.response({ name: index }).code(200); - } + return headers.response({ name: index }).code(200); } else { - if (request.method.toLowerCase() === 'head') { - return headers.response().code(404); - } else { - return headers - .response({ - message: 'index for this space does not exist', - status_code: 404, - }) - .code(404); - } + return headers + .response({ + message: 'index for this space does not exist', + status_code: 404, + }) + .code(404); } } catch (err) { const error = transformError(err); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signal_index_exists.sh b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signal_index_exists.sh index b4a494a102b542..ec3e0595c7b089 100755 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signal_index_exists.sh +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/signal_index_exists.sh @@ -10,7 +10,7 @@ set -e ./check_env_variables.sh # Example: ./signal_index_exists.sh -curl -s -k --head \ +curl -s -k -f \ -H 'Content-Type: application/json' \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ - ${KIBANA_URL}${SPACE_URL}/api/detection_engine/index + ${KIBANA_URL}${SPACE_URL}/api/detection_engine/index > /dev/null From 87f6cd115252e4fa6914c1fc767ab58650c3e253 Mon Sep 17 00:00:00 2001 From: Andrew Cholakian Date: Tue, 25 Feb 2020 16:40:06 -0600 Subject: [PATCH 56/73] [Uptime] Show only total in snapshot heading (#58376) This fixes a number of design issues. Fixes https://github.com/elastic/kibana/issues/58372 --- .../__snapshots__/snapshot.test.tsx.snap | 1 - .../snapshot_heading.test.tsx.snap | 12 ++++-- .../__tests__/snapshot_heading.test.tsx | 6 +-- .../__snapshots__/chart_wrapper.test.tsx.snap | 2 - .../charts/__tests__/chart_wrapper.test.tsx | 8 ++-- .../public/components/functional/snapshot.tsx | 7 ++-- .../functional/snapshot_heading.tsx | 39 ++++++------------- .../translations/translations/ja-JP.json | 3 -- .../translations/translations/zh-CN.json | 3 -- 9 files changed, 31 insertions(+), 50 deletions(-) diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap index ebbd8a4ac56a83..db41dfb0b04c45 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/__snapshots__/snapshot.test.tsx.snap @@ -5,7 +5,6 @@ exports[`Snapshot component renders without errors 1`] = ` loading={false} >

- All monitors are up + 23 + + Monitors

`; @@ -15,7 +17,9 @@ exports[`SnapshotHeading renders custom heading for no monitors 1`] = ` size="s" >

- No monitors found + 0 + + Monitors

`; @@ -25,7 +29,9 @@ exports[`SnapshotHeading renders standard heading for valid counts 1`] = ` size="s" >

- 3/17 monitors are down + 17 + + Monitors

`; diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx index 5ddef3d0aabd10..70d082b26d653d 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/__tests__/snapshot_heading.test.tsx @@ -10,17 +10,17 @@ import { SnapshotHeading } from '../snapshot_heading'; describe('SnapshotHeading', () => { it('renders custom heading for no down monitors', () => { - const wrapper = shallowWithIntl(); + const wrapper = shallowWithIntl(); expect(wrapper).toMatchSnapshot(); }); it('renders standard heading for valid counts', () => { - const wrapper = shallowWithIntl(); + const wrapper = shallowWithIntl(); expect(wrapper).toMatchSnapshot(); }); it('renders custom heading for no monitors', () => { - const wrapper = shallowWithIntl(); + const wrapper = shallowWithIntl(); expect(wrapper).toMatchSnapshot(); }); }); diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap index c1b5970f6456cc..71690432fd01be 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap +++ b/x-pack/legacy/plugins/uptime/public/components/functional/charts/__tests__/__snapshots__/chart_wrapper.test.tsx.snap @@ -114,7 +114,6 @@ exports[`ChartWrapper component renders the component with loading false 1`] = ` } > { it('renders the component with loading false', () => { const component = shallowWithIntl( - + @@ -29,7 +29,7 @@ describe('ChartWrapper component', () => { it('renders the component with loading true', () => { const component = shallowWithIntl( - + @@ -40,7 +40,7 @@ describe('ChartWrapper component', () => { it('mounts the component with loading true or false', async () => { const component = mount( - + @@ -62,7 +62,7 @@ describe('ChartWrapper component', () => { it('mounts the component with chart when loading true or false', async () => { const component = mount( - + diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx index 8531cd1a3cc83d..999ade9dccdd9b 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot.tsx @@ -6,7 +6,6 @@ import { EuiSpacer } from '@elastic/eui'; import React from 'react'; -import { get } from 'lodash'; import { DonutChart } from './charts'; import { ChartWrapper } from './charts/chart_wrapper'; import { SnapshotHeading } from './snapshot_heading'; @@ -28,11 +27,11 @@ interface SnapshotComponentProps { */ export const SnapshotComponent: React.FC = ({ count, height, loading }) => ( - (count, 'down', 0)} total={get(count, 'total', 0)} /> + (count, 'up', 0)} - down={get(count, 'down', 0)} + up={count.up} + down={count.down} height={SNAPSHOT_CHART_HEIGHT} width={SNAPSHOT_CHART_WIDTH} /> diff --git a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx index 85d1294d4b0640..308d6e19241c2a 100644 --- a/x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx +++ b/x-pack/legacy/plugins/uptime/public/components/functional/snapshot_heading.tsx @@ -8,32 +8,17 @@ import { EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -interface Props { - down: number; - total: number; -} +export const SnapshotHeading = ({ total }: { total: number }) => { + const monitorsText = + total === 1 + ? i18n.translate('xpack.uptime.snapshot.monitor', { defaultMessage: 'Monitor' }) + : i18n.translate('xpack.uptime.snapshot.monitors', { defaultMessage: 'Monitors' }); -const getMessage = (down: number, total: number): string => { - if (down === 0 && total > 0) { - return i18n.translate('xpack.uptime.snapshot.zeroDownMessage', { - defaultMessage: 'All monitors are up', - }); - } else if (down === 0 && total === 0) { - return i18n.translate('xpack.uptime.snapshot.noMonitorMessage', { - defaultMessage: 'No monitors found', - }); - } - return i18n.translate('xpack.uptime.snapshot.downCountsMessage', { - defaultMessage: '{down}/{total} monitors are down', - values: { - down, - total, - }, - }); + return ( + +

+ {total} {monitorsText} +

+
+ ); }; - -export const SnapshotHeading = ({ down, total }: Props) => ( - -

{getMessage(down, total)}

-
-); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index dc8d6343007b84..4a627d48c3cf05 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -12781,12 +12781,9 @@ "xpack.uptime.pingList.statusOptions.downStatusOptionLabel": "ダウン", "xpack.uptime.pingList.statusOptions.upStatusOptionLabel": "アップ", "xpack.uptime.pluginDescription": "アップタイム監視", - "xpack.uptime.snapshot.downCountsMessage": "{down}/{total} 個のモニターがダウンしています", "xpack.uptime.snapshot.noDataDescription": "申し訳ございませんが、ヒストグラムに利用可能なデータがありません", "xpack.uptime.snapshot.noDataTitle": "ヒストグラムデータがありません", - "xpack.uptime.snapshot.noMonitorMessage": "モニターが見つかりません", "xpack.uptime.snapshot.pingsOverTimeTitle": "一定時間のピング", - "xpack.uptime.snapshot.zeroDownMessage": "すべてのモニターが起動しています", "xpack.uptime.snapshotHistogram.description": "{startTime} から {endTime} までの期間のアップタイムステータスを表示する棒グラフです。", "xpack.uptime.snapshotHistogram.downMonitorsId": "ダウンモニター", "xpack.uptime.snapshotHistogram.series.downLabel": "ダウン", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f6ef0140e385e6..e0ef4a7a1ebdba 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -12781,12 +12781,9 @@ "xpack.uptime.pingList.statusOptions.downStatusOptionLabel": "关闭", "xpack.uptime.pingList.statusOptions.upStatusOptionLabel": "运行", "xpack.uptime.pluginDescription": "运行时间监测", - "xpack.uptime.snapshot.downCountsMessage": "{down}/{total} 个监测已关闭", "xpack.uptime.snapshot.noDataDescription": "抱歉,没有可用于该直方图的数据", "xpack.uptime.snapshot.noDataTitle": "没有可用的直方图数据", - "xpack.uptime.snapshot.noMonitorMessage": "未找到任何监测", "xpack.uptime.snapshot.pingsOverTimeTitle": "时移 Ping 数", - "xpack.uptime.snapshot.zeroDownMessage": "所有监测已启动", "xpack.uptime.snapshotHistogram.description": "显示从 {startTime} 到 {endTime} 的运行时间时移状态的条形图。", "xpack.uptime.snapshotHistogram.downMonitorsId": "已关闭监测", "xpack.uptime.snapshotHistogram.series.downLabel": "关闭", From ef80ebf1bb4b9b399b0fcb852e305c2f0db3c853 Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Tue, 25 Feb 2020 15:57:40 -0700 Subject: [PATCH 57/73] [Search service] Add async search strategy (#53057) * Add async search strategy * Add async search * Fix async strategy and add tests * Move types to separate file * Revert changes to demo search * Update demo search strategy to use async * Add cancellation to search strategies * Add tests * Simplify async search strategy * Move loadingCount to search strategy * Update abort controller library * Bootstrap * Abort when the request is aborted * Add utility and update value suggestions route * Fix bad merge conflict * Update tests * Move to data_enhanced plugin * Remove bad merge * Revert switching abort controller libraries * Revert package.json in lib * Move to previous abort controller * Fix test to use fake timers to run debounced handlers * Revert changes to example plugin * Fix loading bar not going away when cancelling * Call getSearchStrategy instead of passing directly * Add async demo search strategy * Fix error with setting state * Update how aborting works * Fix type checks * Add test for loading count * Attempt to fix broken example test * Revert changes to test * Fix test * Update name to camelCase * Fix failing test * Don't require data_enhanced in example plugin Co-authored-by: Elastic Machine --- examples/demo_search/common/index.ts | 9 ++ examples/demo_search/kibana.json | 2 +- .../public/async_demo_search_strategy.ts | 69 ++++++++++ .../public/demo_search_strategy.ts | 2 +- examples/demo_search/public/plugin.ts | 17 ++- .../server/async_demo_search_strategy.ts | 60 +++++++++ examples/demo_search/server/plugin.ts | 17 ++- examples/search_explorer/kibana.json | 2 +- examples/search_explorer/package.json | 2 +- .../search_explorer/public/application.tsx | 6 + .../public/async_demo_strategy.tsx | 123 +++++++++++++++++ examples/search_explorer/public/do_search.tsx | 4 +- src/plugins/data/common/search/types.ts | 6 - .../search/es_search/es_search_strategy.ts | 10 +- src/plugins/data/public/search/index.ts | 2 +- .../data/server/search/create_api.test.ts | 2 +- src/plugins/data/server/search/create_api.ts | 11 +- .../search/i_route_handler_search_context.ts | 3 +- src/plugins/data/server/search/i_search.ts | 7 + .../data/server/search/i_search_strategy.ts | 3 +- src/plugins/data/server/search/routes.ts | 33 ++++- x-pack/plugins/data_enhanced/public/index.ts | 2 + x-pack/plugins/data_enhanced/public/plugin.ts | 8 +- .../search/async_search_strategy.test.ts | 125 ++++++++++++++++++ .../public/search/async_search_strategy.ts | 75 +++++++++++ .../data_enhanced/public/search/index.ts | 8 ++ .../data_enhanced/public/search/types.ts | 21 +++ 27 files changed, 601 insertions(+), 28 deletions(-) create mode 100644 examples/demo_search/public/async_demo_search_strategy.ts create mode 100644 examples/demo_search/server/async_demo_search_strategy.ts create mode 100644 examples/search_explorer/public/async_demo_strategy.tsx create mode 100644 x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts create mode 100644 x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts create mode 100644 x-pack/plugins/data_enhanced/public/search/index.ts create mode 100644 x-pack/plugins/data_enhanced/public/search/types.ts diff --git a/examples/demo_search/common/index.ts b/examples/demo_search/common/index.ts index 6587ee96ef61ba..8ea8d6186ee82c 100644 --- a/examples/demo_search/common/index.ts +++ b/examples/demo_search/common/index.ts @@ -20,6 +20,7 @@ import { IKibanaSearchRequest, IKibanaSearchResponse } from '../../../src/plugins/data/public'; export const DEMO_SEARCH_STRATEGY = 'DEMO_SEARCH_STRATEGY'; +export const ASYNC_DEMO_SEARCH_STRATEGY = 'ASYNC_DEMO_SEARCH_STRATEGY'; export interface IDemoRequest extends IKibanaSearchRequest { mood: string | 'sad' | 'happy'; @@ -29,3 +30,11 @@ export interface IDemoRequest extends IKibanaSearchRequest { export interface IDemoResponse extends IKibanaSearchResponse { greeting: string; } + +export interface IAsyncDemoRequest extends IKibanaSearchRequest { + fibonacciNumbers: number; +} + +export interface IAsyncDemoResponse extends IKibanaSearchResponse { + fibonacciSequence: number[]; +} diff --git a/examples/demo_search/kibana.json b/examples/demo_search/kibana.json index 0603706b07d1fe..cb73274ed23f7e 100644 --- a/examples/demo_search/kibana.json +++ b/examples/demo_search/kibana.json @@ -2,7 +2,7 @@ "id": "demoSearch", "version": "0.0.1", "kibanaVersion": "kibana", - "configPath": ["demo_search"], + "configPath": ["demoSearch"], "server": true, "ui": true, "requiredPlugins": ["data"], diff --git a/examples/demo_search/public/async_demo_search_strategy.ts b/examples/demo_search/public/async_demo_search_strategy.ts new file mode 100644 index 00000000000000..7a3f33ce05a75e --- /dev/null +++ b/examples/demo_search/public/async_demo_search_strategy.ts @@ -0,0 +1,69 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Observable } from 'rxjs'; +import { + ISearchContext, + TSearchStrategyProvider, + ISearchStrategy, +} from '../../../src/plugins/data/public'; + +import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoResponse } from '../common'; +import { ASYNC_SEARCH_STRATEGY } from '../../../x-pack/plugins/data_enhanced/public'; + +/** + * This demo search strategy provider simply provides a shortcut for calling the DEMO_ASYNC_SEARCH_STRATEGY + * on the server side, without users having to pass it in explicitly, and it takes advantage of the + * already registered ASYNC_SEARCH_STRATEGY that exists on the client. + * + * so instead of callers having to do: + * + * ``` + * search( + * { ...request, serverStrategy: DEMO_ASYNC_SEARCH_STRATEGY }, + * options, + * ASYNC_SEARCH_STRATEGY + * ) as Observable, + *``` + + * They can instead just do + * + * ``` + * search(request, options, DEMO_ASYNC_SEARCH_STRATEGY); + * ``` + * + * and are ensured type safety in regard to the request and response objects. + * + * @param context - context supplied by other plugins. + * @param search - a search function to access other strategies that have already been registered. + */ +export const asyncDemoClientSearchStrategyProvider: TSearchStrategyProvider = ( + context: ISearchContext +): ISearchStrategy => { + const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY); + const { search } = asyncStrategyProvider(context); + return { + search: (request, options) => { + return search( + { ...request, serverStrategy: ASYNC_DEMO_SEARCH_STRATEGY }, + options + ) as Observable; + }, + }; +}; diff --git a/examples/demo_search/public/demo_search_strategy.ts b/examples/demo_search/public/demo_search_strategy.ts index cb2480c8a5f194..8dc2779a8544c2 100644 --- a/examples/demo_search/public/demo_search_strategy.ts +++ b/examples/demo_search/public/demo_search_strategy.ts @@ -43,7 +43,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common'; * ``` * context.search(request, options, DEMO_SEARCH_STRATEGY); * ``` - * + * * and are ensured type safety in regard to the request and response objects. * * @param context - context supplied by other plugins. diff --git a/examples/demo_search/public/plugin.ts b/examples/demo_search/public/plugin.ts index 62c912716e627c..a2539cc7a21c5f 100644 --- a/examples/demo_search/public/plugin.ts +++ b/examples/demo_search/public/plugin.ts @@ -19,9 +19,16 @@ import { DataPublicPluginSetup } from '../../../src/plugins/data/public'; import { Plugin, CoreSetup } from '../../../src/core/public'; -import { DEMO_SEARCH_STRATEGY } from '../common'; +import { + DEMO_SEARCH_STRATEGY, + IDemoRequest, + IDemoResponse, + ASYNC_DEMO_SEARCH_STRATEGY, + IAsyncDemoRequest, + IAsyncDemoResponse, +} from '../common'; import { demoClientSearchStrategyProvider } from './demo_search_strategy'; -import { IDemoRequest, IDemoResponse } from '../common'; +import { asyncDemoClientSearchStrategyProvider } from './async_demo_search_strategy'; interface DemoDataSearchSetupDependencies { data: DataPublicPluginSetup; @@ -39,10 +46,12 @@ interface DemoDataSearchSetupDependencies { declare module '../../../src/plugins/data/public' { export interface IRequestTypesMap { [DEMO_SEARCH_STRATEGY]: IDemoRequest; + [ASYNC_DEMO_SEARCH_STRATEGY]: IAsyncDemoRequest; } export interface IResponseTypesMap { [DEMO_SEARCH_STRATEGY]: IDemoResponse; + [ASYNC_DEMO_SEARCH_STRATEGY]: IAsyncDemoResponse; } } @@ -52,6 +61,10 @@ export class DemoDataPlugin implements Plugin { DEMO_SEARCH_STRATEGY, demoClientSearchStrategyProvider ); + deps.data.search.registerSearchStrategyProvider( + ASYNC_DEMO_SEARCH_STRATEGY, + asyncDemoClientSearchStrategyProvider + ); } public start() {} diff --git a/examples/demo_search/server/async_demo_search_strategy.ts b/examples/demo_search/server/async_demo_search_strategy.ts new file mode 100644 index 00000000000000..d2d40891a5d939 --- /dev/null +++ b/examples/demo_search/server/async_demo_search_strategy.ts @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { TSearchStrategyProvider } from '../../../src/plugins/data/server'; +import { ASYNC_DEMO_SEARCH_STRATEGY } from '../common'; + +function getFibonacciSequence(n = 0) { + const beginning = [0, 1].slice(0, n); + return Array(Math.max(0, n)) + .fill(null) + .reduce((sequence, value, i) => { + if (i < 2) return sequence; + return [...sequence, sequence[i - 1] + sequence[i - 2]]; + }, beginning); +} + +const generateId = (() => { + let id = 0; + return () => `${id++}`; +})(); + +const loadedMap = new Map(); +const totalMap = new Map(); + +export const asyncDemoSearchStrategyProvider: TSearchStrategyProvider = () => { + return { + search: async request => { + const id = request.id ?? generateId(); + + const loaded = (loadedMap.get(id) ?? 0) + 1; + loadedMap.set(id, loaded); + + const total = request.fibonacciNumbers ?? totalMap.get(id); + totalMap.set(id, total); + + const fibonacciSequence = getFibonacciSequence(loaded); + return { id, total, loaded, fibonacciSequence }; + }, + cancel: async id => { + loadedMap.delete(id); + totalMap.delete(id); + }, + }; +}; diff --git a/examples/demo_search/server/plugin.ts b/examples/demo_search/server/plugin.ts index 653aa217717fa2..49fbae43e3aa28 100644 --- a/examples/demo_search/server/plugin.ts +++ b/examples/demo_search/server/plugin.ts @@ -20,7 +20,15 @@ import { Plugin, CoreSetup, PluginInitializerContext } from 'kibana/server'; import { PluginSetup as DataPluginSetup } from 'src/plugins/data/server'; import { demoSearchStrategyProvider } from './demo_search_strategy'; -import { DEMO_SEARCH_STRATEGY, IDemoRequest, IDemoResponse } from '../common'; +import { + DEMO_SEARCH_STRATEGY, + IDemoRequest, + IDemoResponse, + ASYNC_DEMO_SEARCH_STRATEGY, + IAsyncDemoRequest, + IAsyncDemoResponse, +} from '../common'; +import { asyncDemoSearchStrategyProvider } from './async_demo_search_strategy'; interface IDemoSearchExplorerDeps { data: DataPluginSetup; @@ -38,10 +46,12 @@ interface IDemoSearchExplorerDeps { declare module '../../../src/plugins/data/server' { export interface IRequestTypesMap { [DEMO_SEARCH_STRATEGY]: IDemoRequest; + [ASYNC_DEMO_SEARCH_STRATEGY]: IAsyncDemoRequest; } export interface IResponseTypesMap { [DEMO_SEARCH_STRATEGY]: IDemoResponse; + [ASYNC_DEMO_SEARCH_STRATEGY]: IAsyncDemoResponse; } } @@ -54,6 +64,11 @@ export class DemoDataPlugin implements Plugin id: 'demoSearch', component: , }, + { + title: 'Async demo search strategy', + id: 'asyncDemoSearch', + component: , + }, ]; const routes = pages.map((page, i) => ( diff --git a/examples/search_explorer/public/async_demo_strategy.tsx b/examples/search_explorer/public/async_demo_strategy.tsx new file mode 100644 index 00000000000000..40ddcc1f48fe7a --- /dev/null +++ b/examples/search_explorer/public/async_demo_strategy.tsx @@ -0,0 +1,123 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { + EuiPageContentBody, + EuiFormRow, + EuiFlexItem, + EuiFlexGroup, + EuiFieldNumber, +} from '@elastic/eui'; +import { ISearchGeneric } from '../../../src/plugins/data/public'; +import { DoSearch } from './do_search'; +import { GuideSection } from './guide_section'; + +import { ASYNC_DEMO_SEARCH_STRATEGY, IAsyncDemoRequest } from '../../demo_search/common'; + +// @ts-ignore +import demoStrategyServerProvider from '!!raw-loader!./../../demo_search/server/async_demo_search_strategy'; +// @ts-ignore +import demoStrategyPublicProvider from '!!raw-loader!./../../demo_search/public/async_demo_search_strategy'; +// @ts-ignore +import demoStrategyServerPlugin from '!!raw-loader!./../../demo_search/server/plugin'; +// @ts-ignore +import demoStrategyPublicPlugin from '!!raw-loader!./../../demo_search/public/plugin'; + +interface Props { + search: ISearchGeneric; +} + +interface State { + searching: boolean; + fibonacciNumbers: number; + changes: boolean; + error?: any; +} + +export class AsyncDemoStrategy extends React.Component { + constructor(props: Props) { + super(props); + + this.state = { + searching: false, + changes: false, + fibonacciNumbers: 5, + }; + } + + renderDemo = () => { + const request: IAsyncDemoRequest = { + fibonacciNumbers: this.state.fibonacciNumbers, + }; + return ( + + + + + this.setState({ fibonacciNumbers: parseFloat(e.target.value) })} + /> + + + + + this.props.search(request, { signal }, ASYNC_DEMO_SEARCH_STRATEGY) + } + /> + + ); + }; + + render() { + return ( + + + + ); + } +} diff --git a/examples/search_explorer/public/do_search.tsx b/examples/search_explorer/public/do_search.tsx index f279b9fcd6e239..a6b6b9b57db4a9 100644 --- a/examples/search_explorer/public/do_search.tsx +++ b/examples/search_explorer/public/do_search.tsx @@ -118,8 +118,8 @@ ${requestStr} Response: = ( context: ISearchContext ): ISearchStrategy => { + const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); + const { search } = syncStrategyProvider(context); return { search: (request, options) => { if (typeof request.params.preference === 'undefined') { @@ -33,11 +35,9 @@ export const esSearchStrategyProvider: TSearchStrategyProvider; + return search({ ...request, serverStrategy: ES_SEARCH_STRATEGY }, options) as Observable< + IEsSearchResponse + >; }, }; }; diff --git a/src/plugins/data/public/search/index.ts b/src/plugins/data/public/search/index.ts index 762c278a05640b..853dbd09e1f939 100644 --- a/src/plugins/data/public/search/index.ts +++ b/src/plugins/data/public/search/index.ts @@ -35,7 +35,7 @@ export { export { IEsSearchResponse, IEsSearchRequest, ES_SEARCH_STRATEGY } from '../../common/search'; -export { SYNC_SEARCH_STRATEGY } from './sync_search_strategy'; +export { ISyncSearchRequest, SYNC_SEARCH_STRATEGY } from './sync_search_strategy'; export { IKibanaSearchResponse, IKibanaSearchRequest } from '../../common/search'; diff --git a/src/plugins/data/server/search/create_api.test.ts b/src/plugins/data/server/search/create_api.test.ts index cc13269e1aa21e..99e48056ef8578 100644 --- a/src/plugins/data/server/search/create_api.test.ts +++ b/src/plugins/data/server/search/create_api.test.ts @@ -25,7 +25,7 @@ import { DEFAULT_SEARCH_STRATEGY } from '../../common/search'; // let mockCoreSetup: MockedKeys; -const mockDefaultSearch = jest.fn(() => Promise.resolve({ percentComplete: 0 })); +const mockDefaultSearch = jest.fn(() => Promise.resolve({ total: 100, loaded: 0 })); const mockDefaultSearchStrategyProvider = jest.fn(() => Promise.resolve({ search: mockDefaultSearch, diff --git a/src/plugins/data/server/search/create_api.ts b/src/plugins/data/server/search/create_api.ts index e1613103ac3998..798a4b82caaefa 100644 --- a/src/plugins/data/server/search/create_api.ts +++ b/src/plugins/data/server/search/create_api.ts @@ -31,7 +31,7 @@ export function createApi({ }) { const api: IRouteHandlerSearchContext = { search: async (request, options, strategyName) => { - const name = strategyName ? strategyName : DEFAULT_SEARCH_STRATEGY; + const name = strategyName ?? DEFAULT_SEARCH_STRATEGY; const strategyProvider = searchStrategies[name]; if (!strategyProvider) { throw new Error(`No strategy found for ${strategyName}`); @@ -40,6 +40,15 @@ export function createApi({ const strategy = await strategyProvider(caller, api.search); return strategy.search(request, options); }, + cancel: async (id, strategyName) => { + const name = strategyName ?? DEFAULT_SEARCH_STRATEGY; + const strategyProvider = searchStrategies[name]; + if (!strategyProvider) { + throw new Error(`No strategy found for ${strategyName}`); + } + const strategy = await strategyProvider(caller, api.search); + return strategy.cancel && strategy.cancel(id); + }, }; return api; } diff --git a/src/plugins/data/server/search/i_route_handler_search_context.ts b/src/plugins/data/server/search/i_route_handler_search_context.ts index 8a44738a1dcfad..89862781b826e7 100644 --- a/src/plugins/data/server/search/i_route_handler_search_context.ts +++ b/src/plugins/data/server/search/i_route_handler_search_context.ts @@ -17,8 +17,9 @@ * under the License. */ -import { ISearchGeneric } from './i_search'; +import { ISearchGeneric, ICancelGeneric } from './i_search'; export interface IRouteHandlerSearchContext { search: ISearchGeneric; + cancel: ICancelGeneric; } diff --git a/src/plugins/data/server/search/i_search.ts b/src/plugins/data/server/search/i_search.ts index 0a357345741534..ea014c5e136d92 100644 --- a/src/plugins/data/server/search/i_search.ts +++ b/src/plugins/data/server/search/i_search.ts @@ -42,7 +42,14 @@ export type ISearchGeneric = Promise; +export type ICancelGeneric = ( + id: string, + strategy?: T +) => Promise; + export type ISearch = ( request: IRequestTypesMap[T], options?: ISearchOptions ) => Promise; + +export type ICancel = (id: string) => Promise; diff --git a/src/plugins/data/server/search/i_search_strategy.ts b/src/plugins/data/server/search/i_search_strategy.ts index d00dd552c9e958..4cfc9608383a90 100644 --- a/src/plugins/data/server/search/i_search_strategy.ts +++ b/src/plugins/data/server/search/i_search_strategy.ts @@ -18,7 +18,7 @@ */ import { APICaller } from 'kibana/server'; -import { ISearch, ISearchGeneric } from './i_search'; +import { ISearch, ICancel, ISearchGeneric } from './i_search'; import { TStrategyTypes } from './strategy_types'; import { ISearchContext } from './i_search_context'; @@ -28,6 +28,7 @@ import { ISearchContext } from './i_search_context'; */ export interface ISearchStrategy { search: ISearch; + cancel?: ICancel; } /** diff --git a/src/plugins/data/server/search/routes.ts b/src/plugins/data/server/search/routes.ts index 11879d14931ae8..2b8c4b95ee0228 100644 --- a/src/plugins/data/server/search/routes.ts +++ b/src/plugins/data/server/search/routes.ts @@ -35,7 +35,7 @@ export function registerSearchRoute(router: IRouter): void { }, async (context, request, res) => { const searchRequest = request.body; - const strategy = request.params.strategy; + const { strategy } = request.params; const signal = getRequestAbortedSignal(request.events.aborted$); try { @@ -54,4 +54,35 @@ export function registerSearchRoute(router: IRouter): void { } } ); + + router.delete( + { + path: '/internal/search/{strategy}/{id}', + validate: { + params: schema.object({ + strategy: schema.string(), + id: schema.string(), + }), + + query: schema.object({}, { allowUnknowns: true }), + }, + }, + async (context, request, res) => { + const { strategy, id } = request.params; + try { + await context.search!.cancel(id, strategy); + return res.ok(); + } catch (err) { + return res.customError({ + statusCode: err.statusCode, + body: { + message: err.message, + attributes: { + error: err.body.error, + }, + }, + }); + } + } + ); } diff --git a/x-pack/plugins/data_enhanced/public/index.ts b/x-pack/plugins/data_enhanced/public/index.ts index 93b6b7a9571824..927716aae97808 100644 --- a/x-pack/plugins/data_enhanced/public/index.ts +++ b/x-pack/plugins/data_enhanced/public/index.ts @@ -9,3 +9,5 @@ import { DataEnhancedPlugin, DataEnhancedSetup, DataEnhancedStart } from './plug export const plugin = () => new DataEnhancedPlugin(); export { DataEnhancedSetup, DataEnhancedStart }; + +export { ASYNC_SEARCH_STRATEGY, IAsyncSearchRequest, IAsyncSearchOptions } from './search'; diff --git a/x-pack/plugins/data_enhanced/public/plugin.ts b/x-pack/plugins/data_enhanced/public/plugin.ts index 14b5382bc85aaa..4fe27d400f45fd 100644 --- a/x-pack/plugins/data_enhanced/public/plugin.ts +++ b/x-pack/plugins/data_enhanced/public/plugin.ts @@ -8,6 +8,7 @@ import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { DataPublicPluginSetup, DataPublicPluginStart } from '../../../../src/plugins/data/public'; import { setAutocompleteService } from './services'; import { setupKqlQuerySuggestionProvider, KUERY_LANGUAGE_NAME } from './autocomplete'; +import { ASYNC_SEARCH_STRATEGY, asyncSearchStrategyProvider } from './search'; export interface DataEnhancedSetupDependencies { data: DataPublicPluginSetup; @@ -20,11 +21,14 @@ export type DataEnhancedSetup = ReturnType; export type DataEnhancedStart = ReturnType; export class DataEnhancedPlugin implements Plugin { - public setup(core: CoreSetup, plugins: DataEnhancedSetupDependencies) { - plugins.data.autocomplete.addQuerySuggestionProvider( + constructor() {} + + public setup(core: CoreSetup, { data }: DataEnhancedSetupDependencies) { + data.autocomplete.addQuerySuggestionProvider( KUERY_LANGUAGE_NAME, setupKqlQuerySuggestionProvider(core) ); + data.search.registerSearchStrategyProvider(ASYNC_SEARCH_STRATEGY, asyncSearchStrategyProvider); } public start(core: CoreStart, plugins: DataEnhancedStartDependencies) { diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts new file mode 100644 index 00000000000000..95f2c9e4770642 --- /dev/null +++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.test.ts @@ -0,0 +1,125 @@ +/* + * 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 { of } from 'rxjs'; +import { AbortController } from 'abort-controller'; +import { coreMock } from '../../../../../src/core/public/mocks'; +import { asyncSearchStrategyProvider } from './async_search_strategy'; +import { IAsyncSearchOptions } from './types'; +import { CoreStart } from 'kibana/public'; + +describe('Async search strategy', () => { + let mockCoreStart: MockedKeys; + const mockSearch = jest.fn(); + const mockRequest = { params: {}, serverStrategy: 'foo' }; + const mockOptions: IAsyncSearchOptions = { pollInterval: 0 }; + + beforeEach(() => { + mockCoreStart = coreMock.createStart(); + mockSearch.mockReset(); + }); + + it('only sends one request if the first response is complete', async () => { + mockSearch.mockReturnValueOnce(of({ id: 1, total: 1, loaded: 1 })); + + const asyncSearch = asyncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn().mockImplementation(() => { + return () => { + return { + search: mockSearch, + }; + }; + }), + }); + + await asyncSearch.search(mockRequest, mockOptions).toPromise(); + + expect(mockSearch.mock.calls[0][0]).toEqual(mockRequest); + expect(mockSearch.mock.calls[0][1]).toEqual({}); + expect(mockSearch).toBeCalledTimes(1); + }); + + it('stops polling when the response is complete', async () => { + mockSearch + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 1 })) + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })) + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })); + + const asyncSearch = asyncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn().mockImplementation(() => { + return () => { + return { + search: mockSearch, + }; + }; + }), + }); + + expect(mockSearch).toBeCalledTimes(0); + + await asyncSearch.search(mockRequest, mockOptions).toPromise(); + + expect(mockSearch).toBeCalledTimes(2); + }); + + it('only sends the ID and server strategy after the first request', async () => { + mockSearch + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 1 })) + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })); + + const asyncSearch = asyncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn().mockImplementation(() => { + return () => { + return { + search: mockSearch, + }; + }; + }), + }); + + expect(mockSearch).toBeCalledTimes(0); + + await asyncSearch.search(mockRequest, mockOptions).toPromise(); + + expect(mockSearch).toBeCalledTimes(2); + expect(mockSearch.mock.calls[0][0]).toEqual(mockRequest); + expect(mockSearch.mock.calls[1][0]).toEqual({ id: 1, serverStrategy: 'foo' }); + }); + + it('sends a DELETE request and stops polling when the signal is aborted', async () => { + mockSearch + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 1 })) + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })) + .mockReturnValueOnce(of({ id: 1, total: 2, loaded: 2 })); + + const asyncSearch = asyncSearchStrategyProvider({ + core: mockCoreStart, + getSearchStrategy: jest.fn().mockImplementation(() => { + return () => { + return { + search: mockSearch, + }; + }; + }), + }); + const abortController = new AbortController(); + const options = { ...mockOptions, signal: abortController.signal }; + + const promise = asyncSearch.search(mockRequest, options).toPromise(); + abortController.abort(); + + try { + await promise; + } catch (e) { + expect(e.name).toBe('AbortError'); + expect(mockSearch).toBeCalledTimes(1); + expect(mockCoreStart.http.delete).toBeCalled(); + } + }); +}); diff --git a/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts new file mode 100644 index 00000000000000..fa5d677a53b2a7 --- /dev/null +++ b/x-pack/plugins/data_enhanced/public/search/async_search_strategy.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EMPTY, fromEvent, NEVER, Observable, throwError, timer } from 'rxjs'; +import { mergeMap, expand, takeUntil } from 'rxjs/operators'; +import { + IKibanaSearchResponse, + ISearchContext, + ISearchStrategy, + SYNC_SEARCH_STRATEGY, + TSearchStrategyProvider, +} from '../../../../../src/plugins/data/public'; +import { IAsyncSearchRequest, IAsyncSearchOptions } from './types'; + +export const ASYNC_SEARCH_STRATEGY = 'ASYNC_SEARCH_STRATEGY'; + +declare module '../../../../../src/plugins/data/public' { + export interface IRequestTypesMap { + [ASYNC_SEARCH_STRATEGY]: IAsyncSearchRequest; + } +} + +export const asyncSearchStrategyProvider: TSearchStrategyProvider = ( + context: ISearchContext +): ISearchStrategy => { + const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); + const { search } = syncStrategyProvider(context); + return { + search: ( + request: IAsyncSearchRequest, + { pollInterval = 1000, ...options }: IAsyncSearchOptions = {} + ): Observable => { + const { serverStrategy } = request; + let id: string | undefined = request.id; + + const aborted$ = options.signal + ? fromEvent(options.signal, 'abort').pipe( + mergeMap(() => { + // If we haven't received the response to the initial request, including the ID, then + // we don't need to send a follow-up request to delete this search. Otherwise, we + // send the follow-up request to delete this search, then throw an abort error. + if (id !== undefined) { + context.core.http.delete(`/internal/search/${request.serverStrategy}/${id}`); + } + + const error = new Error('Aborted'); + error.name = 'AbortError'; + return throwError(error); + }) + ) + : NEVER; + + return search(request, options).pipe( + expand(response => { + // If the response indicates it is complete, stop polling and complete the observable + if ((response.loaded ?? 0) >= (response.total ?? 0)) return EMPTY; + + id = response.id; + + // Delay by the given poll interval + return timer(pollInterval).pipe( + // Send future requests using just the ID from the response + mergeMap(() => { + return search({ id, serverStrategy }, options); + }) + ); + }), + takeUntil(aborted$) + ); + }, + }; +}; diff --git a/x-pack/plugins/data_enhanced/public/search/index.ts b/x-pack/plugins/data_enhanced/public/search/index.ts new file mode 100644 index 00000000000000..a7729aeea56478 --- /dev/null +++ b/x-pack/plugins/data_enhanced/public/search/index.ts @@ -0,0 +1,8 @@ +/* + * 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. + */ + +export { ASYNC_SEARCH_STRATEGY, asyncSearchStrategyProvider } from './async_search_strategy'; +export { IAsyncSearchRequest, IAsyncSearchOptions } from './types'; diff --git a/x-pack/plugins/data_enhanced/public/search/types.ts b/x-pack/plugins/data_enhanced/public/search/types.ts new file mode 100644 index 00000000000000..edaaf1b22654d4 --- /dev/null +++ b/x-pack/plugins/data_enhanced/public/search/types.ts @@ -0,0 +1,21 @@ +/* + * 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 { ISearchOptions, ISyncSearchRequest } from '../../../../../src/plugins/data/public'; + +export interface IAsyncSearchRequest extends ISyncSearchRequest { + /** + * The ID received from the response from the initial request + */ + id?: string; +} + +export interface IAsyncSearchOptions extends ISearchOptions { + /** + * The number of milliseconds to wait between receiving a response and sending another request + */ + pollInterval?: number; +} From 29439789abc05d05f7a12305397f23469a3499d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Tue, 25 Feb 2020 18:18:27 -0500 Subject: [PATCH 58/73] Add migration support to the event log (#58010) * Initial work * Add missing file * Add tests where missing * Add kibana version to esNames * Share ILM policy across versions --- .../server/es/cluster_client_adapter.test.ts | 1 + .../event_log/server/es/cluster_client_adapter.ts | 7 +++++-- .../plugins/event_log/server/es/documents.test.ts | 3 +-- x-pack/plugins/event_log/server/es/documents.ts | 5 +---- x-pack/plugins/event_log/server/es/init.ts | 8 +++++++- x-pack/plugins/event_log/server/es/names.mock.ts | 7 ++++--- x-pack/plugins/event_log/server/es/names.test.ts | 12 +++++++++--- x-pack/plugins/event_log/server/es/names.ts | 14 ++++++++++---- 8 files changed, 38 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts index ecefd4bfa271ef..b61196439ee4fa 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.test.ts @@ -173,6 +173,7 @@ describe('createIndex', () => { await clusterClientAdapter.createIndex('foo'); expect(clusterClient.callAsInternalUser).toHaveBeenCalledWith('indices.create', { index: 'foo', + body: {}, }); }); diff --git a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts index c74eeacc9bb19c..d585fd4f539b5c 100644 --- a/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts +++ b/x-pack/plugins/event_log/server/es/cluster_client_adapter.ts @@ -94,9 +94,12 @@ export class ClusterClientAdapter { return result as boolean; } - public async createIndex(name: string): Promise { + public async createIndex(name: string, body: any = {}): Promise { try { - await this.callEs('indices.create', { index: name }); + await this.callEs('indices.create', { + index: name, + body, + }); } catch (err) { if (err.body?.error?.type !== 'resource_already_exists_exception') { throw new Error(`error creating initial index: ${err.message}`); diff --git a/x-pack/plugins/event_log/server/es/documents.test.ts b/x-pack/plugins/event_log/server/es/documents.test.ts index 7edca4b3943a65..c08d0ac978bc94 100644 --- a/x-pack/plugins/event_log/server/es/documents.test.ts +++ b/x-pack/plugins/event_log/server/es/documents.test.ts @@ -22,8 +22,7 @@ describe('getIndexTemplate()', () => { test('returns the correct details of the index template', () => { const indexTemplate = getIndexTemplate(esNames); - expect(indexTemplate.index_patterns).toEqual([esNames.indexPattern]); - expect(indexTemplate.aliases[esNames.alias]).toEqual({}); + expect(indexTemplate.index_patterns).toEqual([esNames.indexPatternWithVersion]); expect(indexTemplate.settings.number_of_shards).toBeGreaterThanOrEqual(0); expect(indexTemplate.settings.number_of_replicas).toBeGreaterThanOrEqual(0); expect(indexTemplate.settings['index.lifecycle.name']).toBe(esNames.ilmPolicy); diff --git a/x-pack/plugins/event_log/server/es/documents.ts b/x-pack/plugins/event_log/server/es/documents.ts index 09dd7383c4c5e3..982454e671008a 100644 --- a/x-pack/plugins/event_log/server/es/documents.ts +++ b/x-pack/plugins/event_log/server/es/documents.ts @@ -10,10 +10,7 @@ import mappings from '../../generated/mappings.json'; // returns the body of an index template used in an ES indices.putTemplate call export function getIndexTemplate(esNames: EsNames) { const indexTemplateBody: any = { - index_patterns: [esNames.indexPattern], - aliases: { - [esNames.alias]: {}, - }, + index_patterns: [esNames.indexPatternWithVersion], settings: { number_of_shards: 1, number_of_replicas: 1, diff --git a/x-pack/plugins/event_log/server/es/init.ts b/x-pack/plugins/event_log/server/es/init.ts index 7094277f7aa9fd..c67d6541ce0020 100644 --- a/x-pack/plugins/event_log/server/es/init.ts +++ b/x-pack/plugins/event_log/server/es/init.ts @@ -62,7 +62,13 @@ class EsInitializationSteps { async createInitialIndexIfNotExists(): Promise { const exists = await this.esContext.esAdapter.doesAliasExist(this.esContext.esNames.alias); if (!exists) { - await this.esContext.esAdapter.createIndex(this.esContext.esNames.initialIndex); + await this.esContext.esAdapter.createIndex(this.esContext.esNames.initialIndex, { + aliases: { + [this.esContext.esNames.alias]: { + is_write_index: true, + }, + }, + }); } } } diff --git a/x-pack/plugins/event_log/server/es/names.mock.ts b/x-pack/plugins/event_log/server/es/names.mock.ts index 7b013a0d263da8..268421235b4b2d 100644 --- a/x-pack/plugins/event_log/server/es/names.mock.ts +++ b/x-pack/plugins/event_log/server/es/names.mock.ts @@ -9,11 +9,12 @@ import { EsNames } from './names'; const createNamesMock = () => { const mock: jest.Mocked = { base: '.kibana', - alias: '.kibana-event-log', + alias: '.kibana-event-log-8.0.0', ilmPolicy: '.kibana-event-log-policy', indexPattern: '.kibana-event-log-*', - initialIndex: '.kibana-event-log-000001', - indexTemplate: '.kibana-event-log-template', + indexPatternWithVersion: '.kibana-event-log-8.0.0-*', + initialIndex: '.kibana-event-log-8.0.0-000001', + indexTemplate: '.kibana-event-log-8.0.0-template', }; return mock; }; diff --git a/x-pack/plugins/event_log/server/es/names.test.ts b/x-pack/plugins/event_log/server/es/names.test.ts index d88c4212df91ca..baefd756bb1ed0 100644 --- a/x-pack/plugins/event_log/server/es/names.test.ts +++ b/x-pack/plugins/event_log/server/es/names.test.ts @@ -6,15 +6,21 @@ import { getEsNames } from './names'; +jest.mock('../lib/../../../../package.json', () => ({ + version: '1.2.3', +})); + describe('getEsNames()', () => { test('works as expected', () => { const base = 'XYZ'; + const version = '1.2.3'; const esNames = getEsNames(base); expect(esNames.base).toEqual(base); - expect(esNames.alias).toEqual(`${base}-event-log`); + expect(esNames.alias).toEqual(`${base}-event-log-${version}`); expect(esNames.ilmPolicy).toEqual(`${base}-event-log-policy`); expect(esNames.indexPattern).toEqual(`${base}-event-log-*`); - expect(esNames.initialIndex).toEqual(`${base}-event-log-000001`); - expect(esNames.indexTemplate).toEqual(`${base}-event-log-template`); + expect(esNames.indexPatternWithVersion).toEqual(`${base}-event-log-${version}-*`); + expect(esNames.initialIndex).toEqual(`${base}-event-log-${version}-000001`); + expect(esNames.indexTemplate).toEqual(`${base}-event-log-${version}-template`); }); }); diff --git a/x-pack/plugins/event_log/server/es/names.ts b/x-pack/plugins/event_log/server/es/names.ts index be737d23625f14..d55d02a16fc9a7 100644 --- a/x-pack/plugins/event_log/server/es/names.ts +++ b/x-pack/plugins/event_log/server/es/names.ts @@ -4,25 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ -const EVENT_LOG_NAME_SUFFIX = '-event-log'; +import xPackage from '../../../../package.json'; + +const EVENT_LOG_NAME_SUFFIX = `-event-log`; +const EVENT_LOG_VERSION_SUFFIX = `-${xPackage.version}`; export interface EsNames { base: string; alias: string; ilmPolicy: string; indexPattern: string; + indexPatternWithVersion: string; initialIndex: string; indexTemplate: string; } export function getEsNames(baseName: string): EsNames { const eventLogName = `${baseName}${EVENT_LOG_NAME_SUFFIX}`; + const eventLogNameWithVersion = `${eventLogName}${EVENT_LOG_VERSION_SUFFIX}`; return { base: baseName, - alias: eventLogName, + alias: eventLogNameWithVersion, ilmPolicy: `${eventLogName}-policy`, indexPattern: `${eventLogName}-*`, - initialIndex: `${eventLogName}-000001`, - indexTemplate: `${eventLogName}-template`, + indexPatternWithVersion: `${eventLogNameWithVersion}-*`, + initialIndex: `${eventLogNameWithVersion}-000001`, + indexTemplate: `${eventLogNameWithVersion}-template`, }; } From 24b8ecf74d559ce1226d730ed961d32d5196ef47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Tue, 25 Feb 2020 21:47:53 -0500 Subject: [PATCH 59/73] Add localization to missing action types (#58554) --- .../actions/server/builtin_action_types/server_log.ts | 8 ++++---- .../server/builtin_action_types/servicenow.test.ts | 2 +- .../actions/server/builtin_action_types/servicenow.ts | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/server_log.ts b/x-pack/plugins/actions/server/builtin_action_types/server_log.ts index 62406cfaf66e19..01355f2a34f923 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/server_log.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/server_log.ts @@ -12,8 +12,6 @@ import { Logger } from '../../../../../src/core/server'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../types'; import { withoutControlCharacters } from './lib/string_utils'; -const ACTION_NAME = 'Server log'; - // params definition export type ActionParamsType = TypeOf; @@ -37,7 +35,9 @@ const ParamsSchema = schema.object({ export function getActionType({ logger }: { logger: Logger }): ActionType { return { id: '.server-log', - name: ACTION_NAME, + name: i18n.translate('xpack.actions.builtin.serverLogTitle', { + defaultMessage: 'Server log', + }), validate: { params: ParamsSchema, }, @@ -56,7 +56,7 @@ async function executor( const sanitizedMessage = withoutControlCharacters(params.message); try { - logger[params.level](`${ACTION_NAME}: ${sanitizedMessage}`); + logger[params.level](`Server log: ${sanitizedMessage}`); } catch (err) { const message = i18n.translate('xpack.actions.builtin.serverLog.errorLoggingErrorMessage', { defaultMessage: 'error logging message', diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow.test.ts index a6c43f48fa8031..9ae96cb23a5c39 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow.test.ts @@ -49,7 +49,7 @@ beforeAll(() => { describe('get()', () => { test('should return correct action type', () => { expect(actionType.id).toEqual(ACTION_TYPE_ID); - expect(actionType.name).toEqual('servicenow'); + expect(actionType.name).toEqual('ServiceNow'); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow.ts index 2d5c18207def3f..0ad435281eba45 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow.ts @@ -89,7 +89,9 @@ export function getActionType({ }): ActionType { return { id: '.servicenow', - name: 'servicenow', + name: i18n.translate('xpack.actions.builtin.servicenowTitle', { + defaultMessage: 'ServiceNow', + }), validate: { config: schema.object(ConfigSchemaProps, { validate: curry(validateConfig)(configurationUtilities), From b56eead4ac7d2ccc5657f51a2be665cbc6118bec Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Tue, 25 Feb 2020 21:59:44 -0500 Subject: [PATCH 60/73] [SIEM] [Detections] Refactor the all rules page (#58428) * Refactor the all rules page to be easier to test * review with Garrett * bring back utility bar under condition * fix bugs tags and allow switch to show loading when enable/disable rule * fix rules selection when trigerring new rules * fix imports/exports can only use rule_id as learned today * review I --- .../detection_engine/rules/use_rules.test.tsx | 99 ++++---- .../detection_engine/rules/use_rules.tsx | 50 ++-- .../detection_engine/rules/use_tags.test.tsx | 8 +- .../detection_engine/rules/use_tags.tsx | 9 +- .../rules/all/__mocks__/mock.ts | 101 -------- .../detection_engine/rules/all/actions.tsx | 51 ++-- .../rules/all/batch_actions.tsx | 74 +++--- .../detection_engine/rules/all/columns.tsx | 92 +++++--- .../rules/all/helpers.test.tsx | 18 +- .../detection_engine/rules/all/helpers.ts | 33 +-- .../detection_engine/rules/all/index.tsx | 220 +++++++++--------- .../detection_engine/rules/all/reducer.ts | 160 ++++++------- .../rules_table_filters.tsx | 6 +- .../__snapshots__/index.test.tsx.snap | 1 + .../rule_actions_overflow/index.tsx | 10 +- .../components/rule_downloader/index.tsx | 14 +- .../pages/detection_engine/rules/index.tsx | 18 +- .../pages/detection_engine/rules/types.ts | 19 -- .../routes/rules/create_rules_bulk_route.ts | 4 +- .../routes/rules/utils.test.ts | 34 ++- .../detection_engine/routes/rules/utils.ts | 15 +- 21 files changed, 461 insertions(+), 575 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.test.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.test.tsx index b369d3a50730d0..242d715e20f770 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.test.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.test.tsx @@ -5,9 +5,8 @@ */ import { renderHook, act } from '@testing-library/react-hooks'; -import { useRules, ReturnRules } from './use_rules'; +import { useRules, UseRules, ReturnRules } from './use_rules'; import * as api from './api'; -import { PaginationOptions, FilterOptions } from '.'; jest.mock('./api'); @@ -17,55 +16,40 @@ describe('useRules', () => { }); test('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook< - [PaginationOptions, FilterOptions], - ReturnRules - >(props => - useRules( - { + const { result, waitForNextUpdate } = renderHook(props => + useRules({ + pagination: { page: 1, perPage: 10, total: 100, }, - { + filterOptions: { filter: '', sortField: 'created_at', sortOrder: 'desc', - } - ) + }, + }) ); await waitForNextUpdate(); - expect(result.current).toEqual([ - true, - { - data: [], - page: 1, - perPage: 20, - total: 0, - }, - null, - ]); + expect(result.current).toEqual([true, null, result.current[2]]); }); }); test('fetch rules', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook< - [PaginationOptions, FilterOptions], - ReturnRules - >(() => - useRules( - { + const { result, waitForNextUpdate } = renderHook(() => + useRules({ + pagination: { page: 1, perPage: 10, total: 100, }, - { + filterOptions: { filter: '', sortField: 'created_at', sortOrder: 'desc', - } - ) + }, + }) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -148,22 +132,19 @@ describe('useRules', () => { test('re-fetch rules', async () => { const spyOnfetchRules = jest.spyOn(api, 'fetchRules'); await act(async () => { - const { result, waitForNextUpdate } = renderHook< - [PaginationOptions, FilterOptions], - ReturnRules - >(id => - useRules( - { + const { result, waitForNextUpdate } = renderHook(id => + useRules({ + pagination: { page: 1, perPage: 10, total: 100, }, - { + filterOptions: { filter: '', sortField: 'created_at', sortOrder: 'desc', - } - ) + }, + }) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -178,37 +159,37 @@ describe('useRules', () => { test('fetch rules if props changes', async () => { const spyOnfetchRules = jest.spyOn(api, 'fetchRules'); await act(async () => { - const { rerender, waitForNextUpdate } = renderHook< - [PaginationOptions, FilterOptions], - ReturnRules - >(args => useRules(args[0], args[1]), { - initialProps: [ - { - page: 1, - perPage: 10, - total: 100, - }, - { - filter: '', - sortField: 'created_at', - sortOrder: 'desc', + const { rerender, waitForNextUpdate } = renderHook( + args => useRules(args), + { + initialProps: { + pagination: { + page: 1, + perPage: 10, + total: 100, + }, + filterOptions: { + filter: '', + sortField: 'created_at', + sortOrder: 'desc', + }, }, - ], - }); + } + ); await waitForNextUpdate(); await waitForNextUpdate(); - rerender([ - { + rerender({ + pagination: { page: 1, perPage: 10, total: 100, }, - { + filterOptions: { filter: 'hello world', sortField: 'created_at', sortOrder: 'desc', }, - ]); + }); await waitForNextUpdate(); expect(spyOnfetchRules).toHaveBeenCalledTimes(2); }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx index 301a68dc6f445f..d05d59d15802d7 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_rules.tsx @@ -4,16 +4,27 @@ * you may not use this file except in compliance with the Elastic License. */ +import { noop } from 'lodash/fp'; import { useEffect, useState, useRef } from 'react'; -import { FetchRulesResponse, FilterOptions, PaginationOptions } from './types'; +import { FetchRulesResponse, FilterOptions, PaginationOptions, Rule } from './types'; import { useStateToaster } from '../../../components/toasters'; import { fetchRules } from './api'; import { errorToToaster } from '../../../components/ml/api/error_to_toaster'; import * as i18n from './translations'; -type Func = () => void; -export type ReturnRules = [boolean, FetchRulesResponse, Func | null]; +export type ReturnRules = [ + boolean, + FetchRulesResponse | null, + (refreshPrePackagedRule?: boolean) => void +]; + +export interface UseRules { + pagination: PaginationOptions; + filterOptions: FilterOptions; + refetchPrePackagedRulesStatus?: () => void; + dispatchRulesInReducer?: (rules: Rule[]) => void; +} /** * Hook for using the list of Rules from the Detection Engine API @@ -21,17 +32,14 @@ export type ReturnRules = [boolean, FetchRulesResponse, Func | null]; * @param pagination desired pagination options (e.g. page/perPage) * @param filterOptions desired filters (e.g. filter/sortField/sortOrder) */ -export const useRules = ( - pagination: PaginationOptions, - filterOptions: FilterOptions -): ReturnRules => { - const [rules, setRules] = useState({ - page: 1, - perPage: 20, - total: 0, - data: [], - }); - const reFetchRules = useRef(null); +export const useRules = ({ + pagination, + filterOptions, + refetchPrePackagedRulesStatus, + dispatchRulesInReducer, +}: UseRules): ReturnRules => { + const [rules, setRules] = useState(null); + const reFetchRules = useRef<(refreshPrePackagedRule?: boolean) => void>(noop); const [loading, setLoading] = useState(true); const [, dispatchToaster] = useStateToaster(); @@ -50,10 +58,16 @@ export const useRules = ( if (isSubscribed) { setRules(fetchRulesResult); + if (dispatchRulesInReducer != null) { + dispatchRulesInReducer(fetchRulesResult.data); + } } } catch (error) { if (isSubscribed) { errorToToaster({ title: i18n.RULE_FETCH_FAILURE, error, dispatchToaster }); + if (dispatchRulesInReducer != null) { + dispatchRulesInReducer([]); + } } } if (isSubscribed) { @@ -62,7 +76,12 @@ export const useRules = ( } fetchData(); - reFetchRules.current = fetchData.bind(null, true); + reFetchRules.current = (refreshPrePackagedRule: boolean = false) => { + fetchData(true); + if (refreshPrePackagedRule && refetchPrePackagedRulesStatus != null) { + refetchPrePackagedRulesStatus(); + } + }; return () => { isSubscribed = false; abortCtrl.abort(); @@ -76,6 +95,7 @@ export const useRules = ( filterOptions.tags?.sort().join(), filterOptions.showCustomRules, filterOptions.showElasticRules, + refetchPrePackagedRulesStatus, ]); return [loading, rules, reFetchRules.current]; diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.test.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.test.tsx index 4a796efa5b0cb2..68f54b35754f67 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.test.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.test.tsx @@ -14,7 +14,7 @@ describe('useTags', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook(() => useTags()); await waitForNextUpdate(); - expect(result.current).toEqual([true, []]); + expect(result.current).toEqual([true, [], result.current[2]]); }); }); @@ -23,7 +23,11 @@ describe('useTags', () => { const { result, waitForNextUpdate } = renderHook(() => useTags()); await waitForNextUpdate(); await waitForNextUpdate(); - expect(result.current).toEqual([false, ['elastic', 'love', 'quality', 'code']]); + expect(result.current).toEqual([ + false, + ['elastic', 'love', 'quality', 'code'], + result.current[2], + ]); }); }); }); diff --git a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.tsx b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.tsx index 196d4b14205610..5985200fa16ec9 100644 --- a/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/detection_engine/rules/use_tags.tsx @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useEffect, useState } from 'react'; +import { noop } from 'lodash/fp'; +import { useEffect, useState, useRef } from 'react'; import { useStateToaster } from '../../../components/toasters'; import { fetchTags } from './api'; import { errorToToaster } from '../../../components/ml/api/error_to_toaster'; import * as i18n from './translations'; -export type ReturnTags = [boolean, string[]]; +export type ReturnTags = [boolean, string[], () => void]; /** * Hook for using the list of Tags from the Detection Engine API @@ -20,6 +21,7 @@ export const useTags = (): ReturnTags => { const [tags, setTags] = useState([]); const [loading, setLoading] = useState(true); const [, dispatchToaster] = useStateToaster(); + const reFetchTags = useRef<() => void>(noop); useEffect(() => { let isSubscribed = true; @@ -46,6 +48,7 @@ export const useTags = (): ReturnTags => { } fetchData(); + reFetchTags.current = fetchData; return () => { isSubscribed = false; @@ -53,5 +56,5 @@ export const useTags = (): ReturnTags => { }; }, []); - return [loading, tags]; + return [loading, tags, reFetchTags.current]; }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts index 980575f1470a5a..e2287e5eeeb3fc 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/__mocks__/mock.ts @@ -5,7 +5,6 @@ */ import { Rule, RuleError } from '../../../../../containers/detection_engine/rules'; -import { TableData } from '../../types'; export const mockRule = (id: string): Rule => ({ created_at: '2020-01-10T21:11:45.839Z', @@ -50,103 +49,3 @@ export const mockRules: Rule[] = [ mockRule('abe6c564-050d-45a5-aaf0-386c37dd1f61'), mockRule('63f06f34-c181-4b2d-af35-f2ace572a1ee'), ]; -export const mockTableData: TableData[] = [ - { - activate: true, - id: 'abe6c564-050d-45a5-aaf0-386c37dd1f61', - immutable: false, - isLoading: false, - risk_score: 21, - rule: { - href: '#/detections/rules/id/abe6c564-050d-45a5-aaf0-386c37dd1f61', - name: 'Home Grown!', - }, - rule_id: 'b5ba41ab-aaf3-4f43-971b-bdf9434ce0ea', - severity: 'low', - sourceRule: { - created_at: '2020-01-10T21:11:45.839Z', - created_by: 'elastic', - description: '24/7', - enabled: true, - false_positives: [], - filters: [], - from: 'now-300s', - id: 'abe6c564-050d-45a5-aaf0-386c37dd1f61', - immutable: false, - index: ['auditbeat-*'], - interval: '5m', - language: 'kuery', - max_signals: 100, - meta: { from: '0m' }, - name: 'Home Grown!', - output_index: '.siem-signals-default', - query: '', - references: [], - risk_score: 21, - rule_id: 'b5ba41ab-aaf3-4f43-971b-bdf9434ce0ea', - saved_id: "Garrett's IP", - severity: 'low', - tags: [], - threat: [], - timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', - timeline_title: 'Untitled timeline', - to: 'now', - type: 'saved_query', - updated_at: '2020-01-10T21:11:45.839Z', - updated_by: 'elastic', - version: 1, - }, - status: null, - statusDate: null, - tags: [], - }, - { - activate: true, - id: '63f06f34-c181-4b2d-af35-f2ace572a1ee', - immutable: false, - isLoading: false, - risk_score: 21, - rule: { - href: '#/detections/rules/id/63f06f34-c181-4b2d-af35-f2ace572a1ee', - name: 'Home Grown!', - }, - rule_id: 'b5ba41ab-aaf3-4f43-971b-bdf9434ce0ea', - severity: 'low', - sourceRule: { - created_at: '2020-01-10T21:11:45.839Z', - created_by: 'elastic', - description: '24/7', - enabled: true, - false_positives: [], - filters: [], - from: 'now-300s', - id: '63f06f34-c181-4b2d-af35-f2ace572a1ee', - immutable: false, - index: ['auditbeat-*'], - interval: '5m', - language: 'kuery', - max_signals: 100, - meta: { from: '0m' }, - name: 'Home Grown!', - output_index: '.siem-signals-default', - query: '', - references: [], - risk_score: 21, - rule_id: 'b5ba41ab-aaf3-4f43-971b-bdf9434ce0ea', - saved_id: "Garrett's IP", - severity: 'low', - tags: [], - threat: [], - timeline_id: '86aa74d0-2136-11ea-9864-ebc8cc1cb8c2', - timeline_title: 'Untitled timeline', - to: 'now', - type: 'saved_query', - updated_at: '2020-01-10T21:11:45.839Z', - updated_by: 'elastic', - version: 1, - }, - status: null, - statusDate: null, - tags: [], - }, -]; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx index 6212c2067384d9..a17fd34d1c3449 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/actions.tsx @@ -32,53 +32,58 @@ export const editRuleAction = (rule: Rule, history: H.History) => { export const duplicateRulesAction = async ( rules: Rule[], + ruleIds: string[], dispatch: React.Dispatch, dispatchToaster: Dispatch ) => { try { - const ruleIds = rules.map(r => r.id); - dispatch({ type: 'updateLoading', ids: ruleIds, isLoading: true }); - const duplicatedRules = await duplicateRules({ rules }); - dispatch({ type: 'refresh' }); - displaySuccessToast( - i18n.SUCCESSFULLY_DUPLICATED_RULES(duplicatedRules.length), - dispatchToaster - ); + dispatch({ type: 'loadingRuleIds', ids: ruleIds, actionType: 'duplicate' }); + const response = await duplicateRules({ rules }); + const { errors } = bucketRulesResponse(response); + if (errors.length > 0) { + displayErrorToast( + i18n.DUPLICATE_RULE_ERROR, + errors.map(e => e.error.message), + dispatchToaster + ); + } else { + displaySuccessToast(i18n.SUCCESSFULLY_DUPLICATED_RULES(ruleIds.length), dispatchToaster); + } + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); } catch (e) { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); displayErrorToast(i18n.DUPLICATE_RULE_ERROR, [e.message], dispatchToaster); } }; -export const exportRulesAction = async (rules: Rule[], dispatch: React.Dispatch) => { - dispatch({ type: 'setExportPayload', exportPayload: rules }); +export const exportRulesAction = (exportRuleId: string[], dispatch: React.Dispatch) => { + dispatch({ type: 'exportRuleIds', ids: exportRuleId }); }; export const deleteRulesAction = async ( - ids: string[], + ruleIds: string[], dispatch: React.Dispatch, dispatchToaster: Dispatch, onRuleDeleted?: () => void ) => { try { - dispatch({ type: 'loading', isLoading: true }); - - const response = await deleteRules({ ids }); + dispatch({ type: 'loadingRuleIds', ids: ruleIds, actionType: 'delete' }); + const response = await deleteRules({ ids: ruleIds }); const { errors } = bucketRulesResponse(response); - - dispatch({ type: 'refresh' }); + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); if (errors.length > 0) { displayErrorToast( - i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ids.length), + i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ruleIds.length), errors.map(e => e.error.message), dispatchToaster ); - } else { - // FP: See https://github.com/typescript-eslint/typescript-eslint/issues/1138#issuecomment-566929566 - onRuleDeleted?.(); // eslint-disable-line no-unused-expressions + } else if (onRuleDeleted) { + onRuleDeleted(); } } catch (e) { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); displayErrorToast( - i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ids.length), + i18n.BATCH_ACTION_DELETE_SELECTED_ERROR(ruleIds.length), [e.message], dispatchToaster ); @@ -96,7 +101,7 @@ export const enableRulesAction = async ( : i18n.BATCH_ACTION_DEACTIVATE_SELECTED_ERROR(ids.length); try { - dispatch({ type: 'updateLoading', ids, isLoading: true }); + dispatch({ type: 'loadingRuleIds', ids, actionType: enabled ? 'enable' : 'disable' }); const response = await enableRules({ ids, enabled }); const { rules, errors } = bucketRulesResponse(response); @@ -125,6 +130,6 @@ export const enableRulesAction = async ( } } catch (e) { displayErrorToast(errorTitle, [e.message], dispatchToaster); - dispatch({ type: 'updateLoading', ids, isLoading: false }); + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); } }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx index 8a10d4f7100b94..a0942d7f6534af 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/batch_actions.tsx @@ -6,9 +6,7 @@ import { EuiContextMenuItem } from '@elastic/eui'; import React, { Dispatch } from 'react'; -import * as H from 'history'; import * as i18n from '../translations'; -import { TableData } from '../types'; import { Action } from './reducer'; import { deleteRulesAction, @@ -17,18 +15,37 @@ import { exportRulesAction, } from './actions'; import { ActionToaster } from '../../../../components/toasters'; +import { Rule } from '../../../../containers/detection_engine/rules'; -export const getBatchItems = ( - selectedState: TableData[], - dispatch: Dispatch, - dispatchToaster: Dispatch, - history: H.History, - closePopover: () => void -) => { - const containsEnabled = selectedState.some(v => v.activate); - const containsDisabled = selectedState.some(v => !v.activate); - const containsLoading = selectedState.some(v => v.isLoading); - const containsImmutable = selectedState.some(v => v.immutable); +interface GetBatchItems { + closePopover: () => void; + dispatch: Dispatch; + dispatchToaster: Dispatch; + loadingRuleIds: string[]; + reFetchRules: (refreshPrePackagedRule?: boolean) => void; + rules: Rule[]; + selectedRuleIds: string[]; +} + +export const getBatchItems = ({ + closePopover, + dispatch, + dispatchToaster, + loadingRuleIds, + reFetchRules, + rules, + selectedRuleIds, +}: GetBatchItems) => { + const containsEnabled = selectedRuleIds.some( + id => rules.find(r => r.id === id)?.enabled ?? false + ); + const containsDisabled = selectedRuleIds.some( + id => !rules.find(r => r.id === id)?.enabled ?? false + ); + const containsLoading = selectedRuleIds.some(id => loadingRuleIds.includes(id)); + const containsImmutable = selectedRuleIds.some( + id => rules.find(r => r.id === id)?.immutable ?? false + ); return [ { closePopover(); - const deactivatedIds = selectedState.filter(s => !s.activate).map(s => s.id); + const deactivatedIds = selectedRuleIds.filter( + id => !rules.find(r => r.id === id)?.enabled ?? false + ); await enableRulesAction(deactivatedIds, true, dispatch, dispatchToaster); }} > @@ -49,7 +68,9 @@ export const getBatchItems = ( disabled={containsLoading || !containsEnabled} onClick={async () => { closePopover(); - const activatedIds = selectedState.filter(s => s.activate).map(s => s.id); + const activatedIds = selectedRuleIds.filter( + id => rules.find(r => r.id === id)?.enabled ?? false + ); await enableRulesAction(activatedIds, false, dispatch, dispatchToaster); }} > @@ -58,11 +79,11 @@ export const getBatchItems = ( { + disabled={containsImmutable || containsLoading || selectedRuleIds.length === 0} + onClick={() => { closePopover(); - await exportRulesAction( - selectedState.map(s => s.sourceRule), + exportRulesAction( + rules.filter(r => selectedRuleIds.includes(r.id)).map(r => r.rule_id), dispatch ); }} @@ -72,14 +93,16 @@ export const getBatchItems = ( { closePopover(); await duplicateRulesAction( - selectedState.map(s => s.sourceRule), + rules.filter(r => selectedRuleIds.includes(r.id)), + selectedRuleIds, dispatch, dispatchToaster ); + reFetchRules(true); }} > {i18n.BATCH_ACTION_DUPLICATE_SELECTED} @@ -88,14 +111,11 @@ export const getBatchItems = ( key={i18n.BATCH_ACTION_DELETE_SELECTED} icon="trash" title={containsImmutable ? i18n.BATCH_ACTION_DELETE_SELECTED_IMMUTABLE : undefined} - disabled={containsLoading || selectedState.length === 0} + disabled={containsLoading || selectedRuleIds.length === 0} onClick={async () => { closePopover(); - await deleteRulesAction( - selectedState.map(({ sourceRule: { id } }) => id), - dispatch, - dispatchToaster - ); + await deleteRulesAction(selectedRuleIds, dispatch, dispatchToaster); + reFetchRules(true); }} > {i18n.BATCH_ACTION_DELETE_SELECTED} diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx index d648854368c28b..ff104f09d68efd 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/columns.tsx @@ -15,72 +15,92 @@ import { } from '@elastic/eui'; import * as H from 'history'; import React, { Dispatch } from 'react'; + +import { Rule } from '../../../../containers/detection_engine/rules'; import { getEmptyTagValue } from '../../../../components/empty_value'; +import { FormattedDate } from '../../../../components/formatted_date'; +import { getRuleDetailsUrl } from '../../../../components/link_to/redirect_to_detection_engine'; +import { ActionToaster } from '../../../../components/toasters'; +import { TruncatableText } from '../../../../components/truncatable_text'; +import { getStatusColor } from '../components/rule_status/helpers'; +import { RuleSwitch } from '../components/rule_switch'; +import { SeverityBadge } from '../components/severity_badge'; +import * as i18n from '../translations'; import { deleteRulesAction, duplicateRulesAction, editRuleAction, exportRulesAction, } from './actions'; - import { Action } from './reducer'; -import { TableData } from '../types'; -import * as i18n from '../translations'; -import { FormattedDate } from '../../../../components/formatted_date'; -import { RuleSwitch } from '../components/rule_switch'; -import { SeverityBadge } from '../components/severity_badge'; -import { ActionToaster } from '../../../../components/toasters'; -import { getStatusColor } from '../components/rule_status/helpers'; -import { TruncatableText } from '../../../../components/truncatable_text'; const getActions = ( dispatch: React.Dispatch, dispatchToaster: Dispatch, - history: H.History + history: H.History, + reFetchRules: (refreshPrePackagedRule?: boolean) => void ) => [ { description: i18n.EDIT_RULE_SETTINGS, icon: 'visControls', name: i18n.EDIT_RULE_SETTINGS, - onClick: (rowItem: TableData) => editRuleAction(rowItem.sourceRule, history), - enabled: (rowItem: TableData) => !rowItem.sourceRule.immutable, + onClick: (rowItem: Rule) => editRuleAction(rowItem, history), + enabled: (rowItem: Rule) => !rowItem.immutable, }, { description: i18n.DUPLICATE_RULE, icon: 'copy', name: i18n.DUPLICATE_RULE, - onClick: (rowItem: TableData) => - duplicateRulesAction([rowItem.sourceRule], dispatch, dispatchToaster), + onClick: (rowItem: Rule) => { + duplicateRulesAction([rowItem], [rowItem.id], dispatch, dispatchToaster); + reFetchRules(true); + }, }, { description: i18n.EXPORT_RULE, icon: 'exportAction', name: i18n.EXPORT_RULE, - onClick: (rowItem: TableData) => exportRulesAction([rowItem.sourceRule], dispatch), - enabled: (rowItem: TableData) => !rowItem.immutable, + onClick: (rowItem: Rule) => exportRulesAction([rowItem.rule_id], dispatch), + enabled: (rowItem: Rule) => !rowItem.immutable, }, { description: i18n.DELETE_RULE, icon: 'trash', name: i18n.DELETE_RULE, - onClick: (rowItem: TableData) => deleteRulesAction([rowItem.id], dispatch, dispatchToaster), + onClick: (rowItem: Rule) => { + deleteRulesAction([rowItem.id], dispatch, dispatchToaster); + reFetchRules(true); + }, }, ]; -type RulesColumns = EuiBasicTableColumn | EuiTableActionsColumnType; +type RulesColumns = EuiBasicTableColumn | EuiTableActionsColumnType; + +interface GetColumns { + dispatch: React.Dispatch; + dispatchToaster: Dispatch; + history: H.History; + hasNoPermissions: boolean; + loadingRuleIds: string[]; + reFetchRules: (refreshPrePackagedRule?: boolean) => void; +} // Michael: Are we able to do custom, in-table-header filters, as shown in my wireframes? -export const getColumns = ( - dispatch: React.Dispatch, - dispatchToaster: Dispatch, - history: H.History, - hasNoPermissions: boolean -): RulesColumns[] => { +export const getColumns = ({ + dispatch, + dispatchToaster, + history, + hasNoPermissions, + loadingRuleIds, + reFetchRules, +}: GetColumns): RulesColumns[] => { const cols: RulesColumns[] = [ { - field: 'rule', + field: 'name', name: i18n.COLUMN_RULE, - render: (value: TableData['rule']) => {value.name}, + render: (value: Rule['name'], item: Rule) => ( + {value} + ), truncateText: true, width: '24%', }, @@ -93,14 +113,14 @@ export const getColumns = ( { field: 'severity', name: i18n.COLUMN_SEVERITY, - render: (value: TableData['severity']) => , + render: (value: Rule['severity']) => , truncateText: true, width: '16%', }, { - field: 'statusDate', + field: 'status_date', name: i18n.COLUMN_LAST_COMPLETE_RUN, - render: (value: TableData['statusDate']) => { + render: (value: Rule['status_date']) => { return value == null ? ( getEmptyTagValue() ) : ( @@ -114,7 +134,7 @@ export const getColumns = ( { field: 'status', name: i18n.COLUMN_LAST_RESPONSE, - render: (value: TableData['status']) => { + render: (value: Rule['status']) => { return ( <> @@ -129,7 +149,7 @@ export const getColumns = ( { field: 'tags', name: i18n.COLUMN_TAGS, - render: (value: TableData['tags']) => ( + render: (value: Rule['tags']) => ( {value.map((tag, i) => ( @@ -145,13 +165,13 @@ export const getColumns = ( align: 'center', field: 'activate', name: i18n.COLUMN_ACTIVATE, - render: (value: TableData['activate'], item: TableData) => ( + render: (value: Rule['enabled'], item: Rule) => ( ), sortable: true, @@ -160,9 +180,9 @@ export const getColumns = ( ]; const actions: RulesColumns[] = [ { - actions: getActions(dispatch, dispatchToaster, history), + actions: getActions(dispatch, dispatchToaster, history, reFetchRules), width: '40px', - } as EuiTableActionsColumnType, + } as EuiTableActionsColumnType, ]; return hasNoPermissions ? cols : [...cols, ...actions]; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.test.tsx index e925161444e424..c60933733587d0 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.test.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.test.tsx @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { bucketRulesResponse, formatRules } from './helpers'; -import { mockRule, mockRuleError, mockRules, mockTableData } from './__mocks__/mock'; +import { bucketRulesResponse } from './helpers'; +import { mockRule, mockRuleError } from './__mocks__/mock'; import uuid from 'uuid'; import { Rule, RuleError } from '../../../../containers/detection_engine/rules'; @@ -15,20 +15,6 @@ describe('AllRulesTable Helpers', () => { const mockRuleError1: Readonly = mockRuleError(uuid.v4()); const mockRuleError2: Readonly = mockRuleError(uuid.v4()); - describe('formatRules', () => { - test('formats rules with no selection', () => { - const formattedRules = formatRules(mockRules); - expect(formattedRules).toEqual(mockTableData); - }); - - test('formats rules with selection', () => { - const mockTableDataWithSelected = [...mockTableData]; - mockTableDataWithSelected[0].isLoading = true; - const formattedRules = formatRules(mockRules, [mockRules[0].id]); - expect(formattedRules).toEqual(mockTableDataWithSelected); - }); - }); - describe('bucketRulesResponse', () => { test('buckets empty response', () => { const bucketedResponse = bucketRulesResponse([]); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.ts index 9a523536694d93..5ce26144a4d9cf 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/helpers.ts @@ -9,32 +9,6 @@ import { RuleError, RuleResponseBuckets, } from '../../../../containers/detection_engine/rules'; -import { TableData } from '../types'; - -/** - * Formats rules into the correct format for the AllRulesTable - * - * @param rules as returned from the Rules API - * @param selectedIds ids of the currently selected rules - */ -export const formatRules = (rules: Rule[], selectedIds?: string[]): TableData[] => - rules.map(rule => ({ - id: rule.id, - immutable: rule.immutable, - rule_id: rule.rule_id, - rule: { - href: `#/detections/rules/id/${encodeURIComponent(rule.id)}`, - name: rule.name, - }, - risk_score: rule.risk_score, - severity: rule.severity, - tags: rule.tags ?? [], - activate: rule.enabled, - status: rule.status ?? null, - statusDate: rule.status_date ?? null, - sourceRule: rule, - isLoading: selectedIds?.includes(rule.id) ?? false, - })); /** * Separates rules/errors from bulk rules API response (create/update/delete) @@ -52,14 +26,11 @@ export const bucketRulesResponse = (response: Array) => ); export const showRulesTable = ({ - isInitialLoad, rulesCustomInstalled, rulesInstalled, }: { - isInitialLoad: boolean; rulesCustomInstalled: number | null; rulesInstalled: number | null; }) => - !isInitialLoad && - ((rulesCustomInstalled != null && rulesCustomInstalled > 0) || - (rulesInstalled != null && rulesInstalled > 0)); + (rulesCustomInstalled != null && rulesCustomInstalled > 0) || + (rulesInstalled != null && rulesInstalled > 0); diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx index b304d77f2e2767..79fec526faf48b 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/index.tsx @@ -11,15 +11,16 @@ import { EuiLoadingContent, EuiSpacer, } from '@elastic/eui'; -import { isEmpty } from 'lodash/fp'; -import React, { useCallback, useEffect, useMemo, useReducer, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'; import { useHistory } from 'react-router-dom'; +import styled from 'styled-components'; import uuid from 'uuid'; import { useRules, CreatePreBuiltRules, FilterOptions, + Rule, } from '../../../../containers/detection_engine/rules'; import { HeaderSection } from '../../../../components/header_section'; import { @@ -36,35 +37,39 @@ import { PrePackagedRulesPrompt } from '../components/pre_packaged_rules/load_em import { RuleDownloader } from '../components/rule_downloader'; import { getPrePackagedRuleStatus } from '../helpers'; import * as i18n from '../translations'; -import { EuiBasicTableOnChange, TableData } from '../types'; +import { EuiBasicTableOnChange } from '../types'; import { getBatchItems } from './batch_actions'; import { getColumns } from './columns'; import { showRulesTable } from './helpers'; import { allRulesReducer, State } from './reducer'; import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; +// EuiBasicTable give me a hardtime with adding the ref attributes so I went the easy way +// after few hours of fight with typescript !!!! I lost :( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const MyEuiBasicTable = styled(EuiBasicTable as any)`` as any; + const initialState: State = { - isLoading: true, - rules: [], - tableData: [], - selectedItems: [], - refreshToggle: true, - pagination: { - page: 1, - perPage: 20, - total: 0, - }, + exportRuleIds: [], filterOptions: { filter: '', sortField: 'enabled', sortOrder: 'desc', }, + loadingRuleIds: [], + loadingRulesAction: null, + pagination: { + page: 1, + perPage: 20, + total: 0, + }, + rules: [], + selectedRuleIds: [], }; interface AllRulesProps { createPrePackagedRules: CreatePreBuiltRules | null; hasNoPermissions: boolean; - importCompleteToggle: boolean; loading: boolean; loadingCreatePrePackagedRules: boolean; refetchPrePackagedRulesStatus: () => void; @@ -72,7 +77,7 @@ interface AllRulesProps { rulesInstalled: number | null; rulesNotInstalled: number | null; rulesNotUpdated: number | null; - setRefreshRulesData: (refreshRule: () => void) => void; + setRefreshRulesData: (refreshRule: (refreshPrePackagedRule?: boolean) => void) => void; } /** @@ -87,7 +92,6 @@ export const AllRules = React.memo( ({ createPrePackagedRules, hasNoPermissions, - importCompleteToggle, loading, loadingCreatePrePackagedRules, refetchPrePackagedRulesStatus, @@ -97,24 +101,36 @@ export const AllRules = React.memo( rulesNotUpdated, setRefreshRulesData, }) => { + const [initLoading, setInitLoading] = useState(true); + const tableRef = useRef(); const [ { - exportPayload, + exportRuleIds, filterOptions, - isLoading, - refreshToggle, - selectedItems, - tableData, + loadingRuleIds, + loadingRulesAction, pagination, + rules, + selectedRuleIds, }, dispatch, - ] = useReducer(allRulesReducer, initialState); + ] = useReducer(allRulesReducer(tableRef), initialState); const history = useHistory(); - const [oldRefreshToggle, setOldRefreshToggle] = useState(refreshToggle); - const [isInitialLoad, setIsInitialLoad] = useState(true); - const [isGlobalLoading, setIsGlobalLoad] = useState(false); const [, dispatchToaster] = useStateToaster(); - const [isLoadingRules, rulesData, reFetchRulesData] = useRules(pagination, filterOptions); + + const setRules = useCallback((newRules: Rule[]) => { + dispatch({ + type: 'setRules', + rules: newRules, + }); + }, []); + + const [isLoadingRules, , reFetchRulesData] = useRules({ + pagination, + filterOptions, + refetchPrePackagedRulesStatus, + dispatchRulesInReducer: setRules, + }); const prePackagedRuleStatus = getPrePackagedRuleStatus( rulesInstalled, @@ -125,10 +141,18 @@ export const AllRules = React.memo( const getBatchItemsPopoverContent = useCallback( (closePopover: () => void) => ( ), - [selectedItems, dispatch, dispatchToaster, history] + [dispatch, dispatchToaster, loadingRuleIds, reFetchRulesData, rules, selectedRuleIds] ); const tableOnChangeCallback = useCallback( @@ -146,46 +170,19 @@ export const AllRules = React.memo( ); const columns = useMemo(() => { - return getColumns(dispatch, dispatchToaster, history, hasNoPermissions); - }, [dispatch, dispatchToaster, history]); - - useEffect(() => { - dispatch({ type: 'loading', isLoading: isLoadingRules }); - }, [isLoadingRules]); - - useEffect(() => { - if (!isLoadingRules && !loading && isInitialLoad) { - setIsInitialLoad(false); - } - }, [isInitialLoad, isLoadingRules, loading]); - - useEffect(() => { - if (!isGlobalLoading && (isLoadingRules || isLoading)) { - setIsGlobalLoad(true); - } else if (isGlobalLoading && !isLoadingRules && !isLoading) { - setIsGlobalLoad(false); - } - }, [setIsGlobalLoad, isGlobalLoading, isLoadingRules, isLoading]); - - useEffect(() => { - if (!isInitialLoad) { - dispatch({ type: 'refresh' }); - } - }, [importCompleteToggle]); - - useEffect(() => { - if (!isInitialLoad && reFetchRulesData != null && oldRefreshToggle !== refreshToggle) { - setOldRefreshToggle(refreshToggle); - reFetchRulesData(); - refetchPrePackagedRulesStatus(); - } - }, [ - isInitialLoad, - refreshToggle, - oldRefreshToggle, - reFetchRulesData, - refetchPrePackagedRulesStatus, - ]); + return getColumns({ + dispatch, + dispatchToaster, + history, + hasNoPermissions, + loadingRuleIds: + loadingRulesAction != null && + (loadingRulesAction === 'enable' || loadingRulesAction === 'disable') + ? loadingRuleIds + : [], + reFetchRules: reFetchRulesData, + }); + }, [dispatch, dispatchToaster, history, loadingRuleIds, loadingRulesAction, reFetchRulesData]); useEffect(() => { if (reFetchRulesData != null) { @@ -194,31 +191,25 @@ export const AllRules = React.memo( }, [reFetchRulesData, setRefreshRulesData]); useEffect(() => { - dispatch({ - type: 'updateRules', - rules: rulesData.data, - pagination: { - page: rulesData.page, - perPage: rulesData.perPage, - total: rulesData.total, - }, - }); - }, [rulesData]); + if (initLoading && !loading && !isLoadingRules) { + setInitLoading(false); + } + }, [initLoading, loading, isLoadingRules]); const handleCreatePrePackagedRules = useCallback(async () => { - if (createPrePackagedRules != null) { + if (createPrePackagedRules != null && reFetchRulesData != null) { await createPrePackagedRules(); - dispatch({ type: 'refresh' }); + reFetchRulesData(true); } - }, [createPrePackagedRules]); + }, [createPrePackagedRules, reFetchRulesData]); const euiBasicTableSelectionProps = useMemo( () => ({ - selectable: (item: TableData) => !item.isLoading, - onSelectionChange: (selected: TableData[]) => - dispatch({ type: 'setSelected', selectedItems: selected }), + selectable: (item: Rule) => !loadingRuleIds.includes(item.id), + onSelectionChange: (selected: Rule[]) => + dispatch({ type: 'selectedRuleIds', ids: selected.map(r => r.id) }), }), - [] + [loadingRuleIds] ); const onFilterChangedCallback = useCallback((newFilterOptions: Partial) => { @@ -237,12 +228,25 @@ export const AllRules = React.memo( ); }, []); + const isLoadingAnActionOnRule = useMemo(() => { + if ( + loadingRuleIds.length > 0 && + (loadingRulesAction === 'disable' || loadingRulesAction === 'enable') + ) { + return false; + } else if (loadingRuleIds.length > 0) { + return true; + } + return false; + }, [loadingRuleIds, loadingRulesAction]); + return ( <> { + dispatch({ type: 'loadingRuleIds', ids: [], actionType: null }); dispatchToaster({ type: 'addToaster', toast: { @@ -256,22 +260,17 @@ export const AllRules = React.memo( /> - + <> - {((rulesCustomInstalled && rulesCustomInstalled > 0) || - (rulesInstalled != null && rulesInstalled > 0)) && ( - - - - )} - {isInitialLoad && ( - - )} - {isGlobalLoading && !isEmpty(tableData) && !isInitialLoad && ( + + + + + {(loading || isLoadingRules || isLoadingAnActionOnRule) && !initLoading && ( )} {rulesCustomInstalled != null && @@ -283,7 +282,10 @@ export const AllRules = React.memo( userHasNoPermissions={hasNoPermissions} /> )} - {showRulesTable({ isInitialLoad, rulesCustomInstalled, rulesInstalled }) && ( + {initLoading && ( + + )} + {showRulesTable({ rulesCustomInstalled, rulesInstalled }) && !initLoading && ( <> @@ -292,7 +294,7 @@ export const AllRules = React.memo( - {i18n.SELECTED_RULES(selectedItems.length)} + {i18n.SELECTED_RULES(selectedRuleIds.length)} {!hasNoPermissions && ( ( )} dispatch({ type: 'refresh' })} + onClick={() => reFetchRulesData(true)} > {i18n.REFRESH} - - ( totalItemCount: pagination.total, pageSizeOptions: [5, 10, 20, 50, 100, 200, 300], }} - sorting={{ sort: { field: 'activate', direction: filterOptions.sortOrder } }} + ref={tableRef} + sorting={{ sort: { field: 'enabled', direction: filterOptions.sortOrder } }} selection={hasNoPermissions ? undefined : euiBasicTableSelectionProps} /> diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/reducer.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/reducer.ts index 3634a16cbf6ac3..54da43efd66d95 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/reducer.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/reducer.ts @@ -4,34 +4,30 @@ * you may not use this file except in compliance with the Elastic License. */ +import { EuiBasicTable } from '@elastic/eui'; import { FilterOptions, PaginationOptions, Rule, } from '../../../../containers/detection_engine/rules'; -import { TableData } from '../types'; -import { formatRules } from './helpers'; +type LoadingRuleAction = 'duplicate' | 'enable' | 'disable' | 'export' | 'delete' | null; export interface State { - isLoading: boolean; - rules: Rule[]; - selectedItems: TableData[]; - pagination: PaginationOptions; + exportRuleIds: string[]; filterOptions: FilterOptions; - refreshToggle: boolean; - tableData: TableData[]; - exportPayload?: Rule[]; + loadingRuleIds: string[]; + loadingRulesAction: LoadingRuleAction; + pagination: PaginationOptions; + rules: Rule[]; + selectedRuleIds: string[]; } export type Action = - | { type: 'refresh' } - | { type: 'loading'; isLoading: boolean } - | { type: 'deleteRules'; rules: Rule[] } - | { type: 'duplicate'; rule: Rule } - | { type: 'setExportPayload'; exportPayload?: Rule[] } - | { type: 'setSelected'; selectedItems: TableData[] } - | { type: 'updateLoading'; ids: string[]; isLoading: boolean } - | { type: 'updateRules'; rules: Rule[]; pagination?: PaginationOptions } + | { type: 'exportRuleIds'; ids: string[] } + | { type: 'loadingRuleIds'; ids: string[]; actionType: LoadingRuleAction } + | { type: 'selectedRuleIds'; ids: string[] } + | { type: 'setRules'; rules: Rule[] } + | { type: 'updateRules'; rules: Rule[] } | { type: 'updatePagination'; pagination: Partial } | { type: 'updateFilterOptions'; @@ -40,54 +36,71 @@ export type Action = } | { type: 'failure' }; -export const allRulesReducer = (state: State, action: Action): State => { +export const allRulesReducer = ( + tableRef: React.MutableRefObject | undefined> +) => (state: State, action: Action): State => { switch (action.type) { - case 'refresh': { + case 'exportRuleIds': { return { ...state, - refreshToggle: !state.refreshToggle, + loadingRuleIds: action.ids, + loadingRulesAction: 'export', + exportRuleIds: action.ids, }; } - case 'updateRules': { - // If pagination included, this was a hard refresh - if (action.pagination) { - return { - ...state, - rules: action.rules, - pagination: action.pagination, - tableData: formatRules(action.rules), - }; + case 'loadingRuleIds': { + return { + ...state, + loadingRuleIds: action.actionType == null ? [] : [...state.loadingRuleIds, ...action.ids], + loadingRulesAction: action.actionType, + }; + } + case 'selectedRuleIds': { + return { + ...state, + selectedRuleIds: action.ids, + }; + } + case 'setRules': { + if ( + tableRef != null && + tableRef.current != null && + tableRef.current.changeSelection != null + ) { + tableRef.current.changeSelection([]); } - const ruleIds = state.rules.map(r => r.rule_id); - const updatedRules = action.rules.reverse().reduce((rules, updatedRule) => { - let newRules = rules; - if (ruleIds.includes(updatedRule.rule_id)) { - newRules = newRules.map(r => (updatedRule.rule_id === r.rule_id ? updatedRule : r)); - } else { - newRules = [...newRules, updatedRule]; - } - return newRules; - }, state.rules); - - // Update enabled on selectedItems so that batch actions show correct available actions - const updatedRuleIdToState = action.rules.reduce>( - (acc, r) => ({ ...acc, [r.id]: r.enabled }), - {} - ); - const updatedSelectedItems = state.selectedItems.map(selectedItem => - Object.keys(updatedRuleIdToState).includes(selectedItem.id) - ? { ...selectedItem, activate: updatedRuleIdToState[selectedItem.id] } - : selectedItem - ); - return { ...state, - rules: updatedRules, - tableData: formatRules(updatedRules), - selectedItems: updatedSelectedItems, + rules: action.rules, + selectedRuleIds: [], + loadingRuleIds: [], + loadingRulesAction: null, }; } + case 'updateRules': { + if (state.rules != null) { + const ruleIds = state.rules.map(r => r.id); + const updatedRules = action.rules.reduce((rules, updatedRule) => { + let newRules = rules; + if (ruleIds.includes(updatedRule.id)) { + newRules = newRules.map(r => (updatedRule.id === r.id ? updatedRule : r)); + } else { + newRules = [...newRules, updatedRule]; + } + return newRules; + }, state.rules); + const updatedRuleIds = action.rules.map(r => r.id); + const newLoadingRuleIds = state.loadingRuleIds.filter(id => !updatedRuleIds.includes(id)); + return { + ...state, + rules: updatedRules, + loadingRuleIds: newLoadingRuleIds, + loadingRulesAction: newLoadingRuleIds.length === 0 ? null : state.loadingRulesAction, + }; + } + return state; + } case 'updatePagination': { return { ...state, @@ -110,51 +123,12 @@ export const allRulesReducer = (state: State, action: Action): State => { }, }; } - case 'deleteRules': { - const deletedRuleIds = action.rules.map(r => r.rule_id); - const updatedRules = state.rules.reduce( - (rules, rule) => (deletedRuleIds.includes(rule.rule_id) ? rules : [...rules, rule]), - [] - ); - return { - ...state, - rules: updatedRules, - tableData: formatRules(updatedRules), - refreshToggle: !state.refreshToggle, - }; - } - case 'setSelected': { - return { - ...state, - selectedItems: action.selectedItems, - }; - } - case 'updateLoading': { - return { - ...state, - rules: state.rules, - tableData: formatRules(state.rules, action.ids), - }; - } - case 'loading': { - return { - ...state, - isLoading: action.isLoading, - }; - } case 'failure': { return { ...state, - isLoading: false, rules: [], }; } - case 'setExportPayload': { - return { - ...state, - exportPayload: [...(action.exportPayload ?? [])], - }; - } default: return state; } diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx index fa4f6a874ca5ed..ddb8894c206b56 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx @@ -41,7 +41,11 @@ const RulesTableFiltersComponent = ({ const [selectedTags, setSelectedTags] = useState([]); const [showCustomRules, setShowCustomRules] = useState(false); const [showElasticRules, setShowElasticRules] = useState(false); - const [isLoadingTags, tags] = useTags(); + const [isLoadingTags, tags, reFetchTags] = useTags(); + + useEffect(() => { + reFetchTags(); + }, [rulesCustomInstalled, rulesInstalled]); // Propagate filter changes to parent useEffect(() => { diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/__snapshots__/index.test.tsx.snap b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/__snapshots__/index.test.tsx.snap index 9bd2fab23ac99c..9355d0ae2cccbc 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/__snapshots__/index.test.tsx.snap +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/__snapshots__/index.test.tsx.snap @@ -58,6 +58,7 @@ exports[`RuleActionsOverflow renders correctly against snapshot 1`] = ` `; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/index.tsx index b52c10881cf42e..7c8926c2064c72 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_actions_overflow/index.tsx @@ -48,7 +48,7 @@ const RuleActionsOverflowComponent = ({ userHasNoPermissions, }: RuleActionsOverflowComponentProps) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const [rulesToExport, setRulesToExport] = useState(undefined); + const [rulesToExport, setRulesToExport] = useState([]); const history = useHistory(); const [, dispatchToaster] = useStateToaster(); @@ -66,7 +66,7 @@ const RuleActionsOverflowComponent = ({ disabled={userHasNoPermissions} onClick={async () => { setIsPopoverOpen(false); - await duplicateRulesAction([rule], noop, dispatchToaster); + await duplicateRulesAction([rule], [rule.id], noop, dispatchToaster); }} > {i18nActions.DUPLICATE_RULE} @@ -75,9 +75,9 @@ const RuleActionsOverflowComponent = ({ key={i18nActions.EXPORT_RULE} icon="indexEdit" disabled={userHasNoPermissions || rule.immutable} - onClick={async () => { + onClick={() => { setIsPopoverOpen(false); - setRulesToExport([rule]); + setRulesToExport([rule.id]); }} > {i18nActions.EXPORT_RULE} @@ -131,7 +131,7 @@ const RuleActionsOverflowComponent = ({ { displaySuccessToast( i18nActions.SUCCESSFULLY_EXPORTED_RULES(exportCount), diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_downloader/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_downloader/index.tsx index b41265adea6b10..5d3086051a6e2a 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_downloader/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/components/rule_downloader/index.tsx @@ -7,7 +7,7 @@ import React, { useEffect, useRef } from 'react'; import styled from 'styled-components'; import { isFunction } from 'lodash/fp'; -import { exportRules, Rule } from '../../../../../containers/detection_engine/rules'; +import { exportRules } from '../../../../../containers/detection_engine/rules'; import { displayErrorToast, useStateToaster } from '../../../../../components/toasters'; import * as i18n from './translations'; @@ -17,7 +17,7 @@ const InvisibleAnchor = styled.a` export interface RuleDownloaderProps { filename: string; - rules?: Rule[]; + ruleIds?: string[]; onExportComplete: (exportCount: number) => void; } @@ -30,7 +30,7 @@ export interface RuleDownloaderProps { */ export const RuleDownloaderComponent = ({ filename, - rules, + ruleIds, onExportComplete, }: RuleDownloaderProps) => { const anchorRef = useRef(null); @@ -41,10 +41,10 @@ export const RuleDownloaderComponent = ({ const abortCtrl = new AbortController(); async function exportData() { - if (anchorRef && anchorRef.current && rules != null) { + if (anchorRef && anchorRef.current && ruleIds != null && ruleIds.length > 0) { try { const exportResponse = await exportRules({ - ruleIds: rules.map(r => r.rule_id), + ruleIds, signal: abortCtrl.signal, }); @@ -61,7 +61,7 @@ export const RuleDownloaderComponent = ({ window.URL.revokeObjectURL(objectURL); } - onExportComplete(rules.length); + onExportComplete(ruleIds.length); } } catch (error) { if (isSubscribed) { @@ -77,7 +77,7 @@ export const RuleDownloaderComponent = ({ isSubscribed = false; abortCtrl.abort(); }; - }, [rules]); + }, [ruleIds]); return ; }; diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx index 0c53ad19a35747..20185c2eda8164 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/index.tsx @@ -26,11 +26,10 @@ import { UpdatePrePackagedRulesCallOut } from './components/pre_packaged_rules/u import { getPrePackagedRuleStatus, redirectToDetections } from './helpers'; import * as i18n from './translations'; -type Func = () => void; +type Func = (refreshPrePackagedRule?: boolean) => void; const RulesPageComponent: React.FC = () => { const [showImportModal, setShowImportModal] = useState(false); - const [importCompleteToggle, setImportCompleteToggle] = useState(false); const refreshRulesData = useRef(null); const { loading, @@ -67,14 +66,18 @@ const RulesPageComponent: React.FC = () => { const userHasNoPermissions = canUserCRUD != null && hasManageApiKey != null ? !canUserCRUD || !hasManageApiKey : false; + const handleRefreshRules = useCallback(async () => { + if (refreshRulesData.current != null) { + refreshRulesData.current(true); + } + }, [refreshRulesData]); + const handleCreatePrePackagedRules = useCallback(async () => { if (createPrePackagedRules != null) { await createPrePackagedRules(); - if (refreshRulesData.current != null) { - refreshRulesData.current(); - } + handleRefreshRules(); } - }, [createPrePackagedRules, refreshRulesData]); + }, [createPrePackagedRules, handleRefreshRules]); const handleRefetchPrePackagedRulesStatus = useCallback(() => { if (refetchPrePackagedRulesStatus != null) { @@ -96,7 +99,7 @@ const RulesPageComponent: React.FC = () => { setShowImportModal(false)} - importComplete={() => setImportCompleteToggle(!importCompleteToggle)} + importComplete={handleRefreshRules} /> { loading={loading || prePackagedRuleLoading} loadingCreatePrePackagedRules={loadingCreatePrePackagedRules} hasNoPermissions={userHasNoPermissions} - importCompleteToggle={importCompleteToggle} refetchPrePackagedRulesStatus={handleRefetchPrePackagedRulesStatus} rulesCustomInstalled={rulesCustomInstalled} rulesInstalled={rulesInstalled} diff --git a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/types.ts index 55eb45fb5ed9d4..b2650dcc2b77ee 100644 --- a/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/types.ts +++ b/x-pack/legacy/plugins/siem/public/pages/detection_engine/rules/types.ts @@ -5,7 +5,6 @@ */ import { Filter } from '../../../../../../../../src/plugins/data/common'; -import { Rule } from '../../../containers/detection_engine/rules'; import { FieldValueQueryBar } from './components/query_bar'; import { FormData, FormHook } from '../../shared_imports'; import { FieldValueTimeline } from './components/pick_timeline'; @@ -23,24 +22,6 @@ export interface EuiBasicTableOnChange { sort?: EuiBasicTableSortTypes; } -export interface TableData { - id: string; - immutable: boolean; - rule_id: string; - rule: { - href: string; - name: string; - }; - risk_score: number; - severity: string; - tags: string[]; - activate: boolean; - isLoading: boolean; - sourceRule: Rule; - status?: string | null; - statusDate?: string | null; -} - export enum RuleStep { defineRule = 'define-rule', aboutRule = 'about-rule', diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts index 51b7b132fc794e..08a0589389966a 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts @@ -5,7 +5,6 @@ */ import Hapi from 'hapi'; -import { countBy } from 'lodash/fp'; import uuid from 'uuid'; import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; @@ -45,8 +44,7 @@ export const createCreateRulesBulkRoute = ( } const ruleDefinitions = request.payload; - const mappedDuplicates = countBy('rule_id', ruleDefinitions); - const dupes = getDuplicates(mappedDuplicates); + const dupes = getDuplicates(ruleDefinitions, 'rule_id'); const rules = await Promise.all( ruleDefinitions diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts index b5b687c284b251..5fac3f79f359cc 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.test.ts @@ -20,7 +20,7 @@ import { } from './utils'; import { getResult } from '../__mocks__/request_responses'; import { INTERNAL_IDENTIFIER } from '../../../../../common/constants'; -import { OutputRuleAlertRest, ImportRuleAlertRest } from '../../types'; +import { OutputRuleAlertRest, ImportRuleAlertRest, RuleAlertParamsRest } from '../../types'; import { BulkError, ImportSuccessError } from '../utils'; import { sampleRule } from '../../signals/__mocks__/es_results'; import { getSimpleRule } from '../__mocks__/utils'; @@ -1222,20 +1222,32 @@ describe('utils', () => { describe('getDuplicates', () => { test("returns array of ruleIds showing the duplicate keys of 'value2' and 'value3'", () => { - const output = getDuplicates({ - value1: 1, - value2: 2, - value3: 2, - }); + const output = getDuplicates( + [ + { rule_id: 'value1' }, + { rule_id: 'value2' }, + { rule_id: 'value2' }, + { rule_id: 'value3' }, + { rule_id: 'value3' }, + {}, + {}, + ] as RuleAlertParamsRest[], + 'rule_id' + ); const expected = ['value2', 'value3']; expect(output).toEqual(expected); }); test('returns null when given a map of no duplicates', () => { - const output = getDuplicates({ - value1: 1, - value2: 1, - value3: 1, - }); + const output = getDuplicates( + [ + { rule_id: 'value1' }, + { rule_id: 'value2' }, + { rule_id: 'value3' }, + {}, + {}, + ] as RuleAlertParamsRest[], + 'rule_id' + ); const expected: string[] = []; expect(output).toEqual(expected); }); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts index ab80e1570c31ce..7004bf2088ef2f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/rules/utils.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { pickBy } from 'lodash/fp'; -import { Dictionary } from 'lodash'; +import { pickBy, countBy } from 'lodash/fp'; import { SavedObject } from 'kibana/server'; import uuid from 'uuid'; import { INTERNAL_IDENTIFIER } from '../../../../../common/constants'; @@ -18,7 +17,7 @@ import { isRuleStatusFindTypes, isRuleStatusSavedObjectType, } from '../../rules/types'; -import { OutputRuleAlertRest, ImportRuleAlertRest } from '../../types'; +import { OutputRuleAlertRest, ImportRuleAlertRest, RuleAlertParamsRest } from '../../types'; import { createBulkErrorObject, BulkError, @@ -224,10 +223,14 @@ export const transformOrImportError = ( } }; -export const getDuplicates = (lodashDict: Dictionary): string[] => { - const hasDuplicates = Object.values(lodashDict).some(i => i > 1); +export const getDuplicates = (ruleDefinitions: RuleAlertParamsRest[], by: 'rule_id'): string[] => { + const mappedDuplicates = countBy( + by, + ruleDefinitions.filter(r => r[by] != null) + ); + const hasDuplicates = Object.values(mappedDuplicates).some(i => i > 1); if (hasDuplicates) { - return Object.keys(lodashDict).filter(key => lodashDict[key] > 1); + return Object.keys(mappedDuplicates).filter(key => mappedDuplicates[key] > 1); } return []; }; From 0e0f114d03f0becb9bbc5b93cbed217f2663efbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Wed, 26 Feb 2020 07:40:06 +0100 Subject: [PATCH 61/73] [APM] Improve debug output (#58467) --- .../apm/server/lib/helpers/es_client.ts | 96 +++++++++++-------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/x-pack/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/plugins/apm/server/lib/helpers/es_client.ts index 86eb1dba507f04..c22084dbb71681 100644 --- a/x-pack/plugins/apm/server/lib/helpers/es_client.ts +++ b/x-pack/plugins/apm/server/lib/helpers/es_client.ts @@ -12,8 +12,9 @@ import { IndicesCreateParams, DeleteDocumentResponse } from 'elasticsearch'; -import { cloneDeep, isString, merge, uniqueId } from 'lodash'; +import { cloneDeep, isString, merge } from 'lodash'; import { KibanaRequest } from 'src/core/server'; +import chalk from 'chalk'; import { ESSearchRequest, ESSearchResponse @@ -126,6 +127,10 @@ interface ClientCreateOptions { export type ESClient = ReturnType; +function formatObj(obj: Record) { + return JSON.stringify(obj, null, 2); +} + export function getESClient( context: APMRequestHandlerContext, request: KibanaRequest, @@ -136,25 +141,49 @@ export function getESClient( callAsInternalUser } = context.core.elasticsearch.dataClient; - const callMethod = clientAsInternalUser - ? callAsInternalUser - : callAsCurrentUser; + async function callEs(operationName: string, params: Record) { + const startTime = process.hrtime(); + + let res: any; + let esError = null; + try { + res = clientAsInternalUser + ? await callAsInternalUser(operationName, params) + : await callAsCurrentUser(operationName, params); + } catch (e) { + // catch error and throw after outputting debug info + esError = e; + } + + if (context.params.query._debug) { + const highlightColor = esError ? 'bgRed' : 'inverse'; + const diff = process.hrtime(startTime); + const duration = `${Math.round(diff[0] * 1000 + diff[1] / 1e6)}ms`; + const routeInfo = `${request.route.method.toUpperCase()} ${ + request.route.path + }`; - const debug = context.params.query._debug; + console.log( + chalk.bold[highlightColor](`=== Debug: ${routeInfo} (${duration}) ===`) + ); + + if (operationName === 'search') { + console.log(`GET ${params.index}/_${operationName}`); + console.log(formatObj(params.body)); + } else { + console.log(chalk.bold('ES operation:'), operationName); - function withTime( - fn: (log: typeof console.log) => Promise - ): Promise { - const log = console.log.bind(console, uniqueId()); - if (!debug) { - return fn(log); + console.log(chalk.bold('ES query:')); + console.log(formatObj(params)); + } + console.log(`\n`); } - const time = process.hrtime(); - return fn(log).then(data => { - const now = process.hrtime(time); - log(`took: ${Math.round(now[0] * 1000 + now[1] / 1e6)}ms`); - return data; - }); + + if (esError) { + throw esError; + } + + return res; } return { @@ -171,40 +200,25 @@ export function getESClient( apmOptions ); - return withTime(log => { - if (context.params.query._debug) { - log(`--DEBUG ES QUERY--`); - log( - `${request.url.pathname} ${JSON.stringify(context.params.query)}` - ); - log(`GET ${nextParams.index}/_search`); - log(JSON.stringify(nextParams.body, null, 2)); - } - - return (callMethod('search', nextParams) as unknown) as Promise< - ESSearchResponse - >; - }); + return callEs('search', nextParams); }, index: (params: APMIndexDocumentParams) => { - return withTime(() => callMethod('index', params)); + return callEs('index', params); }, delete: (params: IndicesDeleteParams): Promise => { - return withTime(() => callMethod('delete', params)); + return callEs('delete', params); }, indicesCreate: (params: IndicesCreateParams) => { - return withTime(() => callMethod('indices.create', params)); + return callEs('indices.create', params); }, hasPrivileges: ( params: IndexPrivilegesParams ): Promise => { - return withTime(() => - callMethod('transport.request', { - method: 'POST', - path: '/_security/user/_has_privileges', - body: params - }) - ); + return callEs('transport.request', { + method: 'POST', + path: '/_security/user/_has_privileges', + body: params + }); } }; } From 71254de3c2b94bf1185a27723939de32e4945497 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 26 Feb 2020 09:21:32 +0000 Subject: [PATCH 62/73] [ML] Adding get records endpoint wrapper (#58500) --- .../ml/server/client/elasticsearch_ml.js | 12 +++++ .../ml/server/routes/anomaly_detectors.ts | 48 ++++++++++++++++++- .../plugins/ml/server/routes/apidoc.json | 2 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js b/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js index 9317d3c6c3e075..e3092abb5d34ee 100644 --- a/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js +++ b/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js @@ -450,6 +450,18 @@ export const elasticsearchJsPlugin = (Client, config, components) => { method: 'POST', }); + ml.records = ca({ + url: { + fmt: '/_ml/anomaly_detectors/<%=jobId%>/results/records', + req: { + jobId: { + type: 'string', + }, + }, + }, + method: 'POST', + }); + ml.buckets = ca({ urls: [ { diff --git a/x-pack/legacy/plugins/ml/server/routes/anomaly_detectors.ts b/x-pack/legacy/plugins/ml/server/routes/anomaly_detectors.ts index 927646e4f0accb..99dbdec9e945bd 100644 --- a/x-pack/legacy/plugins/ml/server/routes/anomaly_detectors.ts +++ b/x-pack/legacy/plugins/ml/server/routes/anomaly_detectors.ts @@ -376,11 +376,57 @@ export function jobRoutes({ xpackMainPlugin, router }: RouteInitialization) { }) ); + /** + * @apiGroup AnomalyDetectors + * + * @api {post} /api/ml/anomaly_detectors/:jobId/results/records Retrieves anomaly records for a job. + * @apiName GetRecords + * @apiDescription Retrieves anomaly records for a job. + * + * @apiParam {String} jobId Job ID. + * + * @apiSuccess {Number} count + * @apiSuccess {Object[]} records + */ + router.post( + { + path: '/api/ml/anomaly_detectors/{jobId}/results/records', + validate: { + params: schema.object({ + jobId: schema.string(), + }), + body: schema.object({ + desc: schema.maybe(schema.boolean()), + end: schema.maybe(schema.string()), + exclude_interim: schema.maybe(schema.boolean()), + 'page.from': schema.maybe(schema.number()), + 'page.size': schema.maybe(schema.number()), + record_score: schema.maybe(schema.number()), + sort: schema.maybe(schema.string()), + start: schema.maybe(schema.string()), + }), + }, + }, + licensePreRoutingFactory(xpackMainPlugin, async (context, request, response) => { + try { + const results = await context.ml!.mlClient.callAsCurrentUser('ml.records', { + jobId: request.params.jobId, + ...request.body, + }); + return response.ok({ + body: results, + }); + } catch (e) { + return response.customError(wrapError(e)); + } + }) + ); + /** * @apiGroup AnomalyDetectors * * @api {post} /api/ml/anomaly_detectors/:jobId/results/buckets Obtain bucket scores for the specified job ID - * @apiName GetOverallBuckets + * @apiName GetBuckets * @apiDescription The get buckets API presents a chronological view of the records, grouped by bucket. * * @apiParam {String} jobId Job ID. diff --git a/x-pack/legacy/plugins/ml/server/routes/apidoc.json b/x-pack/legacy/plugins/ml/server/routes/apidoc.json index 946e3bd71d6c3d..c5aa3e4d792fdc 100644 --- a/x-pack/legacy/plugins/ml/server/routes/apidoc.json +++ b/x-pack/legacy/plugins/ml/server/routes/apidoc.json @@ -31,6 +31,8 @@ "DeleteAnomalyDetectorsJob", "ValidateAnomalyDetector", "ForecastAnomalyDetector", + "GetRecords", + "GetBuckets", "GetOverallBuckets", "GetCategories", "FileDataVisualizer", From a4e82c4e6d9b30d017b290f9d3abbded84f0d3ac Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 26 Feb 2020 10:39:16 +0100 Subject: [PATCH 63/73] Adapt es-archiver to call `_migrate` endpoint instead of creating a migrator (#56971) * es-archiver call _migrate endpoint instead of creating a migrator * fix crlf.... * use promise instead of callback accessor * attempt with disabled authent * enable security again * set mapping to dynamic before calling migration endpoint * rename space data from non-spaced tests * add documentation on the `rerun` flag * create router with the `/api/saved_objects` prefix * add unit test about strict mapping * add integration test on migrate endpoint * wrap route handler with handleLegacyErrors * add remark about limitations of the rerun flag * Apply suggestions from code review Co-Authored-By: Aleh Zasypkin * do not return detailed index result * add access tag to migrate route * use /internal prefix for migrate endpoint * fix integ tests Co-authored-by: Elastic Machine Co-authored-by: Josh Dover Co-authored-by: Aleh Zasypkin --- .../kbn_client/kbn_client_saved_objects.ts | 19 ++++ packages/kbn-pm/dist/index.js | 12 +++ .../core/build_active_mappings.test.ts | 5 + .../migrations/kibana/kibana_migrator.ts | 18 +++- src/core/server/saved_objects/routes/index.ts | 8 ++ .../routes/integration_tests/import.test.ts | 14 +-- .../integration_tests/migrate.test.mocks.ts | 26 +++++ .../routes/integration_tests/migrate.test.ts | 62 ++++++++++++ .../server/saved_objects/routes/migrate.ts | 45 +++++++++ .../saved_objects/saved_objects_service.ts | 13 ++- src/es_archiver/actions/empty_kibana_index.ts | 3 +- src/es_archiver/actions/load.ts | 2 +- src/es_archiver/lib/indices/kibana_index.ts | 94 ++---------------- .../reporting/ecommerce/data.json.gz | Bin 1007039 -> 1007932 bytes .../reporting/ecommerce_kibana/data.json.gz | Bin 2132 -> 2039 bytes .../es_archives/reporting/nanos/data.json.gz | Bin 982 -> 863 bytes 16 files changed, 221 insertions(+), 100 deletions(-) create mode 100644 src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts create mode 100644 src/core/server/saved_objects/routes/integration_tests/migrate.test.ts create mode 100644 src/core/server/saved_objects/routes/migrate.ts diff --git a/packages/kbn-dev-utils/src/kbn_client/kbn_client_saved_objects.ts b/packages/kbn-dev-utils/src/kbn_client/kbn_client_saved_objects.ts index 51fa19c140bf05..e671061b343523 100644 --- a/packages/kbn-dev-utils/src/kbn_client/kbn_client_saved_objects.ts +++ b/packages/kbn-dev-utils/src/kbn_client/kbn_client_saved_objects.ts @@ -57,9 +57,28 @@ interface UpdateOptions extends IndexOptions { id: string; } +interface MigrateResponse { + success: boolean; + result: Array<{ status: string }>; +} + export class KbnClientSavedObjects { constructor(private readonly log: ToolingLog, private readonly requester: KbnClientRequester) {} + /** + * Run the saved objects migration + */ + public async migrate() { + this.log.debug('Migrating saved objects'); + + return await this.requester.request({ + description: 'migrate saved objects', + path: uriencode`/internal/saved_objects/_migrate`, + method: 'POST', + body: {}, + }); + } + /** * Get an object */ diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 451db9750ada75..fe0491870e4bda 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -43784,6 +43784,18 @@ class KbnClientSavedObjects { this.log = log; this.requester = requester; } + /** + * Run the saved objects migration + */ + async migrate() { + this.log.debug('Migrating saved objects'); + return await this.requester.request({ + description: 'migrate saved objects', + path: kbn_client_requester_1.uriencode `/internal/saved_objects/_migrate`, + method: 'POST', + body: {}, + }); + } /** * Get an object */ diff --git a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts index 821a10353f8ecb..9d220cfdf94b70 100644 --- a/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts +++ b/src/core/server/saved_objects/migrations/core/build_active_mappings.test.ts @@ -21,6 +21,11 @@ import { IndexMapping } from './../../mappings'; import { buildActiveMappings, diffMappings } from './build_active_mappings'; describe('buildActiveMappings', () => { + test('creates a strict mapping', () => { + const mappings = buildActiveMappings({}); + expect(mappings.dynamic).toEqual('strict'); + }); + test('combines all mappings and includes core mappings', () => { const properties = { aaa: { type: 'text' }, diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 494f834717deff..bc29061b380b88 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -88,15 +88,27 @@ export class KibanaMigrator { } /** - * Migrates the mappings and documents in the Kibana index. This will run only + * Migrates the mappings and documents in the Kibana index. By default, this will run only * once and subsequent calls will return the result of the original call. * + * @param rerun - If true, method will run a new migration when called again instead of + * returning the result of the initial migration. This should only be used when factors external + * to Kibana itself alter the kibana index causing the saved objects mappings or data to change + * after the Kibana server performed the initial migration. + * + * @remarks When the `rerun` parameter is set to true, no checks are performed to ensure that no migration + * is currently running. Chained or concurrent calls to `runMigrations({ rerun: true })` can lead to + * multiple migrations running at the same time. When calling with this parameter, it's expected that the calling + * code should ensure that the initial call resolves before calling the function again. + * * @returns - A promise which resolves once all migrations have been applied. * The promise resolves with an array of migration statuses, one for each * elasticsearch index which was migrated. */ - public runMigrations(): Promise> { - if (this.migrationResult === undefined) { + public runMigrations({ rerun = false }: { rerun?: boolean } = {}): Promise< + Array<{ status: string }> + > { + if (this.migrationResult === undefined || rerun) { this.migrationResult = this.runMigrationsInternal(); } diff --git a/src/core/server/saved_objects/routes/index.ts b/src/core/server/saved_objects/routes/index.ts index f2f57798dd5f00..0afa24b18760bb 100644 --- a/src/core/server/saved_objects/routes/index.ts +++ b/src/core/server/saved_objects/routes/index.ts @@ -20,6 +20,7 @@ import { InternalHttpServiceSetup } from '../../http'; import { Logger } from '../../logging'; import { SavedObjectConfig } from '../saved_objects_config'; +import { IKibanaMigrator } from '../migrations'; import { registerGetRoute } from './get'; import { registerCreateRoute } from './create'; import { registerDeleteRoute } from './delete'; @@ -32,17 +33,20 @@ import { registerLogLegacyImportRoute } from './log_legacy_import'; import { registerExportRoute } from './export'; import { registerImportRoute } from './import'; import { registerResolveImportErrorsRoute } from './resolve_import_errors'; +import { registerMigrateRoute } from './migrate'; export function registerRoutes({ http, logger, config, importableExportableTypes, + migratorPromise, }: { http: InternalHttpServiceSetup; logger: Logger; config: SavedObjectConfig; importableExportableTypes: string[]; + migratorPromise: Promise; }) { const router = http.createRouter('/api/saved_objects/'); @@ -58,4 +62,8 @@ export function registerRoutes({ registerExportRoute(router, config, importableExportableTypes); registerImportRoute(router, config, importableExportableTypes); registerResolveImportErrorsRoute(router, config, importableExportableTypes); + + const internalRouter = http.createRouter('/internal/saved_objects/'); + + registerMigrateRoute(internalRouter, migratorPromise); } diff --git a/src/core/server/saved_objects/routes/integration_tests/import.test.ts b/src/core/server/saved_objects/routes/integration_tests/import.test.ts index 2c8d568b750c66..954e6d9e4831a1 100644 --- a/src/core/server/saved_objects/routes/integration_tests/import.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/import.test.ts @@ -32,7 +32,7 @@ const config = { maxImportExportSize: 10000, } as SavedObjectConfig; -describe('POST /api/saved_objects/_import', () => { +describe('POST /internal/saved_objects/_import', () => { let server: setupServerReturn['server']; let httpSetup: setupServerReturn['httpSetup']; let handlerContext: setupServerReturn['handlerContext']; @@ -51,7 +51,7 @@ describe('POST /api/saved_objects/_import', () => { savedObjectsClient.find.mockResolvedValue(emptyResponse); - const router = httpSetup.createRouter('/api/saved_objects/'); + const router = httpSetup.createRouter('/internal/saved_objects/'); registerImportRoute(router, config, allowedTypes); await server.start(); @@ -63,7 +63,7 @@ describe('POST /api/saved_objects/_import', () => { it('formats successful response', async () => { const result = await supertest(httpSetup.server.listener) - .post('/api/saved_objects/_import') + .post('/internal/saved_objects/_import') .set('content-Type', 'multipart/form-data; boundary=BOUNDARY') .send( [ @@ -99,7 +99,7 @@ describe('POST /api/saved_objects/_import', () => { }); const result = await supertest(httpSetup.server.listener) - .post('/api/saved_objects/_import') + .post('/internal/saved_objects/_import') .set('content-Type', 'multipart/form-data; boundary=EXAMPLE') .send( [ @@ -148,7 +148,7 @@ describe('POST /api/saved_objects/_import', () => { }); const result = await supertest(httpSetup.server.listener) - .post('/api/saved_objects/_import') + .post('/internal/saved_objects/_import') .set('content-Type', 'multipart/form-data; boundary=EXAMPLE') .send( [ @@ -199,7 +199,7 @@ describe('POST /api/saved_objects/_import', () => { }); const result = await supertest(httpSetup.server.listener) - .post('/api/saved_objects/_import') + .post('/internal/saved_objects/_import') .set('content-Type', 'multipart/form-data; boundary=EXAMPLE') .send( [ @@ -249,7 +249,7 @@ describe('POST /api/saved_objects/_import', () => { }); const result = await supertest(httpSetup.server.listener) - .post('/api/saved_objects/_import') + .post('/internal/saved_objects/_import') .set('content-Type', 'multipart/form-data; boundary=EXAMPLE') .send( [ diff --git a/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts b/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts new file mode 100644 index 00000000000000..870d50426904f7 --- /dev/null +++ b/src/core/server/saved_objects/routes/integration_tests/migrate.test.mocks.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { mockKibanaMigrator } from '../../migrations/kibana/kibana_migrator.mock'; + +export const migratorInstanceMock = mockKibanaMigrator.create(); +export const KibanaMigratorMock = jest.fn().mockImplementation(() => migratorInstanceMock); +jest.doMock('../../migrations/kibana/kibana_migrator', () => ({ + KibanaMigrator: KibanaMigratorMock, +})); diff --git a/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts b/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts new file mode 100644 index 00000000000000..928d17e7e5be2d --- /dev/null +++ b/src/core/server/saved_objects/routes/integration_tests/migrate.test.ts @@ -0,0 +1,62 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { migratorInstanceMock } from './migrate.test.mocks'; +import * as kbnTestServer from '../../../../../test_utils/kbn_server'; + +describe('SavedObjects /_migrate endpoint', () => { + let root: ReturnType; + + beforeEach(async () => { + root = kbnTestServer.createRoot({ migrations: { skip: true } }); + await root.setup(); + await root.start(); + migratorInstanceMock.runMigrations.mockClear(); + }, 30000); + + afterEach(async () => { + await root.shutdown(); + }); + + it('calls runMigrations on the migrator with rerun=true when accessed', async () => { + await kbnTestServer.request + .post(root, '/internal/saved_objects/_migrate') + .send({}) + .expect(200); + + expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); + expect(migratorInstanceMock.runMigrations).toHaveBeenCalledWith({ rerun: true }); + }); + + it('calls runMigrations multiple time when multiple access', async () => { + await kbnTestServer.request + .post(root, '/internal/saved_objects/_migrate') + .send({}) + .expect(200); + + expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); + + await kbnTestServer.request + .post(root, '/internal/saved_objects/_migrate') + .send({}) + .expect(200); + + expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(2); + }); +}); diff --git a/src/core/server/saved_objects/routes/migrate.ts b/src/core/server/saved_objects/routes/migrate.ts new file mode 100644 index 00000000000000..69e99d10acd091 --- /dev/null +++ b/src/core/server/saved_objects/routes/migrate.ts @@ -0,0 +1,45 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IRouter } from '../../http'; +import { IKibanaMigrator } from '../migrations'; + +export const registerMigrateRoute = ( + router: IRouter, + migratorPromise: Promise +) => { + router.post( + { + path: '/_migrate', + validate: false, + options: { + tags: ['access:migrateSavedObjects'], + }, + }, + router.handleLegacyErrors(async (context, req, res) => { + const migrator = await migratorPromise; + await migrator.runMigrations({ rerun: true }); + return res.ok({ + body: { + success: true, + }, + }); + }) + ); +}; diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index ece00539536e1f..fa2b67a3e43b2e 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -17,8 +17,9 @@ * under the License. */ -import { CoreService } from 'src/core/types'; +import { Subject } from 'rxjs'; import { first, filter, take } from 'rxjs/operators'; +import { CoreService } from '../../types'; import { SavedObjectsClient, SavedObjectsClientProvider, @@ -36,7 +37,7 @@ import { SavedObjectsMigrationConfigType, SavedObjectConfig, } from './saved_objects_config'; -import { InternalHttpServiceSetup, KibanaRequest } from '../http'; +import { KibanaRequest, InternalHttpServiceSetup } from '../http'; import { SavedObjectsClientContract, SavedObjectsType, SavedObjectsLegacyUiExports } from './types'; import { ISavedObjectsRepository, SavedObjectsRepository } from './service/lib/repository'; import { @@ -47,8 +48,8 @@ import { Logger } from '../logging'; import { convertLegacyTypes } from './utils'; import { SavedObjectTypeRegistry, ISavedObjectTypeRegistry } from './saved_objects_type_registry'; import { PropertyValidators } from './validation'; -import { registerRoutes } from './routes'; import { SavedObjectsSerializer } from './serialization'; +import { registerRoutes } from './routes'; /** * Saved Objects is Kibana's data persistence mechanism allowing plugins to @@ -201,9 +202,9 @@ export interface SavedObjectsRepositoryFactory { /** @internal */ export interface SavedObjectsSetupDeps { + http: InternalHttpServiceSetup; legacyPlugins: LegacyServiceDiscoverPlugins; elasticsearch: InternalElasticsearchServiceSetup; - http: InternalHttpServiceSetup; } interface WrappedClientFactoryWrapper { @@ -225,6 +226,7 @@ export class SavedObjectsService private clientFactoryProvider?: SavedObjectsClientFactoryProvider; private clientFactoryWrappers: WrappedClientFactoryWrapper[] = []; + private migrator$ = new Subject(); private typeRegistry = new SavedObjectTypeRegistry(); private validations: PropertyValidators = {}; @@ -262,6 +264,7 @@ export class SavedObjectsService http: setupDeps.http, logger: this.logger, config: this.config, + migratorPromise: this.migrator$.pipe(first()).toPromise(), importableExportableTypes, }); @@ -302,6 +305,8 @@ export class SavedObjectsService const adminClient = this.setupDeps!.elasticsearch.adminClient; const migrator = this.createMigrator(kibanaConfig, this.config.migration, migrationsRetryDelay); + this.migrator$.next(migrator); + /** * Note: We want to ensure that migrations have completed before * continuing with further Core start steps that might use SavedObjects diff --git a/src/es_archiver/actions/empty_kibana_index.ts b/src/es_archiver/actions/empty_kibana_index.ts index 5f96fbc5f996ca..d61d544deadc4a 100644 --- a/src/es_archiver/actions/empty_kibana_index.ts +++ b/src/es_archiver/actions/empty_kibana_index.ts @@ -32,9 +32,8 @@ export async function emptyKibanaIndexAction({ kbnClient: KbnClient; }) { const stats = createStats('emptyKibanaIndex', log); - const kibanaPluginIds = await kbnClient.plugins.getEnabledIds(); await deleteKibanaIndices({ client, stats, log }); - await migrateKibanaIndex({ client, log, kibanaPluginIds }); + await migrateKibanaIndex({ client, kbnClient }); return stats; } diff --git a/src/es_archiver/actions/load.ts b/src/es_archiver/actions/load.ts index 404fd0daea91d4..ae7799205b2994 100644 --- a/src/es_archiver/actions/load.ts +++ b/src/es_archiver/actions/load.ts @@ -106,7 +106,7 @@ export async function loadAction({ // If we affected the Kibana index, we need to ensure it's migrated... if (Object.keys(result).some(k => k.startsWith('.kibana'))) { - await migrateKibanaIndex({ client, log, kibanaPluginIds }); + await migrateKibanaIndex({ client, kbnClient }); if (kibanaPluginIds.includes('spaces')) { await createDefaultSpace({ client, index: '.kibana' }); diff --git a/src/es_archiver/lib/indices/kibana_index.ts b/src/es_archiver/lib/indices/kibana_index.ts index 56be86a23eda05..1867f24d6f9ed7 100644 --- a/src/es_archiver/lib/indices/kibana_index.ts +++ b/src/es_archiver/lib/indices/kibana_index.ts @@ -17,42 +17,10 @@ * under the License. */ -import { get } from 'lodash'; -import fs from 'fs'; -import Path from 'path'; -import { promisify } from 'util'; -import { toArray } from 'rxjs/operators'; import { Client, CreateDocumentParams } from 'elasticsearch'; -import { ToolingLog } from '@kbn/dev-utils'; - +import { ToolingLog, KbnClient } from '@kbn/dev-utils'; import { Stats } from '../stats'; import { deleteIndex } from './delete_index'; -import { KibanaMigrator } from '../../../core/server/saved_objects/migrations'; -import { LegacyConfig } from '../../../core/server'; -import { convertLegacyTypes } from '../../../core/server/saved_objects/utils'; -import { SavedObjectTypeRegistry } from '../../../core/server/saved_objects'; -// @ts-ignore -import { collectUiExports } from '../../../legacy/ui/ui_exports'; -// @ts-ignore -import { findPluginSpecs } from '../../../legacy/plugin_discovery'; - -/** - * Load the uiExports for a Kibana instance, only load uiExports from xpack if - * it is enabled in the Kibana server. - */ -const getUiExports = async (kibanaPluginIds: string[]) => { - const xpackEnabled = kibanaPluginIds.includes('xpack_main'); - - const { spec$ } = await findPluginSpecs({ - plugins: { - scanDirs: [Path.resolve(__dirname, '../../../legacy/core_plugins')], - paths: xpackEnabled ? [Path.resolve(__dirname, '../../../../x-pack')] : [], - }, - }); - - const specs = await spec$.pipe(toArray()).toPromise(); - return collectUiExports(specs); -}; /** * Deletes all indices that start with `.kibana` @@ -93,61 +61,21 @@ export async function deleteKibanaIndices({ */ export async function migrateKibanaIndex({ client, - log, - kibanaPluginIds, + kbnClient, }: { client: Client; - log: ToolingLog; - kibanaPluginIds: string[]; + kbnClient: KbnClient; }) { - const uiExports = await getUiExports(kibanaPluginIds); - const kibanaVersion = await loadKibanaVersion(); - - const configKeys: Record = { - 'xpack.task_manager.index': '.kibana_task_manager', - }; - const config = { get: (path: string) => configKeys[path] }; - - const savedObjectTypes = convertLegacyTypes(uiExports, config as LegacyConfig); - const typeRegistry = new SavedObjectTypeRegistry(); - savedObjectTypes.forEach(type => typeRegistry.registerType(type)); - - const logger = { - trace: log.verbose.bind(log), - debug: log.debug.bind(log), - info: log.info.bind(log), - warn: log.warning.bind(log), - error: log.error.bind(log), - fatal: log.error.bind(log), - log: (entry: any) => log.info(entry.message), - get: () => logger, - }; - - const migratorOptions = { - savedObjectsConfig: { - scrollDuration: '5m', - batchSize: 100, - pollInterval: 100, - skip: false, + // we allow dynamic mappings on the index, as some interceptors are accessing documents before + // the migration is actually performed. The migrator will put the value back to `strict` after migration. + await client.indices.putMapping({ + index: '.kibana', + body: { + dynamic: true, }, - kibanaConfig: { - index: '.kibana', - } as any, - logger, - kibanaVersion, - typeRegistry, - savedObjectValidations: uiExports.savedObjectValidations, - callCluster: (path: string, ...args: any[]) => - (get(client, path) as Function).call(client, ...args), - }; - - return await new KibanaMigrator(migratorOptions).runMigrations(); -} + } as any); -async function loadKibanaVersion() { - const readFile = promisify(fs.readFile); - const packageJson = await readFile(Path.join(__dirname, '../../../../package.json')); - return JSON.parse(packageJson.toString('utf-8')).version; + return await kbnClient.savedObjects.migrate(); } /** diff --git a/x-pack/test/functional/es_archives/reporting/ecommerce/data.json.gz b/x-pack/test/functional/es_archives/reporting/ecommerce/data.json.gz index b38981c03417e2d6393878ec6ba719f1c2822588..58ac5616651d418e55f05da71976467b171aa390 100644 GIT binary patch literal 1007932 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�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�^|;run9RC}2+t@{$eg(frO&5O*vDm-f&m z@Y_X3Qo=`Aph*$|w?3`(ru5#CrnAx96Y>ik6!)GYugYgH_wtBsobTgtU8%!;JPQ8f<9O-JqC4ZMK9 zfCRN!uh^ciUYyHESTOf#Umit~z`Jj!)?~1vDqA5A)~n&q^*a{~1PH+jih>01pm;gK z4-Q;c=r=~atp$jP*WBAmIKErX<=+!CrT#R4^8az7Lj(+Y&IR~QQ7*Yz)G!^-;ieB-HT`Q=u8krv zqu${w`b90sTQ41;`GsQaVQyW#sUQYr5n8O)OfG7Tj$5rx#_T} z%o0nZAPnuLHi7xpC076^-eqWwC~fm|fsVHSP4v`8_#SxD(Kq(_kU!)XX>ZwVReXwM z>;uo8v)8@h6APyw9sV6yNB%^~r*gM{THVf0{8O2G%p`@pdF@cT-Z9!1!0Sa#I3x^~ z%axrgfaNae7d&R7$$^Z3Uyb{>-{=pXyxXj{xM68Tfdb*lD(FUlOd-syVruxD=bw00 z9CY^=i{Juu62m_e2jhhmb0ex~SI7i2+P0$~YZ$HIx-782K|*#McviN!{uel3l^++Z z$cP6wXMeKJT!HV`Ah$Jp5$2VZgE;0t*Wkmj`xgN&&$8bV0Wot`DB#|GV?sWbu{W0(mNlfge82R57Qagp z;&L*j3RCOfS7rDdB*-6Y6l8ago!2%AOJ8+8ng`aj_XSQ5(BT5h&(4ZHEy(0y+QL!h z&?3p;(M$oJs6qGE+)P?OXO_Gub4^ws?rz20zv_X!%VmX^t)LJlj^bC`@C-o1qyR)5 ze0uXy^l>zm0{R0LUaWKFic{>~>X}}?lZHK|Y^>f&qU0~Y#mEU{X+29xl zu8#Mo+6~&WK}FLaTGT6UG)*eU2BDUbB_R6jTdmT1#N@RJpt;0)?p4$Fy#o49Dy@TI zT-vAYa4qldvVBeVmYzwtU%JNY79#&z+jmRb;-65Gh9mdcYnxa6$v^Gm?^q9VDEY?4?Ro@SyJ)zYmpQI)%EsjqUj>^r%2` zqG`Y_VYv{_22fN9EQniiWT4TxL|5;$6@U{FYeJOhJr^Q6HRgQ-s+{6f_kVj8-}4)* zZ1qGoI9iV$v|+SW|XDt@EXzk5vUn9LqE)2s?+_k zp3n-reZ{%HQ1P0DzZ_&HB`DqMe~jn>=FY!ZJCWVg&ZQDWmrU7)&3)dj+r6~Y;V0qk z9)~#GuEt|rUe9QrT75I*?KBUBm7XvE#eWqu8%~c-Mg<{$&L8g>w=LI14(;uqGo*ViP*fw)s7BqP**gVkta6FbLC19} z0<|_t`ya3+$UqWqo7MIK=XA0kZ}DD}G|=OWkwoQ*%q(`?k*f0a$O9W4LW>x?%IA~t z=+aO_T)KTlvN@N&b*2{^qEFh$@ScXC2(Lfpz%EETrvxKWzVms#T_gJCPTaU&PN|xI z$eBJ1K#_t^NRH8AO*tn;+M)DYbB|eLr;;S}bM2>`qgCUjS_Aw9V1BnW@1{>6B_YtD zA@$}H_nw%@IMK78s~cbdOoaQ&Kpj?T^n*&P8VH}TB&kzpzrNW*U^d*t|Mbn%3&RSQ zSNOqT)+u)G@IG(usDmS|0Mz87Vz2kTGGZCip+W}yrOo`M-&q@`hNIDcicdj0q;~PNxwDtQfp>SusWKomR{D+#!(ll?(vP4C-*2b?3fUF@2e|Znf zhiUNUxp*DrFb8#PzD;Fw`rPxKbjI&3w1IODbqRVg)3FR_qD8!Pr8+IPtN>=6v?j%8 zW0T)j9LG-*(Ub;71drV?pQm$Xmt|OGLGWkON;nD$3$SLo&uRw$GViSD+Ic^r%8i}> z@jenXTuoGzbOJ~%yT-t0!Z$ z7+N=mnaMSk=s2%K7MTpTZ1CV;8tm@1*+-g^^aZWvjNk6y*+Kk9=`4rRxICf)Xe6Z{ z8KVR4>Dhpv`o)2}ZS?lPQOD}&tw`3AMTs;t^T`{HG}pi==DWgp1(3eIrOOC;6tzio zNETsNa8_ai`q9rx2;nO(FL@&MgG11v5`#ivM@p|3ATt&x2=m`lq?MCjp(6x3iUpva z0-og2+N2Iy;3xX?8uY}8LhTHL#jn$^zBvAgKCawa4dqFEp8jfwM9Iw2%<+inA`#EV zd9Q?jtHjNIP;6ipZEblp0C$KHQZ8UWWtkk$hVAg(Hfgva&D=Bm~gxXF~{#RHrWcc*fhkIe$#h`e%Po zoQ8h>E(Xz6oKaB_(ut8)ojoHQCw+=UeNSinb=wt_LGtH zYC0urv^_916r5<9cktq6Mp_rk)RVvh`ZbGV zdJpFc;}vUPlZCY0DEU5y9gt-vw&o;hrWbcJ#ART$n^41@JIEA0BNT=!9!#*Ad!;y> z841_g(#TeqB(%Or@Qez`4!(!(xWX)3P@1TzV&7V2-?)&bna@}gj0tCkII*MDs^C|% ztrm2#H8?mvqM;E3!@fS5d#+FE))Xncs)o~aR)db?>aSCUHT~uXW1nn5`SN)G?O!`x zq;mS;@8O^g;4cxhZsP*Y-M#nHbtN7(Bj*4QHIkr?9|(>7a`mp-M~E4cU)Te}P1)+y+c){cYV#$Y9X2MQ52YFpuJ=K%6FGitWbvIpdrQby z@{MNx`NM#K!m~~C07}>@4)@-k2_aie@wa*z8YB;E7j|r!bZz+0Us76@kq_kc(O>>R zh%&X{ZTPtLrxEvMIzXjZ(6n*W23XIw=(+uEa0dO#Ko=6r1Pm!iJ`yWe!?95jnGq%) z60VMQjcq?8wDo`%81)OnJP84U&ybp3tQ9Xf7C{%!{WtpTy1iw2t*LLxa?L*&{p`}m zTwm(W{$>0<_%)5kqZhrNJq$QuV38uO}%sHgSd*}j-T804*SO;l_k(;}J{V@yA zV9?3C3eKwIxVY*V>ID(V!iV3v@SsAkuo?R15@@w9uos5;Ed!=A@AR8QYf2-W`vAr_ zZ4k=|lcyABugeM4ia3})JFU_J6+M}I0F7w`Js(}(lo#63d5}$ETdgoQ^uRyL#;j@B zCl2&{#0}c*L-!(R5c;K32uIVpGGi_?{t(R7U(brx0pgL%!UA?t)TjEWZ&lj+GsaEm0P1j zlsWLuBEhCp?9|tN5E=TbQ>N6lF)L+K+qmw*N3jaIO^i#)1V=y1B2>q3{pRFIgGxr)!h*jcHEBYzan!`AKsUlbJ<>sD&^^Wb5KE`y;>8ixXk+WFCSrCt(QAr z;9MjAv7O(C=Y9T|eW{VXuj{HgPSK2@4^Y`51&QZh5;C=i3#;b>;g}^tx7)F{(+}ikEPzaC| zGXRh+@#AL}npPo2s~!La+KY)ttbx?@_A z*Z15+3G4r*-P3R2{cUo5*XApTk+UMY2uQWobi&rkca!X+nRd7s7%r|nQUO#1gZ3rX zCn9u{nM}pb#8Ll^7SpDxHXBfasaj8H9C4_74qkksw_*G8Kkhc-Q%nX}p0D|%gP&0XFc?Gs7muQuK;wU>N_1N+rBe{>b0 zu%O<4TPCQ9c;$1LA-@5)oyczw%iJsr4m|ZmwNIJP>@6Q_`0lT<5HO_JhWY;YCU-9l z>+6NQL07q_>lf~3f^K3`CJynrLB@TMxBmX(wsP1e>L$#Cj2s^g)LN!J1k6$MlBPWa zwyy^ype!G}lI$Pm6{#e!GzfqJl&%BQ)Cm%V!WQWKieW&S_q#P=9`hGoyQ*H2w1rQ! z!QTUatS|JjHVpEPNn?0M%)Nm9A5&);7gZZ>eUOwEknWIf=|);ox`yuV1_^2D?(XjH zZbZ7fTRMFA_?+{5&o{q0I9$rGNj{~3HYBY<+(k6N#p6IFXD!Z1x zbPDb7_k|*FdcFd&x*4oa&y-yZ;RA(=t5}ug>_#g6z$#dDWhTp9Nm1%?4 zhTv7vhn>b5(U=j_W7V%ngEx*f?f0tT^v`T*p6$ZLme~>CBJ}L;PI2usz{SFFVJUhH zeex%sLsHZxdlI6^Czll8;xSV`v-NnWW|eus)$gkzgEqq=D{WR0rvFRbhai+1{|=7J z5`r`7Fy!NeFUzF&t}?_+U^1r}ODrSd7Z`eum*!p4lyLF}2(90MI}ZD|r;#a-ubyWo z3(c5)W_`=d-wyS4({T6J>a(=L4plMS-#;-c zs*}8P*RLKIZ<}qMEf>nw=V2WsC#QG%8uVe$nqKoTs{=~gX?b096pS@dlOZjNqtLNVNojW!s{zcyx54QSy#%NZuSv>=>!lu9T$l2=$+e>Ye2PyZI zXhmXCTCRz;!YTT zcj}Y@rCYlIASk!(-O>DFYr>`*Zn2h5DUA8V%r#`>X-+u}J#5X6VTgIS=-c|vK`_+B zptRKzhna9#!*^j*BfDw==|H=!JBkL03jW9l{1~}JGuBg=A;Zy?!Gy0fWItOj4mSR! z^qG&LsuJ!vyI3-qvFxa@2mq<8G~PB&d5txBXbpWbT~7l3-Vl5|Xd))*LO&v8So_-G zlS(rnXt9r?xJX3pCfh5Vk6K@D<)MNYeE1>vo2vdzn?Gf`rb3Wo6DDfVz88{=y`a%S z#SjeY;pUX)3X8_496!Xt^H0rXEXlDUaxoKCLOJpLGpCV=N(oZ#xh?FHMu?Aw0@V+dOXfr$UyAyA}i-RN`@Qf zx8^Q6r|FwUb6lHdayKC-=>{ZveM!lapeEq*E*4t#!>_MtQRpA&;w87Dhd#m|@JUXK z(GrgQxkCN*ay@C_rnaWy_CuYTm))RWUeoI0F%61cN8tm!$3|p!sp?+y7KOs45T56T zxCh*ptwzhJ&uN)`-Aku?jGLqx@N(s@tU${?{R!3|A&JybSBu(rcvidQA{?s}FY4!& z=?Blv8H&{j&^9W4H4%vtyL8~#@#V9>BsDNV%M`u{T7CaMax!I!2%nsdoBKZUbD=Xq zC7X@rp2PRx$bJk-DoGR=*?Lp$eOaV4r9sf7)7s*10|E>jZCPu9oEMI3PkveD>>^ z>kca_##aZ#h(p`5B?~0G3sKtrZOAh@XxA1B~sJoC9UO0>_UvKUpeT) z$oQ-@oV`Jjf0!WO>)W}&1wry=Vh< zZ-u`q3pfk0Bb+81LFuX=I;k=}J$C(i_qot!l2<1*^uu}qKU}Ck1gtBRrA%j%%n{zB{ak;@ zHy!S0Npr+LI@7vcl?8EY5}S%3grCdFfkbI##l)n5lubI z=^N(vHwet{gb8q*h5nDdZ|u5v60muoF6{DqY1o_QwfmnagN~v;x7E4)$Ki#-pKlv* z{XQVxq1fb5sA3>9n`cAsO)3aI_?CJn(>=YtNB%GrHNsbpAqST$!% zR0TB&fDL(&yQT%MEuj})hz`k5`LhPWSMszc7bjnA`dz&u?`vd;e@U2{Nyviu0F;I0 zmA?ikJMSx;Z=Pgfe!lA9x5<+XTbWF*`3PEaNgk(RLe+V8lkTON3o`yfur@lI4cMkIbwWgoK7pNB^Nh)ODDGT*Mz^Zw238;*z zO0b|bptP{?l>N-kOVsdyFVnP7)-1DUu~hk^)hPM5ukzHD&o915Eb{l;_|}T2oNNY7 z4k^+kEf1)OeF>~E5*i^Ei)FwPmV=UZ66CJ%p73iQy~k`Nx=&qV1n0W^e;P8v!y`?aID0u@O-snUdVJC! zQu#6=^%SHw*r$t9z!9s5KFoWJhY$o<6Rg{f8iT2}?BBAjM;=<~u_hW~KanC;YA(r7 zM1Ne2>re!Xa2G)P4#wwjjfN9k3|7+K&2$JJqT9^V4Djn>?L+u3539NjVciu_bRb-O z&vQLr^YtsueXPpmnoX)}#v4~e4HxFjAaEUvE?UiDiU6?qObO|i48A2p410$56Z9yOWXW+wPg=J2kpcdjZJx4t9(?%>F$pbOU|x{j}aKS4OtV zz~}$ zPe}`Avl0Fn5Y!ib^Aj_%GA(t^P)}9@_L>V)T+Ju_9Hva)c;t}$SOCylUimTNJheHm1JGa(#zGZ= z`e&V%=YPTDE|(Y0(w{x-@3tV(@1f`0E4{y8gtI1*RwH~0lsYZYu3){7@9f9|i528( zb`|0M#P=z^kyyN~Sf5{ZO|mSNHjt&X% zw@}irv3j^UFt{fb+ll7e?C7c{WnM>XSgx)q0nd|Em_f71v*%86u9?4bn&#t&P|n+c zo%Ann2^B9_*ipmiT2p8EtFsFm|9bdKFLGsR#D#f1(*3^ZuR#O&Q#ti6XpOe>2`!mCRqfudD!}xO8sf z^UmwhClv~qxqLrgu)X`vNW%V9q+^Phvh^Xi;ot1|Lq~W1aR(G*WtXKirUeo@(V8wH z+1OxPd*ZkQt8Cqhz3(g3V0 zAAV13h1@n8>g?v-!OVyqS>T(BfAQ>#9{W%+WQzx=h2JoZVslYAF>VWKgx8x?Vi zdeJ_ZTCrYRPAC9VhpMPSNPK0j%hHbSN;(X&BCU0cu(N0X2RmdNuAt}eb&iX@2ky;? zcWLGmmIN7(yLkGOnbP$I*oq>(uZZWPmgB(o5IsiH)PTWFsh|6dj|!(O9}sem7QcR~ z>2)?Bk=rtuZ<9k|yKa<{=cBCp_>;)C4zu2z(3nCAaEFXLAW4TwDN7*vN>En3WK*le zQyq+0vLNvw0E^SZ|8EAopC7=GpB+1h=AIUp|F8{#&;aqHiYQ!IXN#tKvHc>WV3u)foFwmi2QzZK!Sezp|LBtO^@Mkmm z$e(mDsp?X-am$<~H;6VTk}q{r6cZQyKKYj7EN$~zEcv~h2m{<0yiB7O27Mgxo@G3O z5s4fAIi3iJ&OudQ*Q34S*aFqdm+-rmztz^)_K=E0B2{uU6AP>asmIXJvbAWIbBR+9 z!G|q>$6Bq44;a%ZEBvT=+4zJz9o@ZIp0zXQFuYy?kQB_@_LMh-*?y5R+ay2j_K5xx zAqe4ifxCCb}_DvNS>MvQROV6%~J`08e ze`!W<16+IL47N;PeASRehTig@$XjmM#8s28ZpS#kM~vFZJ2n}(1-)8g%Dl(&tXfEQ zeCPqWr>8kqizR;)cg}2z)m_*o+ZIq zL}5(~tL9nhU5xUX(ep)ZJW2$Vs#upyQS`DfUYT-6VAc2YB{gwlHh@;QXq!CH3_73; z6ghH0_RkK~7ie!b7}&tgZ_ry&a)E<_GL7XLFL~WWuQhTF&l^TwmUscPV{JH0xpB?l zzsl@ieuKi(U|?t#B?sjjhR(nI#RtwTih=bDi=2}Sdkr-*cslYF;>NIP})nr+fM`mnT)M;4MY7jR!HPrww4t{RA@?mqQ7d80C9Jct5s{-6+p8 z#L|IotDGw118w4smN?WI>i2qFQc2kl;By7;FIpotdI=C8+)Zhw;ALwHI6{z|8%WR6G}swlWtGvt2R~J()e7oP znAEn35~h_*f?%9wS^@K=kJ@S5S48^ogZ(wmUM^AQX3a4l4|VoFdu{BfDim)wW3RF= z#JMPIC?o$WLFi)$YDrDR`{sT?BpzXozyv7VzSm}03w8ppH4H_uKe;Cz8N7|3YgxZ* z{q#<7g2<%aHKA7bBg6U%cJlcZksy#TZ==fz+x5SzjYU^rwPDx_tTxbQ6L{ZpH={Si ze*WEjE?N&B*~?FJ_)x^7A5r;gb{wpPd6=VDYx{7F0t2vcfh_ZTYA{$aI`(p9k?`$# z9ooQhsu&hWcH3hLIRVLHFIi?>6VWSy5tjhQqn^IY^)LvHlo-}D&obgTjI9+mFgu3& zx482P@11sTD>-$6b*^7+$jIbR-Jaw(Igc1)8DB2T*3#L zrxW1W2|Wl)cB!`~wbpOq0tXFc$??AHILk>I>E^9P(A#?OeS}JoEezN2l9ywaRu$LO2G#p zK9?g~rS_=i&J!M|HaFdJv>>zECG2YL>+k zV-I94m3|CxJKO9S(h@tdd*y)a>Pgk^w9sD zfR3ir!NmaF1NzeOMgF|Q)Tj1lXsz=+f1HDKr3`k&LtV86Utz0)Fu4h4)hYDovw+TC6I^^# z)uYT=vX&S4yPzic${f}k5$Wxy#eRF60%eHC7L{G-a*NeN5hG#wlWQVgNT|IEJL&I4 z{Y`1}>)W#84q@~|hhtd>i4R2I`(BQJDKLaqeOT!XZp@Qd%*%uUjUc6q&!AgPq+<3= zOXYy)H;EDnM}`yIk00*lPhT zEsN17G-7^{t0|hhSAc)>6FO2wUL!V+Mx9^+5-rbYLAlCI_};zPUFy)mzSbwj^lqSx zaGUg)2e9=;%xidM0qWG3fSMl|Ohn_M3lfx!{57g=7h^91x>Y|rctHE^NvKB-oy_sZ zIIU*}R{<7!svQ#Y@Rug8?KdlH^R`^muyCM*`{=>zF^7zVQy7p+56LsHfItm@dpO{W zlMN|~$1!_Oc8|E%(Os?4BbY=BGbF^a%A&uBgfRxRo~P=%r!JF;MFfJFMDrUG>x!D! z*f%O)*(is)27!Cf1A|w9#B@EfQ=BQ+F~sJEIA@t4rA37k!#>arYq591?MrtDvvY2} z;s)-3DM(Z0Qur@M1j?Pg?L8deK3!@&gMo4mhYprmwfqUyW!!|cj3WeO1u%{o?5(dr zJ#NFPTo$Q!QuXe~W*xmG+8zf!{*M|j67^`6+rA+CRIlQz(

W#ldv}5E$L=861~F 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

eM8X_9D$Z5TuX_Nk3@9W$&p` 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�vYwRwQm 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 q|^F$aD4uSd{MFXHvi`6o2 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�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◊TfJGYIwOFadSdu zjE>-y&xMD=TA?izjns;LfS|@Ks11gH_UF%Xh45onp>D&JIt**jI{=aqbf0r$ z(8VQqZT`g=h3!e1-69%cImJO^J(g|vJs!x~zT9RY4_u!c@`jBd3BaKg5EGEWR$FC? zkfK8XSIeH}!LZ?Uc2vdhh_#`suIhFSO?S|KYDjC2-3gwe62`E;eZ#>_0dYiczodi~ zkshgs4duP1%h6?SQ=RsMAnLry4zgFM!}u3)QL{4OC7XvKy!o56`tG0vqub}bAM|rT z5dA7dBAnyg5^dFb_@Oe}n4i$4kBrPPo`^56J*LWd{*OW1UQsVa`9nauzhx7k7qaoZ5G}?3;msKVZ zWcQaZk>Zm4an2-quA{5j64np>lY7f%_m&i`O#6XTe#`qZ(=5Q&%1Kq6W_qv!@>fA7 znr;lm+^-H?-g|!^d$OZy#N>yp9b!UxnU|KfxHc#VEPjP*{5pJb+6IDpA!dNlXX(rV zkC<1vYd*U~B1JosL*qim=6eye)`f9sA6yfcjNB(%*KdufdE1RvciFCjyVtmrwlM`> zVX;Qo3-TBpGMD^KARs3$&nhAcwN&O4Mc!y#kiq^7q(qS_tYD3>=~AQB@{zd!{&OZ~ z{P$lg7A6G~>%S3o+TSw1AYM_y|kFYi$22 z28*z2KzP2us!nEi#hYzvns(h4-&fB}+pPnb=ud5Q&6T&R+Euv1+C&8M*$qC) z`7}oYY}xAYO=2b~HiXf{7(H9MmDvX29TKKB+FnumiD)WeDGb91Pfj?$(MFNG!pHUH7G&xx5^7~AS zLKaOT)fz{+W~qKpTVO{V4Ub~fXzOESr9w7Vzr$}T!i0M3B=?2$;9N}XKpJui5c;uQ z;|fB~$0`_%y;|48P`=oe9SBSR))36Mj(BXrzMPR#9h+jWL^11+jQgzAM_2b>Hrg$^e+g|nIekKbfIAp$rn`n z$C7cN(5p^|00W^at%{o-UqZSK%7FkPT=iHbCw0fOIy6;o%eSPIs=$;g0<^m8Y@H6@9>4_V{W=SaMal@S01m(Z-f0X}8Yl&&a9EU3H8I)yAXpKf=SBidG`lB;xW79| zgAOyzQ%(fTb@*@zAF54jyw{JXkt>07u&oOA<%YUlLx+%1#P&m z;VarD=cHmLl`50JD%!}*j2g#fIm}5Ox27y`zyZDGaxSYXHs$2^=Q>6fG*Hl*&0-}M zFy`oC63SrpoGzXIb8#dWiZY6EZB*MaO8YughjUBBs;w!3jRQq!`rY*|)I(OBxSf0BS6aAPj~pS#9qehq2~djn99-hc&kVrX zu#pdC4Gm+3ir(o{?1=nF)o%dp-yjQB^V>WiS%`Kw0%#b~(@#UVC}(Q}?KIWK*KpdLEs3OlS+ug<8#8cyP1|+e6ssis7Y6=_eHM_+U>^{h+_mK zl#rvf)#^{5ZtYdL`OHo0&g?Js=|X|$2uh&SKJ4Poj2LRRJ2T(Ue%5|05zgq)Moth+ zQ1r3y+b||`z+3?iVS})>jTXdmTwLRSfI*CWQrVLR3&2HVzxfkJnBU!C8#JQAV-hJH zlexNG_hRQWIzKYhwW~ds^g+-7larj!cbj!U4U0M{u?-LjKOqH2X5l}!D@&iVR?!2a zd-|E@?`X5xFd>R)KBQydJH7MNYf%^+xC%213>XI%aafdq8Tc?E9`d|m{uRz*WZdO3 zeSoKnaFwJ-R~z7~T)vQ;w^5rP5K3MGy1Y@w+A6jd-{jj$bU~U+MyhA}Nr)OyW)T%4 z*G(xsC6DhSrFf9K+@KYnUc^O%oW$R$ZQ?GEsJ^(jJ)5ds2rB5y+>Jcct~36A&F2Fs zSP%`(Zf?7Fk%xS9I=65=FRYY_jwd6$;1lc!r(E1ycxa`<_~r&vTS5WSSOw<0ETbxT%rUi z>ylFFS(7(Ob)2xTM^RT+dbO$_Qv=?6aa&at-XMC=22iB3dtZ?H0vF`gm$2_C8bWbZ z9vIJwT)-)Cq(xES8KO)x|)V7gQD96_H z7h)C08v%AF{m`;F_!u9?vxZmpPVfxeRn%f1yA&B90WTi7&Z)`zgtXV`UTFY_OUSZc zxK%Z;g}}hjMXgZ4>mDuLj&<7f>+S{*byW?s zV6a_;qIyQ9e1VSQ-}U1DfN>2apIl`{&(*t#%b^tX)7*%TEn&!y)-R}A#go{Ghh%!b z_vqK#T6Iuk$%PpRQro*`!Ync6_1#H=4Fd{P$>K!hDIs=o9s+w!PdOzh(ZgL3o+Hdu zX^iBxpqo0vkey&Tcn}8jKf3{N2SnZH)UX{lSUTS{K=@u6b|z~+2t&i35?r5^uJAni z2XdvEt%8C7=%uPFeMzgb2nP3E+cGv9cBtL{9e=skvQi<}{60j;n7wl78b(YX{-{Rl zp*QJIl$L88k|?_rCi>fR`LZq%Yf~MLs|uf3Ggr~% zcxv}qjlXWy=>m2-Ko)e*%xWl9lSLsZw3KtD!qwy+1b(}xL6} zvBTrdM10c1E9`jU5NnRAU*V{57=*Q-`hhwjZHz=v@sd8Ty<7^;%I04f*Y@v|4ghtGeoOhr#_D5=>zj;C2-ZJhSH!iv!^j8B5C*%zp0?+KPmuN8 zXYK1uf2;#UX@S_Ur*L@BAJ3fh7ZnXBRAH8XFg0K)sXV8r6p=#YJe9ra<$0(bejs zkg=~=9x{5xnXbs&=K+qv0iRmX$6v#JKGj&8OdtdlnD!9S+k?zTzUYYe>#}!Kt^%3Ex z4XR%R*It-%)8|F96BtE@aFHvRlk=x~rLKwTPi&B0V6p%@j1m*=<>e3k=HwiE6I3H% z)XCF`wFh3^Gm3{wpBI{`UE)Pq0@@pck21Y=&#{#;3paTZ1BJeW3i=BmJ2Suc=fh5A zvio~v$#IbvfWWHDu2SKM15oiV79Hz;>dnr6vPhU<)(X?>K$$_mf$Ke7Vn1UnuzW$E zeCQFsX>~3Dm?F3Du7lJ5$wR&>y>H`}$UnO99=$4HN)0rd#cvIJp3_YxJIyw~6Hta# zb8AZv;27O}Ltqu{VtS$3>i?;2EUsVY=XE_%^uYS(_QvtAgQ1_qr;ocJ1E;PJNw-Kp zqlv8FV_x#(VD*vz`nv9{JaZa(pVc6+k#O6IbQq%! zjxE7@!8-|7B&W}B_xyJh%=85GV6)`kkeX{~eEqcM64%jGf_LByk>FQ=cWf*lgLP~m zEE`0BB?}9s{8DEalOaG7x$X|ZhgJOL1SZUo5Og;A@^abP<#n+uUYwx7x<+*z_LqmK z_$PE6NH*Zzvzp{A+_JuD8TIZY$#j?@rBy3*Dx1y*fXb22=s`G28-i;KhgZTdvc@0kZ4P zngnD*AYV*^bqPy;O3GwUM&~QN5aW+Pw!C>t@f(&5GOn@&Vw;cA|6}SaqpE7&civ}KGL~KCh8Ef1 z5NG|9>#pY{4QLl=HPejU6B#m*zL0?!a5@Vik+G`2AHPk_y7BqFJM!c@o9@eOSj0ev z43X5VANiUxK~*JuLz%K}(MvIvNoz;W;=~cD-!ToG|7#bFvs z8#pREwT{odkgjVUthE_*78`oM}_t}4J^4`+znRDah zrnXiU0u|8T(NT6rHmCw-E6y=2LJ+5ap`U?Uw<0~z<32aUAL8bRGtvGlSr~}8UA70% z&-nKtFY}W_o;x!{q`+6_hEfknoO&_8_pwf|cc#)xo0t2^8aBt4J3!80WVFeRQD)Fu zkqXwm$h-j#9^vEt-ZEaRaaaCrs0E_SDdYkP92x9SLf##ize)=j{3Em)o=)I83?OA_ zM+SPzfCqoPC%Ga2LJPwjK=qOfgaR*r7%dw)Z!-*Em?A7bdGr8~$W`P|uO{1vy)@>5 z_0{uk9GjLrpZq0wNyB~|xouaVReC6;TyoaFs*!0-evJMWo{@CqAq`bGq3Moi3e(AO zrinzDg~4+nR2nwEnwU9{6#@siw)6|_Cg^!=0D#?C92FNTU^M|oB9s%!DeA*JQ=+$F zO?o=n^~6uUum`^BXHKu9V06~^bL2Q0uXh%b>JpH>)o;di1A)HLUx?{ zzeh2Tf0cE56u9A!8+FNM6l)~Ed4QJfgxP<^R zoXHX3|DW3fN?tASqurr4SQXc04EScsiPyW8-!=!v#p1RM>>B{9UK_{N+N$%+Nd{9o zE}C`-U$rK|+@50XVcov!2#o(4j(2nrtu0wES=w!kEp^rrs@vS?@Ms}@lC#<~^0z>x zn>NG;)W?h`lu)nT4+kcW)gUy=IKngEPlEa`3Bc0~-)XEY7KNTHmJdIMfP6R|Zav=h z20aw&Y=JJu%Ay)@+=bj)qfjNy@5n!n%(ipy=EbPKV>9!h)u_@>Ugx*74S<8of34Dx zdOLP;B?ch0q_%)SkdtL85()oIDwp#Q<weqf*3LN+>RgK)Kv*=rrqRs#$sOnY$p0*;*bnN@V;9tV^?$&H zFHR73?C8?;g-RmMB!mFuNS19MD%Gox_YGxV+P1`S!gT9?8qo-b9H5i3_D3f9WorCG zCdXVQJUa=y9_7Wrhfx!dSBCbix1g^g1MJcpx5q}kF0V1JL`lt8D<|l!{frD}{K5h$ zUz$6SYcZ>*hoX$67LR&{tTwOT34Uia7zPPy?XBJ#0jjY;M5K1XN-`7VSZ!`NeiW18I5Z!>M4#|HCsqRzmua!rrsLe9$UmLFI;A zTY9l>ESuNQ@ZP5b4Ee+#-enuq%aSesHabD|eMyrrYgkFXSZnO?@pjLwTMM5t+Ky1hrxT+;qr*(Zq)_ZQ@_PsY#j zSeO%Ig{L3CK3}$fb9io3>a7?#UsExaW*{W6W4vL}P$F{LQKTe|T46E0vM|7~%J*Pr zrh%WeDgtiXfCFrVWG45!tr!?KQJKE*?2nU36c9wh!UB(!Mh%@i&B0Q)gAE-M7sBWk z#yc25d|l%?RZ|TZAPs9*uLgu%VGmOt0ACdhyik??_`6x@%HAm^)}ys2$)Y|dItTgj z(>I40DAt>F>q>qKxR*I7#E;&WC`*$b9Vp^{Gz$y6--n=|BH^AQP0bC{i)#$YQ%Qh% zyWk|uzI;Mbe6Osoz8&2NjRZR!WpFR!5bm`|h%C?U4H_cwILs&>@q)XAFU>&4iA>xN zg0_xUn-jUKqJhCSDkFk8lamc;8(2R0!+t(lk$x=bFx?(DXCp|D;8t--YrsAGu9UG& z@8aHJYV1VD%hI6(o1U}nc#U7Jp^pX5aS;GNo(8Iok}O@OlBQcJ==91DXgLSnjj$!y zvyDxmt=~)d0W2qMMq*jsCB6*bMyVh0>=TJ=D$os&ESSwJf3dZrdnLL#TS~4D_7V*P zoI-X&MhLtv+0TojcB`#b4Wp|R8kF5|6esnHr#d6{e9G1s4LiKu+(&OE7o z`@uu(s-(XE`N@MiH134OflXKg9Jnk-aLBrLJ+t=Jj}D1tCuq`56<6jRGXvj`b=I4i z;L4;zawcx6J>FTWoW}1sIz1xa-D2PAy!}Iw+giaSQjQSrOyKT#Zx_IRv;{RB^_6Jr z*(p~IP9DmQP@(~|s;-#)iQG55Z=`jtt|qQkr`|X(_0El5aRa$c!sek-qV~}r0Tm>f z8PF#K1XRDKe_bK(QPH@%7!)sw+07!`GMx(YElx~Yc}UfsFnL6PVU!V5#;xjJhv(4| zR{W1Jf1_L?d5HXU+^ud(*a+r?iLEK~vdF6P{y#w=*b7^1S-Qrgpg+kJxacxOFG+X$ zTE}18mJ>bWEXdFtR|?!olDRv3=k7^KV5&jQr|Y#vb!Ru}s0)LNga(wHe>8BPObnx9 zpfU1W?n2AhCthFg2Tf)LPwB#nugMzjQEdVp11%v`^O0uVW@-1QjY^M)hw!Zlkz#y| zaF7ZDxLPv*{Bu}&1&9$2*zpWIRUL3}0s*t`m0+4Ct}O$9u+QQ%n`iT5Re)E^>h?#0H4)G2A0tw8lND{5(ja+_3i$0|TQ@tJ7uc5qWkrp(7_Al`HuG2}-$uNycBnT1<&DZaG zrFWhR8&LGf4q$_M%Ore_PR*~;Oj~BwGcl)Kucbzd08IcMr*O|j20f_7&X)xwXnZC~ zNIp!d6Jejifb!@cL;v)r(}Sh)MSmj=IyNk~K!7GHAd8tm!Sz=ff&+_C)B zt(@uj3%7waRwzP_50mw)r{dL*$E1}tdzmP^rtGV*dy}5`pHcc<6=Ge z{{H+#tdd1RjB5#B&zIWX7VzaF!=*Y%Wv{6WvMwLW929sAGU*kl0aiB$10UwBgXkqa z;dtUpd`t%y=GDZ}i6^`qK+?&F$q#p2j7Nx>Q4ak6H%Yh-qGLYUM*DWY9y1S0;zg=B zU#Y7<0;N_JBS~55u?km0=JRT_M=fTbD@t7;WC7fh!cXCz)6cB5<5tCHT+?ktU27Iz ztqqCPL^_={S2;N)bjAk}(>4q=8-bOMv#_xA{>fO+!UO4p58!Mls(*$3AY+cw?83Dz zs}4I%UD>&J^Jgvi8Hut0le&s(8P|*#1HPlErj~6oc*y)5&JrICL|6x zVP}AFnB4o6{n3{RJ$sT7s3Z2-vA8YDBn}_icTq%a*>z!5h8J0PNh4DIc?9gYnsu|% z^ix%21O?TXiq5ZH0c6yq90+iozFR0H%3B}X7#vESo6FzV2=67?!Cb$XBo;6^8OoMf zBP233VW{Mgg64+=K3LWp$}pu*!BUdtZe4TgR&pk4+)-G$t$J|<4Ba2CwZ+Z5-1|J# z*^Nue@Z2TwJ$5~pAFzJVnV(Rj7iL$OdzR4RzJJCl9q;DsWAX!6*2U%1KHmH4BPan- z>D262?sgnLV_mJ#?v|eeHVbnt4qI1tCu8dZn-=cx*{1n7G}8^X-Ysi-6EzUTb$ zW7bRGs7flY0_5Gghh)7L@czUtMuHSyU;3$x&j0^uH-|&!iKL#+NZAq7} z`sPcjipej4g|}L-do(=RY*a!Xcs33j2+Kch{<Tm*x(Z-qR3Cpd3%$<9&}&DSVaf0VF?ha!V&paWuKez@Y!3d z;qm7uDzKxp@lx~4mlzTVuO5zo+9e}f??*-_#y=s9RLh4ZK|e~0jr>+F&p!6R*G<<2 z;XV#UIAqA`l*fJE*x>uL^{UpqJk?c|L{Ff`*e_W3)%ocXhf!g5{%PDBIxwCZ2*|K5 zrfo%S9tUGxrC<&!NCO-~^K+uVx=~?)t2iFQ3O=>(00|#FdePMI+e;yJPC`g$hBp3Z zmFr)sr1YFMM0(YuCp{_XEjb>(m@h-eWw_=!GBCU}7lb|i(O5xr=Nnf>j&skW`6 zHhD@~DIND&`WuP=KW&!>N%rI|0|$9Pc8{j+3xIi?QF(o9r(RRvJ7SKsQc8mY9Nq*9 z3b55`N?~#FVZv<6O1_HcR+A4c)*nx0d|1Vam_sb8LS=QmgmoA3tOOzWdBXn*xVcu+ zh9_|)*p0*H%eoTkfJ7a3WIc(#_=hHdgiiv-x-CSNVb1Z0ldYR562SPo7T-co)rDG& z$>X+K}lh}y4STjWXZ_qyU6x*)EfQ>j)nb&ZKd1+a#&2O48;6F-xaabt< zS?G{(NYGM=;)r?+kebZERKUN0Ff{BV+}LPV#k;R|nZA9A@4f!Bk#~&s zy0M(w(UqofwcG7h`@lQbKM9n{FdruG$$Cg`G@AIf|9;PIO*O~+oYiH1-=FDG0cwCih7LXIv?|?hLeHTnB@IO zXTS1_uy{AEQ8*Gn)o)mE{DpxJB=s}yz{R_;&8oGskNrPKN zAAn{!&ozjUUFWA~?mq+^(lr!6{_-f?KEQBrbpFPFpu6xAFzCc5E)qESG`m~{0RFNo zOhe@0W@NyDM!Xu2$pTy}O1&r*EzLxc4m2oG>rg!xRb}vqV(K&;IirhxVEr-D& zmCW=DL_J5THPtr?bjtv1bnMi`B;965FK0D}uuScHYaa-(s3oV*;So|(@?UE}*#H(Y zCR2Vqc!+89f0tRg2dLF(Nw(hsz#_W$gt8t_t1 z|0`xk27&V82ykIwq9tU($FcW(u>D2)Sct&Pt*;-kG?*jqsoo`Dw`%lgrHRw6XMG?5wavHR=q0oq^4mquc*6u>@N6K zD>eZ5uu_{*VG@-9r!k3v&D0+XqVncp)XRly(d&Hu){P2cc6%)hzCnIHrbr=h4a^H- zj?GLUQR!kW#Lgyb-nOH=)u2P*_`pU0h*+VQK}bOT^t=IK`}LDS4H!xIJVo$MGQCP5 z-A~{)KI5F9oq1rL7&!>A!}*=bb-aCSlbw6+?F0kcfMjv_?@l|7C8oGJxhZ6p7$~Tx z&^it)$d}~u$hrujIAfkWF1dknujau5?J<-F*yD+nMpcF;o%RMXG75lCFY>WmXx^QN$#2QKJyElXB>K4nvy$ZIDZ`l7bT=UcDVA5Q- z_wf6r2i6B>448(gI*DTHoV4$66uD^=HL;+TM9Y2qj#3{)oO2d7wCDD^evO(Rw!c`Z z{-ki+@NaGP3{e*p_qrtvF#+G{mt{U3A96 zu3bET5Bv+?s>^IK)zRc+4qm8-G3DGTAVIAi8BMw;H)I+;Un}S60*I3zxeKyD_|Tw9 zN(2NZG@XIC6)Fv|!B%<@7|KOInu%%LgqwlF%-(Cs1aV1#^ z?8Z-7@GA95jLXwL;e@7&ux@O#nD!Y*WoQ3qqlCr?v^z1Yv$L~!CKB&XkR1^6@*X)y zVske5>miK6ui_wa0uQi}`*4Y!ekoikc&pkC8T+?Aj>A0bDPgf_3?yX^kdnwIem(Se z=p$mqCj=Y6nie6hB>!1bD73qLjrv!B0=l{~Kg_x|o5`xF%6-K!GC)MSFud$#ILF>o z9q|r{`xR{u!1_GXAcPsVOm`%wWSvMRVu00Ax*`4NHAEbN!d4I(5o4z%nf(5C^iwy9gQ~_?| zwi=qsCMD_G^B~^5K=za|k&^FURo)9O0KC#dO1eLX1#QRYpF2=&z>9`7axQ4RC~>|6 zT{J0^XwN4MAajuqb}8NJEvQiGyFWWp&0?s?&%$t36U(-+7KO_f0|A7O&GS_;kICf@ z_+Zq)4C?B_C!{vr3}QO}Ok?x&IW4BK=Y5DJBPd)tD@^#!{;F)gi^ANahV0as{?~`8 zw09k2?NYy}vEU^k|vu`_Iw^pVy?s}qBaJoP=Wif z{3ZkV3CMY3T6^|Uz(qOKLiD%H3b`ipDRC;GJQazP(l+MTHR5!Evz7!QV zQ@diUwDgRYr2-RFWa$#51TpmBCFE)3bnqlLmS2d19nW|)(4VzuytQ}Ib5+lv{-W?T zx@%3)h}iK+8fI?(i&5E+6P3n}#*SZ0br}qEz(iNq7&TI8H2y^UANL-k)Q9I*+S0=9@O^ec<5$$O*8^#<@Vyx4kotn0FkW zaR!luEjiV=XD9zst3jNv7vPfq1;iZKZ}T+-q+vEA>Ix1uY?L^M66QFS(rPiwZqg_M zp;IMf@2{&RL%K>i)4m>P6d`cJXUOZVgbXSQur{ueI8G=I#{N7lurY ztBSVuVfjPH$<4p*@~-LD!q1hhHP`~Rb5SNio$#Xh8ff)T}@K_eg1}?+Gn%}tq;uZjE4CG-DxK| z!@wUAM~k=kFx>dQik(^1fHi^j z6e7xuv5FHK90)SVY}3V_JeSpclQ~;|eBLjkTgbdc4*{jcweQ|{*KgxJcwS$rrPht& z;d@#uzgf@W9Gzc?)0V4FC;F+Pl~%4Sw=~&@;xk_1qkn2sMRus3hO_GcO1dVDTz5hjcq9w@h{C#Dcd{$>lUM^9hAryHF9N5$A z=p$K!ad6X17hX8-SnE_c+rWuko@Mt4ch|Hh{9LzmLxLnOV_rS-*SX`JN^INg)`*kTQI%I4n0NR`_88$uBfxH;Q&m zHT>|f=8oq}Bmi^cTYHPnuz34{UTb{JscZ&U)CV!aFRthzPQTC{qaTLkVk(KDT&uz) zyFPjz!+t4wC20Zg(B&p~ttgSHISM~65LK|EnSkAOUsoNGPR?JcB;h~?Be1KFdw=`v zd8Di_W5yVL4?siiT@-1nSzmR1WPCqzG)~fXv`&<4zkhv*0pKpnQEG+y3^wo5+=?F^ zekr=m$ZK;isf;$kXTCa)HS^>+KlAas-MX+ShJWHtj^tg6{L@@ zL+YPFAM^_XYgc6CZ6!8b;1rjwu3w z%fL?6EY@kn1jq+Pa^AFERjIkkIz~XrIEfZ>{Mq!G@_o9rJ)@yVv%z0>SpweE2ar;N_%VKotizKTv)>hkl)++TPh#P_2zMpqE$qvsj8Mlo4R2C zY}KD2I6s)D;n>8s{eG~(|B|oGm?p|1{sX@he5o~w5R`>Tqsb>qWh|cKrosSt6r>qN zFegwUmQSQrikgxJF7q|XCLM|SSEWYw`eAIjhj#O5>UG5kp-O@j-HC)_J~Q@rQqlEG zoE~(@~9>IlrSb0bx|2R7tW-UP&2|ps^!F zCWp*YuP=jz_B6$b$|W7v6`7u6ZGL0f>|KhO=H9)AWpI=#C`yF=P9hYP#6gonB8X`> zj#qPjaaY;t+Y}r?{Aqa6Wq;+kFY}&qa*<3poBgiV&HQDHNFE^me!G#qqjA6$xM_gi9(g+n0tSHm zFANhvbRJMfnQDZ5Z=Gu=UmQgV8ZK^X&ZqK zUT9N+?F$(grnApHRx9h$F`a-(o)kO-3IZTrH&8ldv>Xk4-n}5-WDJDheAdZVCtv7w zuA*-0{;2 zJ_+y!N#8(GgMe_jFk}*vkH`=UTpIv$^Id#0v-SM{iP5hnkcJXISbF^$9WQ{r91#i> zmue&PdKY;aejYa;ePq}B^RHs$KimNl8W~r6!j}s+fCZBZYN%*EBG6BpUp|K|N1KjNT3UmQ-kv;v7`j@RD2~hFwrZkB2KDaso&1)W%3v83sHmd zQKvQb&yFC1!~d512>7-V3$O^moLQvjj0nbbBcS1imu52_km#NMJ z-goUrBA(XId_|=ikc!q)MKwGek%r&f-{5pjdI3N@&R=2==Y$wjGt<17GUSImD#(xd zxPB^gWQP6ZRXH6G{uTnxp;;M5a$xMB*s1qRm7&QKRrj>Y=O^CF7icQQe1s9uWVtI zu|MS_qu$Wz`8-QFaNw2f?IPVW+k~r8&RW0YPbDbJ&3;3;$1q$87-k2~1li{rpI3eb|5S-+0ckxun$BrRq*lXrhUK;S=qhS$wU$=W(CTqX=fw zd$```?ujQ}HZ%J6I;kYatl+pEUZ<`;`;-x(Q=A+?QB&w#s}uh&=|Rx4F(eL35>zG3 zgKh~9>1i4_6_9qRAYWA8A>dUIML#YoP{F~dQ~hN4RK5NauRWo%c5eVU#nxTkUNZD9 z!YQnKVDzwv3S6|@v4TatJ|H7UBXcDFnyp119y+p~5kh&;E=zg&tJi&|u5WQ(geVga z11McS`4ZT>?ppG+Bt>3?jUf!h7^uPgsp-+<4Jv-qT+jNd+IXc#R(m#`xa;Dk#gP1a z+uBk=W>+o>_=jeL*UolY84Uq6@N#Zs7sj$od+S_=bJjML3#8z*5K5KAGxk6B*B_VV zh7|ZDWNmFX5%%|Qw&7r;si5wrNHp?$gv~~`f2$9W_aJ7wMpLnAru_l9K5|=F(KG5} zErjFIZHIpJ@d^8YFd76^E^Pv%a=naSTU>}Wnks}~SnR)B<6le{rW|e`w0{B)*au}5 zdaT>v;irGeOPQ{0BH(~rk=HXyBqne3XDZgOc#B~jiRlKZk%)fX9|sp zS100>AMZxUXOSxBKPiD*67IlA#=u*a4S^V%jW$Tpp`dx1A*(lMO(zRz8elXe*iM2B zc*I!DdWSvB+|v+L!_<=|XHgrJvWwS9vcV2gDNmKZ&}(R->Q$Rtl2wJHP^UDJ^BDke zd`|aNHWD9UIg%$V6d`$cCnW6MzaV#AzCOTk^!szUC#FQxmoJI^)f=`542=Ixa{vM|wm(Bl68o)vzZW zashomh?@(nGCTc9{Hx3VwfRL~Rsc4?t=s-iJ_)z}xzI1)maY|1ZkO&S+kU+uZYWIG zG7gA84N$2hQncfJSeBzXj*i!Gpo^jgVcsSIXmVkn_R3gG6A#i-H3GO8(bYxq0iqbm zhB{HJ)C^%&X!I~VWk5?tJUjW}I}sKJKoXHc8whD;-DhpL-)s0T5?ya`0BH9oPgGqh z@-gavZ@^f{%>Qx9DkV16XE4kWYW?^QdYl*aq|fX1kVRpU^Spj{FA#P8Mvn)YCtWT9w998X_5viJTqLgxew%Q-{fkl;_blFzu zwk^rvaGl~jP&@O}mu|F`%suHc)cPYIks|&v8gww2(Vn?k zT2$vH)?CwaCZjk`LY=Cl@cRS1*T_O;#^PlENB|E?5IBJ%+8(?jU=J+}yMm#6dN7|- z?@U&s-)eJ-Z`WPnv-mLxtYnDl`+|onRvy0rMYnA4*Sg`j&xv6)*tk$E9dls<=LtOO7Whv=c_f9#&DqhS|O*uGeyRrV0))`z1Vt;SJquCp<={97x`E3-{PR>`jb2U@YSl4(^6V^gMQ)*;=Pm%guqvv z8!7K!h~>hu@|PWEO128ml$;}o041J)tlZE;!gAg`^cM>V5#5}>-UCx23aM6tm$x+L z5KrUVM7{as37Y(WYafoeSg5zQUQ+<0GLfheVZcjW=wR*fh6^R^H%A0#LPAbW8vT+4E1^_CQ> z4if8NI@HP8sBu;rF7YJ3D;q8xaK__XYrDkcKSHLVQvmVlQesSgu^Q=WQIB?8W02s0 zQ3y!*jC;VFpfPv=L1LsGfiMp!F~R34`R)!nv2;9{w{)Pli}T`OVxht3+QEcv*~=i)lf_OK}359e7ekg9Ahql z91RD@oQ?XJ4f66ld~;nHP#11UPRpAjvss_&$Ss8I7zBtLFLHXTCcPlZ*+1L>{M%7Y!$GL z$GW4rQJ|S*khQ=qW+nYo3%_bAc7<-@sa8Y>#Dx?j13N%E9Vmv5Lv^n4HPk-U*m*;` z?@*&nMAt24=yNn`< z68u7irbvt%S_?CkB&`KlvvcDcwW}{{cd3Vz&|zyX7y&fKf#n8QdYiJ-&3F~MesB{Y zU2qW#8_h|y6#a?oN60sOV4wdXoeeMakY#P!d&_X%_9Xhow(urac8w#uA&g4pZL*rS zQDwfdl+9lw+WG-!2Ty@{FG}{tYy_=yn()G zJZch9YJ=fg(9eurRz<*S3|43giAel0w77%3vLidH-|H=67h!_HJ6RUuT2PO1@BY35lQS3`Mt*7VF+Cki z^&dhUDoqMticF-!eyHY|%}N%fXN(Nfu{I&l$7UF}Lk9$lT(y6wc-TkBonoF-RLQU! z<*c0W06wK7Dyk%IAQ_EeCwrH2YDPLQ$8C6F)$Wk-zA^sXe7PNoh!Ru=MEmGdmlXeN zD*|5EDH|k@^Q{&QFcQ!W*aQ>Y^d%-0y=eO5M_lS`ue4Wq`vyp-%C679S3LcFK0bJM z**cB1U`hEd0{Qeb+XfPFD4J5{GjR$Un(}**G23QeOU`^e*j{M=FGbJ`1H*ZLJ6llP=gwPwE26T z%25A3e)dTu?3!Nj{mj6A=RR%J30#H$1uD2+Xw6}bhX#Zkgn|5Gf&!fcbHn zOM40@j4x}cJ-I|HfCt!cPn*)^N4yD7?~6~M%ztlO{5*(|+;9OrZ zQQqR${$QrMQ;~gk5CP@>D?Qq16zK=r*cFvx|6pQ)V=Fs~27nJDy+s84x4QOWglJp9 z-A5D%l3R#{y;_Waj)rIDI=)o#+d*+s9(jJLTouqW--rk;Q}c>Vxl1Oaf}wBz6<+=a zmcnbZ8y7t=okG?(#@fn_{GU-A|1eW2c?`4yyG%po6`nIHp<_V=4NWvue_qKQTt z2uAPPPWP&Dml`#%1Y{brG7#BJ*z&EE?o^BDI!dw0N`<#@arKRu;{%2)^n67+v2 zf=y<&B9s`ZQk075R?`!A)vx}R+`2z;+4`T`U#PB7@TI&+0d#R%W?e|Rio3Nroq0II z@pa`%!%Z84AN#aFr=fv7$O}g1*oxT$KKhPswzxp{@}GysTnY=$tX$2N*B7WDqW7%t z{mMzSiTrr!J()qbwngL*1eWm5#vWP_Qk5)KmbT=QFDjUNfAYQJ!TwTvMNVhM*+>7& z;VJ?xXHQ*b`2KK06CML06x}O~TmJ9|ULOYGf65*c)HemG$TxJ`bLIeE#(IJ-jXGL@u)F`Smq))YQ%*=Qsm3vZk6&4;W=|iFjeI%_-$m znR2yU5rL>MmLisU(^!^YQ4X58&<$5boyy|ZzSmDb)sQx;E>U7S@!HN`GCGVNW_JHL zQI`D(B?AQ%YG7z@@h+#9oDHK)LeG&I$iccSC;1oXNiW)R87{`1UBC9=#_YMY8P1qg z?4Qnho_b%xVsR9D`WWW<*vVPmdn?#da7!E!#TTwWhH5k-Po+FjoqX0qQ$ou$5f^2Y zbj+@W-e)6Ymw;rnl+@~vR6x%DjBqhEghmg2SVL>kzgISBy4pYR{5qexHRlcaNfe^@ zi)2|^H`~+*P54(`Ud`+1@AWe+k5cNB;cDU8f6Yu)7mjuvACD&Vm}^gB?au743LEQM z8c|qvu60T9gD_$Cjo!Zr@|aPVwNUfNVLxGi(ePvO6+}^K3AWmR?9OU|l`4P6m%sK^ zj2sj{z(o`Hn+TmqEB^N8Hc$6-~)4q>LK07+Zpw^7EnS++eU=}}Ad?T-pE#If> zqFY$wRGXVfh7?#zbQ(DLo3w2Qf4JG!HAWcGy^d#p_v;MGri{P@9sC?zVrpDHU-8v5 zXQ(^PrLoi9EuP@ac2osKO+2~AS^`m5?+?k&H7gd+B%+o>%*|KVA&S<{IX`FVr78T^ zWlilo$@I6@zxasr&t3t(%I4s<9gv+lvln1bU!Ir*`oljyNnU0}OyfOOCyyzkTMK%d zN-U-1Xh;L~_MANh2X(e^RbNPLk?q^P7tmgUje*rJIhWQgT#+=kF2(ooiNVINkN3AG zSKb4jC~Gl=uo zvM_pldbO09aqEV)mgmGCm)Wph?fov0eyY)mZMWl9-@P3>y&?15Z@>P+l6Q%GTxm61 z(J6bd7SP`L{modbB>$dZGW-WkA;LBEV%WumytG^n&hxa8%L>+Yw;a!3xvwdeK8L}G z<_J`Dyj|ixxLUKn>KsgcBq_$#1H1RiIjgnGwbjUk5saNUOLw%4PcSi{tC`lA8>G2W z_cO9h5PqTOE5?5d*lSY4l+d7UF1wX&9{J^XRhM#JtFo-J6-6g3Vn49s)~xgA?`WG9 z3e=8&&t^&W_TM9X`iTQLxDiD?S0y(Q)JJS+{9748v2JwKuTe0t((eQr>U+s`59GEg z*~ZR~v>O|_qvszNyxkw8QIGq>@P5)RTvJoCS{u5L8nX5Bl<8GX(-SotN-{xzv-&e( zji8Dpu1K6*v)=NNOK~+1!C!XV8-jO)_Q*;A*^OG@glrv;aB)yHYwSo zsXpg>Shtvn&PnuoHK? ziguxg_;)Uw62niM=fXLKRp1ZZ6z5lNsSf97$&6ul$|P^uvUP=exzsnX_DPc;H#FUj zbAE2@rI(*uO2>j%UX}asJZw86_jF&mwWv4^?f-@eym&5Lk4=b_i99m!dca8?U&EBCE%Mtc8>AaFG}UAGxjLhm)p&q)qOdR)En(+}~!n`00gk4K87X=U-US>H_; z@8Ge$b!J5B;9OgyW}S9MlNJ)A@!s*!{?7RM2IeioZaiwu{_RxnuM_treDGG&*IATj znF$SGsVp(ej7?Q?6@J=r@f${hF3Jj9QzKuK z`rar(3H$8;w+3vO!fB^t4`LC2=a_7t_)KsxG7^&N3KF6Ba3I(aYi_WmM%)lO;WWna5&JZynj4$FE&#`N{HsTY5wY4~JH+74!25aMY7ewv25x?1JaW+OTUU zK2JqJA!M(py*o1*=Wg?M~1@nN>X_H!QRTwwATdWKQ7N$i>}5Bg_j6#W&r95kc~E{#92Q)_jWu|~z2 zGSE|;B(^s^`QDMd@B*}g03o0c=m(mv~jJ}^{qy& z6z)IngKlnaT1?ODce#RKU$5^U;klW4Qpp(MqR7$D-a{(hgx=zH&>wUsWsmz93cH-j z&>;ml$l%obR*{NzJ`d^gx60voLw|3p6y$F4vlu_*f`b>wjiF~Qg$HBc#K@tT+Cw7S z2*J_Km@Ba{gBq`Mdz`ikz~oU*6pJRNLR(p$Bb;eX?Di^17#-jXhZHk*a+gS_&FQDj zG#0&-&~P^og+{9ngI}b+4TEVOKF38wnaa~T%RSE^{;T#A$DOTG59>n@!+GOPbCHuA zM+{hcaZVDwwuFBpj6l;q&ian%((D<@#)^**c zN1~*-7|aM&F%Pi*m3>o0<`rUZBfgL!iG-MC^O2z2p7rlxyFdThYmZn2LzqB+RJm_h zno01XfvWJSMV&_9+?9-f`f1U<#knq5{OoW{aZ9d^^f=kLU6g>Y@b=@Epbxdlt{63` z@ZUhDtdtvS6n1zs_-zONbHU_2M*XLlknlUA>9G0BitbwiwqY)TP2WNfG0DVn58g<@ zC!}bJ!_eLEc8^TTfDC4c(C4`GN>RJf9o-RRMEHq#&3t*0tZ7auBTMW&Pqc(-NpkTi zsnY{|cT_5g*SmBG?J>;;Z!*loja@?9M|R5fw=$0z$}d7#+VhTmI|$41A4odaVFnwG zuWbAnB{vzW)ySL8*lh#AH8YBR4~HZsm;!17THQ8n7FnYnmBo&1Nw*m|pi;~u=q8`< zP5sANhn3b7Wyw^UR-q@pZ-%iapGo%Z!i~u#C`UB-OiqzfEozo%2td?xc>k7#d6-0N zrlG}O7id?2hLkkrxxA+6&aZ`f^JRuW>uEp!H<{PIb;h%;%6{qKFH8N4zC49PBBNQ4%`Q3k!1v~We&p@8 z^m!@VNpqG-{68F{p|DISi*S{s8kI+5>D(-{rYZbP`c9jc*53BdqrdzZ)!e>C_7zMD zC%e2X_ZtfQ!~`1Y0vdp+@1A{4Uq8K}Zxf_mA0b10r*dWs>^-L$F7PogF!*O?9$7>(z zTI>0ukp+o?V(s7bYappXH)yynv!!&f&BN3HSc{1_2BsB4gazp$mh@-x@~XIkfTyhK(kMShVliylX1IBHWnyN&uraRr%!x}j6l>?xb-^4{5fAZI8fDmN>SJ#_C@C8o%fs0nNc#DtZ{XjGd;?7VI8SqKL4<~cUo*U z(rM{s0f9d&eo#*mjcwuO?vDdQs1&(Hk5BX1R`-g(+lxlJYV`$tnV(Lrw!Z5^;g@6h zhM<1S4L1~v(O+JZP*9qBqqo3;LF}v02I5H4(coJd_}N$H+mTMqSJytre&3Im{EAvN z_ZGpr8}Y|nsA5Q6U`E!P-eyUi!9XGrsS?xG`yn~oH=!Vhbb)dIX85>RjD7lBidS{C z@o4y!zAF19KZ8@8$7$${|Lg9~^ovTt_;12(Y)5Z<;A))a6qC?Wpkf`RYQ$ZW1;$_B ze}3(ZTKUs7n}heRZ)ThA!~DAkAYD!Ww%9Glx&rzLRi4!M>@JIIcMI2Mu)!7GF29Yj zDJYD`ZE1r1|51e(C0TCkqi;XB5dI?@TN`j`jfoK+kaHpY0xB*B7lLaKx>Ar1W9nQe24b&v43ZBcOu^v~2* z$k{r=O|byZjYC}4*|T&JlzPI>-?neXwQx)qp&h$F(Y5@uIhSuakYh*Mifc)dn2i$A z*X&aHO-jx!8J_=9f^bp9u}Hv@7-)8ESqC4J4gJM6GZqcacUrliflQTQ%Gy(>xVP zsNWt`w*I964#*9$mOtCF;>Xuh50+UM|9zP->U%o&RSfZJHK%ul!z%v_D>v@|);SOp zaO&KUz`idZWtHJ|NdBJ2xCX3F_}tvo>#~*b9R%=vH5ZEEItxcH7u(pGYML_~h3&b< zkv~=hatKvEOb7u~)5SB>#`1|<@coa{rj*3jC@IQ9jP1#tHq3;;3PF4L;~!xtW2Dn~D1q|6tvW}YrzuZa17SvFToIvL z^sd<+th~yqDF_py9AuI3agOn2;KCu}8L`Kj8ha_%KR2LB7g^1mqwYXn;IjtO8yAqgcwNsifW)5u9{da8`i{f#6r+;#4SdLQUJJq;p^OS)7 zrANT*r=qn#N-!rrmi`B0VJyR6*2NH{75t)_H3V6~+Or7B{{GkS!9JId1_xIUT?8G< zOoh@~P$0M`N=|WGjw&4oLQ{!1l84)2!mT`MTjWUPcY+WGwxgg`a;+}Sg+?H**a)?zKmdHgaN)Ok6zaWC6v0E5dpWGuIJ+slyWFF`##Fs{;$di3(CrJFUhJ`oYi!9y z-ox;}8Rj&dBimXyiYr7ZI;9Y=rW7zc9u6yUow=^}xA7E-8qRRYohk&YFa~%{j%_9o z1&!9ijo<_81le^L`mynM<))M(yllmn(@+f{5E?p4xY_gflom?&2i2B!DX)aFv>P1m zeBrrm_H2w@zB;38Hpc{UQap~=gUmuA@=yf72zBZ9-v6uC3d`3Na{&JCro>Xv7CWlx z-S3pJK9?rzL5rH=tK@n&oPIRU-WDqMl*k`dNu&L<(2Z=$!?B`oV{frt7{@1-9$%mk zkwdndZ;XPy(&{5b0(e!_1YF?Dn2=MF^@b#^9f+%BPp*Y@H=4LQ<8ra~ot1Oa+w~vY zRGrskSn_rAQ?DLz$H#2f-Ez_wW!*MSzXja6`QiMs_(dxj4vyXw?T|{J{(A}J!b-L4 zKHyN203c{Shs^IaL}6Nf>XM6*tKhjDlN?soKYgS=W5tY;ZhXSMm_y5FSV(TUjYMND zDdsqAQ_r&_JT0yw9DX{l zz=USvC?BmABGhG__3*CcX}_aG+Yqjnj?9O+H;>PY_M*!A`fJ0c{A8+bND%qZSpbc< z-j&VeNc3hjf-+JQMVhF@mDa@S2?LfJ2*813dkd zf%P;82SK@mJ^fq9sp5}(?vc_?naD#GOo@u0y^bmB3$yk1@98l4^Kfa?+o~gc-!<)< zRehX(YTCjsb)g0eKv!?U)6#|A_%f>jw9j?uua*6v^F>VnkUpw`@XT*|72DV ztgO5Jd3pE}T$2WurC-bMQe3DD> z>{BHU)GT1bTq#>1X;@A$Vl3V$3ERfP%BskjKDtNfYbG~L($6Mul>g+?N{ClXLc$Zi zhu{^h4I?w6soK7>4tHR2y;Tx7B+h`RK2wYVpNL-s{3d-Y`8Vc=i@(C%47T>%PzDqO zpI;eQt#xG-;K)6?3i^%8R>Fyp{S^GQMld{yX_~j&xY|Nl<&)H^Jw48{)vivC`M#&! zVBUUtu2Qwq6lx7qzf$BusE?XCO9<6uKMGDAGxYB{g@GwlECHDGTqs%cJBC#VOO}EM zO1{5h2HcO!={RJmTYmS}S9PO694JMIKqsh;Bbk{(OG7-Xwz_ELJ>~#gO=T2)^@;Cv z7O%;>4L?cVAI2G((M2J;?E?hlU5iS+Y9TypAg3ZjKYQw*a*KI_lW#YKcp#vi^X)(V z^O&~EF82)2$+D_yadq48xm-t3WP!%Xt=v*WA(Y?C+G)a81T6Pv%A@kc4EeUf*r1|AgLz5Vk7#FeF!9Bt%< zU&ua%P4o?p%NGNUOOsicKc#vH)`~t%2(rv0IG!n_^{`(H;>Wdwau5C7fu`D@ccT4_cvYf~``tiC;z z*8nEmPE^dXf`F*v8FY=D=%8T-uPsI)8c9_S1ImV@gOzH%ocn0!nr?ho!6>0ND+UTy z7Hh-T11;`73Qm)G-XA3Vo1dSago(TO!j9j~eyX%y=x^TpSni2$JGECGXH=OB`EZSi z%TPJ3uzLFY;5IhY9X6S4I_T|wYY$XsKUAcOC(1B1H6Y7V&wmez2 zK)_CxE2rYx(8x#8O+)KH3!iI_KrJCFh8Chzt#D_fJ&0^`?uS2(<@tU>twV5N_m^2M z+%v6b%Tl>N8m6JHBcESE8a;SWZG<^MQxo;iFVD9K8+@eHS~dDAIH>c5)qYbqDvvSt zOtQ8-8h^e0;8)uxCnMTI##tpk4$>}NYOnIR+_Rt${QOTS@~p$Y`i$51k$b?W*YxsL z^xv|9n7fs}MnPHdG(JpXI~ijZo`P0O&MVm=|FO{(3 zZ&^w<0fco~&_Tx+B@D1;SSYk#&pCdmtbH2Y2YzCf=>9+ge8NJ;Rtif!r4S>0G43m^ z3#zDK!R+t@J4X6Ghg?Jb;me=4?DLE7+H;=TX?9GP#_(%T0(jhT zFxn;Mp6(^(=Il!>@P~{=c603WNg1xD^zxq#0iWDvHD^!HZ6puxJP~28v|7qA*F3)- zTdKZ-x0pV^{_7_IhZ2#>MqU2&_jX^o@y$LRGje>#!7s4d->++ba^v1G$0K#QeMN6} zo=l>MlBpG5c>U`2{mh3w;YU2x;=FStlR4HcG6!x{sq#XS!FCavvO19?0Lk=R`B9@7mJe{U8QJes6x`}S0SM^q`+P?x?9a#W zhA-SnjJx($_?Bp^ocj926e`iG5B=R7nq?OIZB99&ux7NY9 z)5I!U8bhA}d@t3YQ%eYm)Jb?a20}Egz;BM?M3q4QYYLb7tc8_<6_ZS3dZ^5NuzgTnUi)x)^KQ zs;M>x>op{;cxk+T8(c#-=$c1>Kszteb_Ztc)jQlhxUJs#))U?364o$K;*=YyC!D)H zfVN5^$O~6|a$i?nvXjMz$*L0mi2$d;UU)`H*T(+)lZwocW}9bxWz+GDR*H>yOR!F% zAIqh)=nh~Uo}Dn`XgG)sa#X2E2MOa(O;{{@+qjR{)2tKSp9V^Oy2qQFLVkvP zzrBP%F=+>1?e%%CHZMp!_1`M&v zFz|~p_E1DSbHR2Uh);ybQYuVU00oToNQ}Wi*{EYsl35KORBS1KAJWBbG*f>R!ME*uT*3qi1;N9 zUy*cs$}NzOq`t)mvtk@ND>i)pC|5;-(d0s1)XC_U4@t0^m(0i1IyvdKUjoY%F`7uO zwC;3Az(yo@HQe6KFGsmi_IV!TN~#F2MF0xycmO!+7`K+AvbS2|h=WNTpNz2NrqU_6 z73O)fNoG!e_g*Xt&fGgEecyH7d~K#(VKrrD+f=Qba=Ki{)c|$eUsN+7-y(kUWx8+B z_8vC4lu^fm0r=l13a*=!hafY#6wE(+K-Yr>?+r&zZP?)f7qqH4*Yh~C?snSE#Vms! zEK*^kGOWrK#XGD5A=>0*SVNod>P?$0*5vbD7mrd{Ui$oO&jSf ztIIck>Lui6)mdC;)>(p9|Ki}4NOxB<5n^-skHSl4kk3xF?S~Rn~h*dN*ch7KiL1f_?zD)Gd)~u z^W+<)qa4QYmK_)*j{NG5Mf&Sst3ki50-@*zRuSLNfw$|zOF8x+WK(CgGUA+i0KNax z)mO~Kg;&dfJLoj}#jd}yq1Q*~914c(to@R)zE(ec%p4%_^y1a?)1<4xtnt9BW8mtI z_e`EKdq*J_8f~tX@~dtS0)2PKj^J1J2q73i#FJD8bW`?vCNLr3W8UZ0;z3>hCLt~wD)4pE6z^!=Q1fzWRq@Q@T;M2nbZ(|65r8};}yt44| zEsCq$IqxXAH}U2-vufPoUcxPG!jURUk^$%4xV31vYumw_G@(y7;J;wET&QMCeWZr{ zD@^etbJV1~q1@2o!Y)!gbR?RC1fV%bBmw($sdBRZ~#jNssQxO)&uSOh# z+po;5VFpSIq@9KzmxvNBfXH^7oTQW^(6F-By$9$RccLaro%;WawQRxpM21!Jqi=ze zZZhuRe*1mdyyl%7amQd*0WF^E2+92LzogOgDrs0o*(IWy&!FFVmQUz<2hDWuWEpti zl*EvXgw-81efqV2a3i#k8M^nvC*=Rk-+a%Pqi^w{ezJF7fDYeZ(*9#98)6ic;>HY<5xYyb-V~c?7=|8DN3x#f_mXWd1EkO2I)&)8Uf%1JUPY(Kk8-~jBBIT~VgI?+vA`4Ral zxe#Cp-;ef?jc21XtC(M(SM03G+aK*G9H+JUNeVz!$Q7Ib!OAp_U#(d|m0S(11+avI z?6kZAB{`b<;(I;)*3E^+NMlJJCR(~VkBfM3Pv88zpF)@nL)nJ?KRWhXFeazpwmzp{ zVfrQ3C&Yxi#q8NjCfXbci>$)SaKUUKSEK z1{K>yU&L(;G7zK-1-kJL!2Mg;CjgKhxj{*<`+6aWRn+6dSJ-uHi6xh~&}S@o@^5Y+ zzh5lZFr&9i!WLz7quINc6fxjf*X~jhML|6E*^41sw1dEC7`_)C{+7^IAe)Lzw@;pN zEO8*jaSiK0;e^e&{Qq^{YcTn2kk)5V-wt`D6HKTJp+%c6!n?w5WIAC)v_U`~>neG8 zKZX9~;)=Of@JD8WCd0H5lH+DH0)eqBd5bA#$SQWlB>kPwS}Q3%P<9fC7O+=`dKyS3 zEHFMj7$qZb{f>XuL6HnnZ+O)#gifqpm{R-Bi?^y9%;?`eKM~PZviie8tm(+EI1cQ_ zg(Y!4o{e45kMyYEA9o&9fH_Gu!>Y$?^WTPNk8zKXW=p<<%yFhnuiJWe``b4Iygr7k zUm$tczK_Bh7%rL{V_eOK-x1gL&uGlFozxS$%XnE6ijeyjz7(@sAZS$v2?oT{ty-+# zo$Bod!zS=k7VW(UiKF@98hx8euD+Q*Dxo8!c?WRTu_KIZQfH@n#v+_rk2<7P@&K?Z zRL?NAYvC`Xe#7D&S-O?g-Q5ct1MkdVh19Q|XG4$nw(} zvZSE~)=XT}*&RMn>zo*Mtq>4M{1b%Sv{0)ia$Byfhp{6R@)maQq9>RnaI?xWM~W@A zD+Cb`__dACs6G$w&|$#5KXCLw-HXCM`YRJ>82W?|$~_?Wa6XUfF$t&5Rc&;rys&*K zSNv!Ud}n3Pb{cgx6EZDC<{j}B54@165oqB!F}ui6hcK&0qFsfKhDsn^HQs5=Rsbg{ zhVum&uB?e9g!8n>uX)j;2}-C{uv)A><#W*?;r;zI62nXaxVcZ5qK$7yR+xrHv zBIqaN#^b(7Xs2sNpfVktvbNa~jV=D1SzgO;!YHis3e|<~Q%B`$YdU&mw?Ao7v9hQ6 zdi4oK5Q-+X-nI{nKAjkS@g-ZmgAB8<4M>-0$bDqA`l231AooO2<~W$rk{VoZQ+aZQ z(PGFn#z`{S*)mvSNU^eBzYUb?IEWo0$DA6=xX}2Vmkr|+tvQ^Kej)#o!KX~ciB_XV zSQVM%6BF5_5YK@rI*d)KAJ$h|PCFR<&0^E&@l^9@RgbVfFNU1??7#;ll_#Pe zI!(~QN!Eh)Vc<*~>I{o0PMZtaX^&`Hc{CWYeecfH`Wi?CYrtV}2gMccpa5ERUUS;@ znvq=0!6h=Oko(WDiKl7%^NkqjRmpf&H6j0dz76-91lW%GgDmvHk@trTqea%#8~&M> zucXcZs+f0b)x`DOv#h~I@l)ux9f9=px1;w~H#>Dyq=0Zs#}s{ztGH|va7aBwP{7Mj zffaJwo?n9MJ@-9beL-4Ww(NLpe6sJn^Od|k&mI4(-Ay;w1S<1R-<)USwUWVq(4fzG zo)f6SBi*!{EbGzhv7$NA+lkPLrgc2;aA2qd9d;GnxX#2cb&Gy%mem=Us`4o?vSi z6tGglt7VVa)qPWkQ90>b0$i{!hCmN=BVG6*A*TkI=AV$C*bFrMsu^gue%dnXa|zt& zT-va8?y<8U@Zkc{$S%Y#qUhO68OSDpyY9{hB4qPclWl_6IG(vZW^zKBV9&u7abzjw zxt-QrN?DZ*0>=dca%BK=t|vo^ydm5l<)fbQS^rt_9MG5-P_I44u^>n+-w5C<8VjgQ zjVwlb`qHB(`qpk~%ViV*oPq2xZj>yFouo>9&q6lCa@jw1LnWsKO9kiH_M04;{bL2q=4zoq<#M9@ziNvhZlNcI79rNvlGWnC)D)oR=TgCNH z$1WZDtyRbC-Ugpt7=~Z6`0Kz=qD~OGaz_-iZ(cjLTFn65NTD%{v&1RbR0fs9Lt`Wk zTVfxP9jUA14wXOPW+4+jf&WR!tZZKJd+TKho;+Bs$5@P_YrFuP2r?`1VA) z6`cPn&Kw@Z+>|i+IEWh{?Ui>4TYrTX<&60X zlPieB*Ia7C56P*5|*}d;aaaIA-mxr z>vLw-q(eNFbHhG5e46BmG3p4nc3Q$*OIkz7!{RyVi_f}Ngcxy1H)kiSZ*H9uF=JgR z*U=*Ovcv2FX0KJD3k+L2vIqLYkjGe1h3Y8%>S`$KWxIMKr&Y{r&s1nP_Di(58x6NI zP^AsJhVoi|uxL0jo9+N|8%44kaBe35(98p8a?sR69dumB-N@{aNx5OGxSvrgAB4Gb z&igZT%>{_5TQweeP3ZJyaYHkF_5B-mYiwY7wI9sEWxv$wxOAO5#*im*$c7C*Myv-M z6myk2Npc~?1dI%D&eL`BwmmX8%*0RepF(CKoePzOA{BI?1WpGUHj|ZR!lxW%$O1i) zcnhimU$tq}a4(;GpF2f~MFrdk>324S?D|X_YX8H8Ioy?|4TUwhnIBA}96KW0|{HLMfnW|oHAN>${(&w!lbiH;5V zKvrw-@J7GS^BtwjCrvl1NFV^wmPD0$1bf2Ub#C90p0%Db+Q#{WH89#9S+9YU*X)Wg zN=JXzttUV}@4buqPc#wyUys;*cx(t!$`5@u%{jHMZ*b?cWNbu1QVODgE%+a zVg}IsjWx(3G}qaHgr~TuU5;|BF%A(>zdU;QAlz~o^2==N6Y@Vi_-0bfa#v#pwKjIG z4aOeaYBC!uchKyONe5d(eo|fg`*z7W=j6RCCHw?8TEQ&s3|h&kzL(kRV)AC2VslSt zAjU~FVmS)2*_u?5f66Gww(dXK)j zENgssh|>rBV5K!to$r8WNX$PR{_!t*A|_l$&inPdTF(Lq&-j8HAKvS7zs!2ul8g9D zZcsdcgFN94NkkMoI&*#Nus3Ix@%3&y@bXnT2mWU{iIvbdo012|{UOBmoO*s~B)Q-< zf3*)GDX6OgYxv~TlZ9E>+&)|Uk>&^s#!8b3qC=+!o1-R(-)QVK{aYl}uBz|L z-{hNZJ|B(d`znFHVg?Sc=K(9;@7!uY9oXi@$=KGlk;^ql5|Ay{zjPhisH;$12W+*d zpn}gQk9e^@iRw&`W*7*|7-tRmR z%|Q;k@Yf&hql@qq3BYvin}Hjb$c2v~EDzBJRa zh0tLBYW`pTcfnJiQzil!NH35T-5ia+Td_Dv$yIt5X4E#M&I^+ z8Q27H_VGxZSE4X|d)L)_A%z8GBqo=BEK(a1i_--RioDACsz@Bv9m#^9K~S3FbmkR# zy1dMa_0$c8d}0h7;62xxYD01#skxsFwff_cP^9DE!2}26>?Ic37k*X?52*j5WYPOOQ{<}Jyg@~n>U7ZV<}?IwN)&{3qb`Re z3%IMa?|hw{kIfYQFDaX>Y%M|G7~w0)n{vHDVwBZ$BMe~;e>}1=cG$j25C}5jdKBhM zmg_Gt&+Rz+Te;i?{GMKYK}BJsc)d=<>b2KihEda3a4iLzJ$PU|Bvup@c;MQeTO{Nm z__u@MSSzx_HddH_F4yKgKY@4`pFH8cvF8d$bvVb5`{x{L2R}WYoI>wm5UMurRxw?i zlXZk(72qT8TKuw$@ZTwL!3X550VDL*dTKd5YnGZGyy@wgdT_yCAGu)58Y7Ny49Tki zJWFF5zWGBno%N#rCY=|sCTIR04?RgZY7+;f0DlZq=XFekJJiK(D^Xflwz5KwV%f6J zZH$?W)l4}<4`cNt0ovNkBm5a|OlCm z9*cL}!)4SAV1_PH{HDWO$RRCk;ZzCxkgSDE_yrxkO^L+8h)=T#k3BQ#I`%hcT2YkZ zIJy})D7K^J5^qXVVdq)f&2xherR(xp<1TIN;hNHJ zP@88`Aa8vO*oIKPHa`5&v4$`;1sd%ch8Be1SDqwIcCt6ennp=FCTqnn*EGbmvd?{_ zB9n>5%4Ek$caTbHs7gUvzZ%Y^BIh6Ia(asz>@uZO&D^S+6RR%%nV!D7=Wf8SgGk~q zH)r$>_X}3v7Z9d$Ng@Z5iIMbP%uk@92z4Y9n!!T=uLpa;zX~BRdRpzvp90`84J)8f zwL3xG4F;Dt)ZDME5qf~_skVBLWm6Nu!cX|N>Uv7E3jX9?zXSJqaunAr9XgA4hy3SpO6zNwh3rQ0IcRg1ZjCAEK zDxyGqtzXFS)pnHK#t8A~fLSE3#`*mzWcQ0cYoCh@DH`4pdMz&)Z~FF4NMturu!*nc9f2_Glh8LZL1c3b&^I|U(5wwTiYDCuF3i8e>s zD6S!EUuQp4JMzBXhg!y@3Sf-^cLWB)0IJ{PzI6~jFp>o;mo|Zf_PtJe6ssawKeTKC z=l}Tj<14F4YQx$ioHWtZ?BTwregbOM1u85>e8AHLu<`jA?z=8`e2W8)k=$(Xs{ID` zZaFZV$VjLz7Gz(t%W@GCTw_4>00X3I<$(o`ycu@DdKy53-<@}L862DD+U0sOO5ycT zN21>lpBS9g;Iv49VBq*}h7=T~_DR9Dyp+2Z{AUg1rzmLfpM?#8BdbEur#&{W!ZUcO|wLaBfEs8a{{AI(;A#2A)c$ zRX(1;P0#VJI3zxqw(?p6B8vs8sp3`;o}fF;$fUrswzeFRHC zaSR1NvIi8V6I>Z`hwN23vJft!s7#lB4)gHUHDxR)V)zNQ#U*TAU?PLW_)7!{5b57u zUso&VT_iOxcA>Lef3bE^2g5$Sq=pAClJ=D~a5dXUCWt`>>>fHwH6jJqkEQ|PkGaup z&v2=4vC9qRzX>k9@ie{$@w$Y5d1~0AT~91hR5Z|>fiYHc3CuiWuNa;!@_*Ce^xB|( z*?_N5WoBU?!9dr0sY$nw9gtkZ`P2iXX-brdqDGqz#XsBxQmAdLjo&wvS;H7u5YNA^ zVtf|bmLWsei3t0B0a<%_i9F7(I3X-VlVS^oc3Mn9`V<#74^7X3Y?=Zx;8#P&)9FL} z>wpZ|Vb&mLdgjdQT0x?k)Xr z6D(e+V+iUvn?ASp9y$bsnc2U~=kgb7WB3Qw+ax5npu9EgW&4swB8_mMEPwiQe2Q_p z*b583S%L|m2==I~I&`+_=0^*4Y5=2x<}7s4?n3A+jUiC^fFzjd8IO6}uhVLHko4o> zMb-)=CDHo{$}E2cZu$orAdpdFdU$Y)`B3Ejo=1v+0{zL@%1}Z@4K!*c>E zFMmd%5e!#5`w6^wo6c4}@74C?SdK>8Ldt+{PE#H>&aICCxB0CGcw`TXgIpO)HwsIw z;xLRDS^-fd3#)~2h|EG2+#B54Ep}~xw(vHL957zuGONKsGI1oz4(|W8cx7jKr-yce zvm42@E~3bMXVi{0kLKije;%=|HX?p zW)zR)5v8p67Vn-5o_TpoUM1R#3CFNHjV~{}$jx8L^yp@jX%gG&a9e=LUIyv;#U5zC z_0r8Tle=Xku(Y|HFbE=Jy$9U31|}P|pd*-K_-*vk8}9HUaJ)Ec8l%*F_@4}n;we+6I(de6RrA&vCijtnBlD=H?A}##xY~_JreOp0JK4tai=of(#^Ar} z5Q8B-&^T#U#25DoX2LA`ZKJOk?Y{IDc*nL}b3Im66P$wM^*5U2XdbJail680$i6xz zX3Bn_$^1l$rLC&GCZogJkKN(T^7?Dy$Q=R}o3x}TtTPGcWWgf_Ze=5h`(T4a#(<-e z27ddQjMg!J3pp7>0l&KxKFDN$(I!DdyU8k1?!0x~$|Ndh;lv#LkTCM=1L*WNrBeI% zWc3pQ&9kp?Q_FAMo!tgDeAfH9YAfZ94*!!oSZ@OorU)n5T-+kx30OGU)$>TWBw1}(wJlG;LIJ=cnLL}iWR!40+XVzBen}r^ zg%WGbD`|L5gtH8~2yJib@X8kX%Dy@J({1UK8|pT2!a#8~u*n?xsh7r-==u1PTJ@x_ zav_NV7bHyeqCg~owKm7;!n9ivE0}@9kIu^?mR!5ac+npFSt0$?JXQIKfQH&e*I$w& z{9Mz~$)!Is9cANv&ij=z559CW^MQLPtC8$XI_;`(caE37zN@RA%$zR+ zsjj=_`t0XpZ4!}%{{3T>N!K@d-Q$@urJMaaRJ(gy2OTe6T+M2uy_<-s=U3n{l|Frc zronB_GJhGrH#m1#_ez_FL5KtTr_g_zoM3^|r37-*f-zwdQ_9$<%Eb!?VnE#~)kNcH znVtHCf*-tWe(}plea2pBk24v{4H-teEML9J0*Ggtzny1lMJn@?gTWV{qERO^$DEWj zXT-$N&P)dbQUCk;lXuiV5#K~mRL~RPe)wJc+BCm#>X>e9etlwEb=SkY@sboU#L~W3 zS__Yhq8mHf&&SToX_1f@VYIp2!jd&?shbgb94D)opU9m(?`kJY9Q09h?`j$)7E(k8 zhBG-udd{UiF;a<8lNlB82mbr)P#i>PNp>0}d36Ui=`_|i1~0o(9UW2|8INzS73S96 zq7`YUMlt^VvVbpt*?#+Z_PiM<$P}4Om8N z-41j-q?CoUmB!UVTa~q~cRvg6J<~Bx&-Q8Gzdis)p(eoBM zLaAsmPU{Rxd+h{lvpSXNrp{@wOc#L%%DcbO;AX9-cGR~zD~?dkt@nvj({a0Y7$0c= zPK6?1qqD8hedE9QGfyUVrG&F0>t2SW$vXI^Ro4H9kgB?%uLR4o=-{F!-ND_R{b)Q;-DFYekdgDSPxA53^3!==5TWH>1(s}g4x zebCzFd!6K1fbtaV&n9mZwIM;N01F6EZS1J=PCK{(8`=}D?AC`rN#uYD!P#inRIYGT z&0?VwEV`T^r4=>{QDAmB9IJ>ALB*Us?~mSIe?xRK)31-c7yhEqg?+vy(#-Gdic+Hs z#FaV~f+L#AJVOYcuS$)?oW&?&3|Z~IQ0PxMuhy5zJg~3UhQsk$)V*6t5Q3*&8Er_W zr*FXGJOd88;sX1p1lN|7pD4+^3faB?eHH$;xf&3yR*9bNmTns;*S=>lVS_V_FU9vo z5{I=TS22|bCy>v_@k5vUKUxl68vcbLkSl8D!m;*a?Y0~q2-3#SjyDNs`iR6SL zG~)_lC;e5asfzB21O~@m5i&bsf8{i$I?L#UzqG_Pth88x-Z0-?=SG4;IZ;9SyC@2v zRL$^zBB`+(^Tl<;qUI3&_3b5fqf`mpEV6pCK$=At*l>tdo&0Ejqc=(<11uSwB4HNJ za?;e3wlb0%f*3yS7Dbth;!Lc4bA3yzU43$VpLU*=mH~8jRr>zux%-b%0EAWu{}St; zC-7<}L^R*KvM6f$_uJWy3+N65=K@y~YGM77d|MV9Gfm3=IWdDWEFmLb9$y=$^oBs! zD*iqQDL!U;r#U{dPiV0n-q+%VDgS-}t7aBUrMX+gw$aIygYHuw(p-_H&FHs5#CoAT zZKG;-o;HKjihqR%-2WXbGzKxkMSq<<$-k0d@HOVLvzN< zb={(ylvKVzDiIH2;3^D`<>VH57hyWgT60zdu(jL%yCkAJq4s5X9R@3OepnC#ht=Vu zv2CF%R1Mn*AEMj+(F)Z{Z$`pE>4=W9mIIw#MT)Kyt&M|hkHM$FI@6eS5%1!3*aeU{ zb}*?a@Qw{R?F&P;g%)0tbblbODeXxJe2k8Y$~BirN)M93h}@s6XSaWRRE4PzLwSxo zIOX>3NSIBcRjRv#$Vy!+bnM3?d0GE#@<7s>JO|&0z1xnsqyT+kHT%!Trg9VDR@FIs zxFUV$UO$|)Yutzh9gk13?speF|5%$(f<`Ng{P))M7Q3Q7E~|?#$gj6}Nm_{v~)xE-cCzgJYo zky@jM9S(Z>x6_rz<~#P@&lhw0(!R7l)`ZxK?MPBO)giuzqCF9dgRFwj?Tjf)dNmvSrO4$YZyR3`-dJh?qIebMn7n2YniSJyf=*J|h=XDEmLin^@ zF%#*Q+9RGmXGQYZU(kThQ(m@NL2`D6?5FVkzWVpNDhTi&nh2MIn7xqN&zsqTmUVjjtSk7gc7bv}20 zirT2ZH2o|#X3P&pJFnm-a(`!a=x_mEMO-eCj=d?KtE$Kc<$q?_F6D1F??rn;7!;A~ zgIotya7!crI7yq6k67_fiX@hmvWK`N3!xxw1s#_&>L@e0ti=I9V6ywF6nlkdHVM~m zD0)8uXeod6`gROhw^-6~7d3}#>AqhtdD!ocO1%<%YSkw=@{DwlLOQ|z_U7_tv&&1X zhBzUGij1YrdJ8ksCq3S$p#_HW!#xy0a4`SG6{It>2un{~No>0a`q}1qyiMcowRCwr z*()AjdMTsy?dK&ONL{kg&73htQvM<*Ln>r<{nswsuKyN^@L-jTw5NLC>X!8Zvo9|) z&fD_yk12e)^i0d;BV^g~zy&Y;y*q#R7g*k84X>f+8%+QKafD?O5D;@lOg7WktSe8b zYco9A9Az2jk9U1pf_o^}G4T4Y`JPWaAwvOAH=;gj-so`(R!I`*p~-j}$;1}s$^(Vg z&3^O*%TjJHYeNYrqf~zb?O}QyJZ3V9MwB>F+K4T|dHRGngE@5o(fyAvK#nMjFbWi` z0&(Hi2g;tGEQUK{?JSRz2qn=zwhE>6kV7<}f6P>7VMwo{TLvwl0kJ98(Jre)*tj~i z?|!E0+0Mru&$R2>!eC#J0gZKZx=sF!FO~7nS8J8~nI6_}6Bg=@P6dQg|Hsxj{^!+2 z-8yO5SWVKnv28mI8#K0U+qP}nww*L~(%3e8cAob=zw_n%2lu`AUTe)Y<`~!9qvHC7 zIRe%i(a7nlSpav1eu^9Eb~{Z>2&8ZwnP2<|zH72j#1kMc6l*))m3^i!H#_xVPwrgk z4;)%V9o?@#JbeVM?+4rS+Z#!E+87=-!mu|uZah<~8y=6FnN;^hoTJ?St!Wl2KJT8m zS*i0jLfh5RGx5Ku-wQ|=zE-9Is%l=2*J~N1DK#zaPDYYcSFQxm)ptoXRat?MKoh9E zpznDpc@P-KB~y=}m(a0^n#8Q81{Aa0AId+a0z?Hm*9)RGeppshS3Q~_)o)JU&aou) z^174wrsj zf54fSx>L4q`E90HD0*3!+8!q5Ync|rk&bZwp64%aEhNX1Q`NxNngfp*pRagOXpA=$ z@$tAnuT=siK$pEYrV-Alg!i^=SNXrXY&F6%&3%b16Q%t5vNK5w-~6UU+PgOCdAE`? zqEUz0dd~1{i#Bqd-?Zu{sWMY$J5uT`ZQ4wN8Qo?|klbs8-3P#Uk*$R4aP-Y1S}GNU z1KMfC2PTAU$3YSzv=*Hr!Ga>z@qE`kKjum>n$g7fZW$@JI(;6XDbWRZI7pX_)FVVt zcpALa43oslVAN3YzX4$*hG{gdFd78Jj1y88s= zzv^U~?C=6opV!rLHgrG!-^WHXxbt7Se|1kpRO{{j*w5pMmzSB{9X^R$&*MDjjhdXC&@awvwplg4I=3Y5CC}L!q0^TAWl~V_` z#viru_tm$xYqwn@82{UQqc`dsd7}8A=~ZjrAR0UscVZ3#3Q0Nbu|z!F% zr|~L@1LbB;D$Yb224|<$t(^Qv(>cj&k*zl54PC?wH=GEy1Rj!vHF`%dtC>LGII@p) z&=C1AA}6tF&qs=3Uqd+$&CFJu)THtgOKi|>UA}Wk5DIKA6gYjP0cZ%iqWET^m@qdVyA0Kfkm#G`6+wLU!nTmkmjb(qaI(6bTMqeZ$fOXjEJVZ|8_a z_>Bvqqe4eS)Q47Cv}a6*I9T=ac<)Io{FLh{jr%xyOlbdlrc#VLiEU2OLc!#}h>4)G zng63nY};ie>cJ&1k!Gs2yy^N-UTqTXBtN^wdogK^InQ-WKifAYh)kd7Z5QdZ+}t0) zJ}+5xF=~uH?hjZi-wfMn8~>`gayNXsA~yHxQ)nSy)UGnc*AfhokD~pWx zbTh0#0iGQxL%2I?@rV!F>5mcoB*4SXkI3|oKEuLmzg(VlV2RYsVcxSz&T0S3%~bsf zQwA;8R$+xGzD|jT?{Iv*JmAMO#G3m$EnB$yLw#Ot7$hhV`0XFQ#+n(6`cz$Q=tD@w zJ=jJ3AkFPhbdZ+3i2Zu~zq`@5FumaB_kzBRAqcd-M&Er5LPP0(rm?nShu)1spZsCa ze|K~yTh-G6W^_ag5i)3(|Lg4Y@dccHIs|FIi8k9^q%6R`ICtNlzXzXMG-`RQd9Z7{ zbr(E8Op}__kl@QcfeP^o_!N=Pg7zTAdZL6YwE2Xcl5PG#|8csdrbN z23+$VI6oVmzJ8ze?U3mX)oQ4KeQbbq15Q+4wh4=-3&R z7t4waTo94AxZO(k3gi&6N5%Aq;P-P)XMCx$A`L3?%=S5H8dGYM6%L!!H*OcH(oxO{ z1N7{t1vL-?WP#stxB36a)&v#z2M)~K-c8t7=O34-uTaybStKY;X%}66ve32TBd54SgS%+2K+N)yM#ATW;H}icw#aDPtx>be7cKwc#>|FM1M^$Ck z^+wkDMroRo|9tTCxx)L>46-YJ8I7zBL$@20E~4*%n?c{qsOda)`9Ye?wxH8jg%~%) zUPgv1usT$pum5YDF1Ktjgz^`T*|BfGdK+85~IwhC@0JuGqap(h@x^LGA z;RrT7`rdg)rxS<4T=HVfrT!G{Bk3Qg_>Sz``yz;oHD^?Xzr6de?#DNFK=}?pP8){2 zzO=oXs_!L|`=D)jzL-Q`m}D;6A9mj&ZaBjurBl%oEuASu@0jv8v_t?Y=VZVzCmTYf z+0f`28YBeIrSw@}E!~jB^9z8Oj|3e0Evj{$5_Wp3SYu#cl5W*7wOmZR>26M96B%~} z&PcL3jfMG>&pY-&Q=1?Ra%|Ps?Z_?!D5D82h)YiEj9xQ=50m8UdV!e|xv7++kQ5NTVsxt~Y~>O6So-sFZWz6H)sqby!bt(J z%Q)=<>2rS|eU6u#M#>_g0P0Q<5>WuTPJKZIq6X57c}-xELlce@XqBn1-1=z-_OH1P zAScvxLt&3;TI^aBZ(f(Gz<+ z1o1mNjB{$P)v=2g8VcaUn#J@#rvsjGUan?buw zwSWR8_^)i{H3GOLEuK+Nahn4;HX|+D!naPAM#?A?5Pzl}?CRZ;GnLO?{xgcfkO%N% zlUBa$9i!jEr#d|*zx?7XtLfCk{E3cGsbp{^zBw)8_9v&B0fpK1@pttl6m->d(p1+q zOQy}==(Ti*qaY#&d6x3_AfkC%lIpie>>eKH-xxBX)*;7?;~1A;UDo9^GbU^b8nbFe z5~MQbHr>VofexS<4;Xjs>y_}2-;u@!HJOc8I#xLdWL^M=Vjs;}t~mq9*9hP)N$^EE zn2FQO%V*3Lc|3$T#yz1@BCdxKmLMlEQlwvCDVk+lT*$8Zn<4={h@>6f6ChQ11pViK zXkI=D*GF}=Sxu~^(-JT~w3&i!!&-AEcQTK7W0up_%QNbjujA)MuK2gcPO_`QHqtB3 zW8YptT}@kS>#^&qq{4vUW=7ZMxgk@ra)clC1YX0!d&9)P5jFY+ z1qmQGg4QKZqR-R5%dQGZRFZE=0Z=#646ZnaNrQ&_2``6ELIhC&o)^SNYM+c?!T987f?TaSvagaok@sX<#d=+BHQTux zKUPz5EpAmQDHdG7`~v`Ui2uG2Mm~zNE?;^)Csguj6b4Uvcnpp)D~6j#hrYzpZ@=eS#`8udaa}10%h$x!38~9(52kR_t!XW zQgVUX%FG^U77_qm{WkRzBAF8!bob+vlX)+F*+h#!UPMZFor{lC;Bw}QH@i-gyz8fp z>m(ms#(vIj+btJZ_WK6wqY!?7Mwhob77cf-BFTwnhv{bYk~j9UOPA@GS;fZib{z zND=JhW<=N^D}#D2sBv{ zTdPTrqR@f#ILUyxO%Ki^!v4n&TsIuL7O1`N8{|Tv^2%gu0WgZ1nNALj+o|D-l8EaX zBVaFG8ZxN`dY>BPTv|XpdPfj;u~UbBu@g^%7w=b?4~lm#8Jd5$@2 zZNI{@XIa`m7?gXzfnKZ|FQxe)342g zm9DYdBuv8bZssRZT#20Q7yqRWZI5Y>z^T@WA+68>(;mqi;8RZbH(QS~8O;L{41X6T zPiKRAA}J^lPUp???V%%cijx$DtIji9W6uAq{!ivMl9});P?qZH1kM&yQ2vKSY z<`EqdES-Y(L6dTUn`cOUebbcbM-oqsX8ZHho96_oyYy-0p1R9t52N2My$5`?OMv!K zXjD ztPKJgJxrNpXXO);yww3-3%NR~sblg52c3n6$#aD}Yve)M1u0rnU}HN>pJ*4qT%UVI z!Rq}B2NAi@2Ha5lTH;VYy$xt^)Hyozm}qAtoz^VSEL%E*xY-y(GG-QGj~tnFNs=qS z&CyJ54oj1dpdfi^W&vBnW5RP zM#%Z&CPH2gPO)<@&dTnqZGbx(kd)cZs{NG>d?zhr|0R=pdGzGQBq7W93?V!9OPuw- zyNk3j=5wU%X)-SBo5biIg_=(+DOCPZc0gx!dVn79a{g(bYs8^41b;c0flWv-2XgG+ z3A*8p{68c=De^@Q+0{o@8!0dO5#Zopp})1IIYEneAsepENBFWMMz`a)_VZOj12lYP7Givn) zoq2qwjNS!de`&L)6i2UpMAdGAxVk#d7EaCGf5cj^oWG`jMY$+)?JgYJ(WGI+M*&zd z0b`Gk5MQ;&A~R_e4(m3qVcE-glQv=5=L_4D!`BG4t*{r)8HF*W-~R~jCWG5zgwRJB zkNm2M%4qfcSxKR*R`7WtFq@&3TQE<_Gu0Szqkc+ZbZ?iku18!Wi-P1c9&D=3C9w?w zI;k;gLi8gIDEaiWEITHb@AeW8*lG+^+DMIR^4|lUK^bQ&4R(%zpM?gVA@*DFks^_?)jsj zv=$&Q2A}4xHX%v^E>|3}MTvBT|c!7~OK?zlY6E67#;QA`f<21zL@f0u5*s z%sfVjGX4L$X&sL8>?_{vzboU*>`#_%a~_DU-Mr}gWs@J>4o{x^c!}4_2p)?bFSQk1 zK?>|HgTyzJ2L*U6^l!lRM>F5f57r(O$GWIjUmtjPD*`9Qi$ z7s_>Gu~pg@2hb#JljTJi@?I*;!~1>#IK1+_6PFy{?#OV}@;qy1*eGeWe1JJq5i=C_ z3vjPy(vt*#Zkz04G>le9I^WrJX1Rjw{0r1!#o0Cvb^kSZs8&aYE(77HQ@zSz*C1{S z1r3qwkE|Fi$aGG3qwp>vo<}8d!owmSXt-h^JMV~$W`)zg_{<6fRKxr^rAkzm2MEE` zGl=XPRgBkdz^E_)PDT^^Xs6D3_L# zP|93X7e!Xa04f5EPj-A@smQkx(o4p-bDO0e)Sb@XJ2r1;ivP7YuySE$2@fI4mOB6m z@UwgvkbN3k?}BR}P|ZB$qo1mo?{L9-wCt;(ellHq_bT9!RwIPEAZC6>qJ`?0e!&p7Yp&8&8tSq%A-(f(A z!w{^B6?MTeQJo^6b3S&m!%j-UoR@hI~iIY z-CG+_SGl@Z-1s(&*@TF?_$8_({6iC=Yyg@!zvoF9m+!y^s1*z4-~BLRe(yta48Uf&B*ufV~7J5Gb>M2L>NbDP<+??_7B8t}-zp=-4z?<`Bk>Y<3uD!L6Ks4r}#A7^58# z;5OPE0?b|{3i|Oxp*IP#}q`^}RBkQy7)f z`94&z8(xuk@MwY9$=u}FM4Pjo3@syAKt#vZdrKp z3AyDsCt9Dsdt!K-BUL8$cLKA&u?L{Ky-(iRTT>d2yj`z8oTB*6W}t9i3mij%R6`Jo zwq!7ayaHCmCwkJ#T8fe^j`^+-RKOhm^bl*>G_`t3z&H)4l;hVVjnj;vW6UW<1sJ7_ z?}(P>jkL^{f)EI-D!aOnTPo%jI%>6Eki!7Wxp(6?w1mu0aAOWZt0b%eewT z&rSII^H9VhyJ4YW(C9xw*US)FZbet94;@<7JQz_zXuWTc_*(z7_gem)A3Tuw>w>1L zUN}`ad$H$B-<6puE(1csb7daE$#dnrjk)g4v(q^ESyjqyu!{)f{gLFZ=d z>egyA|G0e}C46iBsSGgBZ1Vk}08yGQoUcysK(E0O>*7~+U4O7%VAh|%&34Ad5EZ8Z z5OlK(W531pmLzTuN%y;jvE-sGK>j}8P^f#iNQDm?UAJ^AHArANlpxZ|5u~DUi*(^Z z1ij|*JEM(gF$#4Q&mbSb4Skww^AF%S9~J>`oZ7nfY@I?8*b=OCit0}PaS>e7Nr;@( zOQo&d&+j-|7?tJzGs5HwbrEPx9OjL-TPObBuAhwxcQF6u;O!RfC8Z~TO8#k=_YP1K z4nLMXvNm3C7x5kxw|(^-wfgSD(8HCo=h>xAZ-2EnbygP*OVN{Q1i{n+Of~pEF}u^= zsduKD@w_;d3v6Q|J* z2*-LaMajm&s+DJI*BQQ4TU>bRhdpzdn2EpbOx7>#%m|23`1LA^h!uFp;#LDor3N>W znzL2Je})yT<`{hiekI|N?mpW=7V0JDNMm!QnW(2&HCMZbZHwj&;mHDYt9MQF z<%#eo)ecUr+AqBNc=1zoE1)Psu*s3E=|j)rwv}<$r}~c?R(nr&ui=`ARQ5Awd}Ye9 z&nx<1!i*i5$B;3TJ(El}b%gWI5Gbs7x~=7sevS$kv?MB7Y*%1Lq_1ajK)86a^R4~B zdqnx-xj5ml85o_>$c<-QfA-(Tbr%9LOGFlV2l?aWl-V8_X4j%_!CEKW3e(`8dFUyQ zzXT%a>J`U%@(Pb?OuR^!4cLcM9V*viR@-5@k;o-zLc7YZ`5GjL4j_Jxk@pf7`P0}UXdnngBo#O#ta2A;`mjmJ^B%Y@`giZ8>YuiQR?!iC;nSIQ_=7mHXgn0sE0B%|~YOpuc)C z1ilCZ+_0ffI;hamZW3`WE0)DJBHCfY1+^zyo2r-mJPej}h=zcO@BB%0%0wfKTk41T z_T={CiogJVm`A3o^K%`C0Nju`w7%=n2LW7 z1CbHx0H#^8-sTrr$RSp%o5x2%q^E|T(^kuFm-pEF9>#Z%rh^|pA33|w7I(8 zN9c%_)^@VjJmmgKTWBnR3P}LnrUWt$xldWIV}vcgV>JU$ZgVcrJmQh3;3IQu1VkC) zsg`2%e*8wZNE+KWC9e-)#{TX}-<+6c^$-_3YbLkjxvM{Yzn&v=KN9mWy=3zv9e{lA zy*%?A`!^D%s8x_&@%2Mt@lueh!?mpe(rXV;z^>sdJ@bjL)#vzut}S^~W2L8@MXWZ- zgz1X-xAM=tSc+bthhk{~Kq-c1XLWcq%r5_u;W7Of9w~H9`vV|!d{^p&41lB36>TP{ z{{1r|k5j&q+`wSl75%W`n1!c<^@0yuLYnwm*aSa+)uYmc4dz4@t`X&CaN|8#`eV;B zEWxueypd|o9#a7y@{{N$|4DRHZfuXc{SBx!1Ck*k?%IrK1Nu&#`XOvTr?TPp?&A9*xG zEH5iAX5X;-xc&p5E0n~EpD9iC0?_laC5Xo*vM2%{ zJT=M9zpOTRM%YXTAh6|OD`d0IWIv0Qn<%R0YIm_sA5+gt294dcsA<*f8kOVkYHH|? zCCN4X_Ub~N7rfx)Nsio!u-!|J4oE|ey7syyh?=k4^U=k^;|C~#2GeH;5idXkf<;zbKrTn+Ce-;qUpCckEwV&OZW8 zXQUxLd@DKjipyAok=UsAog z>{pCT%|YKPML8-3yJ#+=|LvgAa;VKU06_cJpNLcSdBAAuAos&VhHqa;IS>D_it*}P z{lLc6ZU3dJwf;Rb`Ukqyyc*F0k2xy*g2tiBaDS0koUo1-@b8Sy&H2_ZYb`Ker zCTjw*9eC0 zyb@jY@7_+F;SHXTE`%|?VX^;i{_TcP(|WG3dEFVzqrHHAUCL$LkQFC+cm?KZH0pDz zR?lTihFf9iCFUc1diN662Fu;LX8p8XwiOqU`V(-erfr8;zuoH9HjeIoqsUdzPXCR8 ziqb@vxDWJOQHI+t+2&+TY|T^U0RP3t&z3aRbS_*b>>d5;=bLmVg3BwvY);vo!m*T`EH{-$!hh$-7h1t zO`HbIlVh2dbxOJ^S82OYQPguI;xi_-LqF3=nLP>@TuY0mc4FYMiqL|$y5+P*O4KfX z8;OwdtsduzPa4Y*XJCo=_t*_Cr+^6ujz!#M(>sfRT6(7$>{HMX-mEOX7yxrDM@LW9 z+Z!HBg9bzY>Lt_fr>y-+2>)pu$bGFLO$4f^q&DJdE!&>-MR%`X#}cFQ4f!pii2<9u z07JRlNfPFG&@FK9kl7*gz9O=y(#)1ci2#GYa04c>Rvx?j*~Ya^t0F_y$vIiA;}`vy zPBkbzn|DT;)eX}sOd8CE;BYe&Yu(>Gm}rc0s!GFj{JcUC!R8fh%&f_G^c4AyQ)!bFW^bO+~Da=5*h;cIZT#8d`l`X?o?dF(Xk-WFYOw|anN40)CY)q$AB)&ZJtV|p{?AOXg z=+->YATGT~IpmHRGxqysfu`3kVW(eDO*O+odP7vTTdzz`3Sw)}7;$9Z?1YzrU zzi5rH9gVq*MYFWhIW-D;<2SL53c|lhX#m0bNnQL0F~d`}9^Ngs{7$MaTlfLv)BSv- z{#$028sr}(fy5kbBWUg5<$eu9ceOMT#XkY3T8!7X(+uL6`dPOybJCOc-)~4jEMB+9 zZ5e_27J9>TxGc%~qHAiyGtb>{|ALE>a) zoHl@b^6<}7>2A(bp+BeD?bLN&LHNFAsm7WM=Cx>uik@>xQl?&RvE$8NQ2wL0d~L>0 zSAbhICG9&4I^4#Rl!ZI>PmI(T-9{tJqp8M;zhQ1#@K6yc}i*{It2BasN4o)O2Y_*M{b9h+TphSRuvimYQdc+-~U+fkSxAyFbc z3o+`?$V>2J6BCT8<+WQs>MInFi4t`| zfGp+`XHT`P)EVT7MZgd(f4bBhsKXrj+&q43T%JZGYK*vQY1}`VrAmjYdwM|je@E3U zy-A(W*|H6EPj$5ZetVxfwS>9+9?MOvc8Dis*G1zHIi8TC9trb1&fdMw2P$k?-qCKl=PoaeYXE z`s}dDJ$kZ{U|Mr4bz>|kw)qeIApQ}fu5=4J2cnJZ;k`C^z6Ei+^Kt>}aYm$Q1U9iH zx|Zjdnu;&Dxq=1EkUEV99RNj`RFk7c#jvYqVF<7EFsf3)pC#|b7Rum)kDqW!%Odsb zn5#Ss{f4LF%eR~uW=7pzR@}#6F5aq2onrHmNn5m5vA6b*VWCu|{aZ69G41GyY0+rc zGi8{Et;ieyeO<_^WY~Q{TyxP1q|6lK>Yl%fP5A4@p+Td}xou|C7v(muWQZ2~k1Xic!feKM9 zk-AN8pD8uBb=ORFMg;dlq4?OvGT5m4aI_L(vX*0NiTIx_d0$(sYG$-dn-^K`3Ovv3 z9&(dMc|A+7qw<}d)$EE#B2E2k*xWMACi3DNihJ7`SN0jz#o0Elra@RA`R~@V7+;G0 zLuSOF&_WPIM_uV}-XmcG_hNCZjac?$dlk&Z)t!9dHp_}>6^F-ms`&f02Dv!`AGqEq zw3v$whhs7!1+bK z{%WNR98@9Em;vVE*4t`EPwGSNoef2nqn^%<;`oQ75|_R1nMWRw9>wMXxmC@7zO9!% z9D)C<)Q)0H?Y6KC1fv5yzHmVnu-4w?s8uB2<}`Y`|A4<`(g9eV6+=O}o*mt4d79rk zZ?SuKsth5CKhE|gY$!Dg8M~~}is3b*dvwYJ-d2#=-W&f7Ta=KjLXk7Q}H0JC#wl z7}rmKa733kTCSZwPQRJv7Owbl z9})7Kaw8{rNi+37Q+HZx+Q(R0E>XbS}VD2IdDY5lr_nj1YEIaheYAaSQ7N@#A ze?(Er-#vjPbYC5NP~pBD_5lS2*4kDx<%kLe z2>y){2x57JZ8E@065x7ZETCzKeD!k*)V0P~dvBiB==A>0XG&4@%G27dd2|Kr${(53 z)(VclGzyuf5BbP-d5&LjXAXF36{NlTs)l5z%MNx<)^U1tk*Vqq?VFdu(^PA6==Iud zq-u&fMgEE!c-vQoo*xk^NO7Z3PT=iME)^}>+NV7;VY;WN06Vb_H)?OlIBT+a&dy|x zpb{4Mjt5WolmGMbL5$84wK}fuqA)6(3EWs_@Oag(QNyIwa04o`$M3GK`~|7AadKJa zDQ!~SLL((u@)N3jY*D~Ta=HW^6-p})EG!#p`XdwMyTzF=Qr6=pX9Yjcc{evt=8kmY zZr@{uYMu52s$i7r+{9w249U{CXLx8(571qUoGLQ6QeEbGy%?bk25>{6WuO_U`~ok} zJjT3=o+-!UJ^j=zL7Z!XrPmXFw1-^(JtYs%_iT~`Gr$1#)fn<;*3i|@*&yqJ6RQ~k6l8Cb?u@=9SvT@B!)oD-76pQa(G`E0W z>0A$t;nZg1Y}l=RnVoGVC@u3|U?o7a7aWK-ksUdqYE}b>s7;o!&uz!14c_u=lC4&D zrWy8b$0@P)n>S|$P;`Z#n<<(ODq@`LW`;|*iixFI_sg)Qc3!*Sq)mgXq8vqf=tdO~#!O7Wdik%oC-${;O<(gJmOP|Z{h zci(9x=NBor@fxe;poa4wU5McZh4*K@#D@w=8@$ZsB04S!#^0;WiAwp8IYf}m;&Or- zKHka3LoLsaJwA}AbMc>-?NT0Bl=!;zAyGs8o`DXZK*A5uq%C>YJnu9^C%DvkE+2MH zQ`nfYKGosN?s|{*%p39oXQ@&P6e&t+i5(kYtwwENsnr7*%0g)>0b;p^r38r$vqK+Q z2X_w~&HR~q@E@3^bl4T|1pdzGRLrQz8s~Isklv8uj&B*L^Ar8q$fasSM7D2<$^0yp zQwrVjI1Zil*7`V4>^{9%C#LqNPv0#CczOdr_v;f^NW}^*YsHF*_2!5>w;!bntlzla zY8X%|gmi8)!ZD-P^5~GOH^0KH$0q;5-71l!tXHSCqUq7fDJIWdq_^sw5yMC&+*DC*|ZZ-?myC$w919)l^ki_xEsW?v}kQ+_>`wuZKjDfhk4Mz zJu1qG$cC&<5!i%%xwdkm`Yx-Z^1xo=4)I=woMg0b#BO4!9b*tlIkwRG<}|<&;i*jZ zKm1WPNR`Fq&HUaJH5IM(8?#} zALFEh1z)mBd)oeqSR(0=n1s=nx|yk6d>94~4ak344jKMSoC^Tc!?v)rLNa#=NY_i zy|`vULjh-l{xV$FS1TppY`6l>hF7e+#mB~)8Jhfh-sh7Kx%UE+$2Au7kaAxO;N}#& zcfyM-v6MdUEnCEbTwOJ6zBRX|SZ2h$LN%H-6Od)XnD5>-sA_3&ghMR(~VmPjalAr}`+7 zdn8shDI(hLwV7$b`5Ly`wdp~VniRHaF+^{inhQHQ8z0IHNP5W zUc=c6Nw%)NbBTJomqu0|*o657SOIlpj=^80Ndl@S6zjaiJo;^l#AO~mP8oFlJ_d-v zga4gr%#z%GYcDhcK^k1D;xoeSUBKhSaD7$jU?F1w>UwUz-|`Z0ePjospU)pmUV^|@ zUl}(QGrn#%?<4#=m}XWpZ=I|CuE3}82K?bze4{3KLC`Hw9ul)O0R_7w@ycFCodVHI zvfw0iJ(jL?eWoLa-k0iL0j;Fbd6vOU8#quJSDjJ3L?wHEIgA5m1DMx<&tcTvko|Ck zcYDh;Zo{~Fc?VhYid+1;slc{Xnmx;}tO`$;HnXpzJDROmcwtP^iw+Y*K%7@wC{a7?T}IRTxuIcLO? zmqL**zm6DhiBFy7#jp7hnOF8$uzulu=|EgdH^>Ebfn->}jXtq zw$%bzP*28f+iA{*<$k^Vn0PdKzcF-=UNgenr?OHom$UAdJvZ;@7b*pW0k0ZReo9c~ zR<-HODyfaqt(q=}a6l|#!@3xL#?$38N2D#G>#|H>gP9fR-desD4{cT{zCQZWMgl$?s zk8+3M1>vNX`=sr4@xl$yaVsnI)g-+^>fpS#dv4V*cDV^0XQ;|zgGs6at|Q$IML}=2 zgdVHx*XHP>z8O-)_Q(y{HCXu>h#m}p z?JUT0VoH~l$&HKDsF0*Hk529nlv(N~mv`Z485)Vb)!f2PZjR;qd`e29*$a!h(Ujya$Rcy-FH%IllP2aQKP|^5d@v5=4&g%}{gGoEpcV|I7zC&) z&t4tAJ}i_;`{0X#Lz&EcCrg9aDV^+6y-%A@*BRAB zQ<7sxQI+<c&Cmc79QVzbsBQ7kWFX#()Y4Iol;4YNrAkr#_DPkUugHrfdw9NPB=6@29np&OZxPGV38K-%b_mG&|J&)_Nco?{a4`Y5qrJd#Xj5}r#bzwrXdNivzhpj2lB357%H}{`8 z!phOVB50^GkD{ih5i<_10TiELnFc1VZ*{Y*URvwZ(<+98Mwg-O8tYXA$d{e)To4bQ z;Qp1qXF*97cwS%-@Ea;CI!+-2e?Af$ZUK3vl$d5`Ua+s${pc>hlM%YA+Sa8GLB+o+r8Jsl3wSWX*qb6YM0pkiwZNRr(_Zg1}|m4iTK%T5H5quH=Irr=>5T0-1-geGs*J@<|V&GZI1v|U?sG- zpn}=YPhRCOOO-VUm{Nrpl=;83rrDV68BSjPw9r~c^?KLZ2XT`kj`Xisw#;FohN}c7 zg?3u!V?WN^cem*gfD_Iz6U_v>mvJWYvnWnN22&Ar^Ebqe`M!(y^W3e>pS^p=i6CDg zq9EBz<45tprhY^!r$%K{1UZ< zzdItFz*jcJH%Vn(YJJg(b}SeAS4HsW4#6pXr)p``jq^>F#U3wF&j;6 zq)zsc*{9H$W`)y+o8Wwxab>B&PpN+F;v34sz6a%uNKr1?%m9c%gZn!@R*q#2^$ z1F>Cmi(dQRq;WsfUfT1!p2wfYWpso(5tX}f#pn0cx@O019ghKoB$EM>k?$)SfNpfq z^=A;BbP47wN`NOYWq5v3&@U$yQ$)Bh_1zfZt~!3Gkn4J+EcE+`%5Bh>bEC|3>a~i> z_8;!FUx6Wi2B1W5WNosa#bq};bI4Foari&C@j`RBYcs#1D#Itp|-|_mi2z;6O>U zK^#*-Agf$5W>CTG>=A!2t%vOH2!;r$Ztn~}SQaQh#Gn*Q8U%?Mk!`Og(faQ=hLRY$ zplcLCyELQdrZTYmObf;@1$d^E#NJV5f}c&Nb{JX(U_*O?{ozkqw;)cIgc$sb62Ho5 zxW+m>+mtqKLuQ)(_$G5eSz9e=zveW(xiYu;JWT7aG-rBsouLz*i7}ZeN%%DjRh<3s zh+lfg&Mr@Y|H`9?-znF?LUZ9{wW=(61F1C|%!K3-n@~~Gn>bf!-q2f~gKFXCgkhXw z!o3i8DwlUyh64;u4={&;&O_gZ(gNjiP|CDVD){}7)U5a|{j7bRrvCh6w!ufmpa=bE ztCtolx!vDwQtYO}Z>#N6H{8#$Rfm=YUE^3E95Cl&d}_e?$9=UE{mJ>7xx(zS~-u(J@QKTSZ% zNPo}|_`em5cVboSmEy{VBgB=qCBGFePSlmygy~ht*5EfS^oo;n!+*bp#QM5NXWNIl znPQpTA4TV4zFymv41L6=5nc0qo8E{RTUs4I477swuhhCRE;%9L%O@EiYg5=~`cBAe zAgd_{Twe~r>bDqoxN4nh|A{Z&!I-9tpA~Urqf3grEGD=v&w=tiqvPIVy3(MJvuVj~E6&&9EotgsxxPVQv~pFzhGSuZeVhvTU=eQ)y5E zVo(?dvQNboDS|jEbyxlg3sx~Sujh7F0=82bd)Kz9oNQ~8LqY5*PtcI3Di&loZ;d@z z5uw z(~qn^SNQ7AG64(i1!CPdmqN`yi>7YtzVV*Q1wB^++PmO z(f|wps6XpiQ7o={?Oo3|W-m8s+X8(*YuC*luPN~&uW zQ~>_?FodueB+!itp9sJciz9ZuBbcmz=pym7&n7ZfzP4)%)^R z>cTGbZ4{2%rem!F>k=Dp7_dvUv;Ggd=mR_>KnJ2?p*~*Tiin@QO$}K7pn}r`iqoew z3e`1_|A(!2{;Tx;;zn~#m~7iMHEH5hlig(7m};_JldZ{mP` z(o3!_yc2nN?{^$xxL@}!5w7(-E`yCUBMjV+^ZVyW$(c|CE9X?l43usZfo;{h@U%LLw6=BR5) zwm6g1Bb^0+cv|qvW=c64bYB60&B@e6zmIn417Bu82HK3(Epyv)K-4b{#Lo{dpU z(6VD*_EnpKBlWmowvkz#i$|!6J3<98lWBRl(G(7p5X4Borm!!LJyn;fj~@{{0n~fp zZ;PUfRrod@{Y~wAY3`1y>=TqWbM2=Rd?c zeBfT`?=&Uw7e?UX&(na9^yjD9ygtVPrUUk|Ycb3`fpNg6GR+)z&*NtmY_P z;C4t1vcfS5jF<3{cS>Nu0W29dBb1I3@d3!r6O;*clcj}|?Cx--E2P)ELwSu-C}D)% z2E=T0YP`Vx9O5oZ&vqGBO0whojZqHtbsfFZDl1MtAT>$)arTfx;p92h`xNX$hrM%;CA}>qGC6#gAy;lGxBtU*3}TGFqJE6^yr5pMBLibv(0TWA~7AErR6Gw!~_6 z)=eL+^o97o^?iOP_*-)lBfxpd=5im^RQ`CkOfkO*H?(v&mmmdfzD6?cWU8AIBuC+K zY3=7#^X^}ktjKK0i-Ruzl-EUw(Gj7OLaThAhTfcK_CflpCQ(`G|2%8Fu@#`qS6q0iVIi>VimbyK=R2wWDQkNjLI^63~LedPx8ahgszK%xyq3eh@KoxvL~7@ z0_pQLaH=-ry6k)8flfTx;Gefkwryi&1_dWk`)K3-kADC;_Cryp0NsPqBmn;JGwo#P z%s}x+s>IG*Kvll~6#3K>G039^1PXhHD=#2QZLa_RI`^b5lkjGF zNrz>Qd-znu_Q=3_)oO{Ngys&3+}O%vaKbSo0N#R6#M&nu)z{3%U3w3XtJlvR3fvjy z#JvFh_sq{X?TPdxKs=maI~_iC5t3=?*w@If6q6mMUmzL-8sK+#GkN)Q@K_lAeTo>< zHIl=B?UN1kaPYkH)AIL6g;i)r=T}-VIIf#Ic9kvjaeEzoX><{}ALv`<_5q$a?vv-p z+x*B~*X>Rd3n!}$kLAN)BD>19Klc>+YeV8}r>%@e0>=92%BfflJdn5=K_L8PCKJ5q zQDSvF61?kV|8=Q`?pFb}(k_Dq+>|;^5#exz8+_gqsJB4Je`=kgw2J4fE|nvFc1xII zP69*r*aAP!lyB%}MUAIO+j0qxh^zmuQ3?QP?Ev{vpm9N^6gIeH;aJJ+RFhC84aJ{9 z#H?Q}7F06i$gd+~d5u9C!p1KPy-n5Hrc>$g4T1~uc=??$H%j0=?d5RB%o^ml#f9ix z&~!7jnr1pOxauhzixk)}BtKR#G-VMXqwpgWOj5cd7-Gf{pI0H|-(o~=sc+3Z^XfA> z|BC_Wio<8rjhRl~z9m(2I+sJ3SAkh$IkPsoGrm0M?&5&{NQQGmtVTGKxQ5PZZEm%_v2VchLL}0#odAo^H~~sANzSq*{jaq5_c!X$P;zo} zP0`}v*V*nfI13|ezt_yopo=a$W!Xzqs2ocn+e^rpBg!N$@er?_^a4(mJ+jKU^sN{3 zqF${UZh2oYtl%{i(CYqHILFeNq~*@92rJzZ2P&PADX2g{t7&ciq_pki9!*p%H|D+3 z|3oFoa0$QfH5dKfcXJs1siGM)J24+_12Zjvy;OhI{_4~rrN+HxitoO1Q`Yfj7Cpg_ zzVw01sMYhe*ZXVJR|PX%^j%If<`6)E5#gOAGr{d=_wqYrT8;_I%|h`IC#Jtdyd8p} z0-`u_AuA%33dA!8)m>51)|>#a`!*AlzG#&aVoNy{)6(0F)-~|%xjbqWSSNof1z;1Z zM^5?)4xJlgZuQ9}Pl3|=1iKfZJlqb)PWL zn{Ku)%_9&&u$=Gxyl6ausN2UDJtRp?Pfcetu7n&RYs{@&Bf%lz+_)lP#0J3A&ZH6I z+dp|w%8l98@>?CZXErD%vMbySKYY*u41!C+kp(LUWql81O9bh zF$P`hb`15#C0X?Qxn<|_yo6`vfgxUb{-f3skx+gEm&wa3`23s=z*V+13oWhZ?NKak zsax`EM?C&{z*d(~AXLsCZaOSpbsqAmWx4Z~$+k`vT!O%VTEdI@fRBmd?oiE|T_3YB zD^_>|U-2Zqsq{RRelvgp9CF$fNGz%fj;@QkP(nmBd?}An$K-N?x!NuU;9)TF=L9|V5OpD&Q?KvgNAQZR8C7Fy0iju;mX#9po==6~JKp7|8V z=Fb@Quj%Y`C_Q}xH?N()jF(+b_Qz=ppy4zNsj8#H0=lB(gwWgv%A?(s!F(u5R+` z^i_Fp5%~6yZQD8hSD0(4Wmv6DbYxNXrZ4P0N5_g>y9<-)K{kdXttZ)DX~)RN9_16= zTf|T$_ZJvceH1Jzkdzua91QZL_ z_Gr=_LM1B%Bl6M1IeXkY-W#ehXPU-A^=Z?Ix`s?rxmx!r?-*Y&ibBS5pWSk>|M zjGvO^&Y+qz`NgnwFg|;R%MbbtdBckPIl0W9@FCH2ab^_tmx@?Eda2rMdeRmk#^Sv3 ztWBF>UZc)mb~db59f6dw7h5U;@VOTpd>F_4O{f-wKiY6V0?i*9e*LXHw7--l90K&5 zH;xvb%T^46Kk4K-)crwiWm0W2O|*{na|r ziPCrGQ%m%4WaWjJrsu`F#}(&RE!J}`^8=X!r+C|UJG^CQmPYq*%~1@x!SOdVesQZD zJaJ~Kw;C}z#cvCD3Cz#R<$30DfJ0bOp+@&S=D2=W12UJ<_R5-;V}ET$kVlDaA0>oj)Hs(cGLWW{eKbSgq*VUnJH zGME+^z47U;HMw3wPX+gAkv1fC0Xpul*;_1N5aKDi;`wZ{u?hK^cj75wbKa%ox39L% zTc^VHuAiT9z{}m|%nK|EO-i9ZjKD0NP3-eFPl2V~@N=8s=S~xAc-fN5!~D8!{p}CJ zTlgX~2pK)Vh%lBh^=FYNNGl--n5VePJ8tB@{RUE-ILgLm3P5sWkJI$9b;xWd_af1N z4*MtlY1vV}Y=Ka!s?)qv#WJMU3cn}G;UQ^a8S$eVX5;fKf^?gl8mlZ z8H_vhOhdqjbo6w$oq>Ft*7>-P>s(pjp|mFmOn&N!S2!D{JIS8~yS0*kqRw%C+wulsX3FxtuXrKvp z_pY4?wmUSybl$L|zWY;lh<{4BrloOJas+&6rw1^2`@b5ML^jMyu5fnhoiSso@!pTDeA51KK3v36Q?FCqSFKO0h5PxRNPN;@Jn$>% z3WxyX2@p3Z(h@J5(h@E>ow^8k?})n2QQ>->RPLDbMbsW~l_2y(=+YEwn$z0Ah?e4_244sIHA2`Y4x{4#>*q~~7YH)?)_5~JY; zLFyD?o5^WenODA>0;~~X-eaI*c;=~E>scadT?)EF>Byo^aoH*u9O-w4hJr0*P z>Y$W^J~!i|=>n39G}`1tSWoG0FyJfMC+4}OKJU?TdJ!IJGVi71{YA&%zQQJIRUVR| zE}I`1%=GF&a0h@&oPXw9>_`vvwmp13#0=S^$eXzU#hTAsBI*ZE(_tF4WX_;(On2|j z##hdjWYA)ieEs;TrHv&u;=z~I@XN?Hv9ok(nTjGTB1qlXgr&p2SP;W=ZJ ziH((O3H7ChwHuLTSi1K%r~N!+gkq!wziHeb;V6?fgehuv{BF^W`7`PFSnN4zasTEn zR@xxMLCUPwZ(tCZ+xh@@Pczw;3>4h6*yvcaB~95j;2JECky3mmu{OHQ=UBi|lv_Ws zYV4@Sxc8f(;PV(pVf;UT@D)bp(&U@_fj{&fX)^d5# zW1K5Z$QsGTFdouAg59D_W}(j9wgxI->QokmPWvszKZm1hm7-bOulvX8ps~7Uql~R- z^F7j9VE1%J9v;21#Y9_y7PT~6J|kH0Y*NTy$fb@9<2<39R-7b$pQDhGG;#|C3hi0k zb(y1Xpg}g#3U6lsX|GI}$2xXTSw=&9s!567JAD#S{X~l?ytmN5v-*~d9nYf=OvcPP zM)>iMb8kyGOMrIF^@h*J>cnCT$fsG9|7v>&2|&aebglZpZO|hE@|&Kzh?+(n_iZcw zSFSJEH8@?RR{!&0W^Q{;+Fi`iG}|j|Q6oW& zxf~8(-#1IrI4xgSXym7|!h0!WyuLfNr0%UaYSXSp%y2f44KF1g!}U`~eSQMeP%gTr z+(G``S&Rw58*1_yhKgl(I$5+e-31}4Srdpf#FNKc^XH}5#VA)Cy2DG4(IJ)*B2hM_ znh7)3WHYh=D5~2_M(+d3Vi7@;43v{E7E6Di9|4l~2)C~ef%QKWz(Y#+h^Lz6q8janI&F=B_I6~$|*zfTr7qSefHZ>JEIhyup3g}cVi1{8j*UV}_RPM&MW+|*^H9m(8O=o@{)uZ&SGDc<<^ zS(UE@n03lu){Z`iQpg(c2w!9!%7YgSMHyIZJFh*DBkSFU_hVINl4Piz`v*Iyh#wvI zy)k)=b|aS(1Y$|MAZZj(!diA>$>!}UBw*tZ4HTmf#kEMcf9RKp()FuG*g1+&1%{~? z$lw!hP?+mc!MGhFI2MR!>9%4eG|XOg+M77&?z#h%Z(u$*X3S=%FxsKO!oa?^BM!FO)@Ay7e#3xL9`LGG7&c z7Jy|o0iBTE5gdHx7XiAzMS(%5a5Cgg+nj!%3^Q?LVpIGfEuo+3sL?zA_0$ zYq}um4FO60Xz9h5NHB2^xv$Wz8usJ!DqOJa7xc@-g`+HCHt*`;s~vnNca_NQwZfNp#D z$ER%27l}C!1I?EBK5a_vcgR}xo4dJ1emYleyHS}B~;Zm)s0YMbFo1@t{) zCi1pML43bo)bH%M*vl&4igIC*5%((-5xNo@VC#P#)A^>hVa5*v7Q7(!hO9Fa220q2 zK8v{lZZ~5|98rq1%M#>Eqt?Epus#$_dG)A?_Fr5Nyc*S^i;h zF~v-7y~e25MY-i##|H?di=LbQRl^cSewpnv1`$#^%jcYUdcxL-djJND_EV2qb!K~ z^C3YYovS^5GlPi5`@yfi|5KCo3hKvdu%AwzK^0oHK#G18!oO!Kp`VVjM&|#(m{Y}wTd3_e715Fa4aeM|ZW;y?w zi?i2a-m{!E{cWK{OkbK*eGMj(yUUzQ_v0)Vu{3JEmTdi38tq@VtnLEKK)1{=TL)3z zuBVvT|03c}IBBB&0Uc&=)@*+(98Ge@92tactSq1b@H6p$Lx^bWxICz8h7nb;Rjryj zYbCIwdX%Rw*Nf&A(?Am`(b(oRK?U_eQ;#=5D^-e_|$ERkU|URk21$G4S#0 zsPx&(Z=zUyHokaX*R`h!ix-}Mzy&-1AG@5ED@b&#q;EPI?hGk-aP_u20dhfxb_R@3LC<1u(pNvQ2OMaI4W{UZS)Bc3b zBFBoV{&3SKnHJGIzSpN&QsRLi#=2bDF^!2Hn)7s-o6 zGzO7b`e!&fYK^@98orH>^s3RjGAgdt#*ou_a7x}_QMNA9_X|XWJCTJwhtMg60^nG? zu7GD1pwW1_riAWIEoOaiZF+saNKS(Wxu$<8_RzH^CV1vWT)s5pq(!r}J?&Jc}1$W|n$!BdP05XF4GM{KBw z@2;xEBuc2CZ3M^&n+_KsG1|OHYQ%oa114ln4xT9y(;bVJF|qE8Z9Vb76V1G?bGS-mbaQ}m)?=MMF(8N+@XJ>an{R#I{;$KfiookuG944zRUzt&vtgmy%q!G zI*DxSLq~do`wk>I4{L}&Jsk8pN$OwYlYS(?xsZizc~8ly z6~9q?uh58Ysh6JcDh}`SWH&XnW;rr&Gdc z$d^W1$^=ajlb^HPufbJz+gZrIe{b@Shzq^j0ui)MuPMBiVQ4czc=Vn+#Y^-BDP2CGEdBj zSLzTa(R+Or@6M%?FN$ZmzwqeP{cd5cT9(PP6?&=37&p1 z%)W?<-0pa`*M$b;Ei#x^gShun4WVsf74TS(d9hlVHKgpwJb}LstY~3Q z$=dp_s6!G6-2b6xKk@hDsdwAIe?}VTU3cAvw%c6_k=P|tt~|^@2vBI{$h+UaqY6Hq zz8rgOlhp3sf5R;a6ZdVqs&r4QVVCh~fD%Z&4WIV~K zrw^HKCt&}Jo(AckswB`Z-=aKea=%qec=zDtvndrmip4d(m()pk1NVfu10F-9%|)hA zsyB87FowLcuaqZFdg&oBT-{QmERJXF7wXeeP|srLN6@WtQA}m1>R&^X>8$kZxp7z? zKWPHdPQ}H$KwOamh>e}nRE98CO;)qX+ZCh{QW@Rim}etYV3$J8yZqTVuU~o$Yy;Fo zX@5I+MvtMNH`#ZevDu$055kjQgC`sWO;>C&H*xc1juPy1LcO~7kf^uTLecagK_Mho zj{2vMa1ZH^PvubEyXk2-fV!26RWMr0cpM&3dEb>4J?*T&-eWJ_{fFbl5TO^bl%r5K*o$Lep0?cMt1ys(KKxWYL z>*~>^;nHqOuOPp858eR5a+50=r=PbWj~IHmiYobVPCf(h^b^7|{nsb@q6$a-kwr{G zWBscE*|3n{!iD?D7SglYm3LM?I%Prp#(E%dl>R(UNj!P z+TY`P_dbl!4v9ae2Nyy+tWTpm6u*BU3W{56#=yhLHN!4hdu>$tU}K|#fBN5ki(f*G z3gbyEWP~weS6iJw;m^e-Ycg}VR00IuXS;;$53WVgB;uo7pW*0$TXOu`tDWE|2C8N! z4Oe(zN}`}#Ww`3msNqZ4nHKL$Kx((a>s79pJAkEXxg%79dttg5Y;nuBr|r#SzEom+ z{QcY5sU<$$>wA-y+^(TJH2I-rCIE=s>MUwvL@Y((LmgyoZfo5jV>`qksvI^oR*lRCH1@N z0M}R1xt!*bbIbPQhmamEG5FI(#%4W0ZxeEQAeMfc1+w`32-E{sqVFa` z$s^JnYq41h>TPA~`HXa_>+AB1RfO6YT&!2JJN=)J7oRV`M|D>+BA?C@iphQ@^D;m9 zeg_7=vuu<-UG)fmd?I@OCb~ovk_&2fAOxa1=qlB`KFX90j#p}cMW2t~lgq8hj0#pd zhO_Ky4_q&Bg=X6gg+pVENa0Qpv}j=yZqdl;3J=;w@38{=1%d0gF&A=v4hvg6|EuzB zuFS>t7m-wH8*W{8w1?{E1`~oSy1~#M0vN0BFMy=n{pI05-#h{`vhquSAik~^od2uY z11Fp(C_W=Y%m}U5JM&OyGI`|Ar&Fgmf@j{+Tk!pYdbeo(594kMuDNV-Lg><2#XnH! zncS=^+7fA!@12XV4hZ=bY@gU}OQl7P`3ZZ#4@%sWJZ<~=X&E=o4YE%FQXP63ci{Ue zI<+wYmqi4Cd5y>Un>hM~wtlLt?J^r^tThsLIOk^#Ml4{Ni7nJUz&faCijd0>613_C zpsrj!TS6GXw9_18Me|FS+ih+<9fhy_7PG%%ehM__l_|*A^v@KpVfwD76L*?A7pc#o zqzE4ZO9!wSj6>v*5>VX*dqZ~j?lwh03f=YYbCX$uOrO?^3q{9PXaTln>wa|QzMIPj z34)u-u`$@M2mh{$4Sz>t=Ml+>i0kg9hhpxN2*bOy&DI03`x@$o6T*Q`DUrPo^YfQ$ z5juPgKsxT-kv>=Ucf9rwmbnv2?p8`4rR&ydZYYz2x@O&1f z2sET$kXz-jaG~1km%}SuZMah96%n2KnseomONUYsqD)JzzFYN zTmxY}oORq5k(_vO%~2acfYz=}_%^8{-qk*yxmX^zTvtEbD-CZeSDwK)7|0RWxb28z z{D_7`rAV%t53c{N7h+6XQBmrITx(zLZRcd5fEUKr0|f)FZ4!@31v8jjEjfro9>2af zZLl+Zd7x9QG^oJMdbnfc-1}pb=R_vt@+p#?f+N0`v*}k zYY8I2Ld9ob1F~lr2Ijo;*2c#rvvM(_ZDQqd_VKsLTGv`JX^o*zVd|&$!o`rcgXhud z8p5XuBuPNE_7Bb<1M{Qe*8r$AtgT#fBuSH4#V7>f;RY`@t_gqiBvRzXMwf@HI1yUo zCTY{}vm?V_X&=8tCBVWf$~f6K3T%YDlTlSC;SsR`Yp0JJ=e{=5ItvIBME2IHiU=1B>Kt z$eX#;W_|*x)*j0TM_xKvR=|Aal_70GB8)s5fDR`h)1btbz>rCh zn+}Rd>j(1pMQCjUPlxR>DqjqjExNzmM#)aE?ekQa3@4I5RoH9y_A$oq@fz$mGOscn*68>b} zS!@64Y|bzxjC75`sTjfdVu(G9S#->&;`lyil|7}gOL72pm=E^HdLu6Tfil+WVu8s2 zwO{)B;XvU@xjwDPTuALmFnnt9(q9TWutJrnv)Q;PJ*!A|i*lXx+ZNaU{_k|F#cO(jnD7W)rNRpyDoB9QIO=>h zj>`XQAZ%J{5`m`Wp4oy&2#jFBUzptNLomDu_ZlV)M|#8@h+6JBR$VoREU1euAro7r zHh#BO_rpqtTzll0c;WWksPW6j4YSD_lZj__rYXKew@1kKkJC1*Q{1g3eL2rlFrZHK zD4oR#Z4E%AczoBUz`Ef$o6d)E>#Y8X&`C_C{!ZGzJ025a%>=!<%gLSDYre%YW#Y85 z7yxiNXV*&!PbVkRwKggiJEs_x8aCl0+?%zJe1c%mYgw^_R4Bs3$T!81AeCWh?AQ45 z*}5|z2hZ^o9_aF?gZfpjxv%$RSVtZ>Sa2kZcWE zWgP{f-?X`ZT^nU`D>g_;prHfl2VFKVix?(6KHU(KLjg4k91v{lU8c*>{b)*Kgux7c z%j-9*pSmQ2fP&lFYX(7+K%c?9;8wr_`o*8TS7?7EM$G%`Pt;Kp1W89J~vI!7q)a3Rk$$W6JzU#LLSr%LXT(F~A0cqNq{y{q8G9*%kxoSZ;z znKml-c6I1mPQAc~rmuGws%>4oQWOb^++XhsM?nbLU6+4jWc}usy_rGzwQIHFB>2i6 zD}$^%kahFp4I?-HXK3$!Q(gEMMfI_1D+GuhIDR6f5Ld z*29s8#XuZTl9Ob1dw&M~ItU;4SA67#=Oa)qeC+xA9Ee45JfLcHQX4`r?*({cDLWGqE3kV8adu7;$A+jMPob7aPjz z=`XKu#=W_!!u>2cXRj=bQH{8h^XodaaIzQ{7HQx{u>qtzrl@H0E&98_1W3aMom^78 zBpZ}4Ve_^P{qy*wKn6(OK!6wfPi)MChu8cD3=j7W2E-d5?|Pq>lo~GrqTj{o(nND=LPu zKBRGA=j)GG!QMDpL${e4K7b6Avuptk?QOfjCK6oOt}{`QksvRUH&9wUDIFHY)Xd&5 zY1wZXt4(@P_hrdSaelO-IVNDRlKK=bfEu!MB~2(I_@)Iu_>ZyXTTtclylm6=EebeY z;B=P-ST{jmN&C#}f{$38<4%HmBZd!kc9I&}luX*431L5=ilmbhJeL;{@v=ZRnW)#h zX1U@aH2t4|963mG?|V$xAnzw=%K(IXP%9i&qL?L9**6XTWm3->yrE;aY8kCC_&LBk zS{Twar^DE0k?|j^KErkLrUfMA86(LBoSl^`C<0SrO;s15{DK9aG&E5IkiBMJe(y&K zKB-F?hw6XYCQuyPRaBFvu_{pZkzb{JrnCc60^j5Fd?k($KK%MGH%StW@ZXo6&4=GT z^G(Rmo`0XLS#K|l()^Y=745kv01bOf82?~%iA2AzV)VT<*CEXD#INsiBrApXBfcKh zu9B2S(FXxFp%3y`s{FW|=3aovp$7LGLv)nCwPom$_irJQiV|PsthH zte*i?pOmOTX(`>{g5ZFCDTC^QTTs7y@v1s1!`^DCw7UFm(<}BB;nz7dnW5OMpiYo*cnB>*>t*ZmMi84_#{NH{*+y+wqE^w0H;<#u!f4t*%^Lk z^t(6oOt?84xRx-*9h;0e$iTkC0Xl)=1do5^bZ>ZD*LXcl%6$LYm#xY3WWezno~5yx z+8+~Ixm3XK{#W>{KO)LIbcPga>C;t7ZwM|0aXxbc`XE9ugIx2~ormEjz1$yHmgfkboPF@%x;bh`8?qD|Se&!bNG#Qj_&tJbtw z$qm{Qq9gyjN0RxqPQs&p1r|nt|R#OEK<3M5-P!$VISj# zFu>crXRX-3Ta36XPsEJA*=kH-1Y3n z7yZVAKKXcADS4Snav%gi3zc!U=L1;SWf^)z^kI(`6hAm`A`8yQcTk;8FSA62h$Y2N{=tQM_BN3FV*0%jge;#<(y;&~%o25@MyU>Ovf4bw9J00FoMe34^ z%={P7gB}7G_URM_-9`B4{d0K1bS8-D9Me0;g?oZSt;_)%?gbuN!a8Bwiwkm%yEnmV zt0^u9E%=G1N!Tyro)2vFS9wN=gUn|VDuPA+PZ3Er0+ZqiC}vg~LwKvmayrZed;A_C zkr(0A#;C`pEC_GeGW&Uyldq8XF;BH=Po7|y`7+rY7?bL-QyNatVfsFJz=-|lMt?Ey z{kcv$b2)j~gbd+p`>Ra|$BJer1jcoHkFTKVxu)8f?Txh0V{gembW-z$DYMkYAI|9^ zx8}gASuvoSHmXI@AkLD=o#DLguaPZSpuW+j{Ln>huX&bdE4wM(=P`kIk^ape{OGZl z+@g_wm;EM@WcE>|V5Z9~UDa}!UCFsX6nJ;M+lS4BxW=cHzIM0*L4lxCfBmeA@8*r; zjZF=zNp8!5J!-1(s7YFPULLpSIGa)w)IN$6D z@B$Q8tIym#XAZfkhJHz$QWXt6e2yKbMPv90japxtP;X?uH+ab=XeQfi3NSC@)|%Wq zh(;Pz`xxU_g3=B{z^^&90I2)JVKx`?Y0c1?&;#n~nX4MB$jdF-_D?jz%efRN;MMy}4yQMgc2ICYpwFT9xXdTf zG$7B29Ehvw_yo8U6Q122gk1M6TLGHMSw#OR+1i>{0HYPCe)n8Uppjfx@ds4pyQAyt z>=+E*d94&_A`3dw8eT+HCZ%urv-j`^3bYNhR*A5u_0aK$xNg+B8mM)lQtKM=@ zYWazQ_Le`j*c3Ihc@e(+sMhNN2>g;a_9LEcpPDev=`;O#tBY3iDEsem`PQg>R~{-z z`eE*LSq|;D9kp%0X&UZSK)2*(PYo*M}nWEuZom|o8H}iy=UAi z2#CLdQ5n_h>1OhRZN2)44`ISp$dOXlG|fOwe-*|)xQ~A`x^=*DcM}c_0!2AK!c6h{ z2UQ&89Zpm0a(lcAPHo7!Kl3Df6T)Z}L|*j4vK>P95nl^KosWm9iLV;wM0j;{(sI1K zE&pAp`Js3;o*MUCa1q_sXb_`4rHTORy644Jz0V@43w`1c5wvU64^~%17QkF=F*Pvs z-zSdM_q!dgVlR?W>lPb>?ee`@IlCiWP|(`8dTUQ57N?_5txDa~v7IgY)`wl(>)nd{ z_3;UA*uHEMV%;-R&jCav&qrj;x7EAMJoqBW}wGDowoo*k4`Xh?to)m=9X1Nr}l zN`;?|RGQu&mNyS1+o%gjDthgJ65cjCH&X`Lw!oc-!&hw}}@)4wSsmxUds zi2|?Br(*m4fJ>K|#41CZ)Dtk_jaHTh!ypyh7@1zw@AquB>P){{|G7Mo;+z`zG>ycr zX0`i&txd$Ae`ZzUGMXoEY!uvrl=)L006}EE`hU8+z<^v~q=xDy9IN2J_V_4SDz5AI zHz+?UM7=+iXqxNfMObZu$(8j1k|$aJkMg(DV|_+ z(bxk9Bpw&ladXigc5vz#OJvT=lm@KXCS7@LN*d&6pijka&)FWyVWBKw*qOig|F#_b z_m43CoTL?us-7{hj>feWFdKC7;ak86M~6*XP||2K(x4!V+U@n3S2h`*4Yrat*}N)} z_6#=I(d&yIIEpl@y$6f8?ecdi1=AShnaz5Rn-SIcc4wM({r1Jaw>|VHu?_W!D|EjL z(2h>afv!%Or0t_>GEQQY`0rvd+TzHpbhMEos=wkW?UkZ_E5#iF--h@Dza-*#eiiI2 z7ze23H|1saSb1uLO#O|p0Oeg12T$&%JgM<+sq#^nFaxpB0q&v%R%BjjlNw-i5dmy2 z*jH9#kr&oA_slZ4UhDfY3q~LFDzJ1MA?pceUdtDvo^rX3GMS+7i@rM= zO$&;$lVF^cOkW_#ahWtJUkA4K`ba3_Yuh&AQn&L}B(ID)F(;EA#~`2%jtweii(qFG zK`AF~Mug`3)-Fu}<#xz{WS$nwX<*+WmpoY;rd^@WK+lqu@Z^j|MFY(2z^*EVe@nG9 zT8dCv_ZTKCiw0dw(9Wg-gIw12fYpvpc7=Z53m0cyr-Bz= zxxQ5W2WJ2X!8nHD2E&KLxXo}MobB{uQO7;U+^VJ$TL-((z20Isc@I1S5;yn{tR34l zSj4b#%pT<7FLqB{11>Ol)N6n9<2-8_wqIvdTpMPs-$Y&W8_qA>i;J_gzcy9+-(tnB zD8m-AEgJXhxJBx4E=Jrh_mG^-h^2lmc)DJz{X8(5B@L!03DZy{bUY!y>m$yfA5b$Q z{_FZ63hvMxh?4+@Hz`O9RKt%R?Jx}3jiJoRi+q`oZt06#9xAd<95m5EI$_Rj zKA@S(VmfY70?g%64YB^epiIU}-S?6r zIsJZs_E(7Regqqc9-MzJ?cg}wbawNROINTNxh)Z zWI3<(YGAcI%p?mI5#*q;h^*$tof2c--3BBKbO`gdlA$?yVgF?{)t4sAV#y9m*Zs=; zkIwRZ5`4B#=R5h*K~)tr;xdngAOQd(iw&4ozqGnhRj?91DK1WaOkiDY`jwu1`A|#K z(rTjw&=>J~0!m8l5M5EhJ1a4H5Www%%L(O`cLFG7$hSU+9eZ?$IlG#5=?=TD$dqO^ zPj>{$cJgZ;Nqskncj`H$B&51D%!F2K6sAo@o8*9$mX+C06w9(~_YrrlBNbZs>R*Wl zi(!HT`u_x!%B{w~UjWnV=h}|F3@^r@8dUm$(5)e3g^5%NuPXN$CcuI~p?+lc0ePM2 zRQ!#5|Ij4jz1C0ZEt-`QEiq(M3i)&+V#3OUXa$s1oXesemHEwRFG zqOR?kv5h5b>S=3s3||9**=lb(s-{3x0yZ>`PCb}UqM(559|2;4MZSeVX$^+bE=t_b zeJ{O5s0E^(Ii|8Rx`k{*kw@S%ySqF+{)|wrT~3f|z{4UE0#utHK6eT?4evkPuBsgqiLcr%ay@Mj+9V+A9!KJ?!i$@ z?XEiG^y7z3k#|pL8PBM1b!s0HyQsOjBl^kc|2gMfYd3CM{1TjRRvap1+Q^|4+-v92 zs{Os*Gil#IYDBf1W63ft)a({1zq1Be)Y)zns};5DlQ$rBYebYL#R%W2kt zs!(xXOi2o&KmB-9n$1*Pzwcts)kSgo)(bGi5`C@E4hBjVEEwwBe95#5gYNT*Da%mt z$KqQKJcq|Zc1slusC>!HmVaMrrsSOafMKG%V!|>P6H^u+-opQrS^v9eZZ*eB?l6T| zmKj>#?Co*R*q_85+uN>@QqchMsCP;%O*pyob#YEF((Tr+?Pyj2gz)xsUWlI6^435YEtNwa5U#lV`w`9=DqW`uanR70Vikmg2#AX3cX^LCKm@afU>cq$!qW& zll5h`l4xf~LH@k0m>RsiSwUN8%n&3T8bF&9uG{d<)NuSiG@S)QRbAJ$DG!|@-Hm{R zlyrA@H%NDPH&W7#($d}CsdOH?yPI!wKkxSsV4uC$nsdxCudzN$<&z0u3X}IAfFIkZ z8f%>01=f<=Haz7F4pgBJpj7goI$RbQc1I1@XSaC9OI~*yRS+8=CWSxR2t(-#bh{sW z;fWgrZ|+tb0b2oam8bgP)X3g}qaLI`|KValYBz(J9q)Q{{lKO) zW}u%)@H`cRjx+~X^-=AICtREbtt+n#rdA|!-On7SKrKrdWQJm+l!!bj^zgFRK1(61 zl3bs5jaQkYGOEaD2p~xySB>ofmjP1XZ~gnThDcWlyH+Q-w0zM91q8XS*|6!K^Dlen z1%(1E%wZ+(KUqOu_@sg%zz`}hWb#@f5w>9upMri@+Z|MPQ?%>Ogx4B?g$htVcjw&W z0E)muSu$>&wZ(}}(EmWl&f$bXc=$l|w6qXK(OFPh<5^$x^|AXhOV_M}7(@i<>Xt`& z0)-i=Fcme1vRgj|*USluJn__PVaetH)re)$!{w`$n#a?dpJh?mVs_gH!Uz2aswahD zmB68Br$l1m2D98A0YgJ81V_wlL4<#OHeSn@$Wk0ry{9Z$-$8EeT zd;P~%eS%O>QJND^&Xf~WtWMBk&z&hxy~D|8L&%(A%Cfcw+H}|AiYnR967x=M5Uk`F zZ9E*X{xI;6>zXEk5N=>kcK+5v@uE)m|GxxU0S%JY(oEq85d_S1teZ#Ad<(?c8hB;~ zCfDQyCF%X7A8!S^f16pTV*n(0T^!A3%@{zCj)1aCg%Yfh>U|{j(a3E7?xA+`v5YJ^ z7?aJsy?`1XQ^o@KAOMulq-Iuv^0&tf;uGud$P2M}-8Vcc(*kxP&R_bgKC(3!XafNK z;WL+ku)*J(_ZRLmZy{Gx!bK@8x030UfxLqV52|tTOJCFV77z@e)yrjb5C&{{X@ykv z#8S6xX>W+vqI9uetga(%Sz*UG@QCFh%zeoA%4JWkLcz+bLZRhmLi+dp)9`yqk|uW+ zYvkZkP;nasEYzuXnv{8cZ!z03y5% z><#@0*RgE8&OL|0M=@s){KM&bUu;mow&_>PEURO?F$>wey7~tFL|I)Odz;pYt*ada z>ywdF52a$!SWz0!JUOikw>I3jI9&wA0Hemjs3HLS7@vL-nhii#gg`3x>nx8pmRS+^ z1D2D}!$rf`d0=gBpjv2Q?3oy;`Nc+YPXbO5&~hE2SFa_0f5s&K!Cd2a!|IW7PQgRZ z)gu8^NRE2nGiGRU$p1GS_sa-x2Y|#`1T}0K|J#gMK{Ng~-)MH_N!PJpn5cHKJg?Vs zcN+@sU`)RHDMjm0!A?#XNhj;tVJ3f|Byw#Xxvek+1p3$}pX3fY0Li7MMe7tUY{`xp=Xz|Ak)~ zMc`NTRGC#q95s8m_+VprLf1_y1OS$FUMUDx(?TkLqaXnO4iEHiBNc?u=HD5z&HPOE zhKw)OO84(fB*8l;4{79&{Op;z*#8?K^a7hMytQC_?yE9gJ6y!uw3vA|44zK(f+5v( z*OgOCd;A%L`_wl9g`nsqS8Ns)ZZb} z3Y;_y9@`-b!%I$Vee|7n#QWH06)7GGlQkxq#0Ud`hi`8E^85ON2AA9{-A{~uhg=GD zyK=O71ccktv`}Zk3ke~d-*o+^`D%wd|KSb_urdLIPRpTT7iXe$(Z>1J>xfKO_aD z>3|kao&0^bkVZ)4l?H8akJYADU=A;A%#6M9b`VWOkOu$Hh9UJ!&0$w>mJ&v^irg`2 zI0fvKgff{VOOFw3-Vf;n;G~FspLjB+`JyhG)ymirK8Eb#k2bI<0!K`FUN198)PDo3 z{qrWCPzVU1w9PVmy-`_k0NjYBz7=O@tr>gI4)@$jt$=ilL>c7q)@iW`jI%B@HQJTxnLA+BGTdn_Sv@^(Ff03pb6 z>&G(r%%5`_q;iRO^Be8W%s(luheLXXk2OpG_$X$EzTC|c=}&uW6GMtY0%3f|R=hAn zbr>Jj7mYo`wPGPLr<+D|bxU9+fJ#_j)aS!dFCSPKP&aZl{#(8Z@)_)(N22P`UAXgu zmB+Czi9b_qkx|#GG+-Wm7#Om_wt*w2NWXJOTID^JC1I>=QO`LT2 zFROXtC-dl}DW<+YJ0xTv^$DTZlAy>sSQwgoY}`Ue31j44Fpy3;lE%^Jq*W=E5<*e8 z#MQ@BF8RO*xJ7B4!ZxE>fW3@AP0GqS>3ecu1Iw>5sJXxDSrBNodN8mXc11&nwaQD9 z0&gBQL+Bv^fX)qyF$~uKhPYMxhP)bo#tsr@n;}F_^7{jn5Ez$5BH7&E_;&i|Rl57c zX8bOZuW>FKz4JuEz3xmxUd}oeu46z0RBG06Pd$LlL^0RRhe=G4xzxkgFobEmNk}*; zMv@5lr0sL)$r=i{&JYu8|0U}&Dp`Gv>?QHvX!8D2zpk72qp$a~x`DaE!o;M7kf3v4 zi-g~-P<2>3U;_QL?+{+~C%TJPZkD-ySPko^uP@+PEBo<$w|5xYnt%OKx8VKS(Y5Zn z$G983|HoGVemkkvw==$0x3X2#Wqum9^pI1u5GE`J?fc{TaW*pSf1qAbxV-{pE+aX z3Teo&ZLP_$1@8K`=a{+#!h(BFyYt)G-tjG;4aV85$K`K)=TFBzCllOZS>To{tg9!~ zGmtUkKj(eq>adKbhXpca%txtG9BT;phi^7jH6biOWPq@kyJ$JLNkVb3yAQJd*aQ7! z@$QOA<0NHd!(;R$%?|)`MsBWUJ~V00T{Fu1lNp_EG#EOOJ+NHd)eG=x#IFJlIwdsD zZ$DrBWM-sZ+9p0eI%R*wUf(h@MW63CL<+h=M0A7dXf{xH(Cv4*8KC&C2JPR)n{$^VexVR+D>tiupkL~Y$rz*KpQa?&=6Y`bAPb=mvE4pqJttiGUkyd({K@pB?R#GhMCygsUpQsRl`H0zNP+qDv`5vxw zU$vh8K8i!(4H_{xn`wsWd_jotOHrxtJE|gicf>4N2~kKmb1Kw}ic|KW9$P0q0EgrU zGB!k!ihZB8DN(gWme$I3@eH2s^D)Z#@TFXPU|YmGn%R;_$qXorU;Zk)5a0%C#@*U>eEYc5Fva>)JOz~grXEGE<^|Iej5-7OCI6| zXf;Z_sF6ZM`)7Lr1%U@*4?-D>2p*6{Q#vhQB{-l1Gd`x$L%1Ahnx<6gNdSZx$S zKV5UH-~-G(?}x9$%IF%b6{xpBRLDIL6(YWW<`6HFU^Lxm;J^$HB`MsrVj1*!x1Wcm zGTjF4o(cj8PKW$bYjXny{ozRq%n)NW6?&kSA9|)25|fY_=pN0*2zd8l{(bjh9IMF&xgVEB#Y>8SCO-7Tg7UIi7)ker+g}Z@wXB-K3H@X3)TTQ4Y%f6VFFt2vcc_A29Mt z$%Dl)v)mv^W6y-EULNnnb*cOW)Tn#X^6~_Thj8S%lo&`!$PbkOPd0RF!XH@LiD7x9 zwOKxxho&^}LI+3D%Zom^QCbgDeS<;&gI!(7o%yf1XcVM!JSC|+!~pO!92(1fV)eg1 z-#+vZbQ+S-KXE#V`+HeEnVph1js1!c93p=!vDe%u>tyCd)HXqYRGU9wx6L=$@DpaC ztqKc;G5ZS_!QF0wN5jNi#;_jv4Lp(Qk;$(?H6aYMXpluPE4duZRrNuk@J$$MeNX;7pVE=I@mI*TdCF|TC6#{O?dydzHfz52``XnqTYoJr|Q~bC+Xge zF3jVkyr6^ESYp#rGTLRGJK`BH^H{C8!Ok5V2Oz@cwaZQO3&+bo*M`eZpOv)%pZViW z#czxr>a|hho=u-R9gyv*8v`^D_mLcCiyuWz{~nO44O<*mx3`QGAIa6%R;KN#&d|cFPeQn2|;M`dr-OH zPHeZ!MSZybETlVkKT>XuPGh^tUvl-aOE;0ylsY2`@3Se;OJ1SD9TjzY(;ATO$G(hK zHhqqO5gIV+293wHYX|cnV)qU>k7HyCuL8A;Y9MNZS$2Ol8=72mbOnrjJ6LfL$yD5wM0I177GKH8;4pR>llYwxOV?8u9A;g` z_IowXU?#vb#8n7Kbuo|opWGGNQFR#=ksBAwP=ERoiftxkV+ls;Qqj7G;x~J{d7*_+F%cUxVM%vOGNmxYA^h}pja2Ifp zbVa^Kf2xgqRwTJSy%?5}SSBl}#C*BVWn%C)(cAb|V7xxAy$r)HeUd|{b0Kn>x;|KsDC6D7p$( zC#YuW@b`3CSvwy{t>ZQhT(mRlS);vr{jlu|@0Gp-NjTUaGTr|3s|TS2jQ>_JNLy8QoyM90FrAY@$=v>D~aA z`8qbL4lP2DC-u>Pz>Ajn7furI(o*BTI5p|B=8lfxgZzY?t7)mZg#ve}a%m-xK&rTzYnUEU=(cEX{yWfo&?o_B$G4)HOli1q**JTW-1wJ#0_H(;MLhq7%K$75H;p zj*zLW3JzX~?98GFZL&jRQ4QENG8Vd9ZH}E2JRiAa?`mmQPxMKxSdD5&g+jt0gZ{;$ z(x?(;aR43a}JAk@PdBscIgge9Ld0(uc;}Z5PKEli<$lfR~z|W z&?K<7C~+GB9r#=$p3&&(sfK(I>I}Yc7BlfsrI{l3rWd49kV~8FQPjrwI%Ld}d?*|> z@+F3ksG5beNV#P$6^s?ZN1`d8aio0PID)00dYreFf_Ikm^;-;yScJmz|C=^B!yzx+ z8Q2|rja@e)p?a-@w?+h)Tv7B)k7T`z#^G0F$?*pnGe9;RWUpZ9T!ju__0;of&P5Zo zW9tKI87JA*FwNc=`JC}Q5=Zf!NqNW*=uC8wW}UTH-=5O8>5M!$BncI0=rO*D;OyEn z;e7Q}MqbTU@IDaz)6is71qmG@J#5xc#9v8s#a7#i$Kx>gJ zkXH5qiOd<8)!^L-rO~_}`WBDmBpbeSXafoXWrCaZ6KCP*UwDGmAWb-6Nb&#JRI~E| z*iURKtV8&`SQX#yTP??#!+*=2wvNP@B}Pz8n=OK)Fp3*dq(BhN?j5~07r&lG?n%p~ zC+RJ4!7nrESfTv2dUyNDhy*|)J5OQD{HDn@jb0FbG}!Ct1{*VD&u{HVTZ zEw+NWy&?Z@xCKM__tU8EtS3LlVBG0Y(3h+O=-#hra2u(P2_=Fg)p0Sseb(rQ*w?BP zscYKl7|?X+kY46ZpJi}j`czYwd<$XQucY|-hGwbH#5)?;|8yav;aekHah%9l8FmQa zL+dbnq0yH_!q5c3eL6wVG`}5iaALhBO{=&fl7=-)5^F}*AF(lTNK=sKurX}JfZ$UG zD)a8B_kZLN(I4_7>ptQQGaZ=a_=v-}in-_O?aND4e$yVk@;r#c`L%@o;Pdk+f&cP+ z44Bvdqz<~8BsAb2v<~p&ck)tVUw;5@pRCV8*wM#z814cgFL8nzsqd=1g)1ScK4*1VY>Hq3Bq@5W z5~cPA0*vi`ZMPc3gR#9SnQln1XyyC1Uok5FPlT;CsSxh-o14Y3yLI`$lJVgV)#s*} zWf8gfNeI$vXLSnhVz=ImAHVFD9SRN!4_jA{Brp1WxLrISL|fSd86R6c2Hle);5FWx zM#(@zD5zp=;)~4Oe?xAk%a%bn&a=g+{0%H7#fYB5Ma9rFhDJ`J3b<$v-Tf3x&$tb^ zBE4KRurhscQYohgB4p18Ri>dy)r!r$082zO+{;lBtp`$Eb*fchyUd)_4v#^p_mBA~ z6TRX+SZPWZX5c&w^$}&%0R9yPCe~tjc&{>ei%z5aNg{VhFQb?T)|{dU6!;p+3EAhG zvE%Ob4$@yRNKydr4u$GkBN2J|ww>fRpVN9b6~PFTSO`QkIu3NPSO^YB1rp%X74+9h zI}Z_a`oWab5{HY%PGzlKbE9r_m!4FwD1e*O~Pfg|w$W(Hxy z+F7{Z#`HTuO<&o3Dd**+Z_v8x77|7L6S-%`J5a_q8&WlT9$yuy_KbnNvs)XY@euT! zY$+W$jJY@I{!RW>iHsjv8fn*0p~n}9itF)}x8QjgX7{=KfOTa9)s^hw2XoWS3^(Lw zIkOiu@G}6=Vf+`=XQ9cVSuB8V?k{`wd&M^3AA~-CqD~cxum##psQau+Tz8v*Ub7gs z48>>=R9`ZCDSibk!uy5j3F*)FE`4o^Id@uefVnMC-?e7?8*X(?`cYJrBcd*;#Us%M zV~@RqI=%V#4fTXgHt+lyijXazKXSw4FmW)Q-Wff-!ufw;03V>Ci4CSQP|s;?nz`;L z<&+^}D=)XC**ni_E`?is)gh{AUNx$0z)}1%2Du-2uj%Hlcx+bY#m5nS4#KMIT_*5fvCdCUd6Wv zz4wf05+e5EtF9uQy^HURJ^|lS=Y1iER5Pt;^9~61q@VA9lfO>?^lN%X9g&c45&gd6 zw{4OrT3!BW=BcSYMwxAbTfa!l-R*UlU`>$c^Bx2CIf`*Djok(QJcOH2Y3C%}rJLr| z&lfy%)EGt9&~$g(^#+AiL98?=g3tJj5c9de)tMx>g-b&2`;34(uJ1PNLxj@5D|NE( zd4)$k{C-pqi)QheynhmcaptX!b7an7(Q3Mv>MjR2hO=8M&Kc@H3jBfc8TX*Ed70oX z+v^5$qjR&SfCGNMXXN^lOzVAaQ&aj4+4_i z{!*3NWf)q*P_7K_+>4RIztr8%&>4@sE7qdz-|j=T}Y0EK{PRdLd4E~<}^|Me6Dy(B*`at}5QRc54G7n}63H;0US9YlK$Nt&~?9tAWj z5s_Eio-@UOtvlx$EC&h_H&y1WuZ-acSzo6xPqHhClAo*w9;@bgGVFQ?BYX!<~P_ zI*G_ybCMa4>Knp;rS3eV^H+RSBw1Lf$3Ew$aeGPvW)Q&~Q8pDQCmpNss8a5W-BjO} zZ+T-XLqdr{WBgHlRZ3`?f)c*uGt&^>IYB^s$0-=VQbvguLMjz5amXY7u_-0}Iqc8N z+6Fzy&K(!o68bjqWq2)w#-MkY3UrG35ymk0vz%omrF}V(!wX%JVJxTSnPrS}yp*O> zJMBIku)MWyfU;~&8o`yzW_o7@wi;NyMx$j0*XY@!dphWIndnhMo-RqPJ*cEq0F-c9Q6VNs?<-IrNsS)|bnDgeO_kYI)1QocQV6 zZO)#!mUPr*Y@2{*A~wU_8x1H}OlPAWml>b^J}cV{H3T;=v8y0$-tqVVncyyBM6JqmLrcDj?_u8`o6Un|0Bxb$v zzea?Ze-$q&mG&Tg?;81>I+KcT3-N)inCiShmkfrbc*QL|H)-i1YXQY*-c<(4)l*Ud z%PfekcssWHYoCiW_H$`k-d;)I`nZ?q3?m_-0PVQl=5`19gKcT6D3c)mL--nA@VD6I z9jYwTu(5(;$wWjCI0*bd{8?GfF;xl*{y!=2y4Xs(xja6wu^zeixezBu8&h zC%Qn3$r8g@SG^iIcJk@F%zpCAg9sjq_CFq{8}(mSBVdTFdd1Vrn%UsZ)cv#69{Scv z)Kr07v9SXFC7geBIhnx@jSOrVnRDmt@hRab_4HxF!A2L}rr!rT5P$v` zm4q&G4D?K!dnkj@DU*apGYWDA({m;$#cDn!0(cvzRzsv);&R#@odnapZsvKxSbo@1g5GE$^)3`>W&_k2bm=oxp>u$Z z*tF4tsuHqyh06vXeaMKm4fC^yF%j0=z3Rumu#=k833c_g7FvuaK|{tt^}4eyFb}xp zy?psOXoBh=o^m0NxArnKebdDrSAe8B_)C^zOdE7&y85dG3F==6%@IdMUyX2t*cVF4 z-;SI_|7CUabeFvgUt_;y&bd<6)22zs$QwEU{RBF`zF6R~bo_Gv?BYddc`{Yj@k{M- zH{KJZE>Vn$3-4*`$c!fI6InRN!kx_I*R*)T6AK#|C6kKDaX~^%#U=MtFBk0*KW35d zugJm1K-y7}*mo0OCugzu3yj7CjI0;z6eU>`A-rSwf zu+`r4i^qn8*H4#ulB+eSXhuQh-)0&J51Ni7^0Lqj^plpsYTvD$7#-e5EY>N-GzJ9A z55mT`%T&fK+iNH}T8KfA_|`Yo8KDcI=h1#Cz_I4Am>2(x_)o2 z%Rzj^a(PiYrcktlV`TQjK*o44Up3}}u&##MJIkVFi!+iV4Q8Yv31JcKmLXNXqRXe= zhRz=ysJN(qaKr6I0O{gCZo{<#A%gg(*5bf@9W`-PKvr;s=b% zImutAV8EI8mOQqc2TLOxDJ$hu>jLWR8%93TTw#fH+6%D(YkR#`Zuhle55PT*8 z%8#gR?L<`)7+IG_LP6^cOz5RL!Z}@qY8;EN{7=b$?2mRkJ4()Y-6Zb z#n?cr?OtLi?+*q{rS6FTDbHr9XiXqPKrQ<+eZgfQa_>e-Jo$EcGkI%hNNhc~cqobp zzeo`XmvX4Wi%c~0$yj3U3h1h4Go&pA{-%(R)2IwlO+UEYi>_=8I zs<`~qC?MSOe8}V8Ojt6lDZYh?Dt+)x!qI7Hahn^Zct{%~lnSvQ_{^5cKW&|6eaMZZ z8_kUW$El#M3rP55VKPZaP+X^dSrD#MArMd;r=4GoZ<>s#s3c3Q!^17SL;N03A)WuL zvU}4*h)K-nCmioK@I>-f6#>>jCXHw7ND)h4#1M&|PSy-%CtHxvNl)LCJ`9!K7vo#l zzYzVatb5arX=WL+&~1RaD>b^Z@p{g5CFVZIIWbk3TOwspZp&%$Lh+ zzE$hG)H9cCr)J&q&*uYBcL!3QNv+PxGhVIS8z#36cU};SFpvnw-`?&LhR!1BPcrxL zjWuvqn!0fwjEe(8aL%-+HF||=;L7n!ls^B=AjWqGutYX}+urX2hH(FOE+>BuwqU(; zpQ>@sm1cJNeBb?qzAMGg4DXDEhEKhQeIRY=G2*bJfE9Hs;)g6AuZWcT^3tdh zc(PuHZ@Pzqyro4DO&$OESDTU#M6PFM@b_b(BK)*;C;MQ^XQsq{Pi&V$FB+U=oc@j+ zhTDzMD+F3410oiGk7AD0JF^At0gtR*(4o1GRyocCL#%qONMD=|lpg?+?|_)s}I} za~y2xMWj1EEUKY=q!WIHF3py}c|v221p!;WB;i7;5xXQNz5vGjcB&-d0UZd2J?T*S zT})^j!Z06(R<#jK-WQS|+JSwYTYN(&_Bf|H?PvrU5uaA51mspE-6<~D)89V7_ZPH9 z=pvZyz#bp2kcbHcx}rXsLl}e>DE!6j1G`v&2&kk%ELhf&ukda5dSC`K!X4=TR+%aB zode$%(f~O24tJUpVzyw$5Tgjk7rfSND$=RJwQlNe3@9L|Qd`FKbe5!=4Z_qB=;+RH zuEhd=^N4&j{I#i;J`YaxmQ?@)V}tJ~4-<@+3ke)?sbo1o;Er`!(3`84)N5=_+8~KV z8MJwcAtY{TwB*TObf10XDy`P6ilD6A)Wj2H>W`u+_ zRv*UNBA>TAeldl|3-9GTA!=d)?g7xw_bVFh^EB&>-~8b2=Lf*FMHdWA5O-cMj>pboZFM{H9LNPbr7|N zulrP+X(uTM@qkpfl@FY~Tf+YOqZ&W}?~V#Pm`*zd}_!%X3j0{oE&caTeh zpb>q7ZF5U$El>F?7AI^VbXhI-c4PiL52&5GX zzau=jv;QUuAy*!>ytzpDV@%o7^ausMv(D$p&sbddHKK)GcT?3#CIaff=c~X$iJRX^ z8g|~)Rce_3F~0g=UB``M>(Fb)_ERYm{$%7?Zya(F;vK?lu!baI1Ttsf{Wt2Ow9rP> z?H^T~h=8Ptduxbnw|)21toZb)nK=bqj=b4R^jC&!!IBDyMKl9)_)5Fb+Em|HJ36{J z){QQ_j7`menz(OXntja+QVg-8{SG5Kof2mg;_OvFYw)-_lzS2%S|U1pAZwndYZNO@ zXgk2SrGD0BKjQsRrSCc#m9hiukbtwF*feG8l|iq=b;JI(3c_;;5sE$2*4wQpl}Lg8 zCs84lxkA4QF-EiFQZh8NBwf;#(QpI5Q^nTobANM{6guUZKo{s}{nY=rS777&osqkT z-*o%DrsH*jt-Ioy?m6FJeCFoprHPoQ3cm}`Z93!aF0CDChFbJ^bq}+Q!hUqE#r|iX zoKOotvubeFKoSyf{fGOPl23<*-)_Oqzef>L@MTgI!II%n7zk z$3lYSaV(Sh9GV+9r0HXr$;l_AJFrIJsP^o3V>#!WnR1G>xDr>q^fGe;5El7V?fJ1aye7UfToWHFu?>jI%COKwa5wrTRk=i71Hato_3cBht$ALU8Wn zYeZ^Nq?hFHL`Bi8c)wzBAEYorRrh1|SLcsm>LC=V3jK3Wog$>;76m8TElQGQ{Dt58 zo9c|!|C;ojmTvV<8TSsC6=H{$PO&rDV_X2F6*lC~B=>D84C`4wGQek{rS@_p!@$4L z9Olhv5>!t(-x3A{Kk4?0;)s|bn4B5DKg><5rtkL1caJThwNV2>w}INq|y)YDs1UQX@iukKy>JPa~Az~lIz*tJ)? zB1{o1IzBlL5-EYZ$XDtlb*tf;hupuY;e0obLjz1U3qL60B!NPGTNE^;<#)kStYZ?M znl$$yojk5jxV8KUT7(A1Q{DOOsP7p{8YYkX4^kj11GMv9pta^p2OIaGW2JCiDHV&g zu~Eo8S&i8=kh+Gg)u>-gVwdLmQL<+_=)@w=|{ zp^KCCXN!V_Q%}xM)@jHrq2BX%3-%+lxB%2##qEk9zjMLCPk<6Yii*;Gs*A8?CqKIr zgjg_mnI-r!s2VI~k}PnGk!;#!L)T^*7VuiCn>M|nnxRvw)nV?YrMuu-w|xHPg>oVX zk0QhB>>n`ivN#rD{D;`E^(5M&8TXV^OF>oqwLP}E&1qS>!4FzjYX(LYIR^@jbc%Cq z9JpK1KI8MnTNSKPIXU6oJ^z#d9+XKcer%JD4nXG`%Tk!$KfwR{vz@ol@5KEH{HSPc zIoAeCv3VuPl-xC|i~8i|8L|4Ad})1gNBmF9?K}>!_-O>xy%e2HiX-owArC=5tDAa^ zUVr2wub@SX0&LF_cSDmdPqI{JM^9P~pHKbKrDI%5xIbqT5VT5?Q(%P3r_;WUZjM|1 z5KY`2Vj`=ABK*^t`5fOQPt9L|$RH|s^8|)R--<6QeqdWp#Ns#S#09WGQjff5tK_xE z6N}q*j@*rV@RTY4;*c8cpcTd zeX^U$gJ!mp>p2 zgrO>j>*Q`L!6Q|$tz?SH-bTs=y*I@_@|tUcn=`OQ3eHD&J`a4B9alpg4c2Lh^7Uf% z*I54CIwcCUJxlgs>lN%P(a8q{X=YH-LaGg-SNjdfqmvLLKq3;JWF)%FybT%PTJjxN zyPNP#qu@_`uu7;X=NP&ZdM^U!*aM^UvES`9Cqz;S=n|!DEKYcJlg*a1tZ|yoUGynk+rpcFgc{|z02Dco@=hG1|YdUM>x7^@U z)K3vG$>IEQwxe9b*BUvz!|SsGD<^ZFSNE2TW}hl7Vhx4<;!`B#6)pkXdh>`sL&9Rn zS(1J1NaG>`f%it7&95(>3opbp^-t37y|i@>F{IGQPeL_KM>!gtT4hNz$lopXBtdbuV$HwSnz9g8v(>_;hrtF7PE>rdH!!4T^Gd@gyp+N z+jyRFvplt9_dKapZr3q14Ww-RZF$w(`<4=QAJNt)+tb+sWAlKuYS6X3x=2-PWK2hJ z&p%vybw=-}(AzZ;-W9R&WpChk%D`ae;Or!&67rSH;jQ}q>2H+6m>7~ z7pBa+1pH!n1Z)e57{xqMk^9(thjPO%3oP_x+bPAZy+(KY33lIDSRgdPUqLZv9tmBH zHIdK?jZ}<*M5ty6(;cE1s%QM+BR-Bn^}9u2E(?NnbHz`LAW~*&cW%DK#y36+(3ro1 z!l>lEXQla%B^k$^G@s^&JV_0;&Ex?qjGAxE_u<9c2+A7UJuC-J*f91`By5* z1SwJfk}7KPJtJ{(@;S|Jc5 zmrKe*LoV2!6z}{2S^l$VoY5amvXL>mjSfJXk$$ehm|*Yse#*%BIVfEt%n^51!MR}4 z-QW}E)$dK`X7FM*g>(SvhV+XWZbo9#?T+4hP9hfg<2%&Lzw$!e;uzCg$STTx9q@NfkGOpOFu3_Dj+s+B++U!`59}RfOBGTuR3w+e)CX zMShnvv2=Ubb=o8QQ`>kb87i`NyY+dyb9})OmjAfl54S#W{{v9Prz+}5=NQc|$S!vzl`+@gJ;px)pAG5~6X7rGL|o_buyY8s;s6XdR5m&9Da zTTdRP!Y&gzAgS@m*|I?61*yAB1e--QWDu z6|Ht2j}qH$YjM=$0c19N93TZ~%)3knWPdUUWe6P?^*BK(*AiMRK=hpPc_e(Bch)Lh zDY&e#O3?RU#WNI#3k1FySC8}jwX6}NTp7F%*^-|j`AZaU2GH=l&OPFfEGSNThoy6c z?vPjy^532%E8a3h9dE0oZdJBN@4xG4e~U*2jx9QBKfI2rd9su)IQB@r^2?Gj1M+iZ zdt)GUzQhxWpdOKcTXxzCm*ACKFVRg>I|~p5bOuN7D>Y7brhgxhzQR&^(|~(OA8V(hd#7EerSa*S7$WDshKLFL_FvO>q>dTQCQs)ib*=v?umCXs$FF?)^1H z^ZKkFX}5j|Y#FhHLX7@r2E~bd4gRDYJ_Q#(YWc9Go?ju-BPD%L*{;tSMWLw#eV;&| zvgl;OA zu|O2nvn$eYrCx*?2u;+m3&0uqvsL5%m05rM+;1J#@s#>$db^OM#CR5hC8cZ>YqOdo zE7SC@%w6p*9}Un(tdpwo=WNMYsXXI>X@rRJkpJm#AYhJFEXJ`_;kW`D)V5X}&zQpe zRA!F03@rcg>LpaVB}S^}BG!*I?iX&ms1ev)>Kt2PTgWq7G&fOD<(#X z4%_LDjN~r4%O7u=dF8EK>QR3^?!kc;yt(fn2ET=e(q{dMKwrnWB-?53Ar}t}Ezs^{q z1HlvcUKI_bASCVeM)D|`fIU)G>p2Q#$*f|PX|T|@zCJSG$UlU`q?j0{P%z}B5>nHe zkIL%p|1pCi8ZZjd&M1|atr?ang?@Bh3U8xPFyBIBTLLU;hJQaKo4H$B)|LFUS`{U# z9XCrG%do#NAb3CdQ=OHnY=WOe&fdM@O_OdnO#miGctxDvXEe2PaICrWf*f5s0ex=uuc{S#*d?)~1P?IBEH%|69L9owrM#@%AHe88BdYdS89MzWBJ82d%& z*glscg%Yc;3+*Z~y@5C`9Oy4Jpjyvj{e$U3QUv0UYM!ghX{u3ufV#!- zRV4G%Zc!c5r?f~R92)$?hI!&&R2s+H;ye1-B?C|<+A?w>6)FoEnK}k@%g(~AuEJx} z>9aov(B|a_dennswEIh)gk%1|L*|=|IyXH|kFW&dQ~2WF z9^tmVg@&*&&iv};&%vC52|92lz*X#G=%wm67C8=pN4Rn|zkNxn|F^A2|Mk*>%9Xvf zwH6T%whMW|02vXMv2B&MkhnOb5ceMS;Tv^vYGJunemtYx_w@pWjdK)M!s)fTgyuSa zo`SM4RM%BzsQK?fY%nuiD8OR8pupe%oP#ic1yWnueiP!{_uRWDAkwjMJAbCnskm|& zFn5H7s4q%Iz~7-zcaWrL9lE3@l=ZwDe+K^7?3S)~2 z;bq6C4?P0OwCPSAy+SRsAXVnkE<>Ev>b&(VvH9sH3yoawJZn5r_0c@w*kA}idFIRr zx`t#6?T3`|%-%kpr>TctSN^_P+SrVzvk1(y?Hx2JSD6lKScDELr!&`gYqL zZs))?-zg{AQ`goGYRFqKUXZ_lk%|G+fMp;SasDn013;*NK?6u7b-w>TRhMJn0@Z^| zOU*Iqh{zw;)V?EU*ElEB6ohbIB)~bS(7I2lg?P#wL-9|kumGjIgU4Sk-K_ADoMKo& zL7kErn4Q<8!#73xb#M;TgXiXCP(J{k61m+CjTBKk;6OH0Kur~K^g`TbQ3kV29pw$$ z?3og?Y32FEIO)#m|57stI`D2^QSv&<<*RmdEru_A8HM;Crg~3t$dRY4h?-2Js(zPj z<@*G@Th>C2=KaYl5Q}jS5R)qLcGx~&pOd53bkBtnL5@o2g+oB9x}2ef5JB(fJGddM z>&%wXUK=P?d^n@exG==5>Bd_^R$nIlZ_*p&8X#yRKBa9V4jVIh>NPxhl-IK5)uKbO zeG{2=G%f*qC6$;J#p5x@`NW#Z2>BMoqMlCPtXKgSZPmd0be}}kgo7#k z_|hr8o&?TR2sojnv(SI!E(~1?6+4rXIG&-Wy+a?chTIH1zU1&J-lUt7Lw(l2Dtje0W~+Gpdx z8>8N^sAunQV~^Q~Ik=qF$H=O_a8Eri$+d;Q34WN4NSPOI0bi=X@84Q?+4+C@E>0%# z81s`INgyfAj4>$Z)5X;J33_DGT1Lm`NDAFM{U_P>X#lR;!M)o6Nje*;V7_ z%MJc=0#Y-iip?)>2HT;(FhzOY&1 z!Ss490Zm*5Q;Y!uJ0%!cb@1XbM|qq|eJ-+ShRn}po_;sed1IEW5N8WYedI3^JWj$> zuZ9D#3vpn>)8I2^vsp?*;vAjwJ@*|-6^5d8gRB2t|@N|Tl zzKvh3RhODDUH1Jys?LHdjy77>xVr=b!JXhP!8N$M6Wk@ZLvVL@cL@;O-QC^YA^2(X zox9dO|6r!4yXW1tpQ_THbRmkTCqf;VR<-M~A{e@mwD8o?q_C-=BgO_!G3~*&2b*-n ztKsu7_kW!~lFgwxV}V}W8ttknT~}I^~wH2}Ma%KPJns~(O^Pf;>vjO?!i$qh(b_7GWevZVk)PDY|6TmIE zj4u>Q$0)+Pk=W*kvE~^tjZYN|EVB49s7~!}MqNhQRePx=g#pZ%Ei^lP%%GBv2(ZNLFVo4f&J1s`$Iwhi+6= zU;SOyAKNPC#$@gj{YHmw@`Hhjj-TQFEwr+8O?)ug)_u0iu57TV3)>h@zDu%eSj{|( zdAO(bL-}quhKxfBs6gXc9QO!oCsaE6TQj|c`uB|t(XK4O;d`yd2DwKf?#M5RUl{c4 zW=S*Xf8eeG$H?_$3$v= zaM5VWJw`Y#^G*N0Wmqko?8*e)01?6yu2QqK#xSFxI zIH$gTxCS!)p`@AhY^0f;_FIkkAIcn8UlYxlApjgacGVh(4Ep$+Yb|24SF(GsU+bxQ-d;>_yM*?vLh9x)xuiAkPtD1_16} z&h4ET1Q-3L26!awMBHc}*s6!~L;oGaR_&$tUVFAB^t3I&fgbY1Ry=4LNw+%}ZoGsbE?;(OJ$1*vq8sAIA0XCe-t<=sP2CYR4!3p#l3U zE`l-hi7^`z|5TkFQDcCgQeHA6E*h?h94+7cu?q=l+FXMzJ-1Bm@}DmcS_qs2`yL9K zI|TWiqa>hX;(OwT1&=R~_YHWN$KyIqL9@n@DL1l7TAe45*h0cQD<;=PQsbhgUWvVw zc6jQlF9C)-JE&}<4Q~>hB#+nfV+boZi8~XM$HQ)kRzo5yg$HlFh&Bm3KK#H!@QtHZXd|m}5@pMbBm)R8phndSdx;>N}hWLcPF&GJCe$f!h;;f9UV@ALIf0 zf+&NFy23}OxEh7eRaqfl?wg7}(V2W99)z;^^`-JA@X+YP2H)elnC*u3@M{YWew``c zBqz_>9p#+h%CNj*)F>|9#_nyhSHI|_nMk`M&O8Fzt#Ak(IF$Xg=BwaVJAz`w#SYJj z9i(^k{9nhhTy~|~7jkJGVgMS6)@ind7+%T^biD==1)f9FZ4Q#&2^(&Rb&BfzKNUJ5 zq0;jM=fbNM8MJ+i9PYww-b>{I5q~YVrv+KVeL@gXwRG#!CTls)ub8(H0GZYRn%4=? zBx`Kpof(JPAD?}d$R7-8RudGu?vmE9MYo{fT%>j>7|w8n$^$t6lDV4?U!Gn8soH!% zVGMtVCIBYpF5U|J|IU4D!hCzUJCg;qDyi!ur;lvzkG3(fBa67YVMgwXD6W>(4Lupv zNAo?ul!S8N%ck1xF_OO8pa|PFaYoe1L^^nm;&g z`Cr}Yyu9pA*)nG!WP$N9n=)qG%N^8VW5@c!`JDHAQx(lkvl5G5Fw|AVNkp4m5R~u5 zxvse;i#Tvv1K}a-kTj&oNvOE{c;pdN_~|RlX6?;TsJ=#6Q1y$3OdSKAstAj=-PT=# zWNn0UPZdE_T*ta(5uuSUsIikR#XyZxd;;|nT3gtK0h?Nx5yhOSD5dOw^uzUG{ddU= zv`i-L4WXi&NrgO>BDr@SvtnuqWH1#`@NCJLVHC zDrc}DpAh)#?g2~H@u99rgkc}$7lE3@G)W_rQl~GRB z9tp;6ygN|y z)0SC}`WEk&^gJUb*NK}Y&e2;n_s~;vSS+JggWM(04V{{e0_M%^b)%$cRIr2cy` zpe%pJ*xOzYwJ%|`!CInq-&~9vFoIW{#-4x8P>hPQ(Q;_vV|4|!7 zv3$8b35K>yj-pCfKpJ_RTb#+Qp(XM)h)*(NgJ?Z&VVE0Xl-UmqrI@bEg^0|#sd#5H z93sZM(EaYNALX+HRgiUtJ;Q_upa#I3?OS+s=Hb8G_anffI-=DDqNO-^bq`N zRL=%<^jH09ch{#x)GG3rmfGyRwMUR}(KtVtlloe|d_`$z=e{r4sYoqS;}VL`w6dyc z{-#Sk#9rbSX&Ur`fZ!mLu$6WS$cJe@3XE@0DYc7x-r{A zkH}ZIM1bTk=v{7o^bMu^83-Ms_Mus3ZVk`;wGX0sRJt2^mugd&{r91#}Nlfgp&s z=fkNA;eUs$P?AACk?@2F29kvCVXD)XZAl;~-AX=$RUffEkW(LXqa~Y`wSJIG>QCDh zXm5EAgNTen1gx;`=6@S)s;Fpd6Rh+%H&@I%H+ZXGpx*F@n#fNKW}Fu?vCq^KC;V^^ zBkhXEN8mva^cBCU(lGskc`RkiUj&)Ba=^irR3(SLM|syarh&_GQ5Z51tRG^jln>|< zm-=%$6<}+Z`%K3SXXof)l;?{1&TeJOl!FW~6*cK>7a3VZj46Ftg@tRY1f8S2iC(zs z-hS8VrJfK81XuT0dV$Nl)5t$s_OGrMOo*R()LBW(=ODXxxgE!a?(-I()-)Q-X|E!1 z!+BIQj)W1kZRPIttZ0Xb6@5r_m3t3ye{fwnEbBR=0ZR$ezob2x6=e2eY94*P{8n@+ zy$So*Bz5r&CDe<#@;&KN)* za?7bnawfkDD8ngugMk_89!FZ&Z)#h8ov-U#LgaLFYvd$xIh0JddOuzcej25RExrPY z=?{Lg!j{j%mgg(IF8n>Z_`^_G0H}F$7rzX-cVo-V{5tZ*7|S*RwE*qnZ5);uNCA+w zdhy93V$RA;c=X`$$$1P%7&VzqdZcO3piP^=AGAS`C~G2UFtN4yFffg;11?sPRyVl~ znFJZFwLPT<4^`9`M4s8*#Pg?hv5E4ltFGms_ZEc(3sa{nMB(N8LD0*dYO`A78W^&X zNTtm6hEm5-3*vA84y5#8lA`FF25gI|OI;R@PERm| z2njb|q93|BOcx87Zk@#ILx6Z2rA+cMwW z9wTM%1xTq{!AxE&t%ALuiz9GcaDM+O^nTan#r6#wWZg#(p=%LQsp$$k z+tYNKjXjfAkaPSJRY9_epB(0XGF$25jWYhWV&PI!UcT&tqmHA4L^SOMhn}E3^_|e? z8=IQuu?%IQIpL6M8|i@@c`y6}mYDu{dD7z%V1BLS!)PcM=C*7~N~*r;u2GD*wz8Z> z^Ka&b4eat|`$d6<^UwYk608|y@f#KufH|&U;VUxJfB<7+{CFwPbORuuIJh@NZ*P7p zjD$)moVr>5#6;q5pWQri729$sEf%W3D6}TYSXQoiK48S+B7)C=@YS`lTW5+{rq7R` z#IvguW~OGPHoCJaJY2d;&2eZXeYalIL?i;t4=UWy2lifbGQmR1D@b~10xZL%%t%B? z*{Su^Q?D@`zrwME$O?m-Tx9R;d%D?VR|Y6bbIQ(Eb0OBqvZT4xHmq*1dLw&6xchE_ zX2jAwjDghlY|vQ;}b=~7gO0{?wa;hb*thflMV~kmBjGCjd^;l zUovj!oy2=22uM6(|C0p1)~3}Y$*z1pVKbm*BN}(NLa&FlK=g3c+eGR@tEf9OhBL3F zJ^v?*glI;df$LA!#hdCgi|FxllS9*(cYCtR^DlNfmZoUK4zr0=gBYq{LKXEZeL6md z=#LB`j_v?Gj8OE2-vQGoWoNE?pKjxO;~$E7M{l)y0~Oof86Xikv4q6vNE|Xp-s)%K z_hBGN2xU;G|Ar?g&n0Ey_3hEL==Rku!@+)|H|U{i2`d&9#0JsLi5_zpm3;_nVs^5> z`)!5L6;P=(k(R#d_OX1a6vXvQDK1?P5;y?$bL!>(h|1RwU42QVt^RkwlU=XJZZCfhB!Igf!b{Bx(;LC3+Pj{m2q{qI zRX-(rPSw2Dd3e~G=711n-RC<-^^SfeeQ;-(3YUjc-UqWQ; zD~)@9d@F>$_yxHS|40zekYyehX}gh{X?^{-xd!uZ%iww4*!)lQY*C+urTK3p*VkFB z#B|#Vshzl>=#+zA?~9Kd&0pp~1Lg;jqiWcpsBz#7@Y*~TT6wNX!Y1ENl)>jwugg+! z1S-naFaSSk1r5HPFKSOL1hGXy0xgy%_njwg3~tRotJdou~|yQ`GpptD!n zy5eCTs3&0N5J|6M*_*~0md$z>_!THsD_v9)OPL9E zD%)6{dE(uv1F*TvXuk}Dsz|-?$XZW;9274qSaREXSU^QQY08GE|g1JcHWAptJckN$T(T|vO!Zq%aT+djfE z##%CKOv;(Xo3_KV8!7x!2b0|AvUG9kF+N!Dl(2{4H|OK|iKY&+628Av`2jtzi@pjd zjt(lC6p^Szt+a^GzAVu$L^WsYV*)1HA$5v|#8n^*FBVP>sIp@r=?$PL6OI2l2oLPA zzSWQQO1XzDK|7b26L+NQYbuOQ5^^SF-JDQU#Jm1=AyR4^U-ieVa*(*nzwsyJ-1qPz zohKhZ_!J5YyvwM`ff*3M-Zcb&<|ch;^GaBN#iwla2xX43Wu2*zyC%I2P^o3vacQgF zGY&jRoBxj( zD%&}E-S#d5n_$4kmuHUl;b1WuAm0}or5G5=PB+{;HfW#oSq@quZL1_-oK>vqawX}+3HqNFeV-*gL=^54 zMRu^@T=ox2(?|R@iOWYVWv0Nr8XT>%NX7xQYI*dYMDIj};EL9m6YDXoIxJMZcVR}< z1KW=Wc6e6Bhmm~2?8(m_8bcbyu7Z`420TYM#j0&JYDE;ILb z0GguQ@zo^-7&{jFcdM1rZBK|au7PvBz&x+d^v|SFn z>r>g60jLMjt7|J=rbAFmi*VzfV}l~e8l$x%^JWgdEC5-0yu$y zbqLb?5)d0jH9m;4mvgj?MoW z@yi4RHDS$;y5dk5Y58n#)fElr3NL3PH}Y>I?}AQffHWEcJ>d}k$a6GKrf0gm6M21n zO8##1`Svb$U;*50DilWwWZ%OBdbK(f8if%8+|34T~YLG6=-t@ zLfaf_4q6VXkpBLcdiWV=ga5sGFT{=#$)l^dc=F6)uC>gkv8oYbdh{9Nak+){eEOERRlmpP|~j zg2m}sgoJcIcJ}81aOf}HBV&~MeeD6*WKTX-4?buE0+$hcTT^&;_F=+@#tH`oC4whl zBZ4=(+XxTwJ|onx<1Vmqv-0SaG9X+=fSB&Fw>17>=~{F?l9O*G033=BWotbs7U_98 zG+NWY&9qf8Y(AdNKmG}}d3Jhm6>Q)=jR+rRyYKjkI7=bf_t>F&L^F}Nk_*y_a3g;p z$O7d8urE4U$UXf(=zy3V5U&Kjj#GU`+v?xAat<|8P^USdbtSDa^ydND0`5w^5_K8{ z4k-hVLOb~Ci#@=+%tNOUBsnnTB_)s(CY0dEHsD2(lUooKq9jBVUs4S9#7On^=dD`` zFPHOC|6@$=b1tz-X8H8Max*MQ=%Q^Xirl5n2f_;_54s_<$Z+h_p5Zs$N}Vt>vH8?B@mPQvziLNT(B4W& zy=JI2Zc;o1@>@~H2l&>WUdynz7OwQ&}P>k^X&Eu)*UY%?CGJE)4l4B6KP{U7c2=OTcDM z5SiL61DdJP0Qh?f9IeVdn?0kU#dM&RZBOl&-Ur{2K=gYgracIT%cy#}Hk;S-J(6BDf(9f41=p|jw{8hW z4l8ab>=3{*9tAyg{Ud~l0f4FzMR^jTs-_cB_371p&K}Cy~`3RQU1;Vzcm`(%kvqs!{37(I7TthcQEu*=XMW? zc@tH;OzY_Z9?=sf7%l#9HsSs?WuuoQP$;aysOUMt%XdXG5poX^nhqB7((W& z65cGeDnSCwG7UDn`%f%_d+ac;PTeIc=&Pvp5cmr7?g&Z&UZ>_Ez(Vm-NHtWZucE`3 zr8f`U+*qUdON^_K`(s@qYGQp;~Ank**s%@fqLwT{sXQB6v zsFxeQ6_vr)^?!NasmTZrs=r~TY)wU$ySP4+YgksA{(JzeZ=kwF_tPhsp0(!RJ@@0W zF6u8pQ&*h)f8kR3L<2bd`h$V!NY6}X5Q~UDg4{8npqzXMv%l-`L2kwP5kOo8l(;5P z)W0g$sF=7k zfH}&=T_9-rEh-0lBnN`)Y-$MXSP*=fsP}P&`~GkuE*tpDk%Iwwp~7@qFd;4LHwRS^ z-NC^L4cFPUi5WSh^8mE_lOdcN3=08>+X&x+``OE{F0j5D^)OPL*LD;6k<6$&{oMCi zdU56VOw~uICfB9##Rm*VIL-_+>(&No?%dz1joo-&v2wmq`o5|I^6-!hqJ`HA{90k* z-87oE(2nw&OV=6MEd;m1ahlD0?pvZH_q^QW`@w9`g!3XZrHGIMhHoF4?Jg+Aqo;($ zvNRu`*qANWRot;SDs&O!u5YA(>=InRH!u#$OPJ&lsfU*0K>gPAM3+K3EQCh!x;Q$4 znyPrw^q2CqkQeX^NzJ3T82~FDeSTB^B`|kGOMUVVBZx(thIK$3LR|QB=H6_rFj!`I z8b`Ask9Uz-eUWndEVDq-?~|pvYg0YgV1Wtp?eBLoOH(jJf9B2UT!96}1zQLhhzRtT zP!UR&@lS{9FV@oKiu5uiR2qvh!J0g!4T6H%Y|8hhNb9%7O0)wfcU@gZ zQ~?#o>hW)f0TWH_22d!j)NNmUU~;?*SjYv7oirInLvsXGN{#Br5J10|J^d6JeBfbA zx8xd?p&|KQ(g>+(BfXgfeOY*6LoH~W#29P?y4r{x(yqL5$ z98hngJs*webw4bM241ruk;Lz|k--G@OeJnB_tbpbHY?D~PX}V!53%%XJwIDM8O|qh zY`_#Y^e2<4ciGVDh&)$F_OY4})Ucc=YdI&u$;$$;Y_( zwwHti!;bMkT?uJy=mqHji*Sgc41b~M)$j&XQpGXKP^HT3PM>lAteHa{W*;4#-wymP z5Pi-#Z-3_!D`S?CfA2V1Oip)E$b}&_EDsXolt#RS)BQ$ugUNNaVwn^*Lx+xFV}eaH zHB>AV;OnHrmC>ePY^p5IohQ#E=*m}A92QC^Qyu{s@|(vQK*p?9_}Vuor+Va(uuji5 z4%zl?&KVqVpwFXPv=N9i6jW@ZgF?i7248|#PXueMNRAE!Ltkra;VS8IcgAA*b)u78 z+V@4Fh33;9@=B@gKX*AH%o|&b-BPryzo$Ze!>$NmE3Y5#8`>tzt0ltiU}trTUvMzf z*yS_%-Wuv%_+VF$c?6nWQd~}>K3%}`n?Kvy9LuNELW@`t*j!kn-1eBO#c_;B{L4I6 zPa`zOn0MkK@>9`xIw_)|=znEv_a6ke zy41%jFGldAJ@JYJrEZCem)~BY2d>Se-fwH{bq%}*5>@=r&n?k!)U#o{2IZCrlRDxr zfBBN2B1xCq%2Vz2F;GqHRlL6%=0@YXBP(on2P0BoV_@kcFPZ4xKP7yaK#@Xc?m?Eb zU5pfhl5V!$=Fay#W`r;e()I%Dp!58M*v1~yDN@@nhgVp)z2(}qB@-7mDyo=%4sB(6 z9cS-GXPDW`ve!4OdXEj7BzpBaeyhpo>xiNFk;DN`_(dQlWBZXT5lGywx=-)}n9x3> z<=htr!gu+d9kd37i8syDo=p5TDcvqj~XR899V$?j$H7EahOqB(G`~8kqks$h(L4? z$X?v2ePPt$s!DaWK<~K%=>@naNm@^AzC84L1VWWx?JLv^Zz8iy@psBo36_cgsH-4H z@SJSLCVBmyM^<~sItvcmfb1tZBaO~D$L@bLpU&ds{ZMUFIL2^ z;nCYh0b?r8TPG#V(m$VVl^BHZhtKxy-z6qD3%_MQ8BRx{pKobV9$`O`DQj72SAQq* z3a^i`0Bkopy%Y0E=K1jIK-wvJ){8H`X)U>?##-^a%;fvAle_qp(dXj!k{L%4$DqKN zK^*0a37d|~_Y$eIv-{I5fhea7pol@yDBO_mGPhs*!$`XMIJdgZgu^n3eQ?0CD(rOypBpHuzOd3qH&j zlM-*Cn9N}SBA+7#mf+__{G%YHEtqPmcWkMw;8mPx^JlBa=&^}AC=3d2IbvlZCelt4JOlEk@dnwC%j3=w=>OUznaD2$J-=!ZNZ z1sFda?yrlMf&)s9~ zFCMCjahiifG7%q$jSqLAX}AyEqdt3g1TKA@2xW#MD`;aLHO7slIUzd0_KC;Bq&8Et z)HI`E0K1upirR1Z6$MeWnRQu^ev%YfxBZM zZOL!{(dOWeq=S%@Fa&8JAwm!81>)jk8t8$d1a$k{Q&adyRYD2jI;Got+ zIfAs^mzXyxdsIP|Umls`?-Xk}xDOk&JoBU`X_=G`YLDO?gbr$~k)}`}B_|WOGazx) zW~qS#t2|nb$j{BDaM~F6LZjLvJ;a|rK0bO_DWwd#j|3zW5UbG{+9XO-mJG5Kf!F}$ zY-@b3x+W~2Z{GF|f%yUC*enwiJ0h9`2w0vN6RuF2N=vUDV>={=wF9~r&OlBBl2%Zl zum42^b42@m=Rql#IYxnH3fo{pJ7vzhu$jyHeGJ+fdSgOFFV#fPoVKUcH{#k5dXR#K zLcLNC@&;{$oNW*m`OPQl)HZHlA)`W%C`JySkM!ghIpk!q{LNewC!sL^=`+0a<>q-~ zChfR&>>O9yN_qx;2EARwYZ;PYyt8%9@$TuypMQ}@5y&JHHWH+ofL{_7L5X%2L7{qi zytA7Lum%JobmquYB6XReRTqaR^f%&sZW!r$h=vAqRo{9}wNF%P^?Ld_u?#Ru5scZO zGyq^jUi6utUfMNo6?I`(kUUVrm@wwI0;4XEzf*dD`-vc%T1#1dG!W>8MvBoU1su2p z1hGG}T!y(>Y-{mnIsr2ZE#wm{9J*Zg9nv)C_`x@w-YDtqF1mMrxEjA7LFd_!xKlb9jGFzf{j)Bsg_SgIcWB#W8f zph^RAKMA{{10YFfucGmfbRz^Atc=}P)A&TqoqfRkN&>jN6RV$p1#Q9F#%G_1t zcPv#nwp-nekII#%CC*yCNEV5yAG^ji5y1dAr&g$00Fns(hd1tUvXk@hZvV?^?#0lA zE}0!elxoQ*d|>Z=z@ckKsmeMjm&EZAZa1&&R64}7G6RRI({GkpvX!lF`*-F5r%PXT zurAam#Uc82eEi_lB(|zHJ-6;2B}e<3@Y2kjE0kr(e^IRKEy`4rM-YoBnxVAtCSHn; ziLe2KBA8Tg96%VB(t!DA<;x*q`>xKh?XEm7zC>@9NLMc_aOJheUi-6E4{kVIw&)GAvUyhao zX#i_200=F8E*9SIu-!NA;wa^OGa2h5>OaRpV06jw!RY!(j+ z{QcDH9~FV2tSkG>mjdCyh|=!>$)qW99cT5dBc@OnneSCE4hl}<8P0+5TFn?ks2R}7 zk5a6scY~d-Y|dNXXdnPwd8x6+iE-js6>c5gHI$nt*OXVwXuiW1dBCLz*FD$cr^HO; zBi}f+mHN$3tUPYsP9H!QWY%{XA64pz4O+4p3VoG59GBpXePl1`K2)>6kzXlSMfwIO zbYh`a!d|^(lfnX81#2AIJ|Asro7LXXj<81wp+9oE$j`lA>ij?UU$JQ{v6EA{C? z$?GR00(8R8m@4X~Tf}nU0BI&1kt+9*vG;<7J9%kHnWU69(-r>|zNAIDzIBPJ4_1tMsy)+6#p^segvL>)c(39brL7@LZr8&f|0RNc#$l zhZc=sIGc}zL{vXsZ3R<9wiKWpWp+ExbvVy?^~9+DgcycUsM+wbz?Lsz9GaQi_xTy< z^k$FWI3msU(cZk`Bm@EAAuH!y+$LDZa6Zk9cJ93a`>s`DIc1>;LWGKnh|EMlp^S7# z(JhvXq#Mu-9Ok0_j%^sI^4Y0d)-)%Bp_6);ZWAY;$JSwaQ-;qTua6`WTAMtA zS{luHq^j3IMV)N}wHRwpj-Y&*vYF@>XeGGl%m^59-ZXa1&4USiJv@xTeGzgjl#^1O zwwKCFRvMP*`@d3W8(U`m_nCX156~<=t|bSyY9Cm3GsD$l{abe1X*AkQZm(UG^|`C6 zKKfGXb2n8j9D;gdRxN~3qP7;$T~6P%oPxg(vUy%W=r&>&OM^w>DoA_}9+1oE^dD+0 z-V$k5`vDho;4FD9mvxB=^)EK)1j0O{wI{#)_XzRAqoTx!lvPM4NH}1x3PER$-jNZ4 zUA$Mm%ILCY2QMzs7nJpPkEn{g)B;5H#7ho1LAG>4EsVC0GORAX07Q-M9dv8h_f`0Z zGE(Q3Q(=qnm+&Sa1UX6Q!4!J6Y8sDg%UN%<3b$d8`^G|hf5E$#)0Jio+pygyF~psS zkx*jv08+=$fF4jf0%Dk0o&GRU>5{_%i{0|7oIewh4T99u`GeP(3W;Yr^!E)T zW?M8T@eV9y16bE8!^AU?eQv7W#Kk8Z12R5HOc$DJ< z!QMh#2&}6ItW5|c+B}(9!tMz*K~AWdVBwz1JopR@nJ?-6L)Gmcw{&EW{DrcPMThpk~W0~NIyViVTwM_1fj^v z39U#P_N$Zcx;MANIed978MiNyTXC)sx2+tTG}HQUpY&;0Pr znM_*RNvZBn*dl~>k-DJkUsuPs8&jD6#>)j2%B5Xcy-iZ$^V{g0yp8rPiUBR!Q ztpJ5>4rCIyYT$U|1Ea3K77*eSA_O>d=5}MO&BHIt!KxQnCvj<><={^D_0NA^ICdmLbGydu_2m9RCQ$49uj?vG!3QI{fha<4m`Jc2SlGiba$LBqt|) zs{YbTjWbg|vp13Ng@=3T1Hgmm94-ZuGMu1e#fp?BdbSRm2kEKyIMw&Wx`{_a1RdKL zyy9cDuYYNORZ^(}{RtJ+*B#!sK9-B*$7h^7$I&|` zKzWNH$7J2k$ipE-<=Nnsb4z>Oj%MA?3W|yR-=O~F)fXPbmmAH?u^16bB5GbX9S>b{ z;Cv<5`qy9}C=rWb6W{epX!F_=NhTC4i;C=)zdlK3M22%D+hW7bOd>{PoH}Pw?s*TO zZ;q)-Z)(if_kKaJOl?7|+5gKD5+W4$7NSKdm*S!&e|dkSKAU|Hwy~L6&o6<^1+k79L2DsYN^g4ZXEr9IweU~A!(r$W~|xpFd~PX zC2Z}LU=-&q1^_wqi?84G!T%0Sm_faRrJw*Y$jRzQ8`TCT`V44!{5lW`_8Oy@9Hr^r zDn#lS!n{Ds3XL~RBw4+~t=LaA{`_%RtBTbkYq8;^ zF{Q7tFi>)kCpbw@FA{Fw-$)JSW-%TafSsOVXR#^@Z#!s9g|s~6Jt&ac-f)t?Jpi*3 zvR)0`E7f=`hrUSeC%!Uc?jwVhvYD;@gXb&6b6ghy&rUtQ5avRaYPmS90DXqR?HF*D zIoL%W)nav4cRm_w#HX9=&xRnHJKDnR4DqLNz8sE?f}m>2K!jK8A>ou;^A8l2vtK_n zR(J8Q%y@u}5FAFh-KXQ=ZlMH5#9~~NpxX;I#t4{5xj8VLrmbQi!1GEnePRJVmvKDG zs@ZSG^P9v5x#(4f86g1Hnyk11 zi1@I)i6GyTSyB*J{Q~%TNb>LV01sZ`nZ;hvb7}=%Vt4)y@6jk`P-{$Z-`|gDLy`WX zT&zpp{^c=VBp`9sM4*tN>2Ke8s0F7a`{}BRay}o1jp52Z&t+$ zofAlJbPIa8e(z|bx3I*@lT#$GeB?t6- zix&FL1_iS~41~RiL4hVJ-e+wU1MY8~kK^|lF0T42ZqPm^bz})b>=qURyz9?OUgSK3 z2d4bIMeKu(jgPc>?J|-Vy^1u}E0zgusbA}AT*7{J>9Hj(EPn@gihdP>g@Bvb7}6Rt zZEtAiZ0ZU2m`Q{cB0LEyQ0n9=Tq3$NP+Pa1tJlXbO3s&`*5m!+Qa? zoL{;ETU7ZqjSN%C^xvCo-$1L zb;&(9I~|UgD$~n-%>%s>Dyq==)V))WOgoYaWtcE)jvYb-MAkdm8$6TfOipkKW*OrH zt(I#y`FywxZq8su<){w%L&AUFO_f)|aRk%tFs+8e_fdoz2m~F5(YxIZGwA^XC-i6Y zaDRkn9O#hOLMQFR4mV0|W48q;BlOpJJ>=2WV)Z_9>Thk!QEy-97eXuR^Mq9P(8rE` z>OKlvT!-KkNLOEhE?yI2TC@@bNb?+Slje6etrXU$?qfj_!%q4KhD#b2Tt|c&1&0^x zKQx-6>Yire+JE9;3-R9B3orWtmvNiHui_Y$twFWKgLp%>Gbf2Kn}XvOgEH*)eV0ag zRM%PdZ(xXM?1b#^=el+UE~4D95{23cIb{haG0DN`2f>7_@5o2LaOy|(ZR$t0<$~Yl z;C~fco;yo&#<73TC&wyCD{t97YWl2?sZ=1-n{)_wLpzkGZ5?{@HdsGykU90d8za-_ z(z4#q>BYnT#O%%Bc2h)|EXcVRf8jnR<`Ne-3gWnT${X<&KK!W#Jm$-xfPbVCBi@cQ zS%t~hD^C{d3n<>Bje(Ir#|X#zoTWLwv_Bb^cd|dh2`6A%5Mdf0v>$IZ) z9}-MRR_<4JXbuXMq!nFIcsuVGM?L-|I}v&F?yl%?@yk-qlgRkm%AV;uoq3^v^8l)! zQ`0ik)_7HWMkqfRzjl@5jXSkQ)9olI@Hh^-b`4MD2O;qwIv(ByBI%ZUkAT=sZXcHQ zfrYW`L>N>equS)X;5rK$!V-RJDMwaM6}8Zjt~V}V(R-H@4eEw>oTYydCOEZM)_P#= zTk#CVN=v)M2V+IK^*LjcxtflP#;A%SWy3OG)N+#TF_`5ig>;+DK4M|eZw?j~EG~3? zHSch%e}&=xUf6{NZGbNFX=gKRy0w;jxzESl(@{%P!f(@DDVxb%>D5#z94FJIq^+ z0i^|L%x@)UZUI#t%51ZUPuM0hS<#r5%g~MskUV7R3vG zmmm3<_k7^35)*!eDjN$n5A6*e6Z8|3Sbj?VFTwyv#)bxoYXv8<5ynnIF}#T+wgI!> z9@XySa$=8JpK>At(R;I`dg1c?z-n4gjwz24n8U%J8ZIXL)Z`P!2u~vu^@uLWzVgM9 z)68ZUinYnlU{z-uskx{?6n2mg(;>C?xn&uR*o1JBB<8_gh0sqT626eQHha)iK88ZK zqDt0n9;(PFX(7-m$j3u4v>Ht$IKDF{t0$Y>%+nUkj9RB8z_)4R zjfRDKkcI3Ybo{jt+@m@C>wP)okqaPQrQ8y(4VqTPCTen=5)_*(hjpzf(sN4z|cE)j_F@94Cav6q!$@^A2C67ui*wKn52 zNvaETo4o~Jya^lC{f31Co2$TIkUMUg*NR*gD~)A%Q~JX}-}!gMbFewsMBubne!nGM z;SIU_{CM0%uo@K}(L_l%J&{5p_1;ejx`?|g&d5(+E$|ItG&H})phGw^&JS;iYrEJe z0pFEBt4x04;9h0Inc;v|sDl^&31_Dz^~(c+?3VZm!h>I(v!K;exAl8?)#I?$2Jg_( zP{+FkaIFt5uCeEK`5^BxmK34CKgw#;n=bFjr~iNw#2Re=8l*Q&m_g@3_3;L-b3qU6 zSE?HF4^}s~y=d2$|IM5mD|JpDRx*dzI%imwhO!tb#SXpAf2PTP$05ffui0!4BuLdN zG4rX2%YB#aG`HZmg4sNo>f_+&`37%(wG{v}WS$$8{E2BDxrm-PQwcQ(jY_h~ za?}l9%yYM5NqaXNMTS>iq@#5|r*1Q;OmQ_V`zB0QAFj|=9^veJ=)q+<>l0oIuerAg zqc^Jk(uG^rg_4y`KP5F zE{$2_u%HG>EXBNWUT~qhDE+j!v zwlZF~`%Ar04k3smgHu?>iEbCc(MXy2nY*$%QL;Tp7ILFHcO3Q*r0guQ8S*!s+>o(% zom%2zC5|VApSJ3(d}j>tUAD%2pSKVE2qE4#&~d)HWvdv1+#VW~rk~CzCB&^w{jwKC z@a^9(j9N@jb3alWy+$@kG=?U4m2+MRaGA0Dl0|27SbGy4GDsP`KJal#?X{hJe3nhB zthu<0+OR@T@Q+EnY}hyH7X@LVUG% zk4uHe(=i-LM;0sr$(jd~U{Cr(;rl7`M{0tR^T>c24k~+ zYgVUmBM193|3I^ch~g*HaGf=4m$Hx{67dR*;{gJn!S|}P#fB1!H{ek^CY_(wSw`OA z8N#?F5xW~BW*rgAc~R+PuNKVTu^$OQ0|n6$ZT(K|T>nIF9x*#SOt8Nt@A9nwE)zL) z)nIozaCPZn0e3%?*$MVr$zo6&z3q&=8l#b(Vd$_OX5%KO@>tftpM$l{HL1BetTHP} zsQdNBSqlB%5R#CQL^`1NbSDzI*>SM(oslQx7ycf8`2)tQ1PqI<-VKGIpnk6OnQP^0 z&m$grdIcLJr(h%$#AB8MrqR22>J(5n;7Q3lmQFs|p0$7B2emX69%+>dz}g7NfN756(~ggm}EgDJP=wbkm$y zezhvt$8{$FMX0G@;~2U)=A{uNOpkIfl5!KaRUQX=pw~&0kXSq>qql8dA58Jm7()XC zq$cpkRc|%R76}U#8+-~Ecm~Wt>&?|PGVHdxDeP9>^Fki?kJA88lXm7Cb=pMyQ0rDp z2f4ya^;GM+^^A)7f^$FUZe!H#=hWxcG=vn)iLV984({fp8ZTou1myMtFBb7sKvdUM z#Itk8;YhnN-uvo&DR5n`Irq+R_F$XnCEf>St3EZu!r$bSXseTob^sDghKx$o<07-7 zmFoaj9roc)EYkKQm5I?ktK12g1R1pZWK7{o=HiPXyE*#;aMk)OfhY=sjbo)rkdoaoO=&L6*$O`>B0f4( z5j3YEhayb14P{m3UTm}dXQ&~bWly9kECfckGUL#uO*6IZhhY11j!;NPJQ~RW?6$nx zt}j|FIZ8*+f2;65CK!ir$3UOJZPUErIJQqO$llzfpUVfUSo0N0IdM>75T>FA+7v&i4wapu@D4JANjMUC@HUPb-i78#3g4C%4d4Ax5l z+kKf0$~rpiF9O!)wZWVOg^sF}XR+V(Y|k#obUJbEyEfSG85AW#MJ@PXqL?Z(Rd^3` zr|ngkV}DwS9Fn2TYOn-pot9nuU+ zj4#P0L~xh*BB@KCH6-!FEDmHJIxxy1O9N7)cpHJoC>KN|68EmN<4R8X2nhu5yFP>OPESNT7C zQ5p|-sez>!w!|5VB#B99CfLISQTwSh0fk86YqixlpDPlf3`ib}St*5(G_I*giCTv3 z>U57wdk^+aj~xcpEms0_8%2pS!#`rX|GL|4QRLaKW85P&bV53tCM7B0Nq8nn6`EIGk~&(CMYc z96dG8^FsV}~gop7aI)g&K0wJymPIk?Dz&LFFTk+!;CzAqwhFVa6O&(tlqQnJS9p(?O^`52%)z{znQzv+wfct3<65!5ab#LZOZRf+r8Flt^ zz8>El-AO0$!C5)f>MU!`iDnb5Q)7rB=rNuO>lsS18jyC`*9o-STTy% zQ4}%RiW;ddBtKfvvneJpmzH^HkT1v&m>KHypdHWD&=%F~Yoe6J8U#(>wM$gw5PD(# zaoJSFG)J6zr32`qiud%P63>QetN|@-q^i#$bP(|R6DLZSgYD$Ino0-kcIfeE!O*|Q zW)_=WxQLj(L*kBH8!!iYO1Ub#^w{9py_{dvEH=g-z7#hXaJxr~wGjL zNhg3iG_=~`Ay)gI!EUq94V@Db;eP-EE`4t)_nqRKG;l;7U-FRXxT(BXe9;^Ac#q+8 z$#lll7e4LTINh;6lyEBJz9`!&tzu}8f@j1wuo=gJUiAo}PmGLA{DbZSTHx`fL*%>M zBE!;#Aj(h0hSFY+l0>@65ek;z5KPdVRkmD{rX|10kx8!m9PcrAV=y_9L-T4b_*!NH zB09wV92Qc%%XzivY$F|q&*_M*ks%2$e6?PD#d0VlypW9tk_IO!KPiC_)_g>Vhf#1w z0E6K<4QjXMGQFlwAAD2~dGUigI}sk7nqp;$C1o zv8;m*`#3fCsHg-pwwcc@>-?IUhDj!-K?eJ5eyI|rclh6&jAyKB)*!}FSJEL^?BlQp z;3^SP*f@M{DQ8wHCE_uFsPTU8i<9_D$N>ta&@{!E{|MT%C?Jg zLVsRFymI??bHH4gCqbVv;8FMCxMzmyF)-xIP7YCuFbZ2uGUjC#WMz6ZdG3Q~C;@12uP zCu-nM*4Af3mJDnYKi$6!OZ}~cTA!f^ot5x>`x2l6h7mGhyS%BKVZ6tag>cazVOmId z{!@$@(8vVmD60KbRAV6-1z>=O>^eZjc;$*vlS_YianzDR;nmMKQOp{Bya+?!sVu zyW{1*PF;#|rjN^Uu!Ruv8IZH@KhjPa&>5F#>v5zh?>~Y~^)^?K2&Zn=|>W;r;}+9(wIqbXuWgZLLw?xedKpzu;UwZ7nS60 z#iNW5d3#End}eoV+JtE>-+ROVfELjwKeLzZt>2*FIG+2lIIU904eYdc3wUeFq2llj zBeW$cY6mYYpUkIi8$#Lx9~U+4DR}Wkb*k344 z4Zm;^fm@4;RDeGCI+mO~ag!z<+muc>(sX|7hu;em_2~pcg+$ z0wISg@1|YyVj33NpBJR8Q-THTUP|Qx4VAe@4b~Z!w0%Uw8JWO6j3))X%J)gLfkG@z zUq0xO|FN8J!Dhic=H&46_^j4-2HZO$;12wbyT7Y;dl6LNik_;*LqHat7doDOqxv3R z^~6n?1GPvSKX@$2mlpi_Z1%ItLejoLhtXC)FLJnoaLQYOLqVF3dc1M6AYj&WyR*J6 z71Wk|?AXiA>#Ns&KzLPK?DTV857&=&|9Qcz#N?jUX7W&8b8fE9VyXXm=Tz3dG#fY(K9pnJ3GB`x`T)>)9Qy6EI*L-2I$+Ai}) z;~sqPd<8M8W8Pl^FHivVP|Q1uNn6(un2;T=xIepA1ng@`WJ1bhlg`0FH)X0HSZl5J zz27(Dk1&EbohibIUUWnm_l1ji#GdLeO9mNg%w~`)m#LMeS%KwfJ=!u3pYY!-_G*KP zFs&*AZ~>-l+q6V6F}|ASf}@uGbnmEqv9H#aw1uZZ{2*D3crUO*HsHcuG=iND)m_u+ zKmL_a1dh+W{(-x;*vQV>8AZw0CU4V6U*h#IHQeGaN$kmgH*fq{qgP)Hev%3MT7Zue z0{n-xVT_Y%S{sD@AE7EOZtlPa^GjU}mF#2kNvzsuu2rkc&)s_DvwkrgN@={tk58Nn zbq%7I!`bVF!|d`ikd~u)juBI4N<8gNn_pU0sAy?#z~5H!OB@lF6c44UvG2>oYmEm! zA^sdbGmp^;@{@!Frn)y$^Y9@T|8A4k8Fy5}qDg=(x-8uK&dNI4ZqR2pT&=d;y060* zVHoKzbYLB_O2g(!lyl3=o%Uhd+RiFHcOk>@5#!>r<#nx0(z>uJ1D3!bC+ZsM!zE&eiDNQc6YJN z@}Ud9;Ez$~YgzHjXU-xb2)$t{3*pG^(jmheP(^_PU&-*Fax?aqni|vu$hQGqSUAG< zFF}dm2F2@5jPXBZ(!#()=CngoI&)NrR3d*ruFy<7yx(NpCg*nQ zVV!sn!#D|xdsNd+S+L+me_6uwXXnffWB&m(l#F})_1L46;{0JaNF1T$cRY+dK3TTf zmfwKC1Tc~=<3G)ln2LfDP4DZ!@l803<^ffYH|FnG1TvKrcM_|TlK1*PLYEi6jftS* zbNHp9f^eoMRUB7mi51;vRYtEJNqB!&?$<>=`fvAl6$zzPa$+3)GvXLG9ir>Xb1(Ed z0@~@UQC$Nv;iB<(imcJc!LgnQI|qikIKNNci~vtsXz*|3=}QncER%2A{HPK)diF*_ zDGsdAANsjz5o}z$b)Rtpg1^fu)`ZKBOm9)n%;AD7Ik%!m6NYM- zQ6@I1@<@@bYxmoQ3FM~37~R){@3Vq^MAb?IV%zre4&TFu7((>^i#@I+qAZ%P3~aMJ zF?UmJ7_B+sB)nZM{^-0E{ZNrj_!F`vt{87XBU_Phzif2ud&(mi%GW(wPx4 zDABmjc0W2SHB`=IeyQUjOUd?X5BA@{CGbJNL0(ulT3Erx*3JId_}zADXtG|4{)7aQ z9lQDWNk)%#x}gAFW*L{bG?EN@QtVZC@(+^?G%Aw}#?=`Z9_D}1lDgE+3ecAsfxs>% zs|9IYOwSP|n%uus(;O<4u7^rOszren9+sowgnhm2KXVfa_jm9w0Uv?~1Ie<*c?Fb; z*YdPZN-hMx{>8b>?BQJy*MjBU zSJQpktMzPzpIE>`)?S*;Em}iGt$5DA;m7&iFJL@6*c|F#Asr6SIElKs#KhDIv>W6i zaBJ3*;)}oXi(RpOwJnwi6+cN{1$UX+yJl0XJ%>D>?AeCDVzfx*^}_> z8BmhbTTq+Cv$@pdcK5n}yd$&yCW+e`!!U5?X~wYH5hQ%@P>bfAqr~v{%skBlPf$uN zJ0mQu6+OsBi!6f1pstF_#HVnkL=UQX>gM5^!KYHZ(h-geOx(tpX*`B@G-L@MWJZ0F zLyB9)Bpc*;ldWt@QcR(4G8EceAnooHYba=F-T6h@;sI4m9_V|J6C(2Gu|qJk2z2Y_ z^>pRLp~O*c{ZW=B&oivtt(bwkUv`JZ8!QU9Gpma)5smO4D8SeULyx6K>G1#XRTzpY z?l|M_CNnJs{XP$sj&f;ND{I^==VBVQ3E}b^YLwgt)IKB&p5)XEmurC?J3mBs+2z6k zuNuHym4U!uy(%lO!2F3gp-Hlll|#Er4DG+Iw^l3;ogWi6N7)$m)`M(pgcgLt>Btlm zEus+WJtYBI#+K(l!9*xXemgiNh&t*g4VcDVViLM+tC{k6UN8dCxE}rG3VFqobxFME zjz!6atc_%<*dMxR7_YuO*HCCali!;*=8GBxhHGTuH8x1=8hQs5^y(QhRy8ND6eme0*l|zn8N1HYM-eSoFA@(7@yb<$W|#2k-PU-iNNPX- z{{o`mj6`so)cMtZYlotToZq!P>a!u?cIBgb#@St+9ba*j%R^$>G zYg)@AE2_31Vi@+18%~_2g{BQqL|o}V9T+cs(G(qdk{@L+%?`8^;m8?%e4_D){KGhZ ztWm4(I(We%1xc?l(!rlLW%%HykX-jJ8q}S{zR4=D@vaF6%f(Qu-kS!eT^Uo*6B1-` z_~gjdXT^r>6w>*cr}5uk^~UiF=b`VmIV?+FA7!TS*TTh-? zP8^4|Ujc@#A?Xq84iWI%92R~3vD2Xg$b&xLtbs51RZY~~9@`ttP$vZq)qDsK6ruCH zNGoU%zthW+l}Nck#ic@DGP-C_n#hoyTEZ+85AVQ_zzAoT(7W5~xm`~Kg05~T9x6DV zVi4v0D60tm%>T9gRJ$3EQoCXyBA3c2?9Y$~?>_`2FvUjFN>V$bv!jEOIns8=mU6Ky zw0Jit=4KLm)=GcZSa?xEMl5+D1|h~uyg5PzeP>)Ea^*`c`*JZkXyW4~BEYUPEWJ%| zi+7};;Y(D1Xs8R7zcUA9ul-+o+-g2re`D1?MFBs6-k&gwMY;~uk4)#d3&|xMqq;V$ zR}kM~n$%km^$x@;-hLuBP zn)XMH$WqL=6w3{+etSyOGN^;0SBd%b;j!O6V37E-`{*|MxN@<4pQ8|FKC{<^xA?Y|By)a%2*B?Ze={{?9rS^9r993%e%rfugDl z7Yo$__U{#2>4+w6+A1Fjr&NCb9i5h&4>s!vbrY$$l}=Y0ddo#iM9sg5D~^$7!P@^d%eFDDT&Nub2R zsJe*^ek+=WA`zPOAO9&&4s4H|dPYmUbk#rQj&t!Qu7RmQW@BZ#)T1Q6;?-I+y9Ub^ zO4WOZ8}<|lprIzvA=i+mF)LA47xr+mtJmr`*Vf_S6QuGMO0+wr`{mJoU-}~JJ~<&~ zai9UXs+)Y^0Pw+r?e5yfQda}cgGajehE+mrm!ZaWEpKsJ%5)Ch1PsK$O;6gF-B*^k zAFmooKCwpKK3j|t&i~GR*5<(c?|z?55s>(ByI%afX1mA{nyl*f9G|r-6x8klM-}fuYpWpK|Kz@~F^Z>Yl zwH0ecZ4VZ!4d^xFUMpn=2rXLQryY{5U6z_~UOtFHl@hR%Se9tl+L?(w`Ivnq%b%t) zZ)(jq`PbXj0Nc14jK_BN;rs6~esq}pTd-}xhkj^aWjQy>`{UsneoMW=TGHd7Dhl=M z+6D3^EB*kj>+DC}iEZ9(D_$U5#e|0j<#=$j6i6R>5mYdNHL)(f*dm`5C7tho{wLBw z!0YejaMne1Nc7Zz7ki4Z{*=Qe+Cm-E87U?4Y4mhf_}wCKK7-#6_{u(ZLG|!U$2LNY zv9B&XSJd@M_1D|IF*akQKZaO1D%R=+=6`tyYP-v`k!vcCDvHoA@r?!1-B-mI5u)Vs zw`RCzNrGW0K#ppjg`TA5XXlRvdAb~zl3tZLlq zr%C7j<33@HF7(WYBGi=J^@_*GfR2%spH5f)x(bERaYL^N&OLR=BkZ^_!~z;078`4$ zakQ^<(RfNhyyB+8OLkK`W??$srsw>8_C=U$-Tt&tB_uo^#a-vn5%M>xDbP&thZ`Z88p1Y%= zUio^3;R24kqBK5uUciXfV?>+ZBlx`chbcwO4SL7a?vjPur@d(v{5C}_W9a)R1ekk=~g+>!wb(y9* zr6A}|q+XBR@Bm39n4yp&$?I2XDB#EZod5C^1-HE_>P)m26TTr*yl5qt zBhXl{YW`J@Y}fXY+U~1ouY0K47HUnQA%8}Z<#5pe=U9jTZ$&~o+Lz4%vAZrJ@EtR_ zo%2}NuhMuI5ewal5MIyL^R`P1P*a?L-f{yTAx+O=u3wdSXH3GXEFhn}N2~oP_f!&1 zPZ91nF+&zK?Z5@U`EgI4Q%J`L)9H8p$&Xy7y)ht26LvWo8TuE>ceCv4M!;Um4_Rw} z+o)+`nX1|e10XHz3KysVi7HJ-*HFYU^#ij&T{}W(Eu~R0hv?^l{WzCeY5Zg$b7huL zanoQ~5@Jdds8BqoJhkgAE6dz(-=I3}wq6EE{AB8$=aJx#eYT|8HgYX7uoaiZLDHT0OMUEY4RRkBnIk3=} zb^0`p?r-&0#R{l|8OcE&Y<$v}`*8x*Z5{Z~4$S~7CyRS&1(U4-tI`qMUcuSw##u_2$Cqdy^STwLbmbdp-W5agWL zf}PIFL0$hyGEaO}Vv=#XZZh)f`w-r$avwx?HJg9rebV%EB%zJ2W*%IUS*WFfVqHKsMcGUki1ySA%m zpXg{A`s~OQHSi6&SJWs4-#T9?F9lL~w6?cnp$sV}arw4%?r=Q~qfB*xTk#?WW#CM@ zw(;vypNMWY)O1a(OtRfvg+;FLy2r;lP(6UgG4bosO8y*_ne@5zyFr`Eobw^OwvNWg zBTjJS{BwJ=xsh)%PAze#paz(o3a@U09{<+`_Fo|y*O|A#?epkdg0sYqE$(H}@CFU~ zb=`psjXT`M7p@Czg1G_c8+e#cN1?cj_U@5d1_x3w@cKmX1FQ-p>6^lx02S0H&jCXj z^?fz1R2BtZI|`wTT;V}Fdj5ylAYR7T!-d8k0)$Vk8Me%BRXI^Q^o!>`PMw>O@%Hxi<#A8cfVd&AP3j#oApvHPz z(1q%%!;pf8vp)JcQjv|pQz zP!suPz$#1TUu%KJB%@YGUpN9b-Oq`)I7}w^5rq~3>NE6Kk~AFcSdHB&dp$EAI(5iiWBv4V{?h=fyBWyDKVS1kP>L8)jT$W+LOdnSjU_4`?+Z zk>&a)G@YZ}>Z4?#8i|2+oUY0cFO-VP(1{s7Ga7~ypFR%xES2r|`+7keF5jf1Mv>1z zyo1;em)H9<)P#Oc&iQ*fwtax}KcJ^8UrcBJ-KCzb-~Za;W7Fq~Bc>hU>d0xrG5`-> z7K?gCIcyc;}ZNyj^cxn0IR!aiCdmMBQ|F zH;Rx9{o#Iq;Fyu)WU<3cgOX&j-RJK|xxA$*MCIbK;@_Bmg7sTZ_zfj{N(Ul0`(C4 zC5AqLMhm=7+R0@I|2(qwdecpEPHyWkGRVnn4zf)rTkb?8ai+^Igq_-u2pAp?n<7g&}Pi9 z2R|nSLjpxu%J3ZWP5-iQUnm3AwIY)F-+8f)$oT?_HWNA*^+b>JE3=Lex5Ftky%pO! z{z3C)Do~llItoZIa_P+3lKMN(fGd*kX|8MOsO?T()rn94ThicdYXH^P*0A4Y$J{w~ zC{X}2le0gx=gMk2{4FK*U&x32s)m6BSL$!G;QWeOH*4QH+*z?gHQ|77D-b`!`j9kW5wk6r~Lyyo%6aXyUy_|Gu#Dm$Ny~;I(Zh>^WA@>t(r5}CfAi9 zl+~3Upk)Rv*`155`-Sy%oeF>mhv3^HE3i_&>jMm{A|{3AMV}76m|AfH1_hSPR-oDf zT?$0bCxGexE{&+!ydVYU$I1oIS}MB4XId2hl)3W;33GJ*r6CuEO1XiKnKgqIQ6!sT zpjc6hVC3vTlmn!B+onyx=Rnaq%;FxQ&Ad#GCRjlCWmK~?iLmP(l}~J*cg66fPD;Q|c5dN1umnu5&y;@z3l|IH4m)5{-3ynKfkaf`&<@_A~60u7|P1js)`kJlS z^@sIRg>;A)=jwX+y%Tueq?KK3lEr(r)x`;IhWr;{Q6QnrfDBW~W2Y&Vx5M7}2WRtk z_|_rAbuv7z+wOvtJkb)3y9Mc(a+!UhHrj*oJuj@=UfEGv_Ugk1O?ttsrtW)dk0*Kb z&KXESNoU*rY*?3J1_1$pYK7gfStp66P48I=jJCsopBx8;z10(bEG*~5SVRr+#`A)=`%Xalx1l{M?g0Wn0HFO?L=u=Sf>;oKxF#%yyA_Kx9riflp>+MERaOaPc7^) z8N%5|JXFGby(t>XB++t0Y>el(;MdFqAXCK<<2klm@k6$@BD;h@Mo3_(H>$tzsFzoa z)|8MCC)5xDzJFPdBdkIY6QVUGP3!Kh>_^ht6#Ek?0B3PvnUb}dX3kn)-cb4~gqFgI zqYI5*>Whz9Omn`4b;O~otIpUcAh!Y_fU!0_?3G>>AkT?~z*s5F)HyPjV8&<*FP@B! zF9pCEdj-{&Y@LtA$Oio)OKSu7&mp1W;!emrwk$a(iSUY}Z+?}8TZgp|kHen~+`!(D zvHT<1kwUQ4nTfWDqeK}U!Gz>9o9xc!t0}XVBH>aU`GguDTn72JzHVfxy`@-8cyVnY ziMj2&@y{swE)7=LCF1g+rnJD0H*E-DmbzZ;EjykA5B5F)0OezH&P)n(Recd+N1%%z zQ~z~qy94wgfIXuI{*e{|PyJLRzk`@|eXM`+nXFcU2ws4oNzPw^UF*ID;+%TRyR=uJ z=aHw!1NTZad1V#l9Ap~3rLZ*9Ig^)r8sa>n`$3wSN|)*L{pTQdeb< zaysuVU&6~_7~L${d?vFXY>%ic-hNdFrU?MFD-5p$J4MH%CRzMs_D7$Tp`78~rCd|@ zOBh|H1qm8z4ex+5wm4{K^(^n^knBt$dbYX=hTE5+@Xq<6MABnUR5rMWvv?g!aZ($@ zx6&6?P3&HLhkkD6n6rTEAMdleKBM(U)1e{W<8i>g96aoVi`j|7gy`5BseW1_%{UUjcU3PS~YN5EfMQQP(kDq(!+&reB8 z;NX_OAU063M@eZuBsQ7OaWtnk$2PrvtUoX#X3}zw609@e(@0JS7G@N6MTwF(nu#i^ zPTgU-(+l8VypFQ-fi4ch2`}yVQyI>tW|EG-nGHCPRY&hyYkzj^f}<&A!F#No;}WWpMtU^{Z=k}q5rW{DmXqO z>R-yj-;X3xeTrgzmq^&|i>tWfbjZGeB=I?tUg7Zk=Q?PpAoBggih(1T95QQsTCDL% zi;eUkAqLXizextqJ&e(YVv4Y9LOt2ExjYa@Hu1Y@P-m5LzW7(3(Lkd+xD zkq%NZSO9;_$)3_Q?{}A5b;1iK@fI-8$}){gja56uW{F@shWz@3GB((4Ay?aHmBDlp z3GUk=A-!wx#2vD_oFm<2hk6`}#I?R4=^I2E6j)z^*+8M)S62-GuwS7>0<;_@;MFZY zyq?Tid7hR95;+>8=YI{!!9S?547Fty;FLsPRIxY&Gk@XCj@4`T6_`Z{b{oss5E?Py z_KdR1n63!Fqy$O!jV*Zi#lJTac-0B)~f^EPYpV7P&?afr`%_X zg*32t(Dn1s>oxv7viFPWi+CY=IF7PZ-J<631b(-8wugixJ!@; z(PVI-k|2QsC^~)lH3%+94U=$InLjUMc$-}8uRU4K!b^pKStmJMX3*Ti?ULo!7qqMn zs6mMvjXY~iUNwmpX9-F!6$nS!fMl*a55d|Gd5CSnIqu>wOKAIThwMnH1 zUId%AUh>~}9ctOPypay=?<_)l3d)BJu!2p&##FUL<}aB}v?(EydH5$BuQbfrL6^7X z6M1mCr&A`nSqff!fl<)E9SL#hN>8%bwGV>S)k33|(e(u%a{nol_a;F{e{~BI*uJ)U zTuYOPHYQrMd95Q}NXLf)j#Ma-7tpljlb>fmD~R3+-S8)wbn7PR4;%3uG06hV$+!WH zZfz3&lO9|Hbe?v{n0Rw^q}%$-`7fwQn|uzhk@d zQgsJcx~ly>R#Leef7ucL)FIL-piC87Nml;ZurRL&%_FS;!6koJNkX8dERHE?OzE>U zXN8|~fDi?|x!i1bm`4ZXP!;zNdX}^7P`#rVKQLnKkY7KurL{JV<7M{u=(=G(n#OGQ zg0)`j{~<%a_bp^K?LE?~XFvBG$sv=k7#0R5;oP2mSb0lh6C~VP-mE0dC8La}|D))Gf$7s^-GgIxF9oRvpd7q!7TtJ`hL*W?YU^L-x_T_W^ zPs1Qy-3A#0xt^{etW5BAlAI5HVAyM_JwM3)@-(&#KRGcvwwgKOMTZw7i8g@>$`@ve zaJsRpW$^_kU4Zh^&O#D5T!8cwv-No^ZiUDk&F)f*S+_;FWAJD1k!MHTsW^fUie(!BCvS6P{YN2|{qf^~eTdL6$D@gm)||CR_f89{%w8cS z{Wff9(YEwlwQK`ak;i>u%Gmwk3uA{k#=e(pFbl1!5NKH1KN!aPqFc&y#_^Luo|S&c zK-uv<3%D!mjGHcsY1w(bpGU~aaz~t>3;|D<)~rk@XiT%N_o&prIe6sH3$KCacjOrh z7v}aORT+B6lBopMZp%Y-8qy$eCDyAl`K2Cwlj^!N*3aad9>gG0#x>=H~1RBT!*Kn?6s4&O!aW=~iP0 zweOX<1tw3P%}l$D9U8MxmGm<2FL8^1p&wp>;3YS7uxLl!sRXERh}P0@W>V1>c=YP? zO>@Iol`I;2 zr^-O!K~ME-k_YE+Z+6IkbWFV&rm2p_y$l2lw^zixZJ+3lY!J@9ekY?3sO#=MeiJ5)im!|@J@tBxqcyWbmpNMqCTl*jkTqc}geC20y-<&lyOi{K|id>qKeC4x8{7f`J+;Yl2G+)KJI4|J@|d z@FEX~YHDMpxk1$vAaAMk4d28pXBe|!F!|NQpNBQ0IwL$`^fO$a7@ zF)~p+bnG=u(pHEoj&!i%QsK`38&R})X$6=E`8#SXD5xJ2qdAq6(pav_((;ka5Y7|G zWr<{(lvs-urG(w~N&c<>&*NfTgOUWqO6LBa|0EIx8lo;E_7K2f;e)7q_m8}3jTn)} zdKNd4z2S;}yUknX5r>rb^yDP?;LvR)!citM6GJ}_clmQ#76=2=OKt+Ez*OdvNG@l8 z^^=uIJ9P~5c%O~YHq-EjmEiGy}#gXad45v-m1XadA2>!780&4B>qJNcN+s7q4qHbw}ThQT8ndU~pQ!!o7Kh6kt>*X*px76;pqcwCS9KbeXXisb#((j{ZB{{V8vmcAxy^wRc z30bQAEZO>yWuKtlsR%v}+b+N$za?#Ehu146`IHh|w+^KybV)uR5Q05;lzc+5&0}>N zy1HeuS%|Ufp~DJcB1tnG&Bv-dA#Hm6X#&vCf|abv^LnA4V-!w?evco#m=2Zxt~UUm z6!j+IY)(AL^>4&_***bDlBLdfNMV3%``Vn&{OCRuQ%V7*EI%()2y_AyTTz8vl>1#s zP*n%%$~d*+7wb*>Y5+QOVCrylkLG$kA21BLLJCHewF@h{yB#gIm?->W6Y1gf?C%Op z>{~NeKFmWuugFuk&rc9SVhwf?$ahe!o7|W;thdJoIlCf9nga~8tQ{pLnp>9MZ;E^< zO&^{#=Xl)51l-=!%4J$rp5m178XjHR7k@n3PTh0v>(zJ)O5d#+)f}Cj9#A*ugbclA z6)z$_+rQPzWo@M&q_&RyfX~sZ4=KYE<;qUJ(UHl`*lM>v zq=PC#9^RhKUPNCJ6${@UE#=xEKfKCrE6N`F?HD%)mwWuMqhojFM+S#8^Jm1l^)(z~ z?KyqM_Aj${i1XoHa&o$zPzV9UMyDneL3ao{5+ey@ci<~Zi+uG@LSf7r=85g#6i(qw zYK9lWJ<274pml{!IncMB_xURYp?>en2>laIeT4>sg@4erpn{h+J~F#jGW(~)uJ`kE z0o1npXN8#!SoX))qON!O>|bx6N^9Rm`f1XNb{tncCEn=W|0H3Mj$d^dUetIdn=07W_IHI2u``-J`uH$z z5W7*WrPJLZ*=H|e?b|)_FYut*=Dn-$JL|pG*b6YemwSn*3XHfoK1G{Mb-d(Oo@lo& zZ6P&y?-&lEbX~$%&$mrkzw9?wJeO0CC*x*%hIaY%eUmy5LQdyNK7CV|Kz;MH)ta(# zzJ5+lFUT0{dRKMp^n$dCm{9AO@iMc_+F8Mf3`($lx?n8OVR&;Idgcp48LT=z;meNQ zf`_cUL{jx{HoXz)SiRzUlP9-3ewP)y@QgsFX*K|vafYSykztMRlXI?KVRu5B*d2F4 zvi7hH?9*+WODP|g+c+n|;Kxj#QdmYb4iQ2%gVK_4yHw4Ef7%a$XN@5yqs8qzEbOix zw5;CC3^aOnJ=oUm(-AkRbnM0pAUe-bnr~i?KC-H@y3csK*Xz*D($Kd`_kK&}gB4G(%8Nj`tpr2VPK z;lo~|z85udky(uC#Yf;wMTFge&$((_V7S$;2P1DV=Em2pCB$_G%HB)|5w7ARdzG|v zGqUlF>Ufu^&$OMhl0LBq@$iR-(B4;0T!4NARK7EGsV+wf@VYkdjwP>Q`QY}f5ghYP z9M3ptN4Pt?c$dfVRq5;}o@e!=XY}(7CsAbwT5*}o?AvV=D4$*8V%c~-Vy`wj`>n>D z6O{B2?tl~-D`FA-Vdt?BcY(G)P1#q zK#laB^yw@dZEb)qwKW|J|EBoV>I%FX6Shdlk88{JC`l_%wscxfT$g93ugVcYOE$&d z5-HiZj()yONg0X9siGjM)RIy+4D9nKgd$G6-e+;YjdBgL)8r5yG{)PrPL!DP?GpBg zok9HEL%xH4rBB|@?fiU{yuM{RKdm+Xn09!%SiSDm3gbyuncUf`QRbLT7-z{Iq>^4( z1^#%nW4s&Vpx<#%cWj#8aVh&np3N*VfHE}fwg9Hl!ubt0?IY8WIyG%-M!3j~N?jB@*;JYBKl0-bu(edX)_NdZ+G>w_P)LPNAjp&Dv{{ zckF|53TaU{k-6*i8k2_gb)k9v_;?^s-|i?g)jqTItWfSqXzS+#bBxN|i;;|tm$ul6 zdI~8|tZ5sU6XGn$Ui(p@ud51sK>rx@_dG?4Vbm*(#jm7{ws@#&F6 zcYQLq6QCTS*itZu`QPfOLs5lf-#18;O9!#9g$>jN?o#861e7m~26INuxaFqnHb+Fd z;Pe*c8KV*=1m69-%1tsQBU^7C@rS|oHj@RP{b_mh=O3lu9gXMsUzVu(sTFU0E^-2!II`F>z{^GQc3 zXdNA1t9+%~phRScO@)${1;Go1=LDm+d5Mj?fShthXGRK;6Qd+BubWzO?`;62-66Atbm^JA0$ z{(a!9Hqs`TL}e0w-M*vC8?j2*bP9_8JbEP{^JT+kaDFnkXd4dU%t)+lG1r5L>(mhR zT#ZU~*7;c`^PXp^B5fi5uB96NnC!agcdAWaa75Y>V4sc|y0gRvyz$SEA!toV2q5vQdtDlfP8 z!a-l6f)IF)@Pa{3>)34OUBKi>8kqk@f+%j{A`qpN0t!AO*YbxFej-kzqculk<@n>+ zWu5a)+A0rz;3_eZijF@4)=p`u8=0XO;D1?1JIlAp{KFf|D`)K0Mc|?D<;YwX34Nvz zdH0o89X+wcEmJ8QcI?fUA3HwKCJZW{_VjVo(qEN3nDxX3NyLy31Kt%gf5(6H*JEF}L8J+2-V%(JR$0rPWARb<SOlD@#kuja$(i zOUons`AAC2X%>)y+`7vyK6sKe^lrR;Irl>7n-IRg#p+N+${&8i3=y}ISSkMAm4krU z&^YE=*c=J1xF-wc(V`J>;2t4t>?+u&F^Kx3n-qABR9_U(WSIBUVASc`F}jison&)jkvCqO`%A_Y`)*m)bFCS0lclvS2c8MAMa^o#{hq^d z6nIbVA$L`{X?W2T8hyJxn~?_aK-eorzZNnByPg3p0@?-OKtn43ti=f>=m+BEs$cgg zs|&v#Un?8k)P@B~->~ah4UtI^%}lE1Xi$sOrbReBz9OqQ;)Pm5m^)Gu2xPYu=25ay zIijX!;XhR+4r5?sjY&>krTiq+@a7tk@>a&ucB=wtV;4;9FwAA*`x&>(&(qMb@q8SM z;A+ShNdrk;It*c4CxyES&&B9U6^mx0(D^P{B5yRg;~Cmiu)Vq_UedZ>f;zn>HZ617 zO9h|095*@|FXK^(BuNT9dQby+dY6kl4oTRpE(H8JoY5z#Xcy>ypo6$+;}RhzX9E49 zX&~RI%SNrb-@}y+-)Yr}bId;@tjwxxrL`eDisqV20MlDeN;yqAverL)=TBmVp$&GU zB@-IFpJmEoX7V>~Fej)Ere>-y7#@p?I4hVO;|eoImIoL1z^D^1#IG*C&W%`BK*>JZ zo3mAPma_Pyt2=zGA$QbpcUzXfztvd*+baE?$wOAPYh(K0_(|uHm6Ms8{he-l@=B}{ zt;KbN7s4JnYA@On)YL8jSp=_bbjit|G`X15$dZ!-3M>nGSVRn36?XY?$(|C_q)%IE z*D}sJ&pF;$dJHlD%#+DnDz(NyDPXqZZaPZi?L>YI0aRiUk!|W=a{MdOJFFnMZ_{}7 zD)o(c)A?$(=#wX<+`!bCR0GqK7{#m0-Mlx0@H7iY>HK_~VS>!wE z54z|rDiYYbiB`0S79=Id3%#mgI4AqvlY_=a+?X8a_dgV33+bwXtm^V7v3YhJK_?K` zHfSAa(OO{YgK}eY9T|OQMzF-Puz(YYYnUnYlQ*BiR+)s;R#m&PJgRhY_PL5bbdWP; z+%}=4&)U<@Mcp9L=s@z9oOj_cmmk4NOgM#Q439}A7Tf2djnvvV4Or2}=0FK%%6_cV z{fcH~4b{B-=TTc>s6c8OLqlQ8l1?zLZeHAJY?`;i+(yo*bgsuCJDV}5Eu%L4m)Z#- z9IG|6U~K4*EeY$%zvHd8m7CyMk;Jv(jK^0D)hic&VVZfhWeI;$q!>IRqG;Zx>gA&P zt}(2<86u?g9XdB{3zz%*VddHq z+`TwtOsUQ_aZn455>Jhb3bd3x(yB6F9nk!m&h7eAajLdnFs=12VwMviTdqS&(!DoQ z##`i^xV~wPoO~1{tbqiXKQ&0iK}_b@NwuBIBj(2K^MtL$$?GttVBQGJatmdu3Ode^ z+ro9V2sN|)hjX6>No z_q%DJ-G?5ULAEo#8up=ppU2YukZlY&Hu{26mdvMJ1MT=&V~gJPQUgQpEcK&A$eSZ6 zrT&g&&D3=~D+%*G><`f_Zg&hgOC_As-J$2jdGW6Wh;#;ZWg5cwY2FQ$4bo9eY|zE# zu^)N6vE&K}mMI~4w+JE%`1GaSw7h9-4v(_xP@xEnjHk>ZN&_a@7)v46mVKgIz=1XF z%f+@^g>*pX9liF@3ViiIRr>*@!Vk4^^zu`_Z3Y*ETNvJ{JI;0R7BD9)pi7fNFZ3e)oc?6 z(u}|jWM5(5$s`O9Y{gSXg6~*zSVCxmSbs&kuwt=LQ{zS@oPyRMK?w9dWKw{rKAlN# zG_3;Lk3W*jHyg21<>uq6ozas&d&M%>TG}MuiqM&{oB2E9SAI`=zI>1G${S4NCE zF2B*Li}`xun*d3!oij=h9xDW@(W(43)#F3of8T|tlB6SL*J?Xl zv=-AzghF?>$weo0mH3pPcj#siito`GThTKZLnjE=Va69qEV1IoO$K1m=HnJi1xx6p z^A#i>*y=Y)U_oic>mXwDCW@`l8r4SdUw$$~4q;Z5kiTdbI&`M)7}v)1A$!j10#BRh zEFS*;-HKK#IYwYl!DKI*1E=JPNfFCu+^^4mXeiKTC zu2hvNF_Z74ilbrn$lZ&Z3ECQ|K$$3K9V#cUc~iHe#jhk+8S%&at0vGrqlCh^eSwLr z3`W&#cd=iIi4`&zc`0sae~;sQexq_fOKLw+zi_n(;aIfw8yh?PIr;z*m~T~Kyw54!(EAez9v)pWVqK=O3naGbqN z`I>&*L=RkC9h|o~L;g0J6Kx@NS-8r(vXMU$86m0*-Ux7MC6s-Dk;PMvOAK+1vRas5 zPYpHGGCSlGt5i={*AmVgwH9|#V9#rJL<<5i#@^)K!;WN@M~o4D_A0H8nh|fb(lM6jbkw2wbM#y+QffGCuar6 zIKmnusTO%~hjB+qmLDNYVRwixHpo zw>g=T<1YRPag1Yq71AJZ+%QQ0mO}l?Wh^*S&}tHJt5ZSV218wM!MSMRg_7DdxRkt0z({YP@VK;dw7r`F$Q@4<+TewP z?_9Kw5qe76?-v;uTu<35LbP!)%(TLXrD)##uFB+h1#pJ#;*mxf#p>Ta0eoU}$F0Y6 zl5CISh0)69)ZDaluqxg=7}el5xiGc$IIpk#%FiJni5YoHlK!I}7$nKaYQAd1h~kD; z1GCS7?@aYSY)e`RZXgCf+`y=dH%*S~D>g&nF_cfOyK$CT2cL%~h`;4X%Nw|$_XB)BK zEb&zN0Ww%h9g2(UF#J+tr0z{B3dn-~puEZw5{)|4Xr;@?Nf0klG#!qv0M8&ww9Y9^ zDQjpN9Vagly7qls>MU{Q?*R=PPW7Oj=&AX(;bNZ0fzz6k_ab*~RI#L+;VP2RT|#cI zK2OsBt!(I={gk^o)_)jx)bUUUV7!}7ijYC!n^y8hy+GUAd#c?lS5xE~Y~RZd<%)ecx*FVJJ`VLH270YZ zKBYQl={NI2tL$HNdNQ4-gn+Ht008*t3ArV`VI_)w>qm%|)yX9gJ2})T#ju2A8E7^k zP(D+J9I-GdUKm+OH9~=+Zb?0`Bf#1B=$GX>j$=U#W0=SL#GNgJ} zV1d0e$JM2){ej(cY<+=wZfaGA$=x}iKl7}vYdi3yGjHN6oqv-6EaFb4h`bwlz>CKJ zEn;{6$+-7T$80$GNNoGs72*@=riOiJKg+o~J~6XT>sU(c1;$3Dc;P_+!MnJ_PUvW) z^@=UBgV1ST<#7Moc4yyFt$qe3H>BH!%W0GzC0tG*Pzz$tL1a|E@sjH+7B9Q`T@%1g zF|ePd`*rKq{$>wvuDV|7mFg<2tUY#niXM5U1?pfmmtofuM}iTY!BiGH|Cg$Os7gSX za}J%^lY<-V{Cnu6|DQy+U$NzzA9LvihxOg5M-F9np?CRI;;RAmO~1(l0~J-X_~Y+y zlN8HY-{=xVd*j-N;~o?^uldt}2lS+^-~G_t9#^wDFr92uAzZwIOO~BNiGmp#36KC6 zP_X3GhCQ#Ag&DnPPWsKCv66f#@Mb;K>fELGpNn^8Wf!-~vbJ8^Gn`cnhB&IHNU0 z7dEZBIe??VLC5Xqs=^S^4+W*|w)=)(r3A1!LR^m``f|F&FcK3@c5zmHiohJ^c`WA$ z%;irBUHvOekwOvu%T-(@JCaihB*t zg7PbLKe_UW>9XoNB*b62%XjYbsH2{ zb%grL9yhQve8cLzsmFt<3L_^|Mkq&rLYfRDxQh^#@N9e_VdS5N$uUEhT-&)kQ$1xM zTG=YTQ`)yea8cD7G3yFmM))*n?aS>BCrFd@zs=$+yjgT^kn1DY*|dV&6zuHbX5 z1*bQ&tUxtmsiUa%^yrV?m|-8<0VTu4J&U0MR%V|IC^D-*2&;KI9}TPb!a-GXyd7he zF*ar-}2U-NfN8U zjD(HN(6Bd#5X5|IhhD=9KZJ=L$j~H0TrXgjH@pDCVLmGnqd5M!3$NGRh;A^Os6z)0zYa-aSQ=A<9Q2~=S}~v*R#n5b&tlmsbI{No<*kH#vPu~ z^3D-9_%YIso@Ws)v#i8i>VJJ%AdlwmQyko=e-j-?^BKF>GtkY+p`9Mkx1K-F)lXXR z?xgU(OF++cX4>{)@Kw*EsvDj1aCJ#86BM3%A@2{Q*RWe$xa)tE(e{jC32vZb?>~>1 zaN-UcC{8Yea+D(~PI@J=a7BHh>e4JEnW>wF*A{xEOco})DCAxNk|#x`S%=84+o3Qk zKJ~I*u$$F9t0v9*8PHOz?b$^CM(vLBqfk0?89Rr#CzbyiC&)Wa4s61z@kb7h*8!J~ z;-GHw6LE}DWi~gPDM;G`W*zZTL`kXxYF|;=a&Sy1Bdxd%A^Kp;6(coF)cLawIDZzAt#Ng>_l`KDLLtf_=(BT3`28#7wP%L)!GQQZ<-PVM!i4N%2 ztmpyV+GNc{r8(&q73!IWnTu_yyie@H>-CLz@%l@~1kdfZN#5|cP2f#by9k97o_<7N z;cn$D({Cs0(nokd$>8FQxNJ>{*zWTpy(bvpH;#1rC=tAaw|?iKONj{5F}86l5fyJU zYx~_d6@DCTr}@GHi$7+sv=WzbPbUAJ9)U-48o`o@r(tmZ({&QwQ~KthyX9*V{dkT# zUO|Y&$Sd4LJR?GA!ob3FPRykVQQGgwj8Y`Pa?D&N_9{(q_+e4*A-{N9EyO9(4fuo1>pJ zj`aiQBd;p`t`m=L8*NARZiXC_wiIlSPS`tl(0oK$YD{4X%Ebq|)w&e4APvA~xrmnm z%h5rT&7q$ecF8X>mdEq1Bq#P{NW~T*YCgqK>DHbFDEwQ|Cf}1z;+r@nNMWog@Ny{I zI5wIoKvX&bcIO#u-`2es9(#P|b{u_7F_QyKvKV9Lqb^-|lrG{ZLwTWtHsYwFzUw{) zmx0R#==Iqi`2=eH4X*Zw3dwlrrjq2!@j4D2xPPpktf@8-i2<;vVE$wp?Oc6LFiq|f zfb@<2BXYX0gp(jujf4&he|~gM9IffVgWCZhB1`IG;uTV2J+ZK{>o%RjqM(DogfHT~ z2Oipn&}7=7W9dgtgDS!nnv4YXizAYrV84h=)FR)X(d}MmwirY6f!nW7n3{Hv-sXQW zAiMIayuv2J#>P&=L0id+j)fwUaFOQfPKpX`BtBn|R{v7O@t|{x{>q*R%7*d_u5Qoz z)FIAb;5VG-Oz!IP!+H4_QNE5!dAHuq5c+8<%Ph^858j}nUn0_i7$s)WuTi7>iwsKa z#Qo%{h?Dqu^WDZ?op$L-_JI43(vkv8osMQ$?2kEj2STVD2)d2Kq0T5WRW>7lX&#=S zrlalVGfw>d6sNRrDl_aOGAX|L(lWZJc65B!lG|K<^!O#pkY&TrwkQ`wVl1{*^BR)j z0UD~RFi3(TZj)DX!;{#cAh2-+0YUc_3%`8MZV>3%FJEyz4hL-zsDaF_Rt=^06_dY9 z6z-4T(8){-(Y|S|T8-zsZh&+K(@oTysu8ED_FRoI1a{xuQQ7;Qp*nH67vHndPT4Y& zuN(0)n-oVSAL3I^9EHFK^Xx_+VY2#Q-+Rf}LV#J1x0|2CL+7AqA)N|gppvn$>`df; zV~Ax%d;Ur`P%J?bl+66AmymQ z)}|-KhS%KCaN>Cw?Paf=P-aUm`a^CO__~ljUH=mNufCB`;Ii13=i3mIU#O^4UYxib zTOtbdqJ?jHSn_c)doF#=w*c*hGjFdc21W%>1}WcRJHzU_iVdOGM`4dWVOi0|Qn^q? z8$DB>_hwe2qQpTA!C0o9voI6YVuppH01f&>>lWzOh!XJ`ruj5z-~pvyKhA~yPVS(` zW>igG&hBsJ7o(7;zj}S3s96k%QG9<>bY10cICU@b38Wl+rr0)I&b*L+1i&xERZm0r zjR#wtztJ(8FFNCQjyAF{O8!Pa)jVXktKOXF!gqNX3}JfImS-R3A@=z0cjanHbKYJ; zk6~w3YTr$e*Bb%z}RAx0k`ks1XI z33qkDS%l3jp}BQoEw}7#`ZXUJ1Xf2MwJNmMe@4})>q;ygLLF3;&G;e3N6XJC#M#p&sQmT_lYH&D>&)!u_RQOIo(f zu6RROORJ9P?ve2FB0PMbQ0gk1>OC=UDKor3%dyr9qh~EK9~y`oRZ=s`=2@%Hx5Gyn z%km6ZMq)Ol4v8@T%AnkZ>AH6&;y$4-N4;C$u?+X(-f`p_FKSE?7On_!O>>=E!n3aR^P=3EN^D{WolFA-rK=-Tn@g-P@z2k*jR#(hD zYyO!RO9k$x$lLSPw<4Oy{Q;Wtx1NCv+et6{Hc;JBXz5+O^Z~JwoYJ#bj5)&6LBd(i z;MkrZ98D$J(rb3ze<@heW5U3Q(bw=zvRMWws<=Bw-EGp>Wk*}&oufSV51pe{)_aIi z1|Wm>#_}w{!NoZw^hE#2`yl8nePl47@IYzG};E8 zoak{(ypd{GUtVx>YuDsnK79cRtj@ooYCc4F$ijUc#;0>$g>u|Kl&%)C3P*p2ZE$8I z>M#inRkwcN^sdmyivttjuqkf0tkEYn&X@EYJ|y$c)cAmo68rb#oZ$-`(VZFxd5U^a zo}-5pq%n- z9i#hHpMS|{wy~64tFqlPkzLy?aL(j0f6#5uQr+&DqN9&vv5PF_T^vPt{vn6FHa=M9913~0O2JNrkS z&Jz6PyJwC3Vq;4p@EOj_n@xAJK8FJ4b$=D?tlMi3qOHb|)x_bzLvbgUgbddaYq-rj z6yX^~H2Amz&%3aW(eOXjQ#3M!V5E^gmAt%U`jOSBOX@Yy9Dnm{4FL13d`-vnz=E(G zW8-9b(9tGEsU#v~l~eVZ9xtyXu15OG4Eu1oB`ItFDN9OT*Lad(TNcX&A;+rvn$z$; zG<6!D`pqs07(hOcf#36(o*Ck#_o&`YQP?|<^L`#1p7Y68N;Uhhn;YnJ9@hiC${vnq z9M0$8XRkyihlNzjz}Lru3*G8Z&2%b)rbd$(V^k0IecpUu54$^M`b85@V%?m`@%+}2Ruo+#DAIr6jO2ZCtWw)LGDoY;#h|-C2c(9U|yV5j)GGbuq*zYL2w;)OB7G) z^T2H-no4Z^1i3>eD^!P_ZRqXG)PAut_Piy-ocS9l!=Y0^xwX!ZR4J#W#$pbg?7F8>{Dm$Ipig;cP0rbDW@~4U>g_Y^{_RewLwZ+vq0H9;dtppi% z^;+pf7RGo=%Q#rCZBtY*V63Sd0R%(G0(t@5gb}?YEznvWZ-v;`Se*Bm zxgDY^pDl1_Uv=*tt0sXhhm?mMxM`jv_sV134miFglCQjOG#A$%Po3B3`F0V{7S*54 zCR*I)Upnk$87)?|8D7mmUcl-4Gm7`dNP%=+pIHbVy5ffbQ!x@1a<(OCrS6WcWd4zs zmYnkB{oUm9T|~~(eB+G%nvWP*ZGYt2AJ6`>8QQuifd-ZzF@%j<^l|4Xqe%nLS>JBZ zOGqD{!Ic4{S)Q3nlX4a-jZ&8PAoo$~JVU7a8vKhePZ zjP~6WQNDk}(}uH@A(E%tHB;UZ?D1j6mxFsS_98bsDbCzkbRYBb?wZ>VQjI98UL8Cj zb0+y|J~Yjy${n1CRsh+0sze>PKT@XrkNESBC*UemFa}Q|{4L)UI;}P^9`|Nr_3N6e z#AZVXb5523-VfQ;AanG&2u8FQO;UUT;R%@#SNA+Kk$`-k;u5E`CemPFSJo6u< z+Epwu-GK^tIL-CZ**hs0-;-C)e8vwXx>uY6#;d*dg;WEIRYo(gBq)Sh?I~q&Isa?9GE~s$o$Z73ggdaLlpY$!Z`2Sr{&g(<6}? zQ1MFv4$n_r56KN4BC<2U_!=uM8_jo{Pj!tgf2A^D@}K(j=+>3BLRn!AwOI*l`@fwX zOr{Ba!;=Yzy5~cPo_{yzZyB|;Jsg}uig;4>rJ|-aD;@Xf03~LRN@fXx zn1=R|@%%%X0>Zs0%P#TmTBSaqN0QIF+%}n(mF$AVM4BTBM~vKUovq&&^>=oF;ofs! zA;H5X?<$$u;o`1Yhv_gzOMI#ZY3^6UM7*J(ipA;8+xzrd)%>Gohh59;>7~6Y_p;|* z#wH2YZ=*qI@`-R6WdQfaUA3v*N+fPEn&AG@tjSqk7sA;x^}f;M9DYlfN*%vo#)Z{D z%l*k4iKEaKiaoADeb+1ia|}Jw?b|d=$-?|lri~<9zBtz%!#Mj|FXB#t00*!zsnSTCV!fv4 zkCTGBoqdhAwZ=A0FH1IgNoTxizv)6pY`B0RfLoSH&~Y=()a&oIDDb2FbIPeWMQ&yX zcEwC45>64HZNT(jGVvJw-P-6UG;rz>VPw1#oBnMKiWMWt6@8m`YV=<$f#d<@K7|i~ zBy6l9tqhz!f}e%CV%oA1(Vw=MO_p}prjX6_+JZpv_=H4fr_|2R)rin+seS_;G|>6p@U{faL}efa z6^rBHcc0{**|(}Q`ok}#_L&S)eiTEj7@FEXDBuVLz|=yZW{EndaesFrSb4W%-CmlS zhid+^?3P3#=TMz6>Q-yE2#s{6l&cRRfc(}llE89P`{Yj_b#dX{seK>Gn{Vh4JTzqz z3MxC44=>Rv5)6{R46bf`+a;U4UiQRPzN!HxIXr1{>1|`;=o30%U4SyKK6U37_MHUFwrln^eBvsGk>!!ajjE=-&9bZM|Y zsEeVJ^ap1VQCEx$S1(Rhex9-Zd|xwlmae3@7{$`Tcw<#PC2qi$<^tm5IUShke|gvl ztHZ-cEpvgQntBEjE}F<3*>;XL;pW=`p?q&y{=9nWPD&U48G^8cEMQ{vP#hST``yzT7@ z*QjTRao9yCnTrZ%Q3uaVvgu(7$PXQIPQnPIbnYfUpAI~MGZ1h6-hxfd2F~8V;_BO- zk1gwj^1WPf*yu>z$$r9TiltLg=x?u`NkTQB1BkMj?YWZ?HY{mv+lVCN&PR>wRysKU z)JY`!WFu;bM|aUncWLNE(sZKT{5fsv?Vt-kVr0>1rnM!eimDqm620|-M3fLlxaC>d z$WM>whvba#Pk!`wYu$!L?nlo<4Qz>l-i`t?a&th&Dv)j|oGJX73GL@3&QHZ5Bc1*K z-hnqt+T#e}WXo`*%W#Oz>R#7U>4gf}g{TsUlXdhh!3WdhGfJql!^Nxt{5`+{(Mk0L zT=NlrC|p2`b%%oX>P?XqRYj$aUi zuTiD3M6B|@mMsP6U$yj0FPVrBm06^-*Z+>70DJ$~&^hJe@C{|T(Y&2!$KYI(U{EXo zD0TgEYjDVbBmM;pj#oD9LiEXIBpSkhf~aVP?U&zJ`swj9{s--c9QUe#GK8Cp>bxn5T-fxMsqO2-u}+p44q)TkOZgyoe=eO+6R z6wK{xShu8MdZz3OkiWRPxovG~ZP-he>u-vl`tm16Ks74e!(mG&obizwPOS8#K#D5Rl3Qk=1MxXNFWa9mw679-|QG(GWW@4w=b}2tZHyq%R%pD^gl$02|jZ zpQKZ>I`4Ty5a`A?e{38x^uP!=di2*k5I}G$8KMqnI%L*vEIPd8 zX2k~EXi|*+j>8QrA(-zBtJGw@;5CZ{twCJ<{{P9*nmfcck1fNEjx4k*rq;k#+;_K3 zr0q}k?_SG;E{5?p9``os$m-@q#EUGidvFhbx1F_`Y1N|wmoYl3h(q43-<@HvJ{EBm zV)Pv(E=P@jjUvu_y1!a;=x1!^pU6KtcskWM2ot?t3Z-{fz@Ftd_JuwvXI~$^JVveH zKLDjBnujp@w)M_zMZ4_GlaT@-+S*j^g(t2%^Hc-69f)VLC>iodLM<&#{FoX^>Wd;6o~9~43M7d`5!S&Oj`%zu5!Lb7a z(-T2~Gr;e45TeMI(~*w?(V@TEF#-w*9Qs(#7nb$=t^EJ7n_(v~sr?{)HEvvl#+8LT z0?;4NUQfH4a)Z+8VrgC;gioxH1BZ6zfPmtF_nb=VQ~c00K-4`MQW1qghBH|zO<{`l}AvLu8d2TUnbad@X>4~bu#+iS@SbI93Yw^HR7Ee(Utn5om&cP&PaljKSGSf(d?Hb23>_=AYW%wP8o$`aMpexY)y9%p zQyzVskG&wsj?j3AfCm4}%2lC-&LCpEBcKn8&|qSuX>RzpD_z@;L5)p>Wu=_3BdARV zXka)_!A8pgkYdKf&1-jKU{=j|h}qMs#r9l3#>!T))B;Fh%a#Rb+sp&jz9u;$EfV3t zC#3Tbg-$-jkZb1-&Y+jm9^2#!lZWLFXP|(fYsC1Xa?A9s_Kfw^C>*^$FJDnW5b2su zJrY2ytZTXMs;%h9)XlwgpGxWPr495wwx9qb>Ykd_D^Cb3V}gzI$IZxH5EyJiMr%Zt zbYmbksKC&{Vc9AIQPovF7Qai5fAapaP&GId9SZDUpD2A2c>tg*__O~%bYX^!5!pqC z3eW$Ftptgjte!+`wONC)8D{SPinslLBlA=#hqehDoZ}j(_H0TU3R(Y zJkvI9bOmN8&!%n?xt{M)DLAlvq&1z`{pYqNvj~Y!EfId|q`+=x%d!`&a90B3k};lN zjB;|W2(C00i-SS80g(YUtl@C&)>N3H0 zdw}yVL1iw!x?ExmF<}FYsi&@5liEC@Feq!TT`m0*^UNO`fk6jS;rU4W`}s(?jkv`hQ5n3nsoyNcGxa1RRAeS?)Ke29Yd)y zQUn|XA z>aBB)_yiikA^3gOoY8t!(;`rro@KsP5a*UYfN8wk0eVK<)dX+conEH;MiH)9l)HSY zevKha{FbUC`p8npzmhSoub$E}U>~^-k94M8u&grEyGpW+Bgu ztpPy_=sUpujacp}H=rhgctHp3(eLj1dl zvfd9cZXXi!$Ir9V0fM9n|5cF9@U>BbLeUre|13x|0490s&ps<_9&b~?pmUs$M4nA; z404RJ4!04|`6~xSX^d#jksb-v`K+*YdRTJD>(AQ{-^m}#3HxKMlZOusnXW!k2DQp! zjFr1T9hSWl_~iiCW{1z(=j_IyB^K>Dnr9Q|#cMBUgQ)I}fxJ0mZeJ_pcSX{6kN&=Y z?HRtun&JZ<|bE*OWUnnp~ zKzN1g%=VHv}|@7IarcT$b;*lgOoEM{wRjoxe>ZGJD7M4qc(Iz7K_ z|FiQqR3(lf_rwS;A>EXHR;-2VMmOqAHqrGi>!>+GcB1zm>AJzwk*AWOrKUM}J7Eoq zRltbSgljtD*Re_v+y8S2UxW20e3~a^aEH~*zHDn-_i>YpUD{M5X@JX+l3HYH8f8>N z*>q^VS<&d+hlffN_C01P@+ghR7?h%+k0ovKmedkY@BwiRJmd!`3|JsPo$eeJ>ICx&ZhroTrIa_?2~HiT9Zk_ za@{%YdOYr~`eOwIG>nd!|FT|70qKAHbw=pwz;c#1znl||4Z2f#BU7IcMc)T(Ls(=C zc;|ukAy6wfyL>~E0?N&-VUolbe%^&9%79c<)zlquts?Txqt4OFO6v@Y^1+bB#02*A z7{(L|gbez0c#1Ig|YGe{~4nvVBs;rpaw?t__GpV)89A{6uKcH8gwz+bGmY6xG z{zU6r_TTn}uI6Ra5!7VU>E+tY?TI(fvs91%Rf+V<{_S9?n%hGnR4*($i)g`=lj>dh z&rCU4{(&r=l$ZI*tB1=I|1KDx{pVEDWQ??@LejgewQMu#xd)>jZZ{v*dJ&XY~E^fE*< z7CkD}I}PiEaAINUq1y7(hFsMwVy8rVtC7f^ZhHgzXJ^|M$4%<^)$9{i4nyqB3%O|9 z&22R#lRI0LwjyS0(_P@_V*z3dm9jLyZh1PT9cZ!% zf-f<)0KI2V90M}V(>>Fg(Sxc-yTO{T6jvssUpG|0os=pvX&nWp{1Se;KaUlEbrfWw z3LU)nsGF^tL-%u-Z6+_Bx|d?)YYs)j`Nn=H%60i*7x2%`)4Jx~$4A5+uWgj_HpWhM z-L`Urj_LxPwIr*Lb;5>NQ2o{{)JZkL!W4G!@*1lryRg3WY);&6kF*&Z6UhoJqhR$% zRllTKEeKhxy6aGL^d{Bbu969PH;k8n+GJQ4Mo|@Wwd&*Mp99XB#A@$G7MK*hy5@?n z*=1G%PtWS8ZVwx^WbGM0%rL;q8jZE8CCOirC-)6y6%?qg3Ov4&k<#zo8UY{E4JS32 z23S_fNjq?2t)~4LMquBy1KS&Cyg65XxOl^(b$a| z+h${x>9|RG&PP8Mo z3B9{G$GJG6uC?j?*uxcFO()kQGG?G&a8)T0#S(-37lmimBE-~+qO#?49P|#a;JNv{ zyVSYrEZ-imwffwk{&8pzfr!!17rH|pJe?gxHP0YLXGVNO;t5~Q$P((gi)5e4OC0|B z4Oa*gEWW)X!J$K=zTjFz_4+5-?(;sk)cjDx3Ed%y402#-HbIL*wxJZ#6!nvq`At8t zc0w8`xj?fH&g|^hO8Ov!cC)9-sH+ZxF==9MIMQ%#$8vmFbyJFpLU%j23D|H7PD8)C zpF$~_1HdTO7)Ny|EWSD4PLzzNHF*JuSyQNk%S|S(*?^GB>GGP0xe}(ZPT?I_!C`2h z0}Fjjar#SYO6Vs@4j6RO#OGod$1|u0Z+w96w!mzF$J5VIxGA%aOJfQzy0o-wsXTXe zi!&6~7B+Fhv-Wz_4c~_SZT)I=eYVs&Aqek^xnMw)iwcRNF4qai8*b=p=@MUA%6Gh zK{faMobucAt&#bDLuKt}uos>JuN1%?nT|8N=^y&eO@#BG;Ku!*;MSR~-`}q?xpDev zmsWArqP{x+kwk>eie0!Ii9~;b>&1If)T+%y1V$$g_Z(Yj@PUI?K%XK8WLdgPJ_VL0 z>4uWY@w`x>3DSl{h^vR8T~}!QtjQJMc}W^QS9qQd1AAsfsE<$FkXSvOI0+f3V%{vhiJ%bw~#8pq_wsfv9pm)u^+DwFm+{ zQA<9Aq3(gKo@1kRD7u$@s^>d(ZGB1AaXVgmW>+$TQ-gY<_w%`AEdbsT=>Fp5^wy~J zP=VfL`C*!y={6ENR~Sa7gy%;{EB1E^#kjff&J4_9LqN60Nhgi@@g;5UlQIKQ39ati zu0_o(FDGtwe@d1I-%1tswYX(3?1I>P@v=!IUFXEsZPg18pQ8~1S*r4oknGNRzh<2* zZ4q5k!Os@aeb$K)Pfy{uTC4I{&x0P_ve@NVa8D7HEVcjSxI|&-P8uA9#5m|i14Gsy zr&*EP)q`i%r^+M6SKJeiv6$O0Tr;j8b3T?X1D+4Gg|Rjv|Gh$MJRL z_({tC6PA=*ZdujEO3fiKx@mtZ5~o?_Ix;L!HFfS|0`w1hgI@i7^{@;;9x!!&7xPM+ zs2{mG@l4ByIW|`r{^JhWL&+(x zsp8l%9`h#sUY*R6Yt111T}MiS+9y=tv{s7Qkkn!Uq#eXP|8bx9XxW?#5t`_Ap}ab1*~hU5tTuX;ER8S5ji}-wtoc&1dPO-D#D-X+cTvZM zwg}h;OKHM8!_acnpKtPY%ZIat`rjDfr0Bn(a43zrky0^PT9LF4l)t-b*!yc=)C}Twf@zl zNzTkfh&v8>nfV74;F-5KBb27(7s~!!oN)j%WWqlh_T}E~(LLRsA^UK}-0bV`s{on_ zNDvSo;(NLt;*$=~u~5?0o!8u7wL+eBqpzvs<~?v1F)s-epG|*Y9F&yNt;{{D)E9of zXc;}fIvsaZ$QAKgcpPti*a7h9@2%ai=V}LScMn4XgzoRXE__YNwI-E%zUPIf-mr8; z?kaa5+pmK})vv2MC5*9RI7PcrzLnYqNdiD$A~gCVnu?@*$#HQ%Nm*@{&a~21hQpTo zSiRQdT^8&BLn>W2wIjL}Pwv*L za;hSJC+UFH!pm2$AMrwYrpw^K7_=F3`&#Ts#2^BYlQ~?j`{D8|D8xc@whb-u=7@N+ zUnvSHc@fA|QE}!w19JAT%xR$LjvH%eYgH-#?IDaA%U_UpKj$A zikV3f(6yXshUX0&MS`uFX+8y|Oy37LpNJA2?2b$|ySAu<-R2sQ$;|Rx-=eBkBA6%8 z{(`%UvyM3Et?@A2=~cqGEld2-6<1Me^PN#zi^EKAyJbXY|2Uf&tA;1vC?nAlY~|frdnuni%uJPu8~%Hb9(&S9iPGBt<{iQiZ#b zlq`xOuPCDZJOT(jWr7|QEIG;jEt13H%)x0Bm@4m?7!DbdI`K#4&hRO3H@$&f%b`bQ zCL1rbc~<>;Jg|!~)aO4Z$8@)Yu0J_Qa|0NS)yD@7RUF^n`Tz(-elUvm&yAbJW3~Ca z)s^a!=Xj2_intWez*1{4WPh!Q&RABjOI^T`5hGl$9+a8M*dFqTT#Uz-D{<33cU8B# z^k~p@f~zFKu`%9u@AkI4Y8Zlkw23-HjC9`Lr?8MgY!t1tn|-J00T`+u4YI$L;yKot ziF*?PaMrhS=ZWfbNU&@4vv**JrPws4Qb3&D$ zxFyJ_xBhin`WjE+ppd#;;O7B+2x~VP6(kFfFK-<8H(F72>jE*_oVmx&PU*b#c5ny< ze;}dufu%=~#ANaY0(l|KGQyAZw{HjH$m%`YTTOVdJ79FA91DSj!aJg}d4egw{`avQy)L>OnTsYmB@#FtH%N&P>g#I> zs6xm-Sy#ksZ$<+r)%W)cWcRJ!EE@+3 zl9j37DF1qS4gVExUuHRq5V6wq3f?IyfOe5PX@GG#AuauCYU5BOrAh_`h}N_Dg{~?L zqm~~SsSyt(n)-~YhyIR_E!jikd$-ji7;7IuF?>;RRropx^A!ANg?VB^?7)1lLAbc= zhdb%i9r|aLsyP{O*yB2D({~xajCUo4vO5xxXK`|$?ZDWn?rEY%VI+n)u$_;TW772nmbqPb&xr;A7akJ7~JxjeG z*>yVTtRT0j`s;@FHDhB-gAFXWn)>OzU3DX`M7Wyi8d5&;k2OOQ>NjCkL{x}b&Nfh< zf;Tuey_1oj7^G=)cGce!8s)8dXa$*X-Cnz6Nn?NTWfh64FiXJ2=H~}eAc#5vDnmWi zfr@xd7Xg~kEEC^8*Wf_oH@A9=v&t|aYHfGvmc+c^A8`V1!szKh1_(k0(*-2L9U}0} z8ohHYSfuE&1))k_KmIa#xhb;gb|j7q%9-!?7S}Y@H0Q1xvn;`dfrZvsafS47 zlsF9~R_V(KMa%}s=MG<|X0(cOKPKDRtc((4x%Na%j#r$9$L(i)@PBAe!=!w1u0^F2 zxEVwTaQ`2~LXm^C8^{A(lE=rMs^i6d`R(#wclqAAxmUDV$Q)GYXloG%W! zG|>&Xx?O4gYxj1F$g&sdmIv-)3ANomUKf9$%;CJnMJ%F(`SvdF%63 zXGGvoZ#gp^014xDocz7VbsAvz8)zG0(8FVTJnW;*98ugRr>ZU`W2LnMAA6hP5L-qE6)ioq=IW7b^7Y4IE?iWQ2KD0P%M{cRTp)fO?=L;hui8=qj2 zFKLp(!X6Nl0}~vkpOyG|ZL6R=-jnagg^#8$kMU}z#y@BV)jvY|_X4LR)sS^gc{DJa z$Yva{gFxCR;#?SyI*zt}D~Zk-%A;qGPyMaZ9u6I)?bfWzjg~+pDHc7&s2a6P$bcyx zh==+<16YiFR7&^!IKkaW`{%vzIhcg1n#iJaX^(8W=fKC>KOufoqN+nU6WFhO0(bY8asUM`23{|c#~uazrxQpzh!61>YBcA zLHj^_>plI0^%${h6?Iri0Bk~0JQQ*n(SCjVK>mmKas=@p(%G!h`GT>%vyHqy<@)(# zYoFwM{C#Zgp%qH1-jf@FBuakAjkxUJtxS(7T0j$qDj(iQ!6GTWwpSNYmm`S*H}%a6+lr^M!ehu^rfATncT zy)Er-i|XAEGhkS%*uN3u;#%*P3uaLf8_Js3Bp=OA%#fOmCT)`mJbZpSf94*{R%YhO zZecq+zc`0>K%2^NNkXp$7AQ)@4E$wC-etW-SH%pA19;i!C9Y=j{z!|2@Aq!f?+7$v zLJM=HY!P2rMzj5!nfQR-y7DUCyAFOl=1jlFxiS=J}TZ=@awAon=btnZcCW@jAkgONaN~v?<4{lDYr7 zriMsK?}V0aBAVH0EdqrEJ*@)dAnBpw^cwYKff3aJSV@Yly za}E^EZ2Z!2!T~(?8N4OnCR@kV<0&q;t6$qk@yNOLaywejM=+4rdsv(H|(h5oCs1)>JQ+v9QWT0sR?RY@@gcDid5Of_QQ>Ind+KnX+vy+)O<|Xu4I|JJTkv84~;&|(g4NTQpd0Uxq zPz8v;MKLm%Kd2;z0xoOu@3Wa`&!qmRgBAdBuHy|KXd&hV1e2lt3V=Z*wjE<2I4F$x zu5{S{L%5~qxKM7&isTToPy*ZVyRr^{u~AEjg^@s`=)t?+79=yYFbqfn-o!M37&dYr zhQiJ8OmA-9%MUvwr=g|tFT=$vCP!`xG765k(RY^`!2iEnyD+y956A~oo1;sB(u&k`kP@!r z=2YB?v2z$#LE_s@w#izX7<${l1%q{%N3QgBQu&CaYnU^lyf~bu*b+urVh57%%g8qc z6}MhP0FalU%BZlX(se5~^mWIC))+e}02_jB`Y*0ANXuliB<$C8lIU@U)quD}d_R|w zogf~u;ZIsQr)zn)=`P-3{_<)F*s@y~DYT z2L<0)So#xR6;c`(C2pC$4{(U3lzat_Sjxn}kT%;rq}v@eKI|{MqmTtWGt(PB!sjx< zr|Ol(zu2#Ua8TY0>rs7d#uVc)^)0HKqgf(VP&N1lGG9T;=#+tyG&-OgS|yPjVSZ9U zyw;YZROmI0BKrhMhfwc2bncxaU$6Vj*!?S;88or=3l5UtAtT0ziz2!<5T17gjP{v_ zZS&^3*pgGlmMNcf)9iEVC64hPhntiz=fdA8H^6goZN$QN*isx5t+DXrt~j)7?w7oj zD{~tn-Vet9y5VD4y|#7h$GAf^Q}$CG%H0GmUSl=;w7*9?@R;=qwXsAws`mNiTM&6jNOFsODuu3#fr2n1zf7*W{|x z2vQ2kUAv`UK%sm;0BZ{)HE|%J zN^6j7x9u3$vR--XEd(Je`PmHmaA#Wghq+S}Gp{9?J7REM?b53DNj8_KfQ{`simzga8JjI!;E z%%ieO^X6D;;#%7ha+{@^3Je`R%~x=Dww?A{b;uf$a8{BcsdQfS!%r&7g`95W4bjth z+>f<=v}^)~5bX;5CB-s7IQbCd%ulKPf`f8GQQq6Ai|}RHtLv%dvtlj&?elH(}@dg5e_l+S{4z-So3;mvxG>vOG4_ zw5dtH*%s1|B>=Z#;`cwpK48n;j~DYz*Mm-+Yn?Fwm+)1(yLh4Q`Ah*w^y<|0)dIZo z`B0Cgxz$6_!CyW>2s-C|@?;hP2TV)%&EfnCoJBII9Sk+-(YlW(LAK^aIX*9h{| zn(@(*0im+m_JqSDQo-}Iv?bEPTU~ao0qvqhaAiC1h^}pBUwKy8`DWBS#hM2OMrz0E z7*$I!zdG@|?p*_aNa25A9?37wQA#(B4O;Y<{lnX~HpzySbIwi}pqs zWG`+-Mj1I86!$mdg-PA-y+yy0E3pREEqV6EE*&@WH`DMgv4R-^e%x0t>=T{|SvQ^B z-Ug9h2{hmS{=B3YY7jjAFM-);p`y~TZ}x2(xkib1c&|?HH6t~gDj`YXA`Gg>g?IB^ z69>i9$~Ntw@#WVdp>7Ba{GzYRIo2j(QrLaN6M5Q)4j@$Pi;H*xglZkD#XU*xl3afb zL=o#`(jTZ)hNW2#JC=2BY#hGod9-L0b!CXL-~W|>7$v{D*2^JjOQ2r`yHFFhqg;p2 zr^tObz0h85R>J{CX0c4C&9JWA?V(&yR3ST%Je@>XW`;H_NX=4K1>l=lR@!s-)#NrG zdwYPaf`mv#J;g05(e7=?-N}~`(URmh|C||CKUc{~v$55(^TMH}Tv~aAZFcW1NbvN7 zA0UM40ubDy_K~43I{!E$T!`#-9+&R*y{s1=LP^@c3CI{zU4i3db9H;k3OEC20b1W{ z&FcIk56$yDyYp;+6N&`HLemSGEO-(57~)xs=+j339&uT~FSz7OosPXVQ4F zED=f>sIvJnl{CM9l5f@7xUj)mZ`5&@u1CuJoADL1>*LtXSEG~NvD$?eydT?S%l$i1 zbXM}t*9_^n1Kr6rkf;_J=*;>vwkW7kY9E#;ONYHRlt=CNgk#u$@rd@?E2SuQ_`20a zJWxNBU^hbx?J1$Xwbe*G5T*^o?A@&bP%^ca5atu*#Gpf zite#%Kq3XbD+pw@^h*X+p6Vj`DyQ5b4PNxH1A43suM_5Vn>z9KS0&8rGfpfP#7%^X zq--7hxAgFnvqJ#rE_3gTY?gA07>lv@W$$H3J%jS7h!K#C)v81IzV?!e_EPlisCZAN zmoKIjviKulqrD}SI?d_Vww)|oi7vl*N^`UMcB!+}O<8%0&=+Grrx#P|IhRh0mM4cL zqpHWxGpn&p$#N;2xib26DYJnTQPH0oo!iNso+G>>s@&AOkWJi8`z zq#JM%=ve=IUzA+hya%NPpp>($&+t#s7#=N|4K10@E9zLy(|Q&*m;-VS4+52KAvFoI z-q^z80h{x}1B1=n(aFn9houFk#c|(O&bCktjPLC$&bh+GnUYLKU|h}MrjRZK2qHIk2r<5jJt81vXL~`f5B0MZ2WN34! zIpbI0!IGO~SFFDyftGgi9EW=gPW}}x%Wg~BWslf~1+)M$)2mn<&P(S^26m}a*YP@e ziu}a1$4?lP^f`f4HtM9MZcnVSf?f`Bv79c_8udzl>J1P(A-EoRwkT^)Xc*Q{pr0J6 zd*KN2P@{W}?_am~k~ItS#brx(H94XT8hG)p{h9e2z{(>Glo(*JSL+@*PMMZ9bwFy? zXeev5g4nEv{gko3^78J)&Dr*s>~&U1ne;%tN+efv`jwYZD|3u{&LFwM;B5ybiIocs z`(86sEgAT1<)ghorMEKSzU=)0APRt=sr}J3Og8(!tLlkczmro0+8lmaw0U=*$Q(ms zr&*`wG@_;UhcY}~E!U_65OHE*#3ZessdGzcYsWOazctd>m#9C(t*!Z)`^y7r2&Bd( zsgQrz7F8W|qRod1*_ ztakc)2)nQ5TB9ZWf;X%G590hI%5p7}r^rGf@(ojPToczI*ewubm!_xgAd;^`AV=k8 zLR>XqQq~a+wrF#-8rQZWhEkkVxBHs~^ea4xWJ7tqgpMCjJ=lW=z6W@OWj|=YI+)ky z=gS-e-s%ZI#o^hKKQ1y}=0I!D%-@Yk%JG6V&iAZdADoZsK=#-d6417NAqi@BUwmjy zmP~cq=Ck-}q_a9$i3q>O97U+YJ%2~*b*^&FwYgW2H(WW{+WcyjU}qpGd5Q4aY7!jh zA*7~|UN20yC!y*}BOmwD;9NQwUeezk4Cq2(I5_oIh!ee~wbdO2!>_dPnt#p#EXyh` zppZU5-}i}(iV7QdRpf!gQn350NuF(6$1Z0#e3rJ%X35OwOoKweh-MPl^rQl@^C znyrh@m{R(oYLg98gWOMhG441wEK@>8iN2hp=GS!@k zlcT`bYU{^2GF=(XDfib#N%-QGzHGR`kbJuIC#pL}GX%l+OtyJKpoHd8F7~a>R$eJd z_@A{xJ2adjbS5oZQ2p!Te?^RL%Q$D z$HnjS=c7b(xjQrWV&K-kmX00P81ciYH49s`{oP2aBy#ZI$GQ3N>bG7x zlZ}YzTaR1l9;AJtxrA_2qHyII!Ncy78u-GJ@=V>#VBd==n(5afLqq7%Y zx6*0eRInOQL%Z-5B!u2Gib*IKWFQzT2&;gkuB@s^;MkQKDFYgmuyK>Wa~yI^{kyr;mUVByL#=5wft4JYEGT*VdYPNnE!7w7j!#qU9NLF zue&A_Sv&&(M{h0{>CkKmMdvx}Eo{4_6mT?0N0C1t(7!m0)jOjDf>w^Mg)^ zq>CRP#ncF*=g6G{ke^jwTYqoQI&x~!XnQ+e)LOSrRvZm7LA9Z&HoXmb9>ILmsVhpW zweh^2V&QrH-_n}jp(LrGptH1wx7O(Y7%ErT-V&2Zo1pxNYW6p(+Wv48&oPJ^4IEGp zg}C&P`Rzzs+k4%+6dZz__-aOv`lh>gX-y;d#+ z9C6(TbF|(~#YeaZcu}u7uENV6fcRkba5G?B=}6SmbY@pn!1M4^ z6tx;R#kN(zL{0h?ttcuDHkTnzW{@YXUC*?^8;6H5-xRibzi)@zgq^m>dNnC{H$u<# zO9|U%M4av~nO54Ru2$Ms{@i7o`wwF?>7%fny&EUW<^^SgJ)ki}*sD{4g*@yiT*|>T za{3;(cgVSjQ_^!VkIR2(DSv#w@<2mQLJ;XYE?x4)Xqc7eH^-i$K*gbmsB^cnCX-E4 zn#t4K6eHs;G-QwsFY>K!zQ~x+c&rTgeTcuFNvl7{5X(hr(Qw15*Gj>k+~&o7k3XZd z$;uEkDYJ@oYz~Kqu}AYynzgNNh^m(NacS@-Gx&FL*7D##*8Usx1CELPXa-FxX?`%A z;^j0G6&2{b($2P3hG*gp6+9B_gm9E|9f@YE3Pd1Opgq~=_y@o=a4$sf>UCV<+B%YF z%6)dLf{f+8R{xX>9ZM8k=|$mR9oAk6Kuv9ICE4_+F4i=X4dj4)@r^jM)_QEPx0H3Y z;+l*WkG*t*1=j-c{-Br5El(&bL=o?NnJt$OF7KPOy~bVkPkm*oJpz~ZYGf~I31MgYlah@R`CvFi9)lI5AzW&l3IfMZvc+-T(+ z+j-wFf)4d$oi;x>6(JK5tpUTbw<^i{YtlLKc9@LucLU+tye+O z@(7an8b*oE2dO6-d+i=EYoBlYxjIT4Oa+i10-TYDRH<5VcV)2eqmpIfdp+IaKLW}d znNPJT8xzCWOX@t$XCa_^qwu{Q{6%N3Xg^Af8wj+TrC;*T0PmAOUMMjE^szr)S=!&9 z4w5S1PeI(<10P>4y!v=iUeR9*2hW$z{0)Q{Tg;ekspqa6Y8P`i(xBXv+FaXfzNR?x zpaMY$OzW=cxqAHj{x41UY;ps6wK_fb5k^`GyD4QbvMKD=&lG>ggBs+C#`6mFmX zz|C68@1Pd(>wb#7TjB(f1ezTi(O$S;Ln=Z1P2pHhD_r1qXz-iBwAs02Kl9oGjMqYTY+&M$uzYm1 z66D7u!ZM}{ZC~Kg|54vB;#ZiwXH=uNis3SIqsOM7?WlH-vr4&+(_4Vos}%XO9L)<1 zjj&Os$^d3wrZR4dcMGXTQv^$^BEks`8_ zW4nHcI(UbSm>kLdp>a`w2d0kH#X5ko{6dCH8O#tSQ~m!q7Vk24fMVG&sD(PaR$VaL zNFkO9dj3Aawfe=vmH?C*t32b!Nuk0=0qxsWIAQXRA-!)Hcq-gzRnwXER%9{^;Q-}c zxTA8;Q<8&OvaINsuM{mR|j# zV@4{?>$h+j{{{f?AAj-aI0=4XoFi)2Nr@yxCEA9U0^8_2Vq8m=TTHO534|at*LL{n zyPN5X^f+o(So155P~&9y)A z4O~<#stmwC==gcz;1KFX>~ENwf1ZZQ@xWNPs|W1NN&6rr>v579=Q+LAyJc?NEAb(e zNMm_o0ZTApB3c?Kch#9nfRlUsThNEYc&g>M9a|6C?Q7V3X-Rmluv3Di4k_JWa`f3g zN5)mQ$=;42CqV|#)o`(X>S?}@TzR3ftuyjhDFgl^F##&rX}|ZU76tlbeIu?X*k?Tr zreomg3>B1#Q;zuHSB-2Xy;4hM=0FOJWFoYKp@!&MtyslG%s_R?T$^Mf!QNks>tNI( z7k0J_ZY+y1x(>whO+O$Ohh>-?wB5MAP^}zkI4zxLzz5VeJU*!i703EyBZ$F37bV7- zsqL%3$I{N*I5yQD-U)sHT;j3}S4E1%X(dAyo95ycCcoc*_K1&c^njF~r9{S*Ov5J7 zJl_!xwz)5fyPBtv8ZmTV3;f%KL!o+pnK5x-iE$r_celTcyFSg-X2BhWJY{qP6$YY9 zMxmZQT6rVG02MR|fM$sDovIcSCsEN;x+Q(%2N~oq6U9PNYc$l-0r;%`^xu&<$6BT5 zDu*FruRX;UsBVBSQ%1SxEZ2|=xU}YO0<97zF0ZiGD+z8;>2SJb`=Lwi| zdP;K%1{-|`zRNym)y=9HxGXcVq|~_h8%{L^sVcUd#U2!ddgIs)a22E_YxCxxaiKk& z{CKa!jIHAMo}A4c7T*52nyfTKa+FT~Ta9$M0gd5&l5;%R+ng5s)AB&SY55B7eR$Ox z*pQ2s(q_JkZ2^?i9!<0Hm0?PpV|NOihz zpVFOTRKGOe;TLoo$^%$BD;%DCeKk~69IDF(O*;!hJ0nmiij&D45j=?3;%s9TRRqw$ zTa@|FM?e6_V=SyIlsT&Dt%v-Uw%zpprp9!G08!gfs;t(&c88rEM?ZzRZXmZ@t9eT+ ztudaE(?%VPL~z)W8lt}<9Pu^yp)x%nLVd821(O+2KJ_=+|rVljtyK~RK+k=Iai zQ5d;U^h>Vv5CjLcRN0^1`l`HJ{e(`NZc3LtZP&*129|m^7f4{Rpoj0SGCngR`*|Bi zqE-#6F8F??Y)ll+iY0ZE5k*&G;5uR>>M}@ibVO z_+H)AHD-AYo>Ysv+>p|A@yL=j;xa5>**6Qg_|0<#zbCU89LY2iCP+fwzTEN0Z2WKV z&x8M&!YA+6{3Fw1;-5knn5as!0>uH1+H#I%-U=p+hp1Jte0E_uin}}ZMNU{(`wz8eQ1Efau;4O z4hI`TN3%3sxJT-Myn~$#Fuf&2teHX&DppoC<)L3jalO$Z3HY=QCD9l6&pm|s$%Q_NUP+ms5PUT9BZ<0;>pgQSdGRZFiM_gQZE>e~ zfz0;pC6Az$BLBG7TW!73!(}%^0HDG=XSsd*VDldj=FL?;jx`(V9J2n#@?%_^XDAy+ zRJ&(+h2E6Q?z81-nT1a~*t-3rWz;fL=}R9K%WUZ#D>pSM*iAl3`cpX$7<3^|2`J$HB&g5V4oi8Glj42o^^+de+aJES6977s%IB}L6rAe7@#Om*q9UCw zQKcebd({guWrDmj0PnNCyZFbboHE~!OJDX4+8fP(!y&6MVH1Q{{01a%f`fXX*62XP zGefLJlXt3r8s%W4@z;@yLTX$?DqqGv)B(+hVJ)@Ih%AE{U5StQdX zyXiBLn5i5=GZ6>Hur0dRPoihq+Wf| zGeQ((T~HKfqv4vmpz=sN><*q8R0Eysgz*4@#KMWB4)n97W_H_P{CL8W zR-q6a?^S+4-&Xij4eBti255~>y__wYO8Z^WpKyZ5+{m&*voa6a-_RukeXYv zW0G-rk*qvhtPMLBNG!(CPobr10MTB)xRJL}-SQP}Owz=!WV+)6cn|A9^7W>_kV-ui zK@%6)RLT)S$yeJk<8POJ#xa=R`z%1!1IB4(qfBqX9zcnJInATTY#1qDj`_EN8`K?k z#pq{;zv!N?Jzl9trZ~Qc0LJdC#N{tAf7H^?P1#;Qgd)sntH(~KQi<~C-`FK7kSfN; z?931W{3M3s zu#p)vC?CG4GKLvc{6d|r;WmmcEF%3}FHcVoDA!A}kc|&#t7OiKJcnUJ`7}MZfF35} z`SnYRwhq6nLoIORLilD0c!k^7!e-`To&deXIR{+d`Lzh;Ty&-Dnhnz<08}nnB3> z(~etr7pItVwxxwrY~kB~%|>vaUW|lMdd=ddI$m10n=O_x5Dk~txM`#Y zI?OFjK0)eXmGaO%L0|DW&rr;v#x#aw6w{eO)BzcS#>CLf7_u-e0L!{QxJ;>VeNS|c z`#AKpmd@CnaeCYmq~uonr<;UTwWXj=98^H@8uYK>`hcF5VmJ(jdKk)JgYk)r5vOg$ zp=C~44ft>xLg~`$iRAAb!g(K2+q~N}>MO4KMucTz#VTBPPSeC>P;Sbc^i4k8wDQlq zvtE3k1)l_Ipt~Ye+i`d0yeYmR)1|?{2oZ*JFT4dA6jnkP77?Uws>yYj<^!?aWz#I( zAr(R5 zVBo^(;`t97KYJ8HzBjXX^>@=f;|g%|+dXxJx##81%VsyL!=_8yai@r0a3{tHasmJE z*90a7+W=J#?iPvRdJ-|g>gWY2zV?G_$389$U3N2uX`3F;Hk{b)!8vo=OLAvhiQzxE zjR=7YY2~A^$5|MzG!Kx8rsWryOtwPS{_uENtk_{In}It5`YUA`^|d;?de^WX)vnYV z@sV`d^yf1-sCDFgC7`mEEq%Hri0;mwgJ#>F4n206U zmC%Z%e}!k#T8ehxAbIrKaOKO=Z%|L?Zzj$x?V@CgyNF2H^F<}*WE;!JQPtbT+PLIL zol@cklDB#Y#~Ux*N@&Ng@`rGss!`+2v&O=kCzGH%FPOpIosXQ&XDOFaQ^9{$Ek0+e zjAw6NvWPM3M4j+BZjgD&rTc_nY;S>fp0Gi2)dQ+@g|=E3r3BH-YXF} zBm}(%;s#ZcpMfT5Fa%e>2GQrQOO?0F=*MOnxs(eBP^VS+rZV&;?YCm)+9i5Od)Y;p zQnsZ5c0{IH3Gnn;vg7wdD9MslfI}uHl^@q;$fPXD5&t}XvGOm~J9yQ^zW{`KOF7u8 zWx7FCMVVut@Cpma$~L8VsE>lkve-3CW@P;wKIF%;!M#o&c0aPXiLFqx%vQ-x4gTJ0 zRGfv~2?|#MK4z?Q^7G6)FBux=31Txh1roE&1v+DD7mo=P4YSY_hINfrjK70bTHLpj zvopQsJ%xV1Xg!7y^w24*(yVp4n>e%}`#_F_2y!qH@iF)CNVb_!QX|l)VAt0?zY?v{ z=o6@0S)T}qury?BIrg$Z8Pve7MOm>n&gAzidr#N4(gN}kVY%yhIa8q9pXy)5p{E#H zUU4H$Gy(dq8igs)@m`jz9{d9cu=;3pfrF%``A29UjrUxLhIig7_tpSfn+@_~8m-%9 zNR@UW`rnNcJT{nn)z(@zw?8VLziYB3KdGujZ@DzKnS)9__0db%@3|qE0WUanS&kTZ zd}me5NMuLgv*Hnd>mznq)(sRY4Y+)11nA>{xD6;#%X#K|yQ28Tu%Kez);5WAq1owL z*oFBb7+>Y%z2hg1k!?cyJAm4njQHO1^Lcf%LOu4a7p_UM(8%ekK!gXS z2M)e6`KK7wX*t2M@(+L@o0r+>6or28l)8Zr2SjJ*Vm6ReLZ&b$f)7kUQ1t~dM1uCW zLH5F52?<6fHBJ`XM<#IFm8^zp_od|+ zgpXEvCcGTADg(T4NJ|R>hL`KD^>hWasN+H8@$rXZlWloX%i|B@l!fL$o+@Z`^2W?< z#ZH<5xaGn1P-_wa%2&M~T>dGIYkDOAiyK5qe$#^5m-#tLGLXOi{-b&>9`d!g=xNu zas*K5%yCYR00Z|4`f~IspLWLg$g1kVTRuYllhD|}tU|pcJZ$hv4;LWp5(Cx6alfJQ z+sAth%R!AAe3mmpUcJePq%oOR2&AZmIC5nAc_^mb?1Ex?aBhYi#LC<2}-e2vhOr!w)=q9ToH` z0E%edA?(O?m}-1@l4CNN;kq7MSo8R2ziwYs4>;^13!7-w@98QpiW@;I&sXK|{V_jQ zixd|cy@8%e59%=Z6Z!lX3MAc1>7=7PTLETSSWfJP8I*xNa2x@GF&FPYG+{CW5JJC8 zX9qVV7HaHM_E#{Zv|l~}8@Cv&h_|c*2>pieuM&u5!>1X3cD&ya9a#JJwgIN*zU{fN z=G(o&M7xEbwynu{q*n(cyCfwQ_#qGY1qjHuB%ag>y)m@YJmuS|n{|n?VBg=wExN%y zMdxObS`H8JOJ7?CGxSjBY6?oqKl}Z{<_l!YLByS6HlPAk>kv1>lc`3tSija<{v9Hc0;+OY@*fNkyF3{%qMAnlZ&uox?dqVIC{>g76Ug$U&R6W^4AftwB8b z-tzn*=lMvsCOPWrnL^?s`b^R$Wa(u=zV zdPG88lxWgGGVfFU+eE8zUQ*%uF?^)V4lT2E#B4!u1KnGFsT_ojh;G5o4b&+hMUN#q zYz3K98UG0S&J4)*<$f5bYy#FxZDvIht$gvf@gA$XvA>U0^f)UD6W4&%+2)jEf5c<{ z6RS`>u)lB`OMnY;D~+#fd-Q`=6g2P(as0pT)j9{VXB2>m7-rOW4A}e!ie3Nl`9G%4 zDlE&bjn<-cN+T^uw{#1LDBayDEz;c`(g;X*cb9~8cXxLqz31op_qF%=I#~kmob!3c zxbKw+`8&SrI!Txp$j zmSDST>aw982maMyF^$dKbWq?r%k9ZXAcc_hV|1Q?R?}3-qT#Qbi6Mr>ZajO77&sB) zZ*q0{++Z$BMqjnn?gmNxB=>i>v`BCbbKIm8yOCsn%53o+Gm2Awj5b4a-*mV$L6*G8kG zG5>ySQmLcSt7g>{=>V+ntOyERFi-i9U|8N;Ngu>I(L*@Ufsbxib(0#g5`?k%HL_s}j^0MgwXn2JjKZfg30p2Ac^vg>ox z-nhiDsovwnbArYOx1kgI%dsEe{$L)~lTZII+n&+*J6)a}uUOvq%~iyiW|^}yC2H$T zpHRu#a$Yv*RJno#`4>HT+9WgN8_--tT#PAA4|L@m(5jGo+3M@L3vJO z88G30t#{ z!^J(yfwEb$luY?S=eI`fc6nC0*A0)A7itYKfhq%^Zg9dVHLV3%lLRQOa?GZaI%f;0 z4wRufZM0Ovywd+2lCaP}ijaB?X832KwPRk~Vzf_xKGDC8WJGS<6Bw}-*n;5?VAvO^ zc5?>=+m{{)hYV^df`O}C zTb0E#L_2xOCSs%cTyT{0yYuB@Fbou0ilK=MrK!T#o5Asf(iJuKb@)XHZD*3hC0MK= zZPu2YLPJN4f>PQ!GZnY{zdDpb>ChNZio1T$IY>t(Aqn!WNji(*qEB}OYJS0 zy4xGaggJM0!r8H(=vK!%?E=7_@i>E&_=(l9mkn#x_ghVqsF zj&0)c)DOiM5v1c>xe|?e5QNIUaHIREGE{B@Ss=rB&tEOWTQBNDXrm4@C{YB2sM!pW z226>6Smf5~kE3(()%reA!h(fy7|qkk-sBQ>Mtx#jcX&rvN%fBz5O!EwU{!*B6dw)G zLP<*$r;cd{1!`9h|}GxqaKstg10^)@15smPsA5Y&X%|DM9K$ zaKO{dOjC4%U&h<~!pC-bj>F~bKXTv)>3`(FSKm{;35E#Qp7?)3Q*$bMfsxWK@DPMq53HS>GxzxPVigTBb39-4M`B>f~x0 z4r!v&wxJ5*?Kd9!Mw2hGGr(R`=~(lggzj*AiPQ|g7t3G#5GNW{JsotAK5rI05cZPR z_m7yGk_3bQDOthCZ#kYlNx{fQv2@K?g}V&rliCqUoX0ubRs?vsqyR=WPm~v44sgf; zHt9LNp|LrFM@aNZwZnMYVkj(xpD<+(nWmMLnBUMTT^cyl@fjF?SRl)2oBU(!Iq@}O zEfVCOixS9{m4p7FH}Qr!S0^vvvL@*m9O|g8JoNosPO3hVi28pSJ}G)=%6BYf`4bW$ zq6U_7iFQb}MHko_mnH$`!qc=(r!+5fVMfw0jEFT?F~%FAV4MBse{(6<{6It&mIoue zu%0N$xvIKo(3R|D|HDrbnw<_$LO@_NSs{I!nHbCL>D)pIM~to3yDPBtvUmPRyLGnJ zD*(tbU>%hR`^F`y23RdQHu-Fk?3@#dhO9yWpqMXvorECGAwfbAqB?{`RLsiiN;AmO zVUqbTGAR%$;@euYCi@o|*{;ZX${s{ zks!r(NwXYDn@til*(NAwV~SRSDOF?3hu`xYMWXqMA=78Hvv$2z3^ECnrFr6rXejym z;9{nU!xj0DoI@7!ZOaUGSbRRgB47-5b{@kVe{V3e)+1Gr3~PAz*Q{$L-G*2&Pl@{q zUVSeA7f-yA#rgOAxcoaIek=`%x$N4n|1I%3rjN|DW^6&W_rjca2OvfZEnoj54xZ}h zzLrLTMapv+QRO44)v`1X5@RRGE){bAS1M7E>oYGWr4Ig!R>-1six0+a&JA@JQyyA$ zU5<&^mwCHZiG2BbI%w@G^r)?wUo2ieXuF@m?w%)DKsM*Nd*SN_7EFAYKJo} zvR=a;aFuXKE^rymKpK*vq6i4#bYA-EDz`8S@R6$!2EoOn{A^&u^~ zn#2hQq9f>)ce^cea1Hhh?e_0bamj<;pPqnnUPh-|4L84jYfHlk&NYL}P{xFkupNG$ z5$-n@nQt)Y$9XJ_9QPj>#%*FhFPHXs&+xLN@{tDP68;bVe^H`m$;vis=?rtOMq(#8 z{?XfAFif552wcA}tq2NztPCbqVwYA$L1?SHq%6pgA}Hw&@pbk1;W9H8fsFC->>aZ6M2%rOQ zxryw+KA`L~xINWZtT~aDZm&|vg`z6x(H))qY3}7D*x}G|bA$wLLU(SLcoI2lySq>T zRBig_iue*fSPH@gDhjb6?l&`G!-ONBLjxtp%P#W#T+@hjG0Km{NkD=+MF^#Q!3roc zt9I<3H4W;OccvV(g%oY!jq0G7OS|=&5E9<_Kz1(q{Z&i*_g50HM_I)AXx5tqqnrHW zZ&4|0j6Ml9=GMGY$l|Mzsxkh=y`338{8nA9(L3++Q8f~a0HKaX5QO-LSF}WKz;*Nz z;-ZinQ+qe`W4!A-Smjfm+6q~w+uADYp_&uZg@P85-=jnN&!6-BN(fvWrwfp5IZOBf zr{)`u4S(6tHF@B0{3o65h=W<%pU5Yn|EDn z4${Rd&LD0>Ks`89;DK{hM6V!#%@9WyLmWpf3+onAFLg|ji^PEjIiLZ%nwm1wn~mPU zHRz4%e{+*J!y-but3E|iJT;#!c?>JH%|AN+3!I)30#ELoMX2H1kOlnn+}&T_&SCC^ z>>wtpYRxIcvHuIjr-U_M&1*6p4-ocSE0^Q%21o?2WkbQ{>j=J2KMUV-UW<&kvcP~( zKDIPbKFpS{|qPK-98@?v8-9FC?OeC_I=}R4B?CR z>=*?}1u<=Eas&+cjP2g6Xk{I4RnOUL6a_v`VdmKt-s&~a_Sn)pd3b4MdzAocCbs-u z5K=(j@=iR#+elHhoz+oZ;Uuu^)&eMiXr_=utAr<6GJceekWyTKvncKTZwj-E&S%Y~ z*vt22mwmU6+KWZNc5uu)Qu6rnc*!xt#OG1F)$P^cj6H>wp>P{U^+=^}f-L3$ORfFl zO<(Pz9Ax5Mt*(ja`fW+F-%z%yOmWcczA@14cBU-8oas~_7xsX8ZnvdZJmq6W9%H-Z z(I_u^3L8WF6~&jd#!Mt&H<5n|U4Cfq(R^3befL>U6@=&-FFu+;aQEpwv&l7j8hluT zbSQ2;T-LpAjcrqcd-;p&GZyz7j5*?rW)yNzUV(|jJ2QM_;pBCV%2m;I2i_}XqPfr> zfj&dHtDujeu=B%iuCCV-^MR@*xlR9y{i7!_x%25djdE>&kmiUvQ75EUvNO{sTeLU; zJ2|k#qrx23_ktLIqCx(|f~)I=!8wHZK6; zx(kYn7W>{olZR3dEen(+Nz*rjf8V4Sa2F;AsSjnDNxOE1n69M6BLK?Yy$2J6xRHUf zGX6qBf5dE@vK?fC-(}Ydm3tw><#BKCMach!|C6K85|Ai&L{A~+`hK}=dM9(e%=hCt zT|MxvM-%bLV-(|bQgw@OeDjCKFv~qR5!{*$`QiVe(*o=OI&Cq|@oEHiR(dcE!=>zg zuK$eaf8;c~jlLokr=)a2Grdd#EZL&>fA*8YW<^Sz;~du@Cvr1!#!ki7*8 zeH0t+)YVuznR3#MxpLKUG3ux3kgBkcka$QqQA_xzf@pd=ZJ4{p{oHA4Uu<wo-I4 zpXFMh(Jo{KM^ch=92U|Y%(Nm^MsN~Q+IK?mEvZ88KFFZtQG~<+1Yae^eq)ZuV!kHw zZG%!@b_hIwN;%<3zAQrBIRb2}^YA2E8UM>5Mk_jJSHZ0}D+3HEf}^4%Hx zJ*#f$C^mS@HkV;1UE!CG%3kL|nSoGharlmS!Y&++fN|gL%y%g|MW?vpnMO8&Dgm=L z4usul%wln7yrd89p;HEp-1o6q5Lz+y4+OGUN;QqTF$OukE+^IC_c0?scFUYy6(Im! zYT3$)Fom9W`f`ZK0cA~EHo5V?*WHvFHH})Uvpv=sNqu{1$sI%Ly6a?jsH*SNfkIi72GV%wN zjLUv}lnQtSal6SCDAn&4s?m^RR>Q`XoTy^nUQ(O{UtvnkgrlUB^Z>fZt63Q}158SrNBLuHO~-C-ki6cvDOI`g`kCiDf}B@;3?woV+Bzob(% zFKYPOhkvVbUbjoeAU7+>Z~1)$YC)b3J(z52 zD!WK?jC@91ehKGM3bXtMI8^5iWbb%^7$`*>ygLhcFB$jIL> zeA>TXxKP)&@D?mK9{_$~aS9UpY~gjKd+ILODjS{aqCM+_k={d0Ya8xq9nDQ#@$iYR z7TuL7Mh9%jYcmunA0wIQ>W71m7yAQpci$d_o(~gna^OtYh`No1F6Qylu*sHo_ z-K)Bss1v*$l;rRk{JsCi$06&#rkoBuQf(F9?K{-$7xVhvqS126oIiQ^l-^6FSnp+8 z$Kf$J#RwMf>6j)?#7w=|SfdHagEwc^w)=*>V9*Rd6p0J{(MVFmaiDxNFRm9XzrtDP z5=OW8l8l(&(uLF52Pb{B^HL2kVyKFY{YQyxFYshhA}pM+OFty_*D!Q9*@IRa;m%Nne6?Kq_^K z;D>{#T_HFFeBE22(kj6{{Jd)F1n)1(G(sKwc2oV-Cx<<(9g@Tr-jSJhzOw;WA?LoM z^#_3}+qHjf{Y6I|DcL0^68tW6ExqRWbOaV}`_q&ZwA;FB)g94FsV1AvImP*SZ;kFo zo4|)rIlxqB+V{jpB|$v8<^Xo=t)u~pM*OXjgWwCrg)D6H18BW=LS3d zodRciM5`)%RODZ7xrrGUNH9Po3~R98X!`Ee&WqYSQ6^RBJ_Hij-@tLyjV6N*aJ zc4uFfSIR<9Xv}5R&k`KY3PP7?kFzN8Mt|73^$Vb?&rEdyuZC^nlahc@M5zRb4-TO_ z%i*hQMuFt|SP_mKXmTZw`cBV4^(tmCj8i`2p>6@Zz26{V|5U^@*dx+;UGqU=$ zQyy7JLuqD0@;?1>d&h3|kU(7_Tywnr9oCAn6Z&Mdr2TU1%EeVmm0HdoXJO{T!&#!) z2<<)TX$L4Ss8q-QO$G=IF07Pd@YVmFfs5DW>^tG`mqCU$YXo?yUp*==(bp-71|D9y zC)h4l*sqvzC+P~Sb<`O7q9DRQ(g-P_6+mT#F4Reaab3jD2V6NI*Th1zHw5#u}WbF}|}F#VADMTPB&4+$Fgm);F*)8q$9 zxqRVoP}hso(EX6Q2VZt^k7WvywS*YX0K^b-JR3^+`Q`Sc^BDjM^)*BAX*d9%)?}N! zsMg8NdCiPG9Z;1p_?Plq>7-o9zG6by^`D0DmSJ*gla&(9pOI5$bN)XP{e)il+RraL zi8lQAh=@f(Zgy(d)#hWKA$rxIZF>!yC*8W7`(wZ`#q?|uL~Utlh$m`F8A|b|_r6{# zn(ulq*$aEB#f~1!zH*^nabI4&eQ-YG6yN&ZN=SvsT3WIf+sQi91{EXntl)C{de5sK zvaMgwM7|1bHptySwb zHd$PdJYLUX1tpgzm@^1<_ma{u-gdO14`1SRJ=sIds6vF#O z&x70ZLrN{{%Cd#3(6|ehK1ac%sb_h^FFKXODz{og>?l!ZAgf*qmHPr+>I>J^l(ToQ z>mO7@l-Ix?n~F=rV13{~fHTG+1ETq0_CmL}Qf_Rs@rCr7$ZXz{nY#$ZO6cvXae`&a zf}4cQy={+H0E%b!P?Hu6HJIcsERVTb#o~wL6Dj9Fqw3JSZ}uSe5Zg?^wO*f_3Sz#c zRjSf%ss>;I95pW%@ZO@`45A>*?1XIF@z``-gJBI^X@)#{K9|oB{yvrvdP=d_r5V42 zyP5bU5%N=8%a7ir7#*BnmtZB;;{ia2HMxEBLY$~AjsqoNBh_)Or-M1(dH_3$8YMnOZgj_FI_1Zh@cQTpOy=Gc9tko$-w`*wJCIc+AJD7on zj|)R^q27d)i!1T3Y~Jg$v8$2vYMRm>%(*F>D)e3f2I!a$g9eFU)`5emq}WD%>fMx0 z$X;-M{@(=A!qj%Zpca=TLj|zranKfg*)B^lHECL$I)aUUJt*9=nS>9;JvIh8+j@yq zPO4iFPVoA!k|wBHZSA!;$9nS|4lj&@8JKuDlC5xN+xL8ZfS&J4U>v^3vY%F-?2LXUaSnx;6C zcZwD}<_>|&uV>4G!^baEK^a^z-i0BP>apRyJN#3}`65Hdar6W;E;T>C*5^St+O{RD zM`&oR*diIS+bK`Ge00xfg9A@{6#9GEXZ(&fMmkrh7i1laDErey9$_ulFCYLJbW}xt zjK-H4 zLH9bVi4P3vdGZGBKpF-9loxT1BDmW6bGX|Pc@6_x8neZjG8 zk}s}7)!keR&7@WxDu{#=SMbDv1B>5d9N!-9RZ+C}?2jEh{;pN~KD zp-nfigwO&A^O)^d$kC6D+ogUz>9&-%`?sF#ZAyx|y@WyGxa3 zU7lMSjpFt#N7K&DK=;j#Z$8{^|INw&hKlfC1J_1OA6mLh-KcdWmH&wa&^@2`Xz6!`5i40 zw1g9>S2LazaGxbCAF0zuN zA?$pR5H{nRV#K-xw-!OTwN-+2-X5l+lVqvPPIEBer)8?e|745;lg8*orw_n_~o{5D6tG5)izz{c57q!L8>&}ey)Io??*0$ ziEp5<+}W~|OL$$%`|ye6mM-5T@nAKSwr;wyZ7#R^Fo~)l1H%mK-`hKA-PPtIXBhCZ#PaZ*8qn2jW{;5cSHHBs_5KYe4N@sp{>&S@+uyUx_niHbVnD zyj-D28Q_~q-o;s$J6ZV}whfTEn~81~OI^j3j#_7~FwnbZ9=C6ZUo@#xqW!Q#*~y&c zfC>y!BMMJo{%&({-2(Z^bSZgv9_O>+2Lwd@!z;OzlGL=Xn~7^}a8Q2BL4P7wE9vh? zEn3&+yfnZoCSuNVv~ZOh@}3`Mg9&(bV04x6u`ntsOh|sh9d@(0weIjIg7p{LV^IKz zQD<^By7E^sz;LTW29w*;L)EP;`N!F^Pz*4N#<}jjmErmJQJPI#cw z*`Yz!d>(z8!$GbD>2I&tw;RXv6l@4@B>cb(2=x_ul-$!^v%loDnTh0+U9zXAW8#v+ z!oB95P5RVVROAX0P%b(amQ|31SB8mdGJl$84&tlM#dk%vA)Szyg5!E!BQL?^ExNd@ z)?0ZxtD7>%tbf7zUvmXJ0G8WtO_$rxbz_Bvk_&hXI9>ROHMtU2kjD6`R?mtK znSu>u9~^vPiT`aKMpd}J*?55Xl*Mj5b_4!nVny@Ad4^ErEH-Q~Legu@%l}tmVdk5D z0p0Hz9#_Kmzc;JNVG>La=TAwkVq+L&xx?C01{yF{NL4w(oVH0U7d>VCr?H#DA_vf` z&VeL+z1P+AQdMY_3slx?y(pj}+MSgEe^P^i*+%SnC`vbU!qQok?R@eE>vLm^sUik= zvi7OKbSOKn1`DByw_0X=od84aLqk!@pXrY;sIRabXS z7v{A~bh-Z_->yCek>W{f^V<|7)>OC2kvxy&u=vI+(b-e#)|`2K&Og(RBZ^W#zmM*9 z)Z=QGsDbzCrT0FB|A)pIo;}O_LfD*2-alI)RjAY1GB5VP{xF5S#O^kBhV2%Kdf21f zeUp0iPOIjv*68$EU&5$Pzjb_*a7v+V??ryXIYYm_44azCs=5H{{-ersF~Z*De!rPG zgMr6y&fYZr?Cn!T7CI>_SKdG{FN`P$uP&jFfoT&FvEnYZLi;+xZy(Ww`OO(KZ3(Ad)-QqQS1qg!ftGnDM+|}(8wskIa=N9 zTCgvJD=n|LQ_XhND+1C*68BCIGi0h{tSFTes&PlcvwTJT}59)Iw==rp6pj+HB*eWy~5?kw61>**?1?r|4~wdFe^ z{$+kAkvz|0ct3jq-lYBLylcVI5N+i*Cbvfzqu}T%?z|~Nqbc*-!4D--Wi-3!LZyh% zeqW4#&5Fb47iC%f39^KN;<1QIm| zrOTe8IYqJqkDim3?TTsDNz{1~IJq$0a`qem#?A%wN%ld5!l2z}`AVAF(#Tq0=T}8p zYVvAqZ?71;KW&YX8s><5+-`MxK6{)QjT~M!^iFH+Y#%1h@6~!mGw>EV`Uyk(+FKYk zXPN?hAh`Zq{eiUzIn%WW(Om}fNfDf$>Hx19sqX@LqHpylS-Kn=lfKR! zxW06#1Ader7IOELRQy*qP}+mIRvv?e%8URnWyQ!c@)? zCgd24n*ui2cO=Gg>R<(N+eGvIdZXS{$$4FGng)Bp(UXW@;J!Fv7AdyH0eQU&czRWs zv`mwU?EP>yizf%n%tBL?T>t~6W)*B~gqSJzv{!5-~D}_&fu5>6WH%b2Tr9&ZfCQ zuVo@kB>q7p-&wA5(l6*~2LBdhIq>RyXkQ_szbb>{%tPw$_&^ER;gjFYna?QRWdC|s z_{60$lk^ujn>60BHT8lKYJ0o8=Wu)b&@SGMH_(+|#x8y-u}Q52+-McuyS^#+7{ZFG4oGX50VeKXKi@}7= zYYvHDNDL%v;8{zq%Vjfzso=JA@vLoWm2+4;(xUBWEiFo*QLWYg!NXY9Y?Yd{vaOA(Q)McD7jAl|LkhWM5)%< zTb%*I9TF{KQ6cOBFEs6z3W<&zmteWgqGOU)p;|!vW4jtBJ-`&htPnqcpKs(Y&qAkkPPvjh zZ28^f#1wTMkVGI{`uhIV*3T6mcObj6uekV^BnWT^g6FdUbyD!L@yFbQy(cn4A+TO6 zHr`uU>QJMDhxtejND<;{*7<2w81jG(Y>GuEkD8iZGKHy~ldl$oDO*jD99$phh_ZIg z(_HNfROpJJ{4=T*%T!kBq?7anWQTiE z;@o%CS45?SxusHuql&d^kMTRYiYJFhZfQODA}vQ`wwznhK$7rNm{;1aEM$oNz?TW< z0U``9+s5y}Pse3w{Q&>|u~OBr0QC;2?s#0CCjD*VjIelisdUm4a>;0bizip}vZU&> z48@yK#4eQF*|fV>jH#$ma~Y2gPy>J0{n39P8JS8jkG-b_@=nVyI9Y}c4ZZ;DuzAL= zdhLEy1A?6OJ`G$$@BrxKE|~(?Oyr#pbaJ~h1)7E5hP{yd(=H~=a)7i{yl)^~nNs3U zv10##ANndWq5)b7a>_r~4#57W7VV%5`nBUPnL5k;eX|tz^_vNVwQnb;@2lD3L~REL z+p6)cj@av!jC}eS`}sZl!c)COsA0|#h2zh?hp6Rc^;aMKKpKURX1(sl=c%>TV*eqS z(cJ&pBQF=l2fcCB%KG7|3)82a^&^wdEHY|oWtnq@Kzf4%xBJlCnYb68G9640nDDuLg($gyxUlUhKt|z zkXoD3B^>|L6l&t(IX(KcH+$$f3VPUSc2y9+i;|gCtxtH@_9-P?VCZDx3M~V-qH6k6 z2p9^Sf-=AK6g?f>QUNEY%WT=h^inT0p12EMAL~mn`6jXHbK;dm&^`@6kaAbi+9trj z3a~Wj+LADyrO4<{#=}27wAYdjj)JVrzCP;pzKbnCGL=90lJD@&qklTFs$qpSv4*(^ z3dssA|)02=>NbLn4n4MWEC(QsX^xk3LH zhs<6DWr`Z>4HvTc+y3T)(rJej&BVy55H(AUOMB7hrMbZv{WvQEI;yuoSL8l$oRd%# z{=K`RKedjEu0}FPU|nbA8^%<_%pjLUVsRXg3k%ct!W4*=L7-%waUyL^1h2T0i5w#q zkvVvfxHsY-^h#fNLUpA&pJS)X1*gPSs>{lS3D<2Aok=7M>0a=?T&1Ilqy5=|YisU` z37R#hT?|2EZc2G1>PoSRja0DF&CO4W$V{jGw_A@(_Grj2r*9muF{amQi17jSIf*N} z4;*rB;@Zt*XJOtS$Bx9UY*?O`{Wu603YGFO?GN)TS$Or=q^U+v( zk=A$Yyu|`lABI~0fTq{Ri0{<`+ie_r)}J3ovg|ik56K__UPM@kLLps zIuKac`gKRt7uU7j>;RuFr@(9o46u)XLEjm7WHF|5;5T9N8;dcO1bi|BJ== z4Q1)yN`^?GquL`|caQzLBg0Nao1Zs5Pd*#2;Be3*@gUJ$3``pjG}Ct>P~1^DvwaRwrxqsBO*wZDJ!rjf2x>l90WiDtri&gkH#+y^U7&oS*e{(@xFsqIhoHU zE?Z{8Ewr*;xqaaup4oJhC!MvrZHS}ueu=*cJI?>`ir*fZp@2SQ@Y?DzfxNOlm&!4D zIN`u8Ze>cIwQ-XTX(ZBh<4yrUeX#S?f`rj(jM}Kd$;e`(G?qO2LhRgDox>vx0tCCW ziIsTnVy}|&K@fXEfhkg=0Tow0Z$cY<3N?=)2>CRUnbh_rp2G?oryMD0?AnNfq1| z7>VqWDc%40uqrkqq&h7E1tZi>HxI(jW%ip|3h+zsM6U%K?>QvDFXtWD8;{^e*e~g3 zpKu15QC&KIa^4W2fBL?$3|<{fx=KZKH!GYAh5)VHB7o^I^lX)6=ZC&jZ$tlH?&|*f zKc?N#Kzmb*UX#GVhqXUuccf;r8!FI>)0`G}7&rw56V2hnn}Ph00N9xP*aL#f3*(O) zaPO7XH%I>g$j!pbE^Z$sLN<9}0Sw~Q@o;+SK^oHu$Wf)wwVfW4^u%&=dXa33$K_vf zyoE#$3f5}6)1aeg!)p=Pa6H{~gAF*3l#&3#3bkozHo*FU)IqQOhy8)blJ8f_l_=8( zjiE6!%Ey{jw!uUB&MsiFobGG(2oeD~bbN!1=y#W~g7KaxF;>#Up%e@&Y_xsgKk4J) zE=$pN>G}aYzU0Gz%Qs^V^&;x=VPIGn@)77bs5#lQo&om;?b0=$sk1GY-cn7^BF}NT zuzQgtT*rA*M-X}X=_Yf;v;=)YqR6-ef@k9e2dK4nt%iUSSkF}D1H-Rf$Ah`tFm&D{ zsF}3V_{h^az$$UlwY&YeANpK2Z@4k7$=(v9mD55XnJbX$5)~56DGXgVgv+GU!AN69 z{q?oe+D>(K(?_r_|0+oxMD;nEsx-9451-oU@uTROgFvwU9U4g&5m3utYL@S!S91R-2X6MOg&A^clxbws6KleM z57C-K+c^fl%f>7*(hY7L@#U(HVq3IyxGFVzE7w3U-z5vy>M!eb6}V< zUJRWiGK}=IkVOH`T_#Z&yXw8u!kCAd|VRywkG_uDeZ^&{raiu9$whL3(_&4e^20vtXA`n*iaH3jQxc07cz}GlaS$%2%yQn{K zb%wF#(ALYB)Te#AIwJLD%Z#KX@Ei4VrJx4PNM_m5eau#sQNRJf+R6T#FkwHX@Wm~e z19zzyOU#HD4a}+=t=i(7;os7Bbs@Xu`-jorM7XH__rDJvk?&#mg4t#3COzMw^@#@} z=*hdP5baGVnTS=nkJL^tD%~UuI315K;eNOfbqpbw;+y{QkZy0H=!9@Ur}(UNTo0HZ zZz>4-A-l}vG+c3?%Kb^X$eQuZRgBaA-KxCM?HDeb6n4@9mLmyDS^x_aOh8 z%|gMF^l?4J0p*#lSFIp=rpe;q;fwuyqljIgPv~U$({Uw621K&9AMsWHQ^>yjc(--|Zt56V}ZY$J8o?lhX4dUzIBF)K(j zlF`Xy=y#YY5DU>LiEtG06JU)5J^uv3ji*QY*r$X&hawnHz#HXXuu{pqLsq!laejcq zzNFI1V7dgm7Kc_JBbn;H)Sy<+RZ7?Hax^`6pEMGK@!A&m+vqnTEiQ!~?C0i@t34y8 z1Ugxtlp(!pH*x|gGMf%wrcnHe$R7Jp`S;g#rVb}AkRUvK@z7t0cIcJR7ZIO;U?@%@ z@1BzMb&sJWYG!c#;!gW={|3RA&5sF=@m#u6cWq9+*GEpV&a!qeSo67_t(V3ieL zp^x!L{R?D%J%%k`X0BOuQbr)`Ala4p<9#=TqEzZ#g8HgTwoBKqW@ZskeUm>XwUU1t zg*E;5V)^4GV51~TZ1B30`4t^Vr?P$jtzx0czKIJ=i3jR5=jDh+w^6w5x|V7^l!ngA zUotlhf{|a72e5ooozsg8PDxc_r%&Ov+TzF|n4t4U_=C~{2RB3mY zI4WLdoh*G@B6EzEmArf0q6eE4%H}OW4*}i z9S+78PdGLvITQGa7|A48%wXnX5*6%63^EgO1kJ9uzpQn)(|b;P%YCj+-uS<`lBH2M zn1W2WrOG<#>!f&JPQ4k&zU)0#D7C8a_=ZVL>oCwFwa*(EiS zVC07KQ#u6so6aLzVr4ts>^1hi!AX1+OAmV)$&HEYn~C~5zf&J_Lq%DKYbw+-u(e;z zyrqW#NUch&_|}5x4dwIkRVX1S?B$BI4v|mIN-3}rZfLLvcGL`;;Fk&M_BteZ{c~ce z$!hJ!&aYqk_&m{j);iSJ%V+QNSzX2O$8QgU^o=AF~j&#gZ>5X+>Sx>@p z(!;}tk?(4BgnwyhLN*1K=-IhO^GQzgV2fR$gM&55FbV6Qr!ThVq#BnEb?Qv84m=@= ze9GUlST+^X+ejmeyRf$khkIW&U!E6k_QZGlgPm)+N}l5Z9-jL2w^dol$SeEwO?S)( z!v3i>VKBLag81*0k`~;~T9hcnUI#)U=OLj;Om+2&b}}O;UeKVG#SVS{+YwB~xHT$^ z>|H#y-_WX)!z4<0;3jq=J2df^d4n&**WSgHiBROzUs=0S$S-FgaJB}bncLoV1yVfi zVUgfaeOhr;GjyDDpeu~bpEf_-sbQKG<-wcH)SZEaSw420&NaMY!recr^{RvRY{!~- z-nWcCSY@&xf(ZcU4IVX;Q`0NY@Sp!}>njQ!D|pW+jH2;(djKxH#5G~n7OH0k`_a*a zRVGAfez6-v_$8h+{>kHPNTBPFWv<{O< zy;#zLG4x?dYxyP1e)KCNB)oEglS%YV5%_Z$Ch$tKguId}bB;6vu}E@us-He^$f% z0MGZIfBTJ9j_%!NT~OU2dtAAV{z$)Mx6REE_j5h2Y(Aw z{DMl(5{*_C{oYrlt#kH!v@hTcI4j6XEi#MugYXABMpJJw>6N$A2zMW!#s}7c?*4sI zfM&mn%S}MEM>0YYHp1XA>446*67(*_kJ@p?q(5G!D8Im7FP4q**0MH3tuAmBy(@fx zOJxm)iw0B4qMwV}T>5pbR`V|v$*Pbl$yMWC)D{2y>b-lPG_!p(#q5t_OFV9Y<;F$Yj=J`r-;>SORn~DQbg1iWEuL^DT#Yta zH0=tR&7PPu7Yo;O^x)Cdd!vLUwzSknur(Y2N&h^q*#2z;2rIFe51PGs2laiMCEfAJ zV)M3ydSPUE(l;2bGlRcF`TdP+ca{awhu9G4Fg({oPI!2>-6@TRv;ybHw)kZ5d;{+3b7dT=#>qb*6=W3{pDURevIigP)m3~`S_hrmJ04aJ zxvMG;eM0JcLxQgmu8=21xYhjHyVtm_r)2rge)+L+Jh$?P4`p^2>q4F?cYeEQxuR%9 zXkeFmRIe-oUYywN@XSGju)Wd-kn6nuaq{cElf|nqR8D(OYJW@G-qqEq>C1{ez8`BC zCMG^t{=+Kpd=j@%>*k+&ydc`pU})b;li+b+Pu3dHb{Fg@Ah*OYJ$HSDRz&%yFIuU` z0NSD}t+9~yAX0a|wk;Y2x|q*ni#s$sz0{U4dp3A$#HfgZ09zJvMK(}{8Rp*;(R%yPxE z9pcyU@ZNLaS37#(*ID6C{`Y4ja zlM;sAOl$wJ+M&EjN86nV(YX8#CE1MJ#!4sWZ@#0kANTde%>1?57$!t-F66Bh(hth0}X7GIZ{9PYs;xa0+UD5UR1+>6SSrV zlh@p3GCVa+w;DnXwheT(&dJ2(E=inoh$5%W?em^zA>VCkFdj49|1U*yO4EJlPqW8N zQ9+r{F~hIMVQt|I4-OeKol-}?WQ*gDPF|Dz%sm*kCi@W>5ia^-2~?;{+aE(mT!QH4ymtOnP&5K`w9&CxP)^ z>`SqW15rq|VUiWO+k{!QDJ=lFTOL?ZDa^o8pI~dNzA|9&Pyf9}c}}JJU2w-xuH_Yr zjrs8oJwx?ZbQnbbm%djuzZPCPGVB=Jr9}5BvO2g=G4yhdN_q^BlqPZ|1be`u6w(T2p(%;ZUMa@*h6!i!&n*+RsDF~$;9jN&opqn<=xl9 z$F=2k>kz4Kn-yBOx)Jq#sV#dicSYTgFUMLtmLnXhDZJnQ}4i@SJ!rJ$Bon24I8JiZMBVU+qT`< zwr!h@Z8mnp#(me>>wdoN`vpytxhBRj#y-p?9QJ=20WJpIvO-Cj_zGZTW3Z5xn8g0Z zC1-9vCv{AMWA%;u@7ozgR?e(FC+q@hLa*}4p4r=+_{`YWOA!-je>c$CzjHnRU#hb_ z=k9N_-gX2eM4)r6!)v#BZdR;`yH?8$*?W`dtmygN!sZ0<4|u4fKa z1p&oV7o7_eRHZ;Ew`j>~7?zFOCP9dNf|O=iuBsH^_KRnGjHYAW-IxJ5ioj_r$=X(t zQY(`V7CBn!caHea36f{UVV0nh<7A>F z`ju|*yV}Ho#9AjFBD%%56}$Q{o0`MCWA0u_U@CzF0(LlU!dvik8=?Neay= zY>UciujGF9yiN>1eWvL}qTot7@hB)`R$9XGc>S=5C$jo-pL?-Pswmt%Fvk!}Z|KS0 z6UPZ z&pE>C|5R#HQnr*h5}Z4m(r}^o1yyK~)V3ceN1LAzhjAPTlyD6$3P|P#Xj@uA5?^Uf zgz$-Oy@{(7Yo7`@YHZ`$?`qsKBL%ulfrKZ%eV&!iJ9+?uxjrwh%Yl^PlFR#AaUiI6 zmu-IG{_6}>xc9V%Adcl6Rt-_S!C7TIP$3)`LY^~kuuOn3yb`<%RhN4#3W!Bv(0tQi z2ta#q7c|8ZvQLA-Z<@yr(7zHE-!nhoRsi=E(4i$2*_Z zHae!EgcWGTY-)M#^Qog3gW||}Ic=-p$N-~scZ`yHJy~sBhZ+SW@Pv9*BPHfYuV)?kdl*roqI)#qC>H zoIDE7SqxRSqeVJhPtkDx@FD>2!kHtzV;{z(Ub(?OWzai7Oreo3xEj1cFApr|2;XWx|IY?1%Ha@6TVmnN-+`*e;SiXUFY&9Z%Ukd8A00K?=NP8J0uLPACvwb1JQ{ck{USKuYKJ=b{a8*1{o1MX zSjjK1}`g>~Y_!p)qQEPNW(out_0$ zE5M~Dk@HRoXvHyaqs&V@Ov6e2s?}jZ3()v=bdGderc9)Kt5M2uTzb;LA7Bwjk}}6P zyMm1AAs$H@AnObM-J>2MqQ9+C{pwqzx~x$n-0t%Eylx7?rRhz#$+YszYJaOcCiQZn657LXUsPlX|B{oTp#8^gqpQ`eY9RJG_!x}& z(C!Ux;pjOz$~p+li^RV~iT~nhF22FouWVdmuyLS;;G2#FjMVf_0>LHU!1i@W_PBAy zM;d=2U9FH&6-Z%)Fo;BHaNEmHQoNs^KFJlHtUYnOL67I8?+sD)GOk$cJ<{{!G@(Mj z#UBy&aO3@DhxY-GO1%{vedG3)JojW&llbVFH)UBJixWKdss5saGApQy-ARO${8q%G zozg!Qcx;LlCA9n&{xu2|;E{NmrwwiviE>z=F2%l`jwAn@T*h}gqUXcfGUmg2_@6$q z^BKL7P~Hxg9Yl&18;AKxVSFVY-xp$BK0p0R3e<(_w4J|s-%IFqaQ6f%Z-1G-_%eNi z#f_zU%q&OAos%*)`XC{N6;wpo;@&NxiLu`g@B)R-)^atZyZy4rI1dU{%85JYM6+yre&FG2kW=fdcxSqlJV*~Bndk|(se=n z_ps5a*;DiFsGdAw(Iv1+`CXHxUE@iAdim_(-SD+h-<*Bqi8beFNaSG*Zt>CQ0&wkL zE|-74Q$3e$Yv1nEzfVDUNVYkD-F07VIkirpeJHWg*{>jUjcnfe4L23$8F-BmtjHke z@c77Nqv@yJZG;soxaeb-DCk7@k1v3f{EB)OJCh8S2E-8p{w8f=-5qT_Wm>6Esz2mmNbM+rVsK zk#Mb}b@CGDVHT|WjrAzNhsMaAm0|-K=pTud1*#<77^wd^XZM!7oJZjfMVxgk+Y^)g zdNEerk10bw^=@Si_2ADAQ)`=^A!qONsOfftZ2VK+{c_LIm0#mtXzThVqRRZ1Cggr} z0cnBFd*Ty}wqBPXo^n8vy3Pe{nN|5+nm(x1?zBx>*G9P@oWTX`G@=YB(Kd00?%Z86 z2G=Is(xsV6c+^hdYj)yp zOc6l6`Zw#^AOQDa8nmMYa{b(dfsc{}`ge9kfx?n3obdxjOtpM)5Y2D+Dm#{fBesFPaF{1gC= zuD{ynM9uL2!WRRev(nK_{hs-dAiLQXPcsF*-UiRGCuI_;HNk*&25}X_PP0_(R?+F} zaSFOR!gjM{%=`F|&B5bTatT7+Clnh_F^e$l)=U4!O{`yl*$)s6@o$Zfx`9uJc>XMc$cCE3&l3+&{rnkmi&D@5RaM*_d z>JL^zB!Q!f#*xfURmze!Q$MK-?VUBLzLD$%$x-&)Ex;9UqGl*rn_1z4ERRc6>O0e_-i6j>k--M+@9-%F5KeQN1*fT2m9+`~*(cwP(YZR_py(PZy>C!f6)C^NNMW*;M&E$b9dpwf42(@X*0Q!A2PR)H z;(FnJk@4fpML`R2Z#j4OrxCKv><(Y(l?I`;w-*z1=*eAF=Go%HHO);Krc~~TIWt~N z9Wy4bwpZQXw0@!DR94wAT%c#<2^JSp!N2N{vFfbH>;Xc+S%kp#=d4uLB0S*2ht#EU z0qQ23{P6raKHohY#zhJ?@czQ66AkIV!4(qPbnn{{QZS5erRRv-@1w74070Ogbi<{R zw*Jpq-{$>y!UeuoLd!(j+I`I_9sF+0iXUA&h$4qAMBla-Y-pwVag27jQ!24KOC z11#9eb7g2xPu=P!x=&H~JN)MCIheDbg1y5uuv||oeyZ|1Ne%)XzIQ;=SDYN~HDP-c z8(TFRsCwPxMl3<@t8&e^{Q^=IjU`pWC_2TbkK+Qulv!h{<%W_5$`S<+-}z`;IU2>& zTk4X{3X|PGt8lQEv($7J5}sEctHPe4ik`oqMjx-E6N09ljNA6JHGa-lSa)xxvHRWM z4cnI2@9fhm@1r7hD7bZRC}*waKURMkkiB{K`M7mkJcZC+ZhSrLp)I!C%(SkXF;f*Q zbzcmaOVhzR{|A4VIdgijn;}6jEjj*Xgu0CMQ20)s`b!P^0fHf7?conSAYFsQDNQ9l zOor2mn85x74X)GaZMXBoq%_Tq|4OP;Hu5fb-jJH$(qOrHPAi>#=JP+oQi>A)Swwmo*J_n z71p`k$YbTQQ^!$;vbmH-U@gPX3+rS~?6vrHpm@~w#3P~E+-DbXVfPu#L3;=ph_%%j zfgBVsSgvdgjf@hGsX8alX2@dK{u47;lb{pk>#6x9VabwmOkUnk3=mJdCz&)hk96g+J_V{*7tDMex+Ncwn#SuL<79!hh#6G4Sg}x0yBgq7R#FTKR8~w3=`yrhw#?q# zDQe1z|JCu|#JbRJbX||XvZ6V*dIsUxGdBb1N{zR5tC0_FaAEv-jMtic%7%ke5ZJPW z2QvrA`NGb^&)NAk-|90`yZ*KCR!!qNPKOy{|SfX~+B z+?+Yn`P@~z)w;(iTtjANOonkRQ%%V|@+qN3frDWlQ^^hcX}+E76hQ=_5OLp$nu4lS z7F@N2R83YphP<{tzcrk-hyBW-)61{Qr!wUty79VR$PZDGh#~du5!#D9sFu4eAZX9) z-rg54(eJ@rs5ocM8z>I1!BRfp^SlTNU^{wYC7f*Gh5Yjni^ zm%~|0temQ%N)Z}*1@eAX+gEZo&!)^hvbtth=dD9_qI$ItzGfZq0P#-T>?>0o(Gtrm z_hCB^+$8HH%tyD-$9m#Y(3O zwpQ%L83nj9rW_Z&*O1^Dw&M;m$)A{*zSrl7anO%rq-JKEQOJZe$bTmaL3c_IM^*t2 zNjXG(&dJ|;-y6CR{SX@87pj`PQoB1c9 z;%BS8LaDr19=kg7NR_41?q@o3%(D1{VUj@o*GC`G-5X2~b~Ta#!!lBTa(DsL6a3jd|? z-`?}GYsQ7wD-7`24F2`om$& zt^sa&&53WyxI4P_bsGVtDcBIXZ?Y0#Hj}@!dut z!YNeq=i-pD2B0CKqttKT#p+ygSS|AsTQxP;h8h*G#s2dw;}W@Z3C2w3T%&S4($9Z> z;W!HoRG81V6Ia`2%jgkRsYYk%deLRPf6H3o(I zwq0UjpLIAjNvd4nM&o`O1V;YXdMoW|xBw)L(KY;P#nMnh!`~MN)O_Ik-&SUQ+$&*LbJLk-xw8{zeL$2KiTo_(F{GRj~V_J%w&*e)w3HZ0sk8;p`=2AhoU7)UFl-pQkHGwtJ( zr^OVspYhjk6ixs-$EtBsm7RaK+_q!d#jh95BQ~ zbss!{_UU!ABZ8aOY2g>zHL z3hDKgMSefDoD_K*?Dw@}yPXtDWoC_!SYd?J3^}Nw1$6;Uqbw0%RCO5+KYix6az!E` zzXPOWX&-#&Dj>8lWJSj*4-EW;`2xNA9)lvSd|xy9ENU7;LzlJwWO0-wG0Y&?!aJ31 zCR%oL-K;g1H5G}ul=v`;rO(AOo)S08==RTDB^kGm5;u-do2w&+gPt10XY%;pwcsRz zDKf`{Dp?CSFm~i`pFF#}9oZ{b-;%!&h$mWE%A;E5gs(M1Ee<;Z)1^J$ndup_F_R|3 zYcirXAG`!Ibf&3!%uq&ZTFgcr0)>bA(MTg}p@+Q}a3CMcGg5(q`j1TV`_lu`smSZR zwc3l}3UBXH*ww$wulm2s?}s;tXlVQ$-pCN6-86j28c3kL zvQ7d6rjYIPCt$U0GRoC!HrhDp@8R_Q`{Gl*bEu-P2gMcVFCoaQSkqG~_9ZlGb#hko zvrCr==EOJw;Ix?ST{5;OQc<(uQ0#J+;*;sDobRtl7FeffV+wN?q^3?2(MoSsqwRRB z!9m_x_ka8ZXc(q7y;_`$$lXh<$u>%{xIb4$Wel5sQd2$gi==OPgEnJsmC<%$fLkke z-4);v*w$7O8puSD{v%szJye9BT`EHAU%(T2NDrPY(>MH-CMkTBl;jPVOq^#mO^uYiXo#{dB77d(rek7@~yN$*kr zUgFzdzleC(eb~VD5j4Q5^d>7n@8GpGKc|%n75}|K*pMt8!Pw|MX@HE6=XOcAFgL)M znLGZ!wg!(8@ss-VcBlcu+-oaWs;d^!bM%U2jaq>1`*Xlr!>UUE)0}e(um-WGUJ|U& zy_Bn8u*xn_H}x&PH}xSqeomWPb9@FZz`_z|O6MueG+2uv zOmKyQj{Q&ocz?i@Vntc1NJC2>9`o60-bQdEoYbOZUZbQz){83^MRZYQri#3g0rRgne zRNzLnATNMpaD2ZT^A>)Nsb&=G7-4O4JSuCu-uXgOwLajTbdx^e16%7^9)fsRt5wYD z@h*Te0x2wdC5JqZ+kZ1lesVu0Z+T+UvY-;922@sNK0kFexnA-er~|jTZBDOJ)8RTh)sD7ATgVFEZbp2^~dfh{IU? zoaSO{s{9)!sT@Cu&h)xxELYRidy4)Zw6Rq|Crt_S%beyaVP^dw$PWb7HsO>&vJ31Y!P^rF0{x8vN5SxzL!#+6>qZ2p>v|wCQ;#Asf#yHlACa^mRhI>XppUHCv>CpC|Xo zb1=A1gSJU929Sj`vv)wl512dBKsjqxwbJGfp`Y-WNv>?~Ww{;h-qNjoH;TmS=a$w! znQ-SEMtafv41WA@T6&8CxK5#Zy3em(^?TYeiC_7)IeVp4?){L$;KEfq-uZdJhVgGhlPLIb`K8r`B^%z&X;f}PaT;th?-+30NdLR` z(`|Loqdl|eFjDH_-ZbqgKAQ8gVz0^Af@LIMbFTQ798 z95VnA+n43_PvVh^Cj2l9hLL#uTee%tlAxORK$taPW?pn&U= zBR{s+tXr~zIl!an8us)4u+i!-{qrUXy$3-sT(#*5thpQEbDDEw&rfT^bv^XIYQX!XKP{uLcqD5z+2VJ(V>jI;#I$!niq|Ufio63N zv<*=yn4CumH}`j@fNn4ar2Lj6gkc)ystl@MRnKn=AaZ)`+W9*asL2S*H1vN2-iXgg zktLd*H5v-5SnS>NH|Qn!ZgR)0K5t!K3U$H`*hRp~+T{aJDG|4kgK}DHuaS>eg$fVd z`|%pf@V&IATpVKg#lwpE9jSkF11`yJmjgRwpETeuk*VJpcB=i506ts%12SiV3)V7{ zq+;#p)8W&Glr^?USMkXIjS<=OdJxpn$pw~*mfdIlv$wc^i~+I|r;D;5A}$zkzaM9` zAO=}CO>o$%Tn16ZFTuFYFe?{D8QAz0`>-zm~AlC#1&UCObj$ne))r? zCzmc=Hv#s+2v<@rZx4bvs1-1-YF* zX)5W84SIqB$|09OB$JUm)_#qd2e0Xy7jvZ8ZAXasD#!f=02$EV*tNFqw&n#WTr$2F zlue#BnD=cKbvKImnMlkw7PI3jw!$ z3gQ$t*04%jCVxMpnh3vj5{f_pix0-T5$N-O3Yh7I#72gGl8*d$7t^ffnQ=|CX<18d zVEoypLos9+`LW^%xc6%&N?{#WsQpT|KJyw-;hQC{C}j|f5mKR^?Tob=_;^3W0sD<< zY3`F}jmCz0isTG%%)onLo?6QOFkR;m{AU*K1~(HP#8Q!n9sv&eI-*;zxFYQ|wWSjT zn6sHP)Q<;Dm{DCGG)t&KIubK8CItLTX)a1@7Q||kje(tht|~qPDM3&n=!gRm-$Bh` z#50s0AJsDE$zY)XP%{i~8CKI@$xrb~$l(3t5n%Jb^2Bf+cH&Y<1px(5zt^*wDFR$y z8xV{BOtPzQU#eJOn4#5lJM#9WXv zi`e@q=`&B~76FWH@23h7kgYWs-5`QV2Z}9J$Bz{eL#lao>Nbe$_S3v|Tn%1^G(j*E z;?fqcH6((M_>o@pi4g`dW;%X&*o&Dnb2gOoJ9oo64B#@S6`0o?s%WiJb}W4w6rrIj}FYW&-E!iz&uD|#&jkv9#4?B6=8tm`#c%5Mh zUM-$k!^r_tiDJpU&D)>;-$wAjfpis1U*6n)a>&f}2DZ7~*R z@NJ5)2Odv}-{&bR6Z^?zZ{slX3KXnHLVyG@ghGP5Vx92&h2KG4U@!=%OeA6yfyQ_K z2Ul1)@jB?w?J<`+w(}##^;3=N-VEsKiGRw(VpT_?=-j<^k8N)|8L$q$>mhtqe|l6I z_OXl~y)=dU#=vH*goyXr-b?ylmK2UQuMX^@&GPo2&2TMNz7!8NPQ%U={4HyE78Wqm z?dbcbNYg4Fgo8uuA3CA(p@YUT0^Q?(nJi6IHvaxd5seZYidn4g#TRFEfz5D6J08M; z27sJGHmU?T`zB7&&}G#I!d{r#hMvCn;m74tarENo(_^{-{&26i0rO4FmHkhV?Qb!* zlVwfTrSHOh7yve_jU6&D0HmSe;@o)$64wY|V0ih16Atu|yllKzy-St&^jlg`i{4Qv zCyr8Z^-#)+9rQ18B33%0(Wo3FQPo#v)jS|*f)4@w2_rLyfQi9Oy^`ROtH$(JnW&^fe{W_7W!*`#G2p?=SqQy18mi zsoPDIvsh@T0r1XiQ%>LIEsh&?46m6Pt$vK5_wpGjPkaxe#bYiI0&+Vv2cI#gm)#W{ zUe!>EJW1dI#0o3_KfU?mF7ATEW8k8L-`ge5CQ|J1vOMIEVfihTiHl9mSk;GzY_%v| z;Z9ep%@)|2fFp*?JySU<0S1)<#xU9vzKyLyZ z@K+gd7_&CsmlbC6L$_)d?+swHa=V%jJxAmYVQ+~?g#+}Ox$Et0$9aHDK5U!ouU~qq zwXU4?$YhyAZ8KmnQ%sFo0(fh8ui&~8uRd{1Ckd+zVUv>rpQ}%s&gsCUT*eL^unI%g z7{~2r>Z=zhveaT-3eUStWj#xL+H|oHyzj6mX0H;xw&6W@@Y)Z6sWE(I0>ey->K9{t zo}8334RPBB(q+H)8j7Sgpe{Ppc@XpA3)$!d{r``&bGHb#<($XZqr%mS! z*#v}0YPFdzpW=a3g%c<#x<&pcvyTS>%|MjQX&B{OJV5qf(fcravd5?C!U}&F2n!Z1*0?ar@ zR`P8J_dN&9A@CHU6931n1j{oOj5tSu($k{ zxzXNZP4>Ruvej&1W_AQS*b8@P@oXdqiP!Sw5_nh05iI*wdgd87*Y+6*0r!ah0W-7+ zK4xwU6AFtWOc3BnqcMdNRszs+uB~B_$`lL&43ZRFFxRa;^l{b5q98kFq12&Wgr-hk z#z4cq0Ao}ve9NJ`(oMO_dlm zNQsI1h9I$e0e=lt8`V8lzp-HDsI`Wb*Co2Y#BeS=AQyhw&XhuK`d&zJi9r8X{4ipknrh-V*yK0Ty+ zj}w;}*i(NEgPa*j*)-3j~v^qsI>U*37o<1V*ccwZ|()| zsU<&jMl_px7mMztRFB8kKj8ED`WbKM_fW)MS)}pu&b4r1i+$FwAlZl9&c^@d&3nJl z-No2nRrUh>$AUyujWy%^tq+bGzXXedT<=$I!cgy(_( zJ;5<2*}gs_09@W&P-04O8*+W=i9>A({?1$a-y?kdi{Ew$44)HqKe~N$rWi%7?cb`S z@rDeiuAkjD(_d7kM##6{%;a-lG{hR*<7!-@jx(;297^b-F-n>A&RzV#0TD^(GJPmdDk0P|mScCDV3;64G0_&#Dtk0#@BjuPY+ zMHXkg@(r21=gXS&uh=iSBi)U z$waRcAH5*|!1p5b#}c>^(u0Hak}kQ`97x>XS=Wvl!_MLVl|r72`HGi(T0EHBF@`9u zs}D-QB*^LcD;2X&d$bi{f7irbCL}0~Q<>$hvBlye-jaHyE)!l+{s##u6F^v^FU+mg zM7(}M8^uX?XIgMdlGZ4z@Fkylrl0QVo;qLuhh501pmH$;l8K4ivf5(6&^3>L_8Ro@ z-HQRdeMZjR2g3JSKDWQazDx3Vf4Fshm&JYc;~mpBS`gk(BYce!?jS#KSScR0Sbd{q zbW7VlSkF2umPGnc0~iIvM-~O}cZBO`W8XQ6(XC*&1?;zEt0@S32e3BXXOZAbpw6Uu zh5vk1XmkZ`BeiHTg2tZfWTF*}wX{HtfE7>tj#8fR6jxsq7&~6RXV+Y1PSSkqDMB#K z5O6tgh3f<=$J&YOlon;e`Q!RH#TL zYySO_upIabb4i%|LW~&AV2N`L%{V0uh_Q(-gYk-mY<6DG1@H_~lgs?;p`RxawQ7~O z(ICIY<~@hDFVW-+Mdu3Kzf#W*hMq7edfI`w>pJ`88=)(??hhk(lXraC`l}6KHfL{JL(>DS{AwTXn8U&%>^eJSWNydq@|qeR6!Tl# zB`uO!Ij|`#nlz>oe$g)eytkR{RDv4l2)@9ZkG8cpv6qTaZ#s%l zO~kbwe%C|RE+b%ZFp!reTtv4+S;b8?crYIAmo{^l9%q-DHWyxS2Rr0=wS_n(j$ud#@vTsJZvQR9~v!x z{8HpB&lVM1d61{o^91Vv>axyxKna2 zov{^XwVIa5-N@Z+6r}U?iM-a*K!s63WVpaCXU-%TaYC~K3q!&;c3Ys3$6&zfr^&L8P#)5{N#uYnbYR>IRLmxQZ3FA$Q zZ1?UO4L37kVQ^*)A2ga>>qn)rVcGPWpvI%Sx%yeog@*_MXf`g8osW zF{bG2|Fwpo8ra^=Wb>4zuczz_p%*^h8~~q{`9v`xl@pLNWgGge@7MKkJ_EccgW5di zqop9N3+$>v?S!rJoZ*{`@*kMhX)i8Epjz|h&!B zBzOcGM4?g`Q1*adyQOiZa61dyEA8lk#8t`0e0M`ZU)>F!4+J8056pK20btq5yM?xL z1u)p5Znv3O339RRTt}~3&V@o>jxmlzpB3p9k@b~sF;4|y*V z)oj`4C`)igobfKPWV_*MEekE9JfNwdDO{n+v*p8Fv-y0Nfk##a<^DyP%`A8e+FQO; z1bTdfT_S(wlb7d}SUgvFe;oyyESrC8>3WZ(4Deh;L*E1Y9!`3lq>29AZfOKs0&>+OE95JluW<}O51-2*F| ztJQ{I&;%NkQ61e<<^YYGkHVx$`u#uPr>V!2r4FM*;}JeQIoSrY;Ea+KUl1Qq{9HoG ztp{q(5Qfaj=17%|Nqe`E*XIP|(7O_yRUz~jm^^}m=6r}2uvXOrrtns7Su?uWpILc{ z5#$YbLf?MbPWo#yN@U~;Svc}08%B3ht2{$^|02}rThA8)0oZ;^iI2;jV*m(y6!z<@F$v(cCQ zm3tJYo#bOg9p(a#iRUc${ddB;uOQo+4tI62aPwb0!|KSzgP3KMyXU>iG4@aRXT@DB zl;A-6$nF*SlV=gRkSK=qYPa+HHEof*Vp=#uH?vuLi+^mA#nX!riM8e!FcsDeCaClL z-%1+;*!PP7`##O$LvNv`8oSli*3wEPIFha<1QtDtE&@cdZsgbS31pdNwMPxRn%4uf z$4a+{kL~t`-k-(J+doL^NA7{Ht&gJWQcUm#(Duf_#`QgZ;>Vb}IU4}mRiirdN!u`u zqNjj|18R<vNgAb*-US-9 zU6gF6flFh=N|1jq)NHUgm`H^qXTkXS$c(JZNn2D4EkqrRtGy^Ai41TST^OSq6w>9i ztf!=y&cz^^&zoTEdMdlE*~Ot$r!1xmtxj9crV7vZwZ`={=~EN8nNN|42-gZUA$b16 z>{62`3e0gI|58mXnL_4%2b%oqk~xeKPdi0F11GH#HeonrK*MANKMEkX7Az)1tB!ZD z-RX7MNvZbx$LQIymF=;dB%OwTT&ySw{;QVhXmRTPh$~M+krX7Qyk4`#*&2jTRh&`r zHa3#tqg~*4HdIHoj(`#q5ejAgFs{KK<}Uc#sTMmAkcdW&ono86eS`P zR|;6c?!VJk2&i97>XEAIPV6*& z_g<%5&&qy2b+{l6W{}IV{GhOOdanGO6Ub1Tap@N%hx48B`nyYKxo16O^k6@iB#a~S zgHR(j%6e`KpOw{IXp344!gV_SH6SD)FkWh2-zaZ;TrZh)xN4z?dtUSzFdwj@gcR~) z5Wc5QNqL`to>&WUcBnAaYy74JEVJPw#z+bX%rwjb`Y=sPmm1gC&}(Rt?$mW{N6$0G z#NHhX+ZU2%YbZD&DO6H5e3Hu_FV~|71jBzE;X{AJMrA_c2kQez`G`3^{;rezk zeqD?L8sLJf`oJ9%8B778*qEDO-rpO|hlKgS2K4f#nfyKSX;3kKjV)YC< zr`KiA1MFG%y)Mgu@KcgDtQ0$VAe3xe^B;}Oorn7t;60t6S0hs#LkHpXrl$Un#6!Sf zgf@nnOYE<)r%ho{VP;Gm)gHWP{=ZT{4DO18>hcRi5F$1>$s1>@=1;4LJ{v( zir7^jA3jEKN~5XMs5p%FkaRqkAy>wQm_i;lutMQM(b*{Yuh9o!w9WI1EpGCvn&D{S zz5END>Z$$qulIMN%Vdh!4+)*Rkxp-7k-r-UY5X6Bpts9(wq@K$RJ#irJi7}$S1+DS z%$*LkIbgvJag7T6?UX!!@rG|b-NEEhUlkV~@P@zDdg~$p+c8=GL2@n@*7wZ$c#9vU zASa%*C+YMG`e!-k4to;I$@Q&^2kZfjG@jFZPI1OoJWhKeh&`!o<0j9lA7#zrqrYf~ zr=Ikin6u@?IyB#`!3HZA$9K3K{dVW`#pXUm3Bw0AoK3osd^B}}>M|-RZ!b{{($Vwl zfY$j*jO$s`rleU=BQTG|Bbf&0dr{&%d!HOe$=o>b|Ix-_s5c=7ut65 z(ZjpMLp^$CWfNZ((mQMcWiPOC6IJ7@DJRN=SR%H1MZ9=K{Ud$ zA@%UF4NEuxd}N~I8xiLRoR_ED_pS+5b-tqMkkl_>u!vJrb=NX9(u<-(L2Tu?YHlMw zh(nE4S)b7>?P78J^ZjE@RTn39=koOgU1ZZ+-!JE|8KU*<9-@KvE$_NHsVPNg2^TQ> zhe@z1zy!*2I~~AQwt5kU81`5w4YX| zrc@5?)SZ9Xx4)7vb>^QH0E{z6)Q(_{)4)JY=)*jE#k`{hb?^&kq#>|`4= z1@M3+!(P%X-_`SEOliyo^{-m|2nL_B}?z!sm$C1@PdRuFUk4u9ed}pouzI=MmL2h)0&$} z_AZWO>GKlzoaBm$E(9^scTec^vMrks57j4)$XjH_Tff^e`YcSZS&lEfp~q(x%IPgd zNNpnEdu1`j{>@?Rh=IAz+EATAE%{;2go5kE{cI?{B$e^Nbcln@Pv2-#vVGKu3HY4-1z%Lx$OPywnWvH5yspk^?rJMNTi7b z7^s}ecn;-MWGqvk1VcUq;$wVW_4RLNCH+y*>U@jf21m(IVd_j68VM~AT6#=|)|Wvv zS}PhEFEnW9hdM%17`=8{mr3G`wMrACCGF=>2D|B4N14S2?6+^w=wfg!ePWZ))yh-# zGOI^UJi5Py!@UyRQO+6uRMYLblxF-c2q-lW z)fo1&(wY# z3J8GA@^BSS6JcT@HXdBbR#fvW-DD_FVIK=@&cY*CVjZeqr$q8P!UnOhQT3X2zb{oD7mB;`Bq8VM@iQK zg=ZaQ!ehkG#_v;O{nwtl+^rJZvTjdt+T0R1&mP7ay~u9=&O_oF^@bmFc}KF44>{mF z(5=qO9{^z^KNfj*vRVG|M>%K@({Rn8O3zK}H`SW(u!WmG@GR>HhOJR#CmO=&v(xf# zG=W87MGsYTy~pXCzJawcpZy$|3+E7d?C^9tyV@l9dr!3hiM~EMlo9?d`CRYQo`CUv6}LW1fT9Bzfw%L-r#fnkgbTBtJvAi zAgcQN8?fLPIV4L0oK(j_!jkYG7Ks|d04rhwJV9-2`8B@}1Mz}qO=so!UW#&*DWI;* zdnF*t0>hdLo2g5Ks)R(9QvYe*z8>C$T@m@@X7T3g@LFAz8nL>$A;;%8(ky|Z)Q?xe zl;Y*=jz@B(xjAF(()v5Z#vx+kDrq0OS28z+#w%(lmkDuz0-SC`amArAz~cgEVui>d=uCZlpexKFp% z2`(#Wg{8gvny+XKgZ}9XrbddRo^$*syJdKi$X=E&r zEkP=7GcDi~r+wGiWvyh+~aj(n0Mfp_4%986sKc5&HK5`v~Bl|Td85b{g+ zM$%uch8$y6OQ`{J|2{4k<1b!GUr(?`k}M+3e>hdT4k+IJ$jwQ%SLO;~VJ+FYS+p?W zEB45!yW0KueFz+}nr8I_Q4FS60%7rKG~F(~ZGlygZIe{VVL3jt%y%%`O|*h@m360! zEc|g&9g6x6z30Wv3{#pYxz4VV=GqJg)ss`JfhA{$y{zra&K&HMiw^02+V$5J=;cdQWsDrfPIg0>J54l51w;JzJ*cJghDWXE#?PFyx7)D# zL->UlIkzPymgBn3qK!iV$TH8PM7UUHGNQOO#9^1=Zw}a(tm-o{3Hc46WR)GCj8cbd zyko)~M7K-e_E+Smn>SmXl@B(5uiAxnmTHEU zbx2#-XRZ#$fq5_T#iXlB&#=9H<*!2*uvyNcD;=qE(a=ZyjEb7WeMWKU^>EHr1)Df`B)*Q^lne z*sVmogsg;2uu*~^rN_7EfAL^5-@bD$+FjI)U;GILYa&IC-}I<9 z^#qsw7+C1@{1HCGGV;ChbAIqz1v+3zyQ_HzAiyoaa~*3{zrX;2A{_{H_Z9@m*FE7S zyp{306E2=B$`*ny;&3WpM_UYgdJgd_;t%ntzpy9m7%BVV6mS+?!``R;u}%d){Ll64 zjcal2^3&`1q4E%&;@6tC9F#b)kOYLAG2l~^a7m5nAcjS6_>{W#dzQ1#SwejK=Gdnf3<`WY{DZHM#$9M%KF>iWsy87Rt zVUBChXRX@`Up}~%qCisrWm%dqWQ4=iX9(m8l2NxL`aH!w(hsk*gxyS~jL|~scKTdQ zv1Lgy=Mi5gRuscol2l>?)zo+yjrJ8n%oPLOmyr1}PJqE3@<(9KRFw$)Ju2c<8N{#$ zk-fO8GiE$U#~?H*z%s^ksx6P`GQY%Wf^&D@?j>zzyn-&T=DPVGpp-z}qRK{x@p@xA%`3~>g;f}6uqsMXsr}{x zWIyTyt@EH+>^X5*m|CVc1DYejna{+(XTM}_NORu@PXU&3 zgdObfB(CdVuV&c2F%FPtmKj{Da%C%wWvtLX4uJL35JDgvPWfl9iI%sBY)Q(g`p85( z6}-M(bO`Pl#*4`}YD_dTKFmKjZ&c!Pl9oC|m{l=lM8V+^F9F{E7x5xp&d;v5?dlO; zP=Stfy>5I|MxdHzoAQGj6@*`J_>G3Rjq&Xm;)qQ` z4DZq2z`BsO*H(YIYg1P>Fe!IFIwI$oFhiv!})Fs4MZ=B2| z`_4nm`aqDX(prGE6O9aW+1u=jcrjZ!IEpQYs*Vi7T=BYHm96MqQ(Xt5xh%gm#$kjGtVUcxJP6d zrPI3GZ!`=-j|}dk)oXzMLWG(nX07?-SixFoW(OI)!UBQ0Y>$mLU;T@IR|EMb-BC@L z$tLBo%RP6g@$!S%*U@0AD9Mui8Fd~wg}Jk2lGd~56Wv=^IwuI@+H zhvsox>`UKr2AP1_U{_LB#p(Z}>8k>&>biE7?ruan1nCCpZjkOqy1P3C0qF+m?(S~s z?vQ5F9sksR(t#Uy6LbnC{#Ra0B1?J#9btILlQA50Y zuue{_m0;tvf%)P$#Y_V(+Uk&uh7ynK^9&3v>5{&KqWoHM_1cls z9SAzIMzrGT>Grd2JbH3%Vj&TV%IHd0xZ{c)RV0zOX4(Q8>p#4`_6;+fl%pL5w) z&(ChQ3<7EW{7BR(@6^0{^L&~+y;Bglp+VciX79X!xa{AX%dfY}8DX6775)PJL(eI8 zO%0)JKRVwpV5R>tOtD#;27dXlYrRtCO2-Ykt4qIr-T@ zRf2fS)28&Tn%v;6K`OXOFH#etXBY-Lt17E@f;aRyd3Ar6l+WNnlJU|GEe+!vWepA# zOmL%ZDKI@4`b-Sru}#n@0Rk(6RK&&TBK&j&e!Zoq&&#(~iR&J8k_C=|0c?WsfND+6 z0t!-Qzdx>#o*{al2X6s% z4ze|cV0_(y0Lm~hOj?ht<*b1Sds5xVc~1n{Nviqsru3fwC#zZh+axaU-Re4dT;0{{ zt3eNB+%^5z7d7-XWHu;=wSqFLYBYt{?t~9`vBe#Bu>g){9`52zXq=$oI7SC7;%p2S zmBtI$xOEFx(rM?N53n6W>y~X92W9Q%G3Zj^Kw5l4c_?0-6|MLPn(E12ODWI{wS6yI zl6%S-JDRx|s^t<}r6)Gl=^y4CLiWD$&6NG;E*y+{$Y~MJItrmQiZZYpE?qPq`+IG< zy*>8ReE4gZj9Sw2cf~jD-q4MjI;O@ICUgf@HU7suP;1j&zqYsxp$4?h;*JHrBJs7~ z8A$i&qY^D2M?C&5wlh+_yF8BK?DihjJDf!F|9ki=biD9znpo^?OyEH#Meg>5n_Kk; zS1U)rP=577+d>0O@eEqqWEX3tM}9BH2cl>z9A4cTm-(NyeI2i0^1_?^e`&GFqur5^ z@EM9PN`f@$Ts-{YG|dZ`4xk!pmGUgPNDFMXufuDGh2m{o=(=-Vn! z>b=LE`<^n5zVRD~;03V4&u(gI7kYp$$=wcs-o(B83g2HvUdqY+3`A%inCUvdF4|a% z{M1kcu+hhWzwQ?$I*-U`X&-atAQTW?&51W3MiO$qh-q2l4G4MZ;k{ve{@uspC-a<= zVQiTs3^dZm<(rZ6MC^ID|AQlHj3gHLVcbG0maPaZ;@=kGz68dQVSU#%qpQhb!ab<3 z_`w4KJzs2=XT*pBt#qP^`Q69y#Psc!HMu7B_AZ1^ zm)Pz-t$ju^!pF)FurDOa@Rf_z_Ad;u6SP&r9j2Eyb5OLqQ+3JKz!P(j=j@iF0v05l zBA_55uPIz-QY(li;;0e%fQ9^1-`1%dGl95+_`y{4moMUMy#(}U=bqDOtwaTpWGqrx zXKP5f2n=Qw@p@HB3ZN^Os2LQDCqM&i(~D9j6$5_JG@`W(*m>~OR#$goYF2*5p5A*s zr4Z(MC&U%H4iGhJHHQc@D8VIqlTBjh?AuPIu~{FGqes+%)tIN>PGG zPW)_$MWiLm)pWnbn3~H3;I2=1Lb_oI{CQyWg%OL-w_KNN3*71b?+XMAevEdAcPHmQ zvL2bQE6>9p^o@53M8kmS3adHHi@6gx+g&tSVUqpCh7kVdW3carh#uUJJxJ8szx@7$~H%>07PqT7b@-Aw}f z{f8YmXr^YZ&C9m7vw2pWwG>s<9I>=)V26XXhg!GBX}_fwE<#BpIi}bX4%#9(xxO;o zrmwZ$&rscZX7le^Mm3kc!30l!=QbK?`gVgUP@6Y#kX(2X3GkMG;Xe&2@Yz7l&fE|+_dO;UBA5XJCV5F zNqqpriBc!j++aA-uoF#t?`XRxJX6MC_RG$*%MDwHyjSaMyX-`XC-A2A3k)|51K|%q(a?MV5{auf9ij_9m0$)|#RFNeVJ!)7_Kxv|G4 zDj)pZ9&6upzm8Lg2#_LGnq9$#KS>YVkbgqTOF<@Vh|Wo0&@**|-k({ZJ>0i!%4Ez? zz7Hn`uYG!2J)Fznq;`x>P5YYQAcq=%pL4v9+q7m*E>A0sY%gE0bh{>cw2Yc>>MgmZKW!>sG6@rh8^810b-iyBK}(K>>)ATxWF8#t$Jd1vu1tj! z3us&_Zb)x|Ci$enOE}XId=-fDdngrAr>t=Cy1v=1sy&)HaJ#vE!ZlXWu@t<81_y}! z0Ycoxi8@p^-gqQE^^3YeJldvK#$6kZN%y3$RA*;~Ko*ZL?>q!fj$IAiO)*Gu?K$v? zqq?FFT7Mq?TDL$f&Ub_ZQDkYM)B>a$1fdg{|H`v5z~K)TQAW9OE_(tmXeY0JO_xpQ z^9Hi!CY_*R#OrXhLSYI)Thl-o(@(E^4uGZ}l**i`C}Jxq#K9>8$4F=~9ML_h-{7GI zS2R>+FO!;fk#5*LT?j8G;~qWbwy2{$3&Hg{P|C7H1mxs}LusUsENTYz?5Zo#{bK(< z?}kT!6qwU+{J4YmwYF^#K`M|bphpu(?xHgfc{TYD@H=(WNo+4z2H`y+_s&rZl<4BR zvGoRnqV`{XcvrA7X;m1f85z837JWoQk>hgTMmMVcBqC6b<`fEjO$5V~PK@+{%?R4z z^`Le4jfh^hN(T@;9lj+SkZF8RWV1~CEW73TKF0GGr1hW=$Xx5*O<#P8a#B+sa$^Ko z8b5^WWVk{x_MPO54WSUodV5@zG{0)SLHw>(!w!idlBdNN2Pz25q$8h;%ksJYkZaKJ z$^#!!Pj5e&bOsU*VHIDfHC`ykV34QE?d9z&CK=jQffn0?_0jjC*LKN)-s)3V*jS?RUWTkvGwooS7F|5 z*RM!N=o>DbbrSB$@0R`-d;DGDoeVdMBHtd~O75@s9A_5({)j$!@ehmjruT6gzs}X# zYp($~fwH_#@+t~O<_fZJgSnWHVnD(E z=r;cO{!2%PZsA5t&FQXbo||&Luy4Qv2zv{>m!5eH;K=R3q;l3KJIbCx45 zoX>at*ql3h9^m+bqmG#T!6|$XnNS=I{1$eyN1_4ONc3oe3tCnytETwa_F1!3OKK)t;(&`&Cr_E zjPG?*WfJa`ef>})S9FBPfxI4_dpO=^DsCO{i{G$I+j$o7Yrn7B+OuLhEeLe>&c*SZ zcHlr(@%cWwj*$a2D6VJ+jR1 z-IH!2O9lkKW-T^s=vukUrc4e(R%gdUf!q9`f9qy7UmMSfq+2Y6>FxCeG-adh^-EGo zkzGbyb}xld%2U-;8@HiGFi()C)njYb=>6nUUrmmehy+YxyMg`=jpc1HjeJj}zHLKn z+lmTlwhWB2IlQ6|9xYlI47DY09hoVLhNiV{HLI0+V{IO84U#W8fryE8H;@Qjoz~zE zv-RE`ThnGFD6OoZjxB}MhZliGg{X1^0=+f% zt(9FW$}}>_`&z%@5LXF5K#EB)Z{bNt#Zhhkon+D?`QKid3GhCx6q2M4%ixNkt2lvD zVjFPoykAWd8^+toGw!15b67Arm6}R{q1KRCeI!M(yzQ4paXwcOg*iv z;5N;@s5t+O^6WgYLjs4Of@5<3cYE3XDAZ|vNIg}O>Hf19{OraRUnXB~nt)@9nz+K& z93|vVBTWVj;8*lnC}pH zPqlSD8r4n=!Jx;ZGLkm5XODh$POuA}lTH-%&1@;y#rbjm=p<5B=px5KW!o_+xTN)3 z9?#B$ZHAd(fTyGC)Q|F`))0wGtRjVXaS^P6*26leHK4!%^l%zqWNM?z~_ zGCEfE|8&lUAfbZFm_K*XHmN9LJ#@+oNtBHe2}#&EeGihNS(Kk$4;|Ag12Wru#&qAD z63*XdH5ipLM1ig4Yyg1*%;x|v*=2L2qnAa^-Cu{<*Fn*6(DloC4fbm!I!S5rAwDsG z0%BK>2mKdee%8_M9}W}TW8JD00jxtCv~7MP}wYXwe12>wV37_V&!SAk32^v6D0VG(fKcqb}HE31P3pdm9Js z@8{v%FQ%?!3y|EAsHNLTdrLAYfS8wPNJd?bCC&3;?>n%ypZyL{m7JWT4nowj`|9=r z#4|*tj#{@Vj9qlwgi2MwxB+@%C2ZJQsaOm|w0s zC6I&~Wuq#fn}E@?JNlDx@fS?E$Pz{Wv)w+)7&?Jt#Wr`kEs!0H6txsz)Xhe2}?|D3nWq_g)swl5Dm^;mA; z9LCnbw{DRg3qhn0jFy?%umF68vGAN1v%0nLO9iY=mif>*;UUibD!=-^251-OI@wIqxF#D~h+53?9Y?dq2 z?k3!$uiiMHk6%-9^>1iEe%HO7XJ_xaoc>GEy-jL1uVAZ~n#777@+Bi`0tJ$2@^em`4qzSnL;w}INd8(w&y zM;da!$r*4NZhoerjv>pm9mHwv}@j&h6PW7tz<>Ur0oGY^lbS9s!btFT9q_u3FK^h@$cmyGa(d#9&S^F1wn z5`Z=e`K)XUh7tV4fQkQN`fg#xloIz-yXd?}#!Tq&x|I57>y)o;e*!8u$+P(QzxI{xV?b<7K;Z}RbP}))a(c3FV#^gs*?Y~ZP^#W{X@2sd}tS;wet&?NB zZ~f>3*xnXr1i1z$Gsfj#ygrpZDyPXh6c1U#HT)ge1!F67(1U~FbF>t|Lt){Oo0EYu ztV%23Le`2)>D!ke>#3ZO&`X=%4nsb#eJnsOk4J94#X2{} zROZ5MP-A_U%yuU~;P?AY33cqOOmC``f#BI=L+mp8wLpvO6lJcw6vd(xdpzZA(WnI48kS&Fgf9AZ za1!VSY}&Gc?e|QMy19&~*v`b&UQN@6%AA8>5sPd5$B`SBEqIWo4a}H#9jZs5Z4o?H)`L!EXlp-iV~65L_0hlnn<0BiIv;PScI9RXYWU76xwa85me z2s556QpF}N2mkWUbAzqN3TC@sa+j6=t`h?A+`@DXApFv>J;^8Ac)ixDj`1pWaY6&N z+RQ$6wKolU_h%2&vcaXH5l#WdTd%)Idy5`%wslm83VrG7XQu`cFBj2&5#I{Arb)Z{ z6^3(#SJ5AVH#7V@y^Y>;@6f+xC8&~o;Ac!D+8+mM?-mFalM4$NaT>4}r7=R7xCj@g zza+{a4^WgBy{bQ6S3~<{F&*r&&9y2a#XD7mlNIA)KgOx?3E+&~F0^?xX?{h#zv&=B z62{Y+|GpO1okKl-7-=K+-_q6Zjf3RrEC|yP<8<#UK!4Z%!a--k&}d1|Fn+}_bBlZb zJz9PF4#6#Z=hlb$pr>#Ws1Oq{^H*D@n21LD)yK**P!qr$vRqN@l7IsUa^NI*Hiz(Z zXPPg61DVu3Jq#8k`{IM36Qh=iPd|zCfPZ?|bb4;0Wdz)yRUV%?BO28)X5m~{MdMXLNLPx@(KYqrKd9Q?`T<@(Veg4-NYWn`Q zlfjgpoVFN=%H!aa^+;!|pPSZKQOI=k{(c6>ZRFlLsW;6wlkWemh^k7OL`}K}yw7;2 z`&|V62KyZjEvwHTbly6zF9i*gC}88y@XgA2~(k@HtVRkdcARac~1Q<11i(S zvdoH707HR(v~5Cm--{1VXPtkZZww^r60qZ{Z%h0|d|8+`*?W21EhdBR&>Q&Cv z&I;)`H@9j1#Nh8AAHpGui^*_n)G+mVSoQPUEgM}QY0_EV_i)^!C82_@`9zn}>`~Fp zoS`2mB!F6R-fmpY51r;r-LPt1+U@s42F~v9#qUmTOc%SoYokB^UTzc(JT(}k!x%?@ zr7gX`hk(e&Y4^eZdUT$0lFN=C-$Zq-PtN;e-0atQUI{T?{B9uA)#~r`i{y)}thkuD z$}+SPpAyj=3_vbR_En^Z!XYZg5#Op}n@+yXW~E(?>|%K{9<_)NW!;J#-kV67xdtvQ z(rHDcj$C!vKJeI3E)mHxrl~vG&%3#Zf5R-~e%0w3e#o6h${SDT_WPQIE+a7f3o(y? z5iyiVB6SI7TQ6R5qus{jGbXjPjSU86&>Gx`9+hWT;lQ7d$wyWcvZfWI(4HU7fGA66 z7gy919*;xcjrGDYS_UWh(yVu*Uu*VEC25NoEzkkFF*-oX012;!X*pq()No1di@WrV zF0C*@;}7O-;7%3@cj>8E>cymxHTQ}z?L@gE?& zeZC&Jk5YO)-39}MF;wnp)H)n+pwV_R8llmEj&z@Ajoe#++-{)Yq5$eWuRn}loi(?fo=vJzeM1DKf_{T?O7#vN&pZ1ob2Wv=&*0>=4 zmV`}ch6>7wT)=J@^F;$h#iXTXTgVB&b2MN#TFJ$}IqrMkisa2n%2HjiaYNFP!D*Hy zBm*+3q}NK&{1r9GSj!q!I&DIItmuieE>}9A9~eyJo^z$^g>7re!O!Z5NKaO>Z4fut zF@28LocaBF>BQ!)UUE@}+}11gFmv+?s16*a$9nHb6DiWl!QE=~*jUm;IO$YEO}@@N z*3i8^crigp8u$Rww-8c(fnoMzR}vOt6?3J<{R~SOKoBM*sm;lpZEKAhA-S#OY;Zey zWg&@S)Z09v=3H}S^eb%y!Hc&3?q`f;cInYIkD`EnZ!{`QMPEF3$e#-kvSFkZs~whf zvIha0j^0{3Ygc*)17iu27>{0#2&9ZbboqOZ5y}FKIBhvWyqzA)T}Ne9p1>RcLMbt7k3LT&0-fqRAr>t zoNS2{f>ogc_l)0s3}uMZm+>)+9d#b#oMpGqVLxuAM{pzn`~Wai{XZeBoIIfd3KBth zAG5HGb%Av7WQ)rL2P0+rNvruE!cC%#8=bX(`(HekiCN`O7T|F(4_Wc$B5(pja*00) zgJRIYdP&3eAFMo?pL)RyPLUM#(0)0mYuWxEx2`o$znZF(`eq zq%D>9$YT?hDE9!j%Iy`^rr9%}?d5bl^dRv-eaV&>MnkHo&hrCm0v zZC|9-R!IO|881VZLcG)vAn@!fROD?g*lNv@pN&fjwMa`M-?d@|b&2HSX1(7+Hb4I- zL6}=K3^xMKU8SYKDfGrB7WhjFRX3Bc+3Ju!6x4s!keKWAvd^0z;SMN@R9078h}|~i zw7$OUV|D`@XxNKYWBg@-M&nN=G3`VUr%2o1<#nD}QpDU z*wm(qz0lHcWS2IlI;<7EEozo}EZ?5Yxb^{;mNm---}Qf*bvcN3noc3W2V96{(QOpm zi`R4}snlsQDD%`XB1_&s?f%EL1qixeR$k#2PY@9mVU%Yu>yUeE^){j7b59r3^SApu z!J^!VhBSmNYvqrX&CVKLJy{bLE{5OCBr!K$Xxp)!ILk9kC|8`Pok9{uplcj_d)^Uc z4V~{U_SV3yNq&h5Ak)&3`ua3)IA%Aw@mvwkU5S6}*-@%uu-gjX3XrG+$Ce^X;}DlG zWJaK-D{Y8&=2^Y%=ZAgG35a|tb|nd4@hWDYFOLhHK%W84o{{fLjTO7{5RN52!1LPN zyJvctG>hEsR`CR?;=_%N?oys+gj5v`?@-Qj-+FOX_)u*0=}$~;_HFabU-Eem@0p(Q z={yA8xKDRVM@^8OU6)p9<`!{Ddo22{RXw||e$JmDuM;1MRw&|6g9&*1enxGBxHy_@ ze--G-vitC=W|Rod1(E8Y+_2_7rUgKFp~_ia9!F1Dn!ujNCl(I3c|Ce`d2d}lQ}uO; zbm0M@gy>0}NWOS&)7V@HA#Y*R$n^wPPc^lL`r64;S)bxJU+&wVzg@}v)A6Ozjy3!% zn=%Jfa3p50sQ;R}W`>++@iA?~nL@V{K+8F~38AeVM8i8-^po7&$Tk;kB}_*!9Ape; zUIz-=xBXJ_-CHk^mhE;?tgXijq(YRme{y&t!T&3?gcYghs}0=LuABVKY6rh$j42V) zjoflMF1U#|6Q3+n8`~7$)u$mk<-^<7u>IWPSHdr_s0-%?87!6Z%tPUNcv#o?wa&5x zsK5=5ZkEQcjGAFlo$&#EXm$U37YKG2Euvo-vj8CITOGO~RNu&8S+)x%W_j6f0>(Or zuM;XKCa(v7IcnmhG|FP%Cpoka#v_=35_);YA|=PrQr_A=*LLU4lvzB~g_epFU!r#} zqY!FPml=y^2SWX>Q~L@1^RBmM!ATp=AxgSrc0<`sFzEBr-6RJiBCk-pz*RJCq61aN zqV_y->BPw>g9%;C4yyAmVw-*jE>M#JaO}1r(nc6yg}DP z!tyBqY-SW^WOGH%^sl%1dh{u>v%To_Xe2;)0+l&*+k~9j>+Gj6fn~yPEhzbZZh=-u zBM*i=n(#3@?cWB$pHn=fFrK+{H@hO-rY-9~yw8Uy9Mc*0eN>hl&$t zT@7_n5N4z&CCPla>Q@obNse0jPIo`fo|7QZLqy5=-SxmtFbJy8UUpg!_V%Y_@yTy) z1d;b?TADn}5cQS0=ukkZpO@G_mz*(|DN~eBf0~}ai7Lpc`{X%*oq+tN>hB_YE-{NU~L&1J6 zLhraMn6xU(I9<#_NCIO#`J0_u^-;8WFFSP*JcE{^JjOz@&{fumUIj{7LmuNL71Q z157fgSf$BA#R!${si4&^WW2>q*15G6%}AWZeiOk61Sp2$SCf2>KDV4-LOC7I&g!Mh zv9@MV9rcG}{U7vl4nJ8H&+Iual zay)=`n*t+_Y=;n0=&kmpizNzy_~*Ef$3%H-^f`KXf0=qUerT;;H@75^JG9XPl-FFC zZpCXy!l0_2wQY_)5gy~(2|by&|hn&PRHaI-S=u#nuQ(tlll8r@=pYNtr-C?WrI! zJpCuH?JrF`FH2UH&i6mzqPy3{;x>FvFqcYjn1XM;+v)g$e&gxh+1R+>6@THtouc!(xr#$Lz@AL<8K0_U zzFJ2C8*Nm#!7_6xj+XosmxmcBU~0Lh~^<4vXX50G2(I%qrfxoKong z`W$He>xsZSOCcZE_1;Y0CEUwc^%Q#X6()d%Ai+j@laUlJA0onst7f6b!%!9ZiJOPHeQ14><+)i=uV zLvs=IIEDDevml^C6fJ^W*JY0@7Y^$``~LQY>MN-g4rj&|4=78O2?EF-Xd*W4i1Bqi zCCz{$1z@qCH1n9sI=_lPNqCK;v(52P2vKRoMHpFb1k~tB{5=qxoZ7VUy`KOq&lz@`xy70J?Lo4O;0 z4}+8{rZB(1Jk@qhxb~8e>#tW(MCbO6x5-ASR>DTRzVZTuWwX(6{*z1-X!A1dvEU12n4YwAUk3KUzmw3Rg68>Fx$H8q9_rzbIsnQWxSbQ|pkFu-H zG=UOIFB03Xq=;UMa<|3{`M|N3rePMirz$r$l#(GJ8L?SQ)q&8ZjCS&n;MO5pl!lat z;qop6k6v-J+jIHDEjsiuE0eLkp;h9ws`ibDx)AL60XbdRs85sx|q(q1~_J- zwoqO$!UPF6rvahzOwGYcEt4Pz@84714)B8pRpX|(`#As;y-+2 z`~HYBQ2J!;aNR)luQN;CQeW}k`oG7<1yD{6GV(59;+qeROfOkgbPyks8q7%u7wu%& zlA%BUv;))+O0OD8e5FprXwrA$Vue2eeL6Bru56z#3mgJerx}`&6haU|PLhl6XJ8lp z>Hney48q{p$=jat`JJLaE;%Ef$Vbv1FYezxi>T$(X;#%CwDXSNxX<{gHUEYoq3~5a z8_LzmA$I)toZOLVGg`2j*S3BEuTv+|G4U_Tr4y)o?(m}7`69-a1yj?=E+IO+UEbFC z4=fP;Fdw~q_>yNDmLLl3o%OUJetrRRXPc)E;>LB zNVJ^Wy^CKD5c+$6{rS1M^&~Xy-t5Iy%Qr`HEpcnbD{yRv|cFX=l~mqt+TlYHkA=zJnFdo zf+y^p0fd1xyvBNPLiuMbCvAzIz}A}+l22MBdfA_j zM!ZIJ<5XdYPAE^9RLoCCbwsTozdvTU&e{RfwXa_f>fsdgAi~Gd|F%>(rdmP&X#=?G z`s;P!ZiS%yTbHzsq4Cc0(JqMFhYZ`LeDBL3l;!+NN1x?A!&}_?`{Blgc*)~~bsHXM zr$&SC6Vl6^KM+rQJN7wk{f{%^Zxx42;4FZ#_4CwYy-k71V>~{Bcc~4oiBc8mXQ7dz_grp1HFDWOGCxOf|)8G!Qi{*-))V~sA|-pI-?l%PC8x{ zu!6DIKZV)QW-`Jd%J(TQby{o4Il8(^Om>mzt^w}oZLx=+eQe=f2W$x}adlXP0_A?` zE$r`P;-0eQ-sJ;ufk^oIC(W<%Mg82mTYO-zC;!({cI`B%sgi!h>slr$EBexewt^N- zWGSSey0U>3ATih=!tnxR)_p8Sm1(T}R*C%{d$sSF6ct)rtE@Bvh#Q@FAW zUYLg??;P$+X75l?sTH|`D_8C<87i-tG=qJ`ik=DGy-YN*7#7Trfzy!483d~T>6Mt! zwN0RRexHjtuUo0*~}CG-QUajoN9!jL}xGoJb*Gzt-nns zU&2`DdMW6u4$^|H`8}geN?odVs;6n_TU5SqaCMQXnsIH zVX(W!{on`>2w)xhf$~Tfoi%ShIT_-(lgLPNSul}VgU$J!vk}n7D3Pd3{$!f*K%+l2 z{JLbAM%KOEQ2TV9J2!3+xUY_b$w>LT7WsxwX1+z5;~o=63P`Cb{VndAvN3E(QB=}O z&ijC?=??#=r#%=9@V&iizy~j`o?66JPR#i;Vs`w}B&BDmxy4FL3n<>$j7qn^Zm+1L z?kp#l08AHoQ8l|RZ@0hskn%+lAjt`_02XwV1B8d8W1IX7mfi8d&vu{e=FgYgqB%4< zaUv{)>tv>&bWxtBG0BkL03iKiO5@uUO$vzzd||F2UVb@eGhL_ia`;Q8_BE>TZ@_;L zs5!3FH>B;V+3yU9!!=`<_#62DYu{PUSqzqjG(A__Od zHc)5~WYkp!jp=6k>_>G9bvSks9CLHuq;y=+YrNA$qm*tV8~}7&PpL;k%w&wISX{7bE5*HqzBkx)co_<^mO<-IaxP4gO&n{(~ zVk;MA1@~*tM*4;fVJL9BBHx>R5dw@1gKxBt6xptv_ z18Y3i)*pl)f2LhOfnfC6I&!`5$Br44U6x3i59=XpYeY#E;*mIx6wFQrL%T;GU9oO$ zK;C5-O>n8JBezwv^|D^Xc2u?S~t0mOiY-MSyv%hWE)Lz6GO7qT zfOTM(u-T#d4E8gkug9@Fcxk!n6gXTP7aRd9@x?(bzLY)Pg0eR6%#D3|e_{@o%PIO9 znZvsn(Anvwho;rTK{#kbe`&Yv!@M`$vnP^YVDRj^(`@wC;E-~LY)RIiR2V}qDt_P~ z*5;n_*lr!uwj}r$4+L-%2w1?&1@nlOI zZ$ppz@D=~-2gJ}8<5P~WgxOGSE_+37It3T^Ok0hwY3;{4zknB)rhcq z!yQx(ItQ*N5i5CL7!ttG)I={_Y#`36sAVr?MStE^H$h7Ncj7pY1m3{Dv9$wDn+-BJ zCrL>dC{8v){E-DX09ftZGp$|K;i&@hx_h_gc54?bsoah`b~Pba$xOTU!{n#smm&FM zjPNq-=*63|08z3z4KI)exGW@MiC$C?6k>6|&}D4T_1$(uHM#r3vuUN!3gm4%KIWBm z_?l+dnELhCUj}Z}R0QS(5QvVqYE841r!6covwHjSZ1UM7ZUZH=P@6zva_$r z)*rD=c3xyUVe1RCiur@mv$!qTO<&x|%2;c@NIGeeSy~heww09XCmpe_X{%FcTv|p z=`M6k#qm^GjFA<)^h8wa7^s|@Jtoo-!{A8d*1o5gsLBAX#hhV>Rk;nQG;3TdTftw) z6N-8uekhk)L40N6x*+H2{pLRM^R@7iCwo(}ofe$VH1+U?%@cuLfDaRh&0t#*@!AX# z;GWKCqvi4t3}F8BXAhs~3Vg{37D_yLJ3}+VeMkM&TDxNHJ*==*X3B!7zrO5=!(ct4 zhio^WQ>w)(x()+R0EqlUAerzg<^K>5CcYC=G$~}wOhcO2m;W;-CgMnPs*gb7-4@gP zJ59y$0)vA}+-2ls6^IsOek=hKoKhcy&<7mCIT4MTI5pMXy%`KwHAY}n#P+#z@pOOWEl!T1Q?Ir_BplKtmHNY5;0QL5R*#%&W`r^4G+LT=r0ot#`MXspEQq!c zna*U3E+Y^FeU9f2Cay|#*l*(CDD>6HQ@^g>AnmdHO)L5~J{GTMt2}v!A8G)r$Qc@j z5(o&R<7Eo3hJM%cnfZe4@v`}0&MQ*w(|S+WCYN6zma{6!mT#IHpFR*j0@A`OMur0G zGvQQ#nyio4`hath0|?Y&y7-l$>HT?>$*^a`vjLr_&s&OFokd}ja zbxTuIKK%LGMhuhk``&~KuJ%WAAjbP2aYotJeAT`~Atf>B+vaF|=4X z8eYs;rVTWbDY$r%*8tC$m7yGHIKw$d7aW?hA7<-Wz`LN`w4U|)LkKnl&~(-a1hYc1 z6+qDHZ^}du8@H6yX=}_+BR79_bnDc(XoG%h4}+do1eCLy+GGpbw-)EpCZ}2 zeHKp>Z0jD4GOMn_(t=hZcA$+nm_92j*K-L9o#YDw_6Mc%f}t~nXZG4Ea9~1lwnoMk zqb97s`~_-%IeWE>uZ~0~ZYZlEmnjhPf?;fC#O@hEUmVuYOKK%v;xNl?1NLM!&+z@Zy_yk4t z#F(0A^I}6|y8n9k9w2>;))O39^%C;`%g|kAJ;4buUY{PSxZBW+{1}O6o}kx>V0OMB zAj|q0`oH#VPUFMWf_pMgy8aTezH;9R?Bl32zyZk|QDtx13$hHzRDt{TJ1>x$R&wXi zzyH2|3#qgY6EB|Vv!kH^qV6^>N8ayN@bh@&)|%PL$PWt|g0#**u-$^TFcywY*7?p{ z1#U6C5y0{>M8I-=VJBj$U4=5Pv}Ip-QKVb-iH|Ph?CVt@9Lx`aoH$zXjA`Z@x_MUk z8k8sWC>>RYN%+zt`XKa3D$%Tb+Q{6}-#Rl|nJ*c=Bg5CvjkcCp(11tbu!`AGHDelE z>gOJ~Yy%eZPj@dR9uhQ!47ft&6A7c@3HoWZKFIO;m6UEKahy=yX8DdxNndhmtZN%`SLSCb~ z&?b*~SVtjDDV(5}J<(gL?b0%f;{*_I*TwqhGE#ju*LMkvO|5cD`4RBm{P>}7pnIQ1 z!tvt2cyNb@I=1xDg5;C=0f()8L+3PBoCVsUm5=dSD=Qpuu3!i|Co$Jo{{-woDs45= zaKOmEu24f8B)#T4VF#dK4H1mGb?$4{;5AmepXnzsZP4d6N3@Dz{czUZ9=l~Gt%=Dn zr?9)eAh1y0h#KinF3a!f7!R=)v`~1Nxrobz`;SMm=}<@&@v#%60gTqBjeQpJ|Aj2b zi};$OPgKYqqnDgTJ2YvWUHjX3cnw(MF1yl+h-2pip8c_PPhBhbZU6b=2cg6hu_kE+ z_p>Ar$oj4JDgwr*EUsxIsB=dDlw(~G59g-`lGG+;OzOm*{lj{VLEsM>lmr4?MB z29IIHR5*K#BL-`X22Z?$p&e#V$o+4QzE()5wO=;GwA!g!tqA@i%f5Oif%Eb7`<)emO~SXuL=bz^+ANfBSVyUPXaiwd4hM(yUhsD91#*SQH11ZY?-+?t0K?ta zSm`~b(;xkTqz*Xn_i#x>4Y~G*>D8r#PoyH}hby2jFc0c~t)Y}B-rXK#gey(gYyEm` z&S{AB=(8g`FCZcn|A;gxq)omAct7V6L>>Q&lk>`j203xzfmrK6L?Ru;0f!)Ejvv*7 zAMOm|-IVsKP=t3+`Sf3M#4pJFI`B_{00lhD*`1D{r1q_jK)d79q^e`6hqspH!jskY zQUAxUdCi=1=2@ohsM-y0K99Y~f>~@+C-IrM|Hsu?g=N)+-C86R>F(}sB&54Ry1Tm@ zDe0C{8bm<4kq+q)q`Nz%+dW^ufB)CM_NjRCu9)kIG49cJ@dqrV=ib(NMdy>+#h$KF zwf1I=bZ$s3hf*m-W4b+DwuoB>Q=ne@~Ei6W0etKYsTBcvHk zZGw-8B^|~^+VX&Jbh}J_pqb!TdEqNXP~6YQ&&q8A`yI`{S&B%@0Qm@j%WcD|uCO%` z1b(mdbh>e_=H$NEc5Tg>thA@+c!|-V+TOw9bo0~0-2<>OEZ63__PstB$FIDkJf3(M z%OPDSZ7k5K;PW^_(_y{pp)2?FuOzEG6TVspBv9Z$U@2#d4N=v0YN5pe-)HI+SP=}$ zerq^x1hB|q_UN@(?`LgV=na@-`~t;2E{kb>NVDJ>>I`iM&G4&!R`1m_(53S)59gcA}EkMurf z%hO-D!CwSrSh}FQADuHo=cm=~igS*}6tI(>P-U6OD2Q`Bwo?Vsi5c}>A7y=Db`jgq ziTYG?aKVVgLX7`xRbt6GX-#;Mz`bnDZV7i-0vv2IUh7NAvBNsHv6Z{l&VNlpmi1_8 z;a?;6oBL;oh*x~URW+2u6qMcWd+jq%D~4jK4ro@P&_BU!aoF$Kd>AndG&Z~cL|+}p ze>;F>Id$y9ZBfhEA72Gm56k1{7vy>4Qt-ww!(mS`b{S1E5+b=F;)GM}elqHfYx*Ko z*w}~&lTF|s0EQL+Fu6mqfAULwD_w$~$H|YF^nse{w_@NQFmi0RBbgKU+e^&6Vf3DB ziAvAx)$kkURKP72PsVX-LgRe(HeLSnwusLP76{O^gfKjm32nt%f+VaoGbd*r$-e^w zFQ?ABS+48~hJ-T1Y6KG6$|2ET6~F45cTCxvJ*Sn5@7`HX6LGx;&{bmmp0 zw`@^0ZE7hKPKl#-6;`8rvb+u9OIt-8hxwutf5XdcLw1{U>T?1WNHg-1fWuq zJPP}ZLzaN2x`8*}K<(4hKijCxw?bOdCPO!|g$b-dsBp^?m_e0G;;1@b2Htz?srp%6$r$C`Mu!hh& zX*bq?^x<&%P2E(O#^vB0Wwy^d)BH@Gt&jO`)2fXD*xkL$49>tw6mH=V0U=&H(>0PxTd?siL8~XTFJ->xjA;Fp;1jf`Dc4Y z{2GtS2AW%~c5=FY)HdG7Z-VT4OFBePObp!fWb}I9*tc$O9Oe-PjSiv2#Y zG&%L$xOu#?ZSM^s`2C~lV<;31+}s*M%;TKnF+wPKhQ#X&DNQMl(^54c2>+?C{*8N@*}tY3s9t|UT6}sW_atA)$F8@ zk-cF>9P`95rs-Y=u3S8X7_SOQs~gxqU5A4h(Er-$MO24M?uvT*KH47L$_mAZuNeaX ztcHVnYeooD(5eRzSxQgp0ls% zW)m(_!;h=Mlj9XX=15U}WTS^v;tJkC=u*pC_Ch1kE#APec4ATo0raw&vb47;SeHa@ z-JvYbs+tN!)gVDE8GI)q;Y|_baZ&nc=iL3z{&LtL8%Z6pe%NUlrEYn9|7zI!Kcybq zpq9l8NJBua*4{zFV*I1D7PibMzn5%Uv~eX`jPu6hmCrspP7$F4}iPBeVEn4es*k4A zH`W`@k1u*bpAgIWjV^+NPYw=K2|^TkjjD_JYO^aU!GM5Rq-f zJ&`iLe=xtYuVoAK9M)cOJZfkgYqw>~3_4~3YU5mn~+LHvv>);Lcxw(16 z?eC7ytsV*@%sBg-7`|=g2qb18bd>w_o>>@jcl9mvV5>{s^zt%aDNkcJGPj&W79xXI`2 zvd>VoyVc5Ru6!>$*iJu1@wjl2K8OZY&9=Gq%RAXZ@w)bKgU8AKvSjY7?Ibk;hJH?* zN(~Yg9j@=ln*-tNO@0#^1BxD@kW&*7RLg;MdaC7D-{fN_=mP+t0ql57n=AJpV*Yr3;P9;ZQp#K5E zcM4}MlJV;UvI086(hUTqeoHSLN=&q+ICW15DyA%z)+As$$x z3Q=Rfe8;@A)7Ev0`vQ4!zLD#`mT|6)4)M;5Y1kd>^z_yKADdL-kUI)44;P zqKB9hX>yO~%7T_A1UDR4{;2K%*CIV~^Fp)~$Tqv&zEU*@8MS)G3(^lily*k(c}P#b;PvpitJbP$ti1g~+faCpT&Hr_42tyEt^dH_<6QX=d| za;HLGP6ew_6gk*J83C_3=Wsk4Kb}^Ph47F;%B0ewl6gd&dSdc#y=lofP_;s8t|^EV z5C!%1q-h^AzU)6D)HrJc?M1{ZhKsq3M~CY5W6~di(3sEdf4>Z7x?)KW?0V&F%}q3K z%qC+Mdv)Nw3IN61s*00CfqJT6dH0A2VZbVO$g*Z5+X7+J$83BJvObM;v!^g z>8!c8bKkfFt-QI;JM*P?bs_;4EV({Fc()qn2*w<(H5mk~9|juvSAQiCLmTY!`yzVX zRl-GvoXf67h=>uufS9@e>}A6QjO!$hc#dn(X58nfE_P6VO+JLt!MmNI++jzCB+2Nf z>-?Zx%d2L81sy4%K9q|cXBs^71vElw-q{W}t+vS4A;};vBo?EQ>{{`d*V(D^vlcBm z5Bh7KDg*ArlRSAsPGJ!M&Jg04F+HOb1r_S+WJpfnkuWJaH*B|ARUq4oz&PhM8TXr~ zdg<8<%_7+#Xz*Yv&A;6@JETX$aICd~iWWXo{B`4b_O89NTEw=#CL4R8UFjnFwc-Xi z`+5m0-7}7q!S^Qo;-!hmAE_`=Z(sgZwlRXh%}V~v*(xR7mJ`B0Zu^sEUP9#+*R%$U zQQqfLnXJmx3v$Eb1EHS|NDJu1yxr@Vsscj=>+3FSG3OBdwQ%)}KYNl0M8AB{lS}^` z;chESqh;`DT=PwDNXORaDMe-@!T48?P5bpT$Yk>HnR}~ZA<{dfu|rP>f8b3=RqqZG;TIFD*bkqYZ;=uMR&#;T&P?-hoZC;C5P@bV zNpY2B@b=m)>Jn+pd4$KIDA3TH|`L|OJu6YUR9A z06#0g7>4uC-%kdR&x{d*h2G(Ik-R+w za7U8DpwpcFuq;N3mSKQN?5F=r?TV;Vbb$s6=oM9_ai!eGrRn)778|77Owwid5Dj~+ zzG+eDbz1&TE?d2@@nkqvbQ@>9D`(qpSYGfw=3iIVYiQU7AHFsJo5L2v#(<_O+D75g z7t~xBUhU5{L#>M*h4m5nFmRd=Zw3FZ7%=sOQsUPiRiMa=X?c`=!BdLJWLcVe6$Z?% z>A;onn3}M<>KjK@pO^z+m8yG%NHIi=p9qV=9WlZyVtbo(N)-ZYd^1;|YsPJsx-4{% z<2Ge_^EiX+Z?4)}>gJwSIoYzr`*JMlw41(vDLJV=Os@xi!wTDj~YgXNOP19eZ18>AT@37 z2{T=X)QQfQh%<%nQyvsk-+U)Ee{r{M@%~`PKJkP8TMdPS2XJYo39FC49BDz`ZWvPp zmlQ8n7c7g*7KtFwkh7yfCnJ_8FP5n79+wub=Kbtl?+;%MqoeSgjf}ZP#76Ng%x-O~ zr^tK6N-J^9yjoV5=50F8bOW-H_|#N(TWVM*3AU6%ybf$l8>&g#qmIG9TmaE*EQS8! z`!=~~7D6_Q(PeJRPH=|Gz4Os_EJ=Ocd!?W@#m;J5$XbYy%+qSXoqtGy zVTgp4Olt@IeN_quSd_WD2JjEV@TAJ(M-&jYU0?{6B)iCXq_C&S;+?;p-{v zqZ?chg?2Uth9uTPfNgX8M)+FuFT z;uT6PpRQ3W>E}G2xcZf@89JTOkbWKwh?$zri;&JgBSc^KbHLc-bEjjOmnICZ}{7nkDT(NM?uL6%|@2UO4!8mV1P!3hLGf@deoHHOnU zOBa`7_$FXjIKUkg=u31(cbxX^PTZ|dTNPQ;M+SU_by+l)pjT=*GDzUSPdXRXHU6K? z12lRxJ36}-o{Z8;yWJdS_l)q_qsLt*S|SwONs;$%W2R*(?3=IDxIlNBb_4;rYQHIM z=CaVmK1$m&P89Tjf>|}3gYJ5vWX9ETI!;;L6UvEh=aL4cNlfoEg6G05e!i^%rswrD7iK)#j*gpsY#uV$p@?lPe%@= zX!QnrJ56{pOyIVqcaXB`Uvy<@c+bTqy1>}^7k|1=Ub8pptUM(cp!DA89HQT5`i|4< zav8B=gl+y-Wq73FHwDlAddJU~f2l&&JKDBSai5Tqka=Eo4exH-BvxOf`phmy!V_vx z`{L}UX%P9T0KKp~CO!5ZENOuM{GtUvZ_BnEf8I}quvZ)_>t5!x>1q@kxkC2Snl7e#^`}&T?F=rEPU!1kFukdxCB)vXGl?Z@|JNC_ zamP>xhlo>!e6j3Rx|BZa`H!s$*uoiZ{%I9UpGu@d0g(=FMvDh5l(1i))PMTvQ!%JA zU@EDstb3kr2IRyWVOub$bs9p2DaWx~7$4!o)|-+rj&gIh)F2)4Q}A4VtkgTqOW*2! zqL2=#`6nG{5Qh_RfmIc!@CUa}mr2)s1L-Hq_d=rYSUy3nO2d~&3}v_2XH2_quP%R7 z_XyucuwLZZkE5A*UETC2{w$tPgkA#vic6Qn8bipg zV)Ugv77^fGboqQ>BKfuRz_luExbWjzPs>nt4o4oomUSV!mFz*qW;qSXpxb&jp`xNd zfTB+IhQYydI~df3b+xo=Sf03Ac_LFfVh^8*6t5@O!65a4TdQKq))??=ZCv^-!b(Xz zY1kKMp6?fAMQP4s1e|ZKs9Pe5`vo5U2nLdz9wyQKy=suo;f@_O$30g&A8(TtTasJW zi{fa8bJ1gf){Ea&*Z0QG^xw!NQKq9)k+AGN)~riH&?-%?Pvtl=)Eu2=Bgcia)XYvS zRLY!CR}b5wg?t`Yl#QTP4?f**?L)&%G6f%UF;v=qST1_Jp3zIw9RrY#lroQ=-=;Xx zBvb6iUmZ_jTd}J0YIPg7bTRbRVI8WMEG~Na47X9ZDxFgX3*gfWo-wK5SaBLzI=3Nu zdu!g2zO_bLq@sV}-rJ2sLSHp2yA&|9su2-!^u~1_<`rC2BTRrJz-98*yfODPE}DJ2 z@S1X7@NbE)HQh5(EbiN5xiv31su7#US565>VIlu$vi@Ze4BtG9hmy-BKaYo==%}dEnh6iRM|$+o2M%BALaQcV>(O}9DW$*^+0k4j@Q3{(bNk*z@tBUqNS2KR;nP= z&jfPHxMXTt$I5&e(Xe9J8pR2IgD3F`ajOVpcW5X)Tdd1(((}Ju*A4y>k&*xqWFs|JH}G%Ysu5hr zVnpc_-2hY%k6`nGq=W0WXkhq#)sHBld`%YnWM4Hz=lVJ287yBy2ef9it zB)xLT^`M$}xPzg^Cq>Kx`mx(HedRX7GVUhZJ;>(~zGoZ}-qux- z>E_gUZm9!cw~^%9ml`%J5`E{}wkr_0x0Z$-+dRry^C*^yd;Gm*ldRVcoeg71_cocTto3L)~=he9AtLM{4b#ryzLRaS8Rl48}2Cm*{ zanq|j8SB;F*4$K)eEU59m;A$QrIZq%lq)__$EE(9;`2N`T>LiL_AC88NEKp_8yF?$ zmj;iLG2hlJ>?KAJUM61Kic4DJNcv^_qL-q@SU1%F=Auon);_C9Pne0Sz*n$B~u@=B|y#A8RA?2NYSDVVj0Ga=O*B9u5AYG z3YZyCbb0oHTm8Gvn|8yL7dF-}tAkuled_%#PttTxS>UMhBq>Y{3x8;!M;SS_YvX3Q zg9ZJI%p-BgW3m?Uu`&*E=lf<@tLfv6EqnIf8!M!B!Rc3Gav0{caa|L*jWgWLJRo((rPTFu|eoDt1$cTW?m+sp?Vz^ zerCwyHM0e(5y??G&%>9!+hz41aOAmfE--n{Gxcyd5h*}n;XZ*H@0|6O^LJtIM{FthWHH_`1C0~OS(RE9)B-jjNRhV$Fspp8Aod`o_*yN{4Is0fJ|Y(l)l{_K1u z^K?$;s`Z;eFsZYv8A*(RCCUl5S(UagBwEqS3Ml6whv*{x=@w)9~ar!yElVwO8<#_6wX< zRQ-}ybxz%>KgiL@<00#D+T`M@7N-KE7ET>AzQ}EB8EVBh%vR;@Pjwj|=D%LBjP;^Y zLP#OU2edzb@tt1JkEV z4191vCk8Mq(eUd+D#!Nmd`WJ?GRf4%CkM9Gb1BlFE!tmeHm2UZ*>Y_))SUNdw?eb> z-)>QX(U}G&Etp0-UCWyX38gw+`{|MEm2wS#4$tUbc0}oKoS6JMv#ds#9)VCG0uHx- zVdV1KpN%lsKpf~tt&VU)_O@F z6xf}~eM#HH@YNmDgZ%b*%DtwZLFSaxnrf(q42)vG{U1!p^x z0Wn%@lDln|^`{~e`x#Zs=Tzz)4KkqP@KZwgd>fUd-Btu^R(?~*NP-O^R?cTN%FKH1 z57p~TNWBK5MC3F{D^yHOmG9e5ghj5aulaNyL{v&G->G<&AYlrEm-_h8{^quBp2@p{ z_JJG``-J_JS(k-`z?LQ-f;L}PFRRKsG6OG5Bofo_i|(%97tN>f)r6!1O2^1YoScuA z&9@ff;ebagtyvSLJ6tD#VOg_r+-B76=qF^^XeUAQ&MO65;+|@evAHu;6N&u+_x97Y zL2I-<>iV--|2e%;k{S#59{37P-QusxELJgo`~55>%}UXaRnii}BL2HS4{RM^gX7?rt22b#o-d;yHD0rLk)HVC? zN3y#XE9>++{fdK1cVbNr3KRajzz7`9+t<2$4@21gAt6ZXxy^!Kd2ta}jekaJhd9Yz znho*9EPkQ`!y;B{>5Na)D&}7Wygye$l-w5jugQlZG6i8tLd)vw$|+nZ^T-g#1iK8P z$TQYD-jkt4`DIOhc|sd$#4uL0eS90NqqEUrMQ%m{F2ctT;Jy|OQ&u8p&`d89S8<0+f$Xa=xofuODp#VMNT!yx!q@C1O|7 zN%Or52FEr6tfTS#Th=*LMA7OI{pRn;OfB_@PkZc8oU!2@+~6^S)3 zJ9)GQED(-LE0ethQsz$#5709sOjk6CtujGPcRHaw>}RG^EgJR3y@(h>z&5-GY{LZl zz&7lJT8B;+v{$fs;NJfw5jY|FK4ERbr}jrGa2@F__{a~$yyCF;)#9=2v#HH&QLnA# zPechRjf<21NyBdl4hSf*P^LFh2cHy?@R2)vi_TCy(!_81>&UnRMboE}Y(J;(>FXpg zwUCPLbu0zj-sNQ2H@7dBBRY)-zufr-FO$RQj;hP0;S2PLfjJy~poXS_OWjTo-*ZxO z>hl76hM1C>ALv>}@0=C+V~SA0En?mbqxAcRE;70-g_NBl@OzUqo?jh5Ly^$Q;csV~ zVNg>@^F9#7BAqsgl4HW?v`d@hB__!n*Pz8|Gfk;Cea!B; zjST@v>>q^UHrpHEUu3XmJA4edFBC}i?jT-f35B&Yzf2jtbMW%$3455NLiS_R{ za+(YKQ7*CynTnHsrYYCBhnj2^`fc)Q7$ndjxhTMr4q@Gk_^l4bW|bSwlYDBs`-db* zX}vJfg|e*B3!oCMC3QmX*%F>T_@}9iSQFN)oDh`wReyTisrTc1hXqmgk8k@yx%CYR znlcu>a+|u175JQx5HKEf$IA48ufs$V*xM}|nHXv#l2ki?C^ghD@NB$()YUKCRnJ`Z zB30Z$DFFH23f`e-FP{Dck6aw&D%Nn=rrWw5NZqH zdi`!!R-|W>JzSX4Bx-A4Ts{V@EwnDp&0{bgZe;=ElzcpKI@WZ{-jUC@wvMWPH>gyP zcK`mkgpn81`fiZ<*_kD&b4fnD?-`D~GY?W7(sa7_yGOOg7avsE#o&?M*DCqRcfWCK zfUr(0H-hMVc$Wg#osAj%`Qf@IUBR!mv*YC?e=zfk4cuIHPIxOmXTd+DQ+WNc3lHx4_rtF@a6@BSfQieR zpw%hNj)}NL5g2E@<~8V@rD6ZrycF%kpc;*WEpUdR#kA0H!Y{D9qx$m;gmPFNRMNV zryix``eyS5o(^T>#beikTZXmRnE^jBf2#v2(~I=>1^s3|-Od9=QZNqPeQK3ev}CKP5cPtqNvpF>}zq* z&d9u%|H_9Evl1`#A=g5AG#v*R}%T-_gh3&pSA1b%<7<5kfM zJSfT6oS!CO1}Cw_>87TV;B`t)`&;|sB<$bgcS>wLq}WY29Qj)+e$!c-NnHf1BNgzMd#6JgUab{>mm>8!B|&_&7>q=c^& zcWhqTxcbL{JS2`l3~tgFJjRkzFBCmefhq>tX)525fT+xoVD8KzZ_y@Uq&-g75t1rK zIEGub2=-;piRIY~b(RH?a?C^m8`$QQ|fTbArkeiYl5)7zjruB3v>i@*QOC)=>k2Vtmeur3QAdA=v|0#zKW3 zTEF};(+tweZlO8pFcARLq`nIilF#m@3_YA6Wza2ZwcUXa90Ov!6%kO9&EFU1MA3SA zi@rsKuObu@zh@_N`H*O5HfsL}AgnS*PScXkDDL*);8#~= z;FW=Vn0UqQUu*0Iwl|>DE<2q~DZTzu^6pGPuEu6}ZZygJlW>53GBS0~${Mu}MOFe|9@c!Cfq}eOhH3=PxO1 zF^o=r+8chMQ9qNPx%1RzBuY?}70IIX=h>ih#s5c9Etc*i+Hv{pw}m(Smdlk2xQUT< z0+MDSS7Vw=^E=DxI*g6O{UNiSq0d%``xA7?h@&o_nSPdMYnN6ZXBlWe_G+q;#wtbSVupNl=0}&aBBMkP%i7Az*utx%uEf~ z=BZGX*PQwg{ecZ1Xy@NR04r$G?+6L*(-Z|i5X{F7`fI=0Y!xv;d2H@;_3p$1bp=ag9>*NYLD<0O- z{s4m037KoBT>3UtSQT6F#}@fE`(|GoW|Mal_dTK#?w*t@ytNACnib0 z(vU^aA@Qh8*~P_uFDcTgqu}T9j-|$KI^T&q1_xMx{v-761_EW|NRK+acfXl~tsIJ}^(`aApJsx7ef)!grSCc}&Jqi)2rWIW$E z!8WUd@V*U%C5cZQBf2tqJW~=QRj@c8d5YS0#UUeukuN%5%SyOdRh-ytN39R*04 zEQB3hIfA2E(xXrm?&_IDYJG@6i|km>JM#N-_Fzi?$1-)Pu9P$;k}s=oQ6164bljE* zCQ@klAy+$(-$W%^1dgGXw%oVB(;*P1jVwLs?}%rHf`?R^+FN=AF=T3d zf(!yz8(j=7t$&nZTtBQHmEKqy_)SoBtlTD+2!W>L`UPtZ`5++T1NZc|(Q;FK5)O_a zpPK zlA-A-OM&~^CK7de2j5M-Vj`Ks+Y4k6f8n{g-UMCDPSNt?aG3R`oTrfHOGmgOF#RZq z(JUq7*Mj`2uDO>;eIa>WZ6K)^Ia{k`F(<9$$2=2Ix*I$fsTb+monMxK1=-p1AAzjp zKUB*ZOV?|?VlFJ%LL%LH_V5#e0St5Pr|HS&Z(qYoQas0!D8XkZX@yVZzo>U~hXX)l zLKFRClZP-UMWn)iEEafl1kk+-m|IIV* z!E38;>r5`I{eY%&V8$AWWj}^UKL}f{KIq?eWAWpj-_}4hx*HNW_LZQrNz?;kP6{y( zk`SsjstT|$N^gNRKQyR4cJnM5qo|!dsv8_4{O;}Lmvlon%+0h>qXt55X4ER*7Ssda z=z_4V-*~FnGtuglc9*96`Pfryi$eH`E}H!J)~ttitRVd#5&-!e*tVnCxR(|0y-Be_ zkYAx9?rfWi=>=b@dgDaz&+53xmj|m#@>{!WMWK4`r z+L~%2JLrSD@qRcXBiOJ`CpC=CT0=4;LSNH&aW4b!&6J#Wq&tD;lrw`)b^9L&lCfa%IwtyucNS z;INB*LbV3Pp>~!;gLXxmcff}n-tntj%D^sO_uRAtdxkw4en=poNQY@@%5g!qiN6WF z8xnuYGUIuFkwWP^KGRC}QT#R!hQ$+*y%u1xWoab&!>rQRq!dC*ld&PrGGV8ZMtHXR zosEG4k}Sxg+}BXFVMc&Z(oAF!0;N$*NRp3Ox}b^5-?S3m6k42Pl#6X*Ol_PFZc$<%WC9`UCIoyB5o8j!uup z7I&271@NAsPgj*Xm-qVSvrxgq@+D4Fhk@S&@?j7`*Gis&qgmc&{Of#v{r^_KLD+`B zu9?p(wbxg0Vp0Eu;P*xW3S7N}@4O!1AAIc1V%_|=m*`S+TpMRidD$1JSVnJ;vf2z~ za76LW?yHXRH%{wQnl12R2VW^y7wo_&$l+t8kOITu6MGkBg6|szybEB!&F~XYihgK| zuj1_f)%9a1jA!fdInVbZCgArj2n+g_LwoiIRiDo-&M#3aQZuZVn@3UbZS6Pc=8rQehYr(P z6EIf9LB@r!kJu0>3*gngU}5Q|bmL6g5WcO%4^^{?-~y0nVs;e@)IL1;YWV1JphaTX z=i408$L|~s_Lrv8Dszpns(A;d*ZX*@em&B}Kj5Efv3LFWl@bj9_G2}d$@t~L4IyjW z9D;>0U196vFS%~)D2gwcXauXURYTpfK4byax17K#9^_CBcefNm$ZJQ5dSL8JXLnI zwk@8arqkorNro6FxR`omAT>i(F4Q^qg2*)5PSANQzBEm3!bd4tq&z(&QoA&brTs@Z z`S8rjrbE5{*oFE^rpL$kaDlg=+vo%TUDEO+;l>Y$%%v3;d(f}T=!c(CA3vNU&GfGZ z_}U==K#Fd`M$@MF5#{rd7{M(Xj4rvFU2u!m3O&O-asQZ+LboDp^uR8)X@r0dgRLA4 z5{`;LZWfq&AXrFXv4a);A(L|a8N-dCX@k+r86D*f|92gaS=!@=fHLhXNQyCJd-6yc z0Gw%0ocDtFW4{@=l9az6dm5{7G6Sk>R-F=j1g4;g|0quc_$?&1L@Zu5!VG>==rAF* zjdNO(%wu~)yfk2b0!GLDW?ddJaHjkxdCE7|ftRf(XUo&=@s&{P$G|LI^EYeoESIR8 z!+S3olz1!0zPLHdJ>TQ}ZPO$i0zGfI*QX6v7NOs5D4E6a1s}a2_WNIy-ex77(J!ni zGQL8qC~|>fgtI)TD2`%N0B|Lw$mhr-0_Qbn-WxEcEJ{~@Wis z?GW`xnKVGTyi~ch9Vg}{<#g{Tm1Tcryt_}#(|_fs7)_8PCo1yc>*YQkHH2^JAOt+n zM&wl%BSgC@;(i|-MMa5yY|+bme4P95Aogd>hfiu*7pGH0BEzYhL4EFP@9t}PuF!IRH`|MC@Sg4v+Hmu9)`tl(!k)e5PV6Xuox8T2?WPv5b&Zv(&O*BH><% zr=H(=g9fxME{VMu-f6U-c0-1>PVe@<_Ap*S@~C=jJiME{-r?s9R3uX(y2Zx#H%B3s zr8QWwWaj$xeOs0Y1(@8lx3H5vNJS2egDP{L+IGWdrO-!WP>B8RIMu=aHUB<;M{Y$pVyr4^n_vr)*~Htn*WDACh3u+}w^=n^eqct|Tph)83|6GB)lLz}~I zy*4HP5TcnZPn(6H6?h6Zi%ejKQ)6!r+$?GipQjO$7&2X}lLv;c+}bFmR5qZgF}i=c zeXgd$jmgcPF*tMz#!~a4ULmHoEDxCZbV(>M1MgWy#Y9Wof9UleJ}&R)IJp%8GIs58 zEZO#7ffAUuj5@974rIg{B$j&U8WoPbg+K6ScJP~ zjN%;nr3g*o5)hqV$rj_tqp>?vhdaL#F@kXAC=4~t2(&ThL1ssWDulK!I8w61qFq}= znJMnlNfVWqirhr z7~eHf9v)8-=V%5TmKpa&==VkA2~!G>n#bU9lufMQ3>dnEwhKe(DwjJ5kCkVz!4BjH z6y**&w?OA#uH7m%t~@-zc1Dh;j4y4X>yWva!>QVu6@) z=0vU7SrrYxR=O4s%%?8GVE;??hY!9AI7jW33;(og13xZUdEb#_n_)R-VWpHwhgy$&aR zdT*VGC2t!!j0Me-S)SpPS4dwPRoY?ooTwRRm;!*$kyesR(d zg%rSSI_Re<{_8tq$Iy*om>A+1QRf_FYhOBE-(IZ}`v`D2N4EQgs{R}UuNDRy^Crh; z+{tM2vr@CB5`^*`QpmvKp}h5ZNPL3%mf$u3lqWiInt0^=@4+c-+_p)s5Wsds)YB%i zu=mEH^Tc`WAA2ORzA$rp88hr0Rp6+HdalUpgHk$6h(eYA74{73W~OyKIN8Y z!e)zP3^7qgDi*`A56a);EQ4uI1t_y}NPr79Z zIsb}~@JG?;IY%C?y++Q{5;i-iDMV)DF8)a?JAm}0Ly~$>eCgr|dJ~*!?wF0rno^)P zcT#dmhICB6uXWw#ij@vNWyC{&aadn@Q4;W`YSvrgY=f<(wgh(N*G0vSVa=5%op%fs zQ4IWL3C>>03)}{{!jA1B$B!M^3@~m(SEd$W^46?ZS6idTnDx71kPsY9xP^tGnK7(J zKYBx|*Wgwl;wp&p!f;*>n&;0fEJfS(E;IZa_+}93Z9RYl>kox!&(K-ol)?)ysiN<{ zo(v1YX-ExU3VP>o89#6-rVEpPnwY&4+*v%1(uOnmJMnIV0K&y;!}Oq-qPl{GrlR={ zScbR}OfC;+PQC3*1D-K2!|jq7ggX^&1@SqJA1E9rMP^~1F&$4|-KH$h;u^Ww<~VEh&#;>Q$!8G3&%lEG00f6af5ao;N19QC%m7G-q#8kP4pon*e zp;-zp$F1qDc=5#d<}zT--jYP27-DzC++U{u1RHjokP`{5^Ym=MlZ#VTTD$0?-WVKL zNBf&)-oiLAP-A%>>_2Wui)V_ha@KGbg*%@bvsqS_%??M;10GKNw*93qmOVZ7tU{h; z-&lRX2fBrERbh-NC|FM4LBwA8=@bPMgkkzI>t7B3JRsDI%nMY{;iaLMKWfqza$#Bq~s--#)b~JpuXM?CC z*bYn$-{WNXFD~!+L|OrHs6m_-VB@NSvjM7&wQk@DA^fFJp~@-tzP)19Fa$A@-W#}Q z^xl?P$V_&{wrBeWBEoMDA^0;s9dddQJ5-s;Lukz*`Zj>G&`h>oKEOHYwp@h>thUf* zW{%^!w)(5eMM3A7K89{dER;|?lN?}B(P*Nnnl`3=WSP>rM#w~v)#q55$vMMbA0x8) zHrQq11|N}H^y(u~JPA(S^9)(?@$;4kRF@1oa7sYo#dj!qR6*(zpZ>npS2OLVUuSLK z=lJheY}G27w#Cx>3YqnOSufEjW9~aQSSEj(xn<7Q3}Cple?@HQ9MKABUVpOt4VoWY z(4{<}vX+Yf{B(=?Ca(Dw-MBm8K___Z9PCU?z87p-q3{t{?mqlWpivu<(fd*GBfVbZ z2{LOYS{TGSy5#m;PQXRORm65UnMVKg)xc(4l~)y`lQ-C6=);Etn@H+`k~nx^IU62! zt2OF4duO*KLb1+D3Jl}-ygn+E7r!hLNcFM!8}>YD$9P4aIPtpg>t8EWwO-`W#vY*1 z;xuWfI`S0pDwpnL9G#k!9uQliMjB($95HKoh+FRTN))y_dFX>bXV5Z4S z21RtV{A=U7WHH;mQ8q8k(oC1%)Z8R^)&_8zd-{is6#iTw**-Kl)mn75Q!Ty)&4u_f z?yo-0qcD1E%S)Q4r_tX{)$IZ2gV|)iUQJNh$9&e!UX8{htDLNA+OX;1^(KE~;Kez8 zep57G6hVi*k7{@du~k-q4hVScm5xmYh-Vd8J$8%cwqn%oxCy>|tQnK#r-JD!NG>S@ zQj(ZVS=v>NGy&e+d^VXOgk2vMmYTAW+P8=mQnZUc32Ajg1V-eRT;)&lk+j_de%-mn znmy504)5xG9UXCd6kgsrHjU;yDw}utZ@S$j1beIz7@-n5IwBET^>n@zn|Wr&zo*V>h(ox9G`VW)<%P?}Uu9rZ)Xr zTAbZ{$;hhwrO*B6)ndTbLL1hKxL)j}tD^kQllacv{YX z(O;nAyfwv?vir5L4dmYYvb()9+Twu_3aG4mCLHhK=^%3c!^!J-Gf1P1xEB8PnJy)z znsUt{9PHC;!bov#;{NTD+5Tl`AIBvgT=9D+;4In@o=<>W4#y-bd0ncw3dVZ-h=*LG zw(Ei&jmad#!HU53(X#f#rxa2N!B%w;!#8AKWt>RBJ2fiV9r{HhVCFZGNy9F?J|c2sohSoNI-aCuerTpnp@vd zV7@1sYqic#y`(Pp;VF7*fBb z&DkM*uRlQ>Wi=>acau~T=$l$U z*=45}66u5f6UE2gOpSrY>~OD2zbU7I*SWUFvhkc&tg4M<2oQ*2**nB(n5YH4mx;1J=h6C@*MrNRv6Y znQ8NL|E9y(Wm6W4Qvs?{%&h!G6;5H&f8GU>O2^HF&LvO5ZVR80^6Ko8eZ(olGPOT0 z_>Rk9#plvw^sYDtcadPDnkL8Q8nd;d*{iX-y4hKmHo~KlX)bQ^mu-~;eSbCbU|V~I zvHG6Ti$n{bI57gCEQMJi+oKCgs zM<~VJK(j)4Qfj(46?9dI@QhV^ zlv2$^A>Z_r)Mv$UddG%b?OYE*MWIS27Ct>lnvE@s4E;?p&MhaO_Y^CfT$2x zb1bzW-D*HjVGaRv3NhtBDIdIKV}**-?dcHN&};S*vP$_8aT#yAR zULl2Yin-<`PEbwJTYCuP$9TGj&#D}T{Px78e+#eRC!LyGJNT~wzcSKn<-n#)_-9~5 zI9!|%ypcEY<3=_9StG>VySs$JigGLvsNUzU(|l(IotyjX^mVgVketCBWNd#{aV1~x z=C_UpL5ya}Z~3@J{kCF2*T0lVI=0}f5~NwA{~Od|TrE5ilp?>tcl@2mPo&`UdnYov zuA7Fqb_-nTg;AvCo_a#vDG6$L&-X2(NS)m&2u7%)Z$Oibv(#OkuBy3LiUTDG@+UcS zLVJBrNTo1N!CY9e^Pph3JD3&syEkc&DvF0MAVJhEPtdI#X!G)L#PZ&K{9@;cC4o0W z6(UM5l<|F2$-M}2NcZTke@||ZHAUG0gSE=mLBvH+&e_pCI=lMmaor^GmYlhcd5wgN zdXau*6}e&Yj3kqJF3Mik{Z71X`OZJ=YVCw?bw0RxD1h^YN0N=~9CDq{al85t{y$GY zZ!fo;C!ji-ncD2;WUrpqwgxdvr#b}860E}?gKY;0cEE9%RSuIx5w5bZ8uYhJHU0&l ze|gaXm|=Y+U9cXzDb2f5-Bz8vRj57Q{I_tBAQm$Yw@Q5;2-m6_{fy@+ncOB7J=sM> zqJIb}ti@EU5a=0=zj+C8zT3M3#$Ew}tD;Mu>hFm|APJ)a>S3%nNRWe-C4yi%`_bGe+u?CId4IPH?Udcumy~us(lKy5IashVp;Uzr1 zd({hO)DZS%=!V7+OE5fX1j7?km~+F=A%&bSY~WaE{dtd0g(8|u*pNu})4%rk<>*h5 z^w)uDj3JRaaq|-+&QA z(cU44zt>UxV&(D2)4<_X)(qXr?G+m*u1W`0`s-3K9nlaPr;s=dS!p{ntbIB0lw`>N z&wtn0Xwsand^1;;Y;Iu2|3Q=H{vwp9qrG^$rC+;Q3Gobl4nIo)rgZj=$d*XdTGZ1T z_3&>@J2g@Y+&iVN40nQ~7RzcdxKklZ);gCi`8xkT=zu_;;pJ2b6Wi80#y=U>a7&wO zxucnkD32&BIQYFJ!kEYiAz0pMS7XK?Pbf<;@>$J%&k(E5etgf*kQPTM;PKkJ)ZTw# zr2WIh9bW!tlu!Qm*58CnCL3oTY&I^rOrB)DPb~m1kCy*PnyHAf-((ucWQ||SUmSC- z7T#mGUMh#5tLHw|q5doXn4t+nx=LF+tw{=`N8FjFRB`ea$c@XecW=2w=fUjt2OpTd zHpG5^St;s%mf3oHx2jt?ij3AwC?a4P;838o(!Xn=&%>o*)a~@As3(%LKRD$K4f;B* zu86y*>+6Kmk1Yvm7|-_-;()EC)g%Ue4VKp5WZcIBc4xkP>dZlhw`z|Zx0_%oVZ>om zxJrqc>A|7Rj;v!INQ~^rGuPAwr31|#B!oEqO@68hfr6kmEjSvb(A&?R1=y7Fu3~Y z459v~==Y%=?rRSJ3~o?4jmgUklr4^OV&WHu#0YziEtwdk;6^t2Vn59rlgR zxAE3Zrty}JJdhFE(K`IJh3oo6B0XAteSJxA4l;0*TSbJY30PV@)1BA3Z3L8~VMsE3 zRRY#0=_%BS4~9NiPZ2_cR0m?8hIYWXkY$mnI+U<#BtY&=R*R)-y8TGp7MszV7X0!- zK3Fc1DrmjoA~#K>O^uNawerO5t(<@7Im0_1CwbO2wV5KzO!@7+0i*QjmzIP`K)6bz z(^0lP6SNuWhCPX}JE@dE3!vqE&*rSwEfXs|*fFC(+1TJ(QZsVK`Q8CjMmu8O zfpKl>I6da?8C+8F{U6jR9FEdv9VIuI7e*d&iW%i$p`G3F``}7kblx}yV7s*Mq-$-H zwE_GtA;apbvUv?{T|u>v&ZYE8S~iWcBje)PCebI)9G=o!nR1%zP}AROs*pV_-FH4j zZn-Ak+(eKZa;AlrRGE!udF4E#*B^JsaJxV~ycyz=Dzj8fb}yUi0KIyn_w`S9U7qtH z*Bhn0MoPMTJC)hS0OSZjN|L?1 zM_lStkA-((%<5(;j{dKn$lUtGG~a`>eQ5SVnyLCK9{dft)>?ZA`OED`Cr3{0H~Npg zo|?_n56E5g6SJ-%>zzqc&`&)UVJ|171}LIKKnw@(Oc}xr9On62o+E-~sd60$;w&*o zyVM@PJp%-}@!ViOLQ#XnWU|&$xX8$?2M)p>brjpQQ#E?Dv$NCaz!Hq2Foz;ceC@a$Fa+qPix!-Cl5b>H7^A!G<`n z4*h(ZHr)5E{1W0<$s^&?Mb@qikz8tfCgZo_7%^@kqlQieoK<6$kb7sLy?6*oI_byn z$0!`#(;0M+j+o^586+I$c+Wz`miRN~vzZs4vO?4rlF$c8!o0sZp;u~=AIb)tbg-?x zh<-IX`_(D3_f{{`TFg~AIk-S3?)&FDZh~0>Yq0cZK9qF%e@lM@YhN(D$)IC*PrEYW zPV&z8U^&S$pHYb3^0R7Jrf|GFaI4A{v@3}*9oF64#6>0WcDhGQVe|SZ*-cus>OVbD z{BKr4zKi;)Yu3dA?_weMZ)nDh5GKo3`8yP2&D$)a%b#xKQ&93J3V3cxW!|lu`mVd$ ztX0KDczcIYqj#Fz0I&vITq?%7Omoi4-upp^L-Ogf%Ca5tIBfmMuQ%Y+q59;eO8g^4^$N9kj{*?y$C z6tJbec54&}HXp{AnrItP`+k8%5Kn_wg*vrGcWL8QzhlSOid=9b2NenK!xi%eENo~8 zq~$gTKO{c^XkC?*tLJh}>(@Rk4drv~f$v5{==AU3Dm|r9dPc%JSALNuilxx;Leghq zSs|M+TU;&G2R9=fyHVT^t@T6hDP9R_ww{WTnjCX`VP7df6|}{k(R3jqgg(B(?L^uG0V zl48*#_^zTImZc-n2C}%f`qssX8b-b>a^C??yx%)>OB>hWTfy-J8yz`VP}$Ji=awaJ zeDa@q`_sYfDrXja;6gql+FsO(n&k$+y%~*4y_YS8YpFl=$gcfbd)VZCH%o^RTZj^L zAfaXXnu)R9YqDcw$1vShj{DR>Jel^!=kh6L9f@~9d;6vp$Wh-+TrU^F)xy4Y9xBq_ zWBl`|-Pl-t=f7W{)1&leclM~z0dVj~{5{F228-l``?!bA;4Gpj9!WADHEP>~tHBT( zd#ZTAXJ7m`-6Y;m2uJ1XK9Pd2*Wa|CSWtME=>2a^xKQA=(*?a5gRFWK3hQu0eOB1G zH==$_D`G1a3ZO2F@WLm~9PAW-yBMX%7by7cF;;vOZeP-=z(vv1{o>m5HnOOE(cgv0Gw8wM`ORFNszU=-u5LhUe+^oh9q%k|{YtrjyyAYK6-AiM+Wlul` zS-%-=#ntPsKi&}kaxDt#b^<7yb>BEOHor8K@yEaYIFo71rAi|)6{k#;!) zn&gA{V=?iS9&a(>+Jq&JJ=MihfqZ%*>2o0=8DUYM=x@Cq(0tlO&W|_7-A}PJk3sPh z4(q)8CS=sufZ|u^|Dah=&H!Vo>m?&t*HAc1n`t29_fhR4&}^qYPfOd`pS*oAI=rSQ zQ~+DJkZVn~wY?shw>?(4t4L|~{CT9!J7A~hu(&hc!wIMl68atu1***S0`4xJvlcW) zI1T&??1^#WR_;P3zy3BkIK-TVxv8FNTSWu6Pef6^w93D+Z4S9I_|$xF1|uU9wr6Q< zN`~L?X&+^!lq;F-9=lC}y!l_WWjE5Hyw#>dPrcu>Ug>tu!TlU-vQOSi(oTyia(9^T z^kD2Ldg$PyA+z)M1_)eQY$xd|U_G+ZG$RnY6u2Da@DXcl6L;&r@5Qr-v=jPXn&_vA zNo!A%+LK1QpUN69vy-t0wn{X|L2bp{%3?XTG*n6mWpuARC0|KvPuU%!TNV$fl$<^G ztSDRbtMUA^VrxC(@}`ciIB|5V)2+8iz`GnL+@fh#P9ct;8HtNX zd%wU=0Ei=GTi_aF=R2u0v?*k2MZEO}mbD~2F`zcqeR44TxNlZ7St!Oqpn-~XJ zQd+^%I(&FB_vm-o(q)+}J}fKGE=H_jY}2efcCXvBYTuQ>8|@Sfjmv3=2to`gED8@q z!a^^RLA}}*o%6h}LZlBZzCGkKZHu<-^p7LO-Ty&) z{aD3#Q7{a93%pvtTEDNJda&ZQZS}E<9QIBM$tP~8VMQK zeb8}!u!st>Ub77}{%A}e&v>@UvfkDy(w8{d=HETgLBjx4x#k2q2D5J$#rOf5+wUJG zocpxQq<4*%YWVvqpbGG$q63BCr^nth^7&$#{9L1~X(#EgSgMM5EKzFm;y6Bq*|jMB z`o(!g^T4`RAvWgV_7`HfrE=r8J&EJ==bD=e~PS0P-4#Aa=IX z{GbiPy_$Ov?sa~l7>{$Z`9IDhpB#cKxfUJ&=^2wtYcorSDPAGVC$ARf-(RfiJZ^c% z8R#LWfyDs2ujss-IgtUe$a=Qwmh&Ic=sylWovnvF`sJCaeR4fUZaSdw+yaOa4q^o{ zxb+lK#>UUrGUYRi6A58&6cABp5w9(zArPEGJe{ck*x>1aj{x_&hno0;M`Y_ZWx9TZ zhBL6kIr)~{xOAen1g^Fe8C`k@opM!1gA%wH-hb|)f z3YWIZ;a4GREH?!lZ?_PnICyf?8W93OIXfd$Wih6TQ#V}xOdC>q9&RaqPobf_z~<&i zZyR$W*`&vY@~6hfcYz1X{k0NTur z2AinGRS_ff1JrfFjhN+)4Y$M|0$oTauen=G8v1`!FAO#0T{4p4JMFZ`Sn~B30%gnV zZRwH>FuFKXeSkSSiNhaw657#?CtL{c_XRl>V-=#|{ez~n4tH)hpFi4`Y}>Zpsx_iU zT=bD(;Q$(`u7ez0 z5NbV*FB|BF)a9FVOM1=72h|?C_7y&mh_aM21|(3t>eToHV!@ijt8>egj7E%>>4UCv zo1hFQ;Zs!&g4fgw{6&MW>@WCxy-94YMe5Ir@Qy#Ut&DX|1HRURnQ`3YuR>h zl}z`YGzF>$f&9uK{YhR~#>S^n=+=!+$Zum0gqsfYg!a4pjeg5gU;F8d8mCau#Tx-D zuH9W~Df?}=kh*C2-^bRq7PzB>qjG0W+Rq;UE0v?rjTMnxOg9RSQp$Xr##{W}^8ZI2 zVom?NvTnN|!mA%W3r=y2lgqihg2Qzq*~qxj(tAyP5HFt?@HIAt@jXnZdBgrXSmra?9nq3a`T7y6bnz&X_s_B z5WSr7_qTVUMr$kFb*0s2?S)ti%?h)&>hg-sP0Pl@^WuVXpweC?>ir)qe!X=&IeSSF z%hO{db~o9y8zMHg`RWt&+$gm z);=JcCGY*~Jkv)`BZ4h--4*NRhJoPE*4$pYw93FrHVN26k_&I$Eo1iUT^zfASw24@ z87U_g4FboJh%*Z-$j?5+!{DbkBxZ98Z+d))zMeMUpJ}&iZwRK9Q@tuJ2;SkBz|1T&cg0QOMa)T*w7H zUn%V3IN$w3t9i*>p&LKEAwuLxLhF>NFV=_;Stn)hoa%6gz0Y}XYR?*GFr}ye2QU*? zjK|ty3$~khMSeJ;gU&@*1-S^a=PUf2m=?W;5Pqw_1ftBw&mnZ2Z&k9{gSk_qb&BHy zZ_ghtJo2NtB?tWzksXr8+G`pFL*~LeHF;zFO%duVaHNt*iVtFsSP3i7x)M5D9DQJx z*%XLg_mwe?*v9+@bdY*^N)eDj)xHE4$g(TV8a>ZP@ddNDb-d6g#gP_@94tlN`IE#x+7tqid#&|=e;?6w!V7>o5|3|YZ?_DD6 zR3*(*%KLn~kCWQ)Jg8{{Jtfn_=|NCcBleBg_Lt1n1P0vN@s|6z``u81>kZgbXa%xp z+Thp6bKF3YxuoIoY5d7{aq3Agw>*ec(DkP#^Y7^3(hq7rV<`fvgNaT)Q*GW}$WeTB zR`HyY<#*fAOQINzU;t71Jnkh{AsMXVq=eAP7z#%2s?EXhSQHMbG*Q`7MqN~P)_(PO zN!32El9gbZHqPk|hhyb>oV!^R`B-tXxlg~eTH$ew2-HwTqX|8*uw@_*y6@g*lGdnO z_B0yhkgL~m%@zHjmQSOlPELFm)(L0`*3R|yk7_x@WD4>O z&(Am{A}Q&LIIm?(29Y>b&mC25r?29!B8`pgC&Tepu<9*>`{TeQchq0Us{}pg9~mSZ z9RrOyLfIxsskjf0lnF}tMZ_|ke`A*Yw*lxf9N&hlomQ3$#dO?ygxz*%@*>>59tTh3 zlY^r`mcLrB^+!EkQW!JuO13S0aV6x6h}R`>hS@?=FWKfrV-(laNefDM&$~LLUXnQEW4YwW}?8Xk%6!k$H&vZ zwEk>&1I&$3>yWz8kn-H;_${!4FG?@n@`QX*FT|1YOnFkH9UbjaKGAOHXESkLFxZ&^Ya{=DE-#C;Sw%Jcxa$Eo!8$h|*gkj3}TwQOI;zrSr?o%WRwAgb+ zQ6XS?6$R6MN;CT#MiKvtURxgR)nZNO*^iGMYo9P;kU$+4k#g|gZvj6+XA3W}^8(oi zkuoVMXYl^>2tgOy3z5|BfeVZ4mSj^ib&QCO<9BNw)k9o*TOQx{_%(JfP@U3RhF{)1 zx>PHI733GvoB64o6^`>4S^-*eCE-{^g|}b@Dbo68NIJ(usAdS|H@0p1e6MK)TKFs{ z{xBG6B1-e!eECf=OfzatfD)^r1|l*sl?k#`V-t9xDnnQn&RpO5+@UUZc;{4E;$GZ;=X>W{Y$r1dSU$C^){>5 zn?Qmma2<9M8cZ9&yGZ~~|MPY4FU@P{jD6fORQZ_OSLfAAg8uEF?fg+AAmPa^V?{sv z>o>y0kz^VsS~G z6A6FAsyiTdPS_C_$!JcdMEiv2+t6Tj#q{?A?bmJpu+f83|Pl@g9Q( zz0wDQw(eQ#d%mH-jrbJiyuJrzC-e+|DyIj z+xF`Tob$|T*`;0GSb;lzEu|b>S~pDFGvnVpH^-^xYC47E|ptoESw`siZIJ< zlMd<~_3mX_LP0#LJv3#uB({9L^_`J0*-31_^8XOZ6InuImqJG;T#Y4WV>daEgSKzl z-!p3O(bm3eudIe+x_6&;Z?&1#P|f7u+@v>sw!Tw^!KOWSu>whwh+Y|FX#P#p_lbI? z=wONSMAGv$GH^)G)8=j?Sk6h#)o%Cp%uE=wRM*h4j5 z*O!C)au#qe^_1CEISKLLRC~el*B+K#s9nm4>&iQ9x6@jtkb+HTnm-_$UL@KvK=wDfQ$Z4Vw;x zyH<0=4Vh@f#Y0ymCX8*Gb6+kqVVE?(0kDGET|KiEV;47FrOZ#Mz}2)sD6pYoL;ZVv zu(Y&90TKI*kCeI$QO4KKEPd1dzQ(mI$XRZC!KP@!qx)*T+D1x9sLS5qmuv` zelT-hW%nf0j{D_P1L=hwhwW7e>@6>M@ne@mS;wfTDGUd`lAq1{9PHP={aLQk!GPN# z@t)_?fSq1n2t*nZ3x&mCz}mZ|P2*HL@)%!sI=E-BPx!&!`jH0`u#;az!AL$JP_c_E zA0Ipl(^l5!TNlCL;?kURQnkIlpwPF=)c4Cyb;;;GA?~8Yof-INc36vp#SL}qR9P#J zLuVz4{9a4819wA835Ta};fa+$eKF7qGf94wYhzSqlufJQIppDfQ)7HvimHy4LYg-5 z{=oKd4|*$UCX;oYIztS3zr^Cbs?;o-DTdkr*eusZ*#~XisG^HzN+1&qQ{F=_THc7M z4Fr&;>&YI_Vt}HF+FXc=tCp7=U*e#O!LTzSYYIfguY<#hJdzp}r$f!X? z7}GiSN5v@rYKN#?7TCYKyD4kxk(}^0fzKSvbu=n8QN>v+>TEH^=m9VKX>*5PNMQ& zJ^=TCrV(q#hYo+et?=$w4E@U0Vl1^pt8;auq_@#++oxYH4Ig~O$Vlavr0r8N$br{V z_d*rB#%f>}Gzmu6bAS2alH!0>j+QedC&y-I!x1Ioauqmo&A$6O?0U^ z&DR4xB?O#=14pIY`#z3O$qhmZ!cqb268=yWGxriJrGJz=cI02KRq>A5J37u{05HD| zY25c!3_9w3j*06g6sFH=8Iw&9?j|uc?lV1DyxTwNf(}N4wZ*ITixD~l z>Q0+@#G}?AQxg8DA@k{_nV*RLafWw{m*V3VJX}k8RolKLacE5~KiJCuFcsu(Uoc+i z+KF<}n>QeakXT}@U94Fnw_9#=P#C0Az*f&in8oX-v_1_kCL2}{g7y%jz4&{kWp-?) zTFlKtCE7_Wa}~;)dob$X@ekUAos~T*Z3q$>^rmarkcYv2xF;%ad^8$!t{9gi{KLv~ zf9k!CQ1vVLpHY^YR08+T`&w3TL)8A1A3hkyl|SX~w5*Ax{!fO`5&=vTn82ltsfWG0 z%6wC6;7h}RJA&jF*jest3%D7f0SdR7>c%-CDGQ>{<}iHG`m^dl@e>h}U5B7>SeAq) zX!0*h>%>0$lla@$G(~4NTh#Sz)M2|e%YwMz8l2oY-q0FoVs!ir#f`mX+FK+-iG_Rd z`zoFD+s9nDsal$3&}z$0*-v6uG>Ql9mfg8$PwL959~z)UFUDVHlw=ar4EKIrc6;ja zn^2pxAR{Zj!iKKftDinfB(mMF4tU)zZf`@|+s^FHOZe)J^g)mv_V!>|>8I<*lM3M; zPdSvfdf56m*&kDeyXeUI7Ohp88Aq*APq4+nnT#W2oGQ7mSppOZY4NIN9534Nb;m{F z4Mi}3zAK8*_8oXX2J@Ar(2=`Y@Oi^8BSy`?4vwW`Aq_*}d$Zq*7soZ)fc^tE3`-$D ziKGIOktMDD=nM2DndWO>bej&f zdTn1S=@UM8T0EgUhb!*u(pG}CcJJkp{$}w<>!tD0I4K&&f9=h zZ#-0Ej#;PLm#p}vi>`yUp(wW@u1OAJ?s2W!gnUD};%$n)(_~C-dW6@ps>==g?wMga z|A0o%_^(%i3cgV$ixgEzNc>9({UL-oUC6@h;m*a9;wI*YHx%@!BFHo$EqHYpcw07V zb)I3(UFm$=`ga2r{rgdUlOh=hJj?+0eZJ89qwqpOOQe98RzGBFjyx$VR8=6yhXjQ; zFKODAw$dW$Fk!fjn)EF7Pb0a1ZPUfqZ!40eRriOPiU7(?)8m;6$FIQepLxz|x2rOj z71Q2sp_Zp9rZ4gvsh<_&@_mWpw~0Qa4FSMS4{Syex_@W{sIHLIb4c9T(b3_Uzc={D zyCt`+NB;INUwEfP)-pXZol|#5ZHQC#RzT9><DdqWL`?~)cOWhQUWH!W@vppT9Bx9zhoE?Am<}NLQI!7pIZPi)bpBtH9kCa8nEu>kn11-g0~z{Jp+&CoV?*QEu+u)ZM3Q&NmJBJ1)Lt%j;l&wAv#1G3unfPp{G_Tp;8$R zU_LH?)IRE1c!2E$HrfLn2WW-DzwaW2{YW#s$HV-J0~5}Br{|_egf=H}BQ8RZecm6Z zwlY5m84GGN+D0r12T#~A1U;~GUU^m?Cmu)OKN0AfuE}}vI zhtZGWP~Sk%d-CG6B)+z_g30f?2fTt6?);-^aQR`F_(QJHB0YW8t>BpcYPpYR9Os_Q zS4y~_qxPz&rAFEO+S6Rbva;v{r&XsQzZjAj=B^6BaN9pl_?O+urPcYe^ad##_midb z3_t((pqp~nC+fwzLoF$Ate#E;$&?6X@7UfGH^5A+GuAzPeH#Z5it{J?qT1yrK72q2C7Meys9TnJJ-2?qZVF%7T zS2P$=QLNnPo;rsrX9}dhe`h6rX0F3B)=d7cNCq$6OuYSfyaCe|c_D%I4_5Tcj|E;6 zbf}d08Q0Y*q>NgBl>dd&e+BSV>>1)_ym@8BVY0dq08rrJNdLPbh1q27&NskZ@1cK9 zywc-=U8bn5zi+KQM|yI&nZ9RdY5N3=4v0ZvJ2x-ba=7-+wuiVo!!FwD&^lPxkM4)J z&~p*OoaUNT@W6MZYJl*Hq#53DFCGW-Ot-a`Pn4w?3w+xM*Z8Sc>y~oTz@6Ib$}{Xk z6ZBy8a;7?^K3SOh4N{O^uh0YzS_~{g_^bjW559s}!8f1R+xaOteTjyIXA((i?Sjc`E0etwsBHpV*Nz2wp{fm<;z`34s0L*i^|2-m+@-t&#)~o5omPO+LWLy5Nq6^Uw1*c9UN0gFoQ~9jG2tj zTGjD!Tm}Ek|Mt;m7XPe!;+c@=@lDi`Z85CKk4f-hw=1>l>)ed&TLs@;G3l1d`Th(& zWw}^nuL36&6r$Pm&mK!3e@%B%q=1JJ->I&^%R{Om233va05D~6x&NmXtSZgWE53tb zm-cmZuO=47L;F37PusK-aI9aP8R5=FcZ*6RR*m=NwN17$)906q7SMG)!59}Hc{Rvq zw8=Ry3i;i>GD8-KK=>8x_XqZwk$+Q9q({ro2>~I>QhO;(UGZ6G$3wyCJ%(oz)#N~ehfvb$<(vBE|E#vegZvl-PuR0as2L_VJrptT^I6wS2Z|mnSZMag{ZZ3lR+hs9k$U*w2$w81~7=3K5+2y<1 z8*-C=L+G||=`3QR_is@_+v^5~8B5ROx)}{u`whTcyRI7M$}O``odi}pivwG`mQC%GARG9$^5zU!T&ls1j2Soyn8RGo7-xZmNh#2wEu_S&(jq!! z8jKxzlKK3HwZSG2oGG+`wZnN#_8)856MXN%9=~Z0f@xvw{7Xqe%j$+CQYw?Xofap@p@*g%YaB+i3&`8gZDnehE*-a zOC7`10ucX2LV4aVd}@{GcsaB)mFKT#8>^GW;WnX4`0m+yVDcDP8g4@(&)Fax{;Gfo zG&->FRlko=;Ztkz2L)*bD1VM3Pzcd@QOv{K-uXL__P}xC*_CnK*f?KW&sLZm=pP}q7N4%sdUyH< zoG)hzww3tiGa0#apJ2i*#A8nhl)|GPb zAVexLGAMNIUD0P*Qv0*}-qZh%pFMx}?qNvY^h8-?7RADk<$1Q)fG+$Zh7NEUIh(tL zLb+}P%{$es#1(41d`ejuX|rqHdx)GvISrK?LedSDkz{7?n{@0+kUT1tO?k@nqi~4- z)v}q^U)O#NcBSJ%)cI~Mz=LRK>=AJWS$FsD!7^ES;mzyCl9euhO!y-@jasOeO}4Uw za^vQXT--)3dh7oIjfr{qyNLJ;Y$es4<4hv;i6$k;qk|^`Ge*&FHGQh5eIxwetIEy% zmwl;hV??b~EtWg3*dur)nJ*~IPtdTIYsg|xh@=ObsQzFCmEA8jmR7PFb{2pc`kNH1 zMvE46Gz(;uQrTv^VlrRxZlcg$&XJBkR59Q14U!@30;4 zwatJe=0oKE&V0YjCeZ)2iEjOU$E<+r3r|?fX2mno>w=n37?g@UoxH2P09ZSgQLh+k-mi?jbGL-$~(tI_%bGqhc^00>d1ZFz- znyKd-B4sK2L#!b^o7y&cDn4anNv+(S7|v71{_RGTeOY!Y6)>PEc(2FQKnGM!LiX5y ze&MdY%5r2rX(qqBgCN8v^_DL6DQ(HpHw<$bb^Rg?sd!l3wp3bL$@(G1k>x75Rp;lw zKX;fDNWcE=#Fm85#q(I7kN!n)^C*$Rx=OmwD={SY1@g2xq`|_uje=SZ{9GG$m2XmL zU#)*}qNVR1(a7v)@jT1W?9<~mK353e-N%~2aReh6b70pTo85iusmYlNdl4NG`ROZg z=@pGpx7kxAh+-mu`{p01lJhSakn6SyY2`;R3)a-WVeh`z4m!|nKtADybVYc6>33L9 z8*URQ%m32 z@Hwl#Dk+(1HAnwy;^n}lid{>kN%g0e^JIUgBK{97K+2}{8U=zuR^kKIzv(%c8|qz7 zbn0E+tUvNsQner2-PC~Rj`^#Vl*pBySi|{6jfXTF;m^paaJA9pi{>{_PlA35F%lq&b03czQ2&11 zy^umfLRlU>-iAojP47^a=M^2a~51WdRvA@Jt6Pg zq0(FJCb??XF!c$GZ(pU3ddR;*=a|)dMyVf6S6vn=p^wjIv^R9-rjxm2it|Wh_ z0qyq#O)TlxOOGDk2kI8KWG*ROy+7C8yvGaVu>TBZb>cEKNGG_e@Yi)ZVK3(I{thwt z&?i33+T3~UJR0QIkJx>X0QMF;2&*avJTX7r%S~@hjWiv~90sA$E^z~4ahL;6$VeEH z5$M6Zo2ix~39cijVC6BE?kzruC;5-qfvx9yfEXU+4@U0R`tN?!jUPvp=RqZ0Dw@)5 zzn5GG7-p9E@?85BTw47eHdf6nimeM_R1+fs>dL@;UK%Hab$xKo5aXFpThZ$Pc=;g} z-S3e4icuj`TFAv(DP5r606dm6rTSorw~rhL_B|^Pkrw3&mX&MFEeKpHxPBI+t58*Q zN-WHaDWiZXE|g*pjud&3yX30L)@V^1)#%W-L)wzZ1^|yUVotAu2&2^bpgpVDHI~1S zbckn5>KXY>SdX)2A@h1YFY@+d`T7_Z96VP4VL1Mz3grccV+Og0{OX-yxO-o_nt+lG z%16Gf9OTk9>%X=9-@0l1DX5!@w}HCpM_)AuGI3uli{QJp`+}9Rq#;?XIgd8~el3sv zqK(E6qZ?|_9U&eM*nit*p-i0Vn%ogSzBGIByWB&*=UNkp{7+6#i2+*xcbkk-`=+eo*} zdlqhIgs&JHlW)sED`0w|WwiyOMCknQ;^xOTkA>W*iWK@Xs8f^k{ymm?D2!z|1SLa^ zubX==8Ju?>2x4t;NY=iFIUTA*7e)od)3vf&>~&k3EaT?tD~gSKM4VYZENI$6?_T)M zWhFWizJHl!o*0h?-F!qnTq33CfK>V3nR;~pwfDb1mEMd-?!hok)c1F~l)+Zp56e*` z*bbL@93?I^KR+b#x(QOlhJsbRrW3nZknh-tr~I-6+qnBq2W|?6)9A~CchwT=d_R3s zG;<2KNzv7P(B9!yIk4nyDoJiqA(}Xj9}p>2*b>CU zyl?V&bdwqBa*Q1=(8{x1PnuJF&__lfW9t;0KJ8jQv4C1sLPdQY!MJgeU$p*@Xxh&I9*UVgcyRH0< zQrKXa(>pxkGU|)KYkRzDskg*THc{*2%Jdp|<_>v;@{snZD287jnAMc}6g{f&eJ%8E zP30?cVzbq}@J_&6#9h}@0MW_yh4a6K{{^W4gP&)A&qRr@Vv%H%lbozvy5%PBFKy;q zrssi^)AXYi*xj2+aKJQdQ_`-wAxcg~1G`jeI&2Or|x3 zcZ!#MVgnl+M1$h9sf2hIr;VzXh@b?2%Y2GR)`!DDj=|okImvfwk)yYA!?k}_NEPugn#a1N7B02ioL-JG^Zn;^)jb9v$-uNzbdm* ziY0rMln)FYXlYcmzaAOpDfoIH2>7|;N^T%%zAwqpX*n;60jYn6Ij&Sh+`emT{*Yc+v6=<>i{1&*j6^rCz! zcoW(R`DNeHjJk-_tmSPJBw@8OCb{Fd^2LEki0QUE18(PQ*Wi#{j7VFwrB&5T z&rktiw8R#DJ5pQv3^559EnOtz8T3C~D&D2%LVbr}OU915A7XQH9bNE>7#?BD)_P`+ zbk}o{L9}rB9EMy+IFS?G8R)e8C_a$fvz7<~Wac--lXUl~VJPE-#x!TtLtn=cnrGE@ z4Ao#7)BR09DYB^^ZM!|I{LTwy>Z^xqF$$;=n`5OX?MKxX%<2uB{ZDTcfaF)uC~!R!)Up5 zMN2AKA)SRe64s?<--%u6{r+G8F9jqVwp)I~e20V1$Km8m2*1|_E)@U`S}1lmYh zUh0$AuO_%5Y<;7tINMgmx-J*sVC!%7(X`&1*jn&5vQ&Wz+P-aXI+$5`zGl_CXm`yk zx@no=9h8N57XP^$$D3s@?s!6;p(}&$L`d2m&CRz9a$(3;k;coPB{8FpDk{yYoFM*< z(GLMmkL=yHMTrV%7KDzZHyWI#6@4^9VoI%=^k&=@&dL&KJ)7k*q^@O&{{~7q_~cmQ zv_tY;Q5u)g4l6N-E)@~dPi2snRi9~& z#<}#3-n8P7r#M-khIyk7$qed46mZwKT83Ot#2e|dZx^ZAaX*$UF1Eqv-S?>jxEPr2 zJ{mmL1w`$)R-gO7cIwy>cxVQOIt71nBgsM)uBdSW0g7kfX%$cWw-iq}W)Crrbdcio zimWZBEvWllI-YEQ3HeE`Q@XNfx-@iEKLpU=DOXHk6KG#YW%BpdoX@(|F9o=;dqRbL zNF}ib3o)>Q=5dGn8F9!#2_At457Z4bsav?4d<8xLWk#3OemGUAhqa6xM|FO>x0Rbi zIuq5@;?)zR0**FaRZ~>UU*O;o{V~-t4=m_4>3xWH*ukp=d`RDIh>qwbJ*fOOQ9?8I; zaw*IEP8SH;1B}hTKNwhG+${(~Dm--oO^FJjgdW{8^6p|aXQTj_;T-`!Gzr~4b4!#- zpxdm}@W(x+8WAQj;F#5Vwm{v0y*zb}H!zN}6~n5ubeKRcODD_H|DKdZ6_{rGl@lL@ zxN#Z?K@l?R-exjjZ=@ZQM;qa2-zoy4(f3uoIyD{;8O(rhS8G;lmhu+=+?(~B(5O@Q z`j+KZ@$~`1SHnlIDhjC^aGQ(Y)tHM$S<`f=(CG`7*02h6wG$sAf}8#>yC&DW$&~A# zMn2Hd(blPRf)-;R%2oswc;JgEOr;Ux0{8H?WVfnZ!{iq6bu1B3*UG05{nvAi!7wxy zb4)hq)RnEiWT_w6SM6l3ImV;eT&2VrL;VD-o-{RnReo^hnJ(RW4Q^2 zDHGBW5wk#kVM^k>sbiQu)h(URk>dQtA#uIA2?o%JGv~$fi~+nZE8%t+=)6wjNNZ*N z6BPjpLmFj@NsQnV`|o>ti|kr%Xdi?w6pHWJ*c&xM&?I!8zfzA}63@>^In^(0GO>S` zqknyQ_K2^vZItHyTIT?><WpyIvR2aVYA+JiWiW2LFjV)72DNrJWc*$VOQLHb9i zsMet%T~`)kk?1+|nMG^_V3%OtkwQF!`~bWADw? z{f-2T+dynVSD-Q_^htdM#^_hz9O;~Fo+EggC2v#8DLv8YQx;PlQm=y!M|n=>i44dj zcUo+R`gjX-?Dqk-P|5iI8ad&kd$Y`zoZ%1mR*Uuh7g4r_H228_gkpDJJ(Tmx)%ow; zNiNb*+88`R?pb_?f>}D=Lxae7j6V%6X73SX%X8Md8P>s0a4jB7fnvDsE@&h%1JQLTFD@{$ulqJyP;p;!a=CeJcza8EPop0R@aAei5Ve17QdWqJ zmq>1zBBaX}7TPQhFP)ZOFhoUZP!(oKUKwA@INaZH{mW~DkieoQ%b&-{QMQ*7=(YXN zA%qW&B}3n>FGA0Ky}`uAQ_|M;Q$v>rZ%dDJw6&#GI%0gaoh2njLWku`3e#p)zYsjw zJ$a!W*aa$^>sy`H9U(*-Q%;M}gQbJo?g_WW_&RpxV>hCZ(z>M%{Hq~9*>l~81wKF> zWezN1BezfB!~d^OrtZtW7(TG7MM$;DVJE-qW8DhBWtT5v8#s235`n$#&iIptN&vW$ z0$zVCf`S?nWjh=-h55xEZh-B^X;R^(o=}RXuQH~FA$aQJAF8X?nJ^4%hwHyt=c*_h z2vkd`u=cmlswe>sz-c+V>Y(2a96f@fd01c8Q5trN37X)?WYznkosVZLqfoD7l3QZc zt)w59I!?-}Kd2KC4t{a!5nbylvt%i{&L;W zuTH_b7WaFTY@#&q)Fl$J3q*(A15>fGr>**%g(%!)u@69=y)HZOIrtO979z*C$6VI| zZ2~FPFK^hzY4~x#{5#l)Vjt@(mu&lHhSv{lnOFQ;Tii?kUZRc98+mt)d?k}8_Hf26 zqVAOaFK+Qz5%0{OIa78op(Q5-&T{(w^BRQT?sR{w2A}U|2<8snpR{kqWc=j(iSzMB z0*SEB%s~v;F_{B}D?)yG8@9z?DoX%$xtQZyQ%p=mkQJ=i{QC@LX%W9TizAFa29!OX zP_lO57DKd)801vY$3nC!a(x^w16()|y&JX#k|T3*`=?-R=tz9D8A z5%k!HJ7^C-f?oY?Q7lfMX?;!~{lnINx6Yfi9rhTQ^YGyt2J{nvT4ZN&IUBs*uRIF^ zd`+E)ogaE3S+%&#$VQO7rd8}i-vvEs*zQ-T| zwye6g>eBR*+&}c8i^lGHPEUNlk<0I^L_5aVkf?8cFuFGh#t7S|ZA%i#B%H}5X15DT zCJw<-kxG+$#6`SS!YFUyL!>@p&h0wRTT;}D-XC*v6FjesWLrD8RtKg4dUt72Q+kUB zpm&!(#DD-fw9`4F0_=FSIq(CWMl2ix-?DiS8=Yhx{33`lOE-9?1VOKz5T-lQ6p*G zKmY(#YiH+NxtD1;;E=iO=Bzr5S~mmKjZVXfDrT}cNI6oc+v0F9tlM-Lum$L`61jg} zXm6xK%0RsMtzt_wz}Q4%&OaNcD*w&33CO|)I*Rv?f)BJ9QL!7B>3kSWBnp`SbhbcZ z(&#}NxgvXQJ98dFmz=h6dL}IPk)TLBw`yc9#L;RWU;UxIN{h2osmC<yDIsrDtT217VOK$aS!U9EYY zZ6MK~L6Qm-eLu^uOa$b@oUC05&=PSgZ>SKd1<dtedYdgqS30g(JQw*(gU_^Kt`(Dv(Y zc0@rPmHAkv7rH5q$zfDMcy&hp^P1Dr>l4ln`CIV&8-%k?2Eg5ApMfuajK{<{v4+yU; z$kXR5oKITCRw5n)Bi3OQ>8AM0qjPm5JxmE`4Nt^EXl^3qA$1Brdi91fW$viBrc|G2 zq6PY4>D$~oy{tFeuPML&5RV}Y`1mrhKKP=gT7KnkR0XXrmsz;4?4Q2+V17iY#6LsY z4)IOb?H9-!04Mg!rsx#0`0praDSt`kcx=%1*V;_p?lGHd?QO6-Lkxg_?m6ECTW}W` zyQ-8WU@ag6a1!bQn^(F_dC^I1B^3_zT2;y_y%Z{-p>xaUHis#fk>g9j<CHg37$1yl0NHe!A8xhREoSHI{Rac;CdmYYlNn*+eX$ zOc31PqPhN>mG)(#+#1?nD((6G{^@%brp#l6=W!@~mp~j2p^w9=phz-MOyC`79+s$u zy~f2xOEq381E7~v5aHwCN{co%R5tv}>rL+)on7>>teTdz6F}~)l(Pqw#+;;3k!t$s zt^vfg?;>vQQ9LjHRC5YTEDO7SrX=&0q(!e+^P{xSNo(is>RFBb*EQcI*vTZp0&4M> z4}#9%;6RS*c=6Q+nfz zdcBDfONbEbXLo-m3San_BJR)I9!g<;yvJjwH@kH=7;a&|Y#c)y==my+i?45WQT_Jw zv+MMNKq;1Mcd+=a>ffy|C4}DnwYB7|6R%P~1~5q}9rnPy8VN@P5$b63mkb? z!##2nT=ifdOY)^{_k1wX#m8wI!^RIOFa7a~Osp+?@!--{5a;+2pOA$h7k(2K&vH$h zE=44K&oX#biQbf#hc<#sbJppT5Gq1Z%He<4*$=%t+q<5uuWKZ|KX)3|Ph*0~SFDY7 zCQ5(D$X!+H&CD%#jhopcL2o0MP6z@q(a*vi_17-VXJI70rN@PC#_Dq9wSzvhB-ac= z&(?%)C!j|!wnM&#cRDp*BM~0hp;<5GKIvAIa6)`OM%{3{^cqk#6?5ru&tUkYay^1X z&)k6R&V(n%PmWanZH&CI&oUf)#xgpr9|P00lzS}1Ov~O zs=J(PF|cm;ddgJUEL$U}cEVG%8#OIhEpKcJZUOXfLq4F~+9j2j4#At_Cgwb+)1Tm~ zB>4dTinls5lRsg!!%fu+58PH^breOPgS@(=iCst#8Ms~dP@N?gc$phEG9&kWC|Zb03+9IkZ~*nc;v8+xF~)-j8ZzrcpTcX2jJxIGXTO84&< zI>=ShDQ^c@>ywvC?OTyG9|)Mh){wx@7jH^gKSaC<$q+0gG=)Ja9R(rhS-c^VPrz*m z42`554T^__g6tQ%U#%#4C|(#IsuY_Q^gTTt(ei9qP9QMwGZHjHPzS^#tX04(Y88|L58IcXr2_rcHLJ>z6boB?M2D1>qWCFbqHe1`jz)@(OyUqgP6nQH5ROL&6 zdRZcttS8Wd5gsfqFS8=$%5{mEW?{KJ+E>0HV|t*yHtRQe7#lPx4PnF5un$BuR%2{B zDWw<91fN1+NMDb0H6I#3aJ)lX4&AM6pZ)Gq`S3QPv7YQauC`X!*ctOzM z_IA~9$NlIed}W4cr0;}>3k`ROn5T3i7rQQuBR;J4V-*(-C<&9_U8p*0cb>C63V~Dh z2aavy(?XXbpQcpc@{$Vsjcx3Etk3qU_)=C#d@a_W0zSzY*duk{&U`CFrG*^t^AU1( zArU&zRhBW3l9uOaQ`B5n^@pQSj7r#LSN^z+o>ztX7~}YHG`&`hCRLG%lf~Ri2aYPJ zTZJL0Vs=h3WeSxiA+s0=Np2eGqv9Yz!y_a&bQ*baxc06`e++%kv|Bhn=?+A4`_l&W zFc05Et=ClwlD*~lBLeqVcx)dAcGouq_)eI}ko{KDu#H#OJ$HZ$wZ3zQqO7gQ=)Xe7n`h^!CSIEPX*KJFiB9VI5J*(+weSRzhBo@n9J z6%9K9HEM>yqr(#&8Z+V@W}cqo;2=%CHQw7h2rHYDC0Yc*!4xKZ7Y#g*{F+#T$Fm3p zCi0dr5X{zPAcLIHj|*0lY=5Vl$MC7z0%FyoQRU1r7Fd&xdV5N3ECHxa9&$!WH%)T+ ze5tO}nXBDWS{!L8lYciajrG~f@r-dj?ka=}S+VZzSFYYi*eCNzdwLaF^mb0bBf`w^ zXFF>xP*sMK&@)H`7FsRpBxH5<J*)NrK(NsWVU%0L9OX%FfsKt^6_zYiPcwKBNoJ=2>YG~qNeI&nQio(TPz#=PaatUj(j0Y$ z(}ozMz0m4;YMQm4-i4pNqf;mv5y?er9pBl`(A8kT&DCjS)e-V-rGBqna~1Q^aRuWF z)l?2aha*Mh*K=nE_ilblsw$q<^?{g#l42Pi?$DQ=_9FVCxCXIe3leg;^n zs*1u1gDSCv{yv^IO>2D6^8+Jh!X*)*GJ&(~iLjO?7&0T8F69k7bXY&HqxR>ap$*ai z&b=&Q)!*O~(A_@l#t{A&HgeESlfyaAA!5((BJ0L!>f3dY=xMwjASv)|y>bVdO=YPx znNhg&IKf-4Zpdz9<`(g>;&Ec)oi^F!cp#mBFTLX2OycKz<#h$`TkDG%#0w=uO_aZI zauyy~&v~{7zZ^ZKEaPVX5tG(>QKD`lz0IP~Z}!WC2PKRHuuq66wmM4iz;9#f=@N)l zExH}YQKa$(DZ4ljRM6^d;@h3pk2pn^Ksg(>QZ=0#1dgmZzA>0^|Cu3cz3q#w1Y=|m z7_^$x7u#R9w*9zkB;A?cC{Slikm~M*xxb!8<)q%p#P};MP2i84R15}`@pPI=H7~E5 z@wYpizTUK{H{V18f$71&aScL&H9&<@JRyk;E$n?HO&jK#R~zM zuMF?Wn@5*mBx~gt!9-`dY5_U(i|?^n*j|$2E$wrq;fp$?EuB8LVDF(A@1ksr=Z24C zcOHpY5#!qyRqS-57WZ8}NMPF!(BywUrEbf^fRXwy-){vaGlGR0>3kM7{s7j`X`@A$ zBS8)bkE&6`<&;+!>WVZ8-u6FT2B|4p|Ggls*9ZPh&xU=TLH6-Q)A0 zY5h*Pudu-%A*t!U?EvTbl~4bEZGLE?Woen;V@}*nq_AwkHM%`l=1m90DJ@8JmuFLjPjd)Ph`l(bseb z@yGGsN}ZO^18(McTbjkfEgfNK-cSuYm(fC%$rZ{?nP$z^s;=%q ze5;q6u>`N`k@NszG~lF!x8oCci0?04S;&G=r!y~h{Kno^vpnb(M1e~qINS2hq+#W9 zo4B%q`gs5@sGDlbRFW~yS@?)f0A~{0CibRVwN2pDZ5;npH|n2!Z<7T0$huhbj-))rhdZC|FE<@4x%QNFX=wP?Y*7_OAqv5Sue}j`(E! za)-;uNV7oqwc0>d6L96tD4LYBDDyz1eaq1-D$~xRRCk+nbM;Z9ej)JEt62=!uNIYyV_1oeRks>TfhV(WZT#ZOmePVHo{b`1vbaGQ9FV< z%h@!#Cr-JvJk_x0u-f7{5kGx4g$~xhh9Fxt^Q!+5h?;4TE!NWKDnn;o!B_;Z^#w51 z&W2RfKlIL5*fL)J?T^kAu-wI#+0!h0e!dHPJsR8OW8UJ$La4N@$|hU}88&BEslz6)waxy986Gsr#;$fpTBAE0hPE+l>ob2vC2 zN?h4r%M6rS-bWu=^A3*Wj;T?l=Esbf8))V9jM{2pI)m~f2Auw>ZZ!~~6}MEFjl3a1 zW$_NB^L6l3g6EoF%c#jmL-wu~;5NVSTtAd#L&F$T0xsMxA~$tbxw`V`-TYe%Y9PX61`Sxv<+l=@bZBf510N_APS#6EN+r6YPGs}B3FOvu;P7{qK zY_}PvkO;3MY;FIi*R6YluIWGB|bwKcmGw29;Wf*~k zcd1Xv;(FI^l)*0WbNNhu-L9=gd0wL&{Axslh#zhuiyOT~sjZFDoIQjvlfg-xFR=`0 z?WtPwu)SE}T@19Z!n-LoA?C6WwXqI3bnU!ddpV)ds=!80uZ<|U*GjW{xAec{vUM1> zCuaT4^5%c}9~~XR(m>5-HJui9zjY zLAMv_13*twNI{9xC5bo!`rWM_*xM{s`AMY;WD@G4gKGe{LB+SXEX?DR=PbAWs12rX zUI0Fld|+D>a5utv#4&?bjuUv=)QHq-TYqNhAXHs z^XLyWbV)1hQ>897Ch#3@HFW!Bf>}3rYk3$DLF|0n-}yz(xAPrVTQDGWzeb>!!pB7k zD{U!()`#jBDypnLM{_g%qD=ryJ{?g@&i#4)$tpEAd5sQx@^+(dz}w#lc<;HFktIb* zyP)SIiL(rY_A33_4 zTWaj0l5IcXX;Bw3<_9Hb>0065tD|oxW71mBuRB==8BtuDG+mB@JrggziZosA!ib*D z`r5LQhrju}7o=~$o|dTnhy`7Tzh7{B5?|YCRF6bB$Ga#-=YH0A9oZ2cM!YHtJo>^) z5{Wj$cBR!}9LyMAFL{YI*07!7DtYNs4)PWn7Kr^C+CwLow^Hf~EN^TT^|*Iw*RgI} z@#>A{cdO>9es35%TT@r3VmI-!XX_UW)^ZRlf^{g$$!OM0PGc0Kp1!1^5<(|aQxK*` z1pvEwnF(l*Kq|!cuv$87Jt0o8$E~1luR@L@mqgicMhYmTRDDasmOGrWDoW;%0>}BL z%K+p6d&mQdgh1@(k|}i}DkhT=dpIlBt5JWwE$*WnfjAETEy!zQV-yh+DCMHx|Dc`F ztoNvaAx_4)v-Og<-0t$vvF*Mb47HOtvuYK#TSrhHVQmR+ z7cR{Q&xBs?Qjpsl57QVh9{zt|$qiN;*4!WCa7o~%6-o5rhp5IZG`zElK?g3+p9+g+ z3ea<9Y}mE0yr%JNc0|20YG47(nivhAazqWp8qFPw;&R#UzIv^#UL2Y0u9Ws$FWK%^$n5Cdc9L)mWjsnwuVWnF>XjUPCLllG0C(@sC)dR9dfp zzgNlFCGX$dy}ej8?me%4e^~!Cw*8th34X>|LV& zrJ#Q_7G(&77yggECA)3y2X0kh$=mp~A%&aGM; z0Jv6=&+IBi2sHW2Zn@Feq_9A7>z;3VUmAV>NBHXIz2YrCqLrIsqD>uvpsYh`;TUVd z#;92H(dXLadBHHZ-TGXm0IS5upLK&_#g$ecs`l9JTBT!*7<=xc z?o2*2|7LJxpOVx~*zSqv++7?JgTWqwkxjuH?8#9I=*hel{#5vKydcAsDe?{D7y#&s zcKSe@-l{bns*Ymj#q?}OGJ9?*+4(a|_X9NSR#bxsaF~BIc$ZT8=lr48(Qu*SVse1& z@TF?TkXP=reXaWy5f=Wr+}#&JiCEvbnNwf9W2)!?FkncAU=$m`k&jF$8fxB3?1p*F z*C#SqQZ(N!%7c1@d6KsdFxW(2dp1!5EZ1$GV3TiO3Ld?wV5$ALoOjl^$7O`jj>eu~ zZw*L`3tYT$V!srW2t)$=TY?MmjDf?VT=X1Af(Rpr)`PB8UtnumLV$w*H)SkA7ovZS zXX{Joh8;Bvdl{+-FTTO$=UB$;H<~{G=J`6K257BG*eA<}UUY*LdqjXqpJr$MLZ>={ zQ*Z9j@a_JVLTAl3Ik>f1^k-r^#S3qZCuf6Y^2;6kJAZu%p>Y(k$4?}}8dk(Pmc{EL zmK5mV6*jSo+Tktowr<_bmja_6+eTeeM__D6nr33wV++{6HQr(>vE5)ym!{D|6o7VV za-#GK&!QxpY8!$j6Hmzcy6CVk3{1hJY(pC75FXMqi>CaXajXD1(0-)RsxmQ`&#aNR z@$_dwf-%Xgc3GhOEm-PTw<;}iB&blc_L^=D!oj^d?^lT@!JP4FoGmF{f4=3yT27|Q zACZ|1vq+M-l0e;>Zh^_B@a>~oX79fT@e~>DTBQZRI+w9%7jbn+AQ|)`v(k6*EYUW_W#~>deRRzhRVgJ~>Op)I@#dYOs-}^6%EbkFrSEj?}G- z{ZzVx)rI9!10?NVxHR=z10-L+6rl-Mgr`etR>jJ2A-l=6ovEG2=t1>hWqmSg2cV0{ z^?iau&SIVySEr<^5|Nl;0)^nV^hOmz^VAIC*6r%`o2@yF9A=u48l!an$ceb}|9wZ8 zsrzj8t8e=CtC?n5?~|W0VN9C$=h)18vhy9*AFrN0Y^-IKCax;k9~Wfg;tK8L0%XUb z6TjRj9%ObmOf3992y4ix?)o|Ym~!8|aUJcfekZS(tg zZB{^3+-NZnsGB-y=jZsAz^s6~f)v~X)n=J|xwP@VkH8f0Vle!?!_h0skAR9miC?m0 zL4_DfKb+?srM+T!XyuA7{j(mu1`Vy| z76Lyw5^F*1InEp6iuZ;3=EnBn_qEccI^1{a-Dj|~;_eorDEMb{(b?V7)?pdy6`XmSGpj}<`hO-D zz$Mf1S_UU{(q;kV9sPmYyS(E90Sh5}AX5s|9fsm8+eJ-DcmD+GzXKJA_bM(W1GXOv z-?XYY*S=ZQa)d+Re8Yx3!}u!b5f_Fkg&-zB1l^1jn*l$w+q(xSX*-=*jZlBM&y`vX z1nd*nJacl#dq=3kfglTU114AkfQkf$YM<)uF@T|3Pyx_74Tcnxr_WUzM4O-csd}zX`CIrgjE~{g1-+f5bb_ceHVauf|2|rJIW_a zm8Fj_;hsv5jr_fOIln#$MLxBBjV{dHc?YPJ!>1`!AP{@Lv#5Mr1_2fq7_Kql2{kcv z!km^_&R|v0fMHO7#7P|5=w%*|910j%h>tqUb3cnRW+VqJR<0VWf`Cnwnd_SJ=3zH_^PcfbkFHP!=LdTFdT{cc6%T<`FT?^*imMuXHq zA7rI=mp`1BRg?X>($@|8Rng{J=kITbSgtK@?``d}$exg#U;Xr6965x2j|b|+x|P;j zsOwu@k~=TomC}ovEqtGJ8M{|&`NcAkChPHnaq|xbF@pa;v8 zM^`nJBF27QMeyan@E#v+&DEp^`!E8{NJ*9m)9g_JL;(Jan``z&hv$6`&qOuu$ZJoX zsP#Z7Mn5j$zJR}}p%4ijdAq29R)&**+EOtVg#xB|SYEM(2mTdn|*Y{v%!l{W!td-G$ss+~2yg!KfDHRuf^|@WD5H6H?A4p>;_pL@1@-)icj6Bv@7uG9 z*6w5~+y|c*{hweKnFc4Uj}C@&$a|aEZXte29LO6v?oxTwNc9}ZP`_N}m;nK1JI1o2 zMD#)=AB0+nVOF47YjT$)|2}kv#KHb!VoDbynr}~ z_sI8KHTaYe85xcdOpl)L40g|2b`<-Qzgx8aGDEngx}{=C3ui?UuD7<-4SIe^RZb0; zZo`&E8nVxb%^2LH?NIUA`1$1yJJl&I4w{i6^~$%7Aao4Ub#nqFB7!}>x>CA1rhNi! zEN@Z84}&*c(ygZ83jyu@I|Nr~nl6w%9HBs(|3Fjt7mRH?$9%!4v$((eE}q8)t3sIx zN7&y)n&1p8Ksuy*A5#0d?vZM;ks@^!Nk3uR+p%~&_NC@|;7JnPAHX0^GAUJ&{}V&T z#7QHb_ROiq?oGG2#k~1HVm1gD-+Qz&p>Ec}-_l?o1R;A8AL{hBoX4&g0{Q3OlH>jF zs=v|YSKZJsp=oTgWlH$_{pjb?HgmkW%|V*ZhZ(kf%gjGV5(O2YDy%{VimblyH~!!{ zReJM^%r~_LO)!S-BF%u|Tf@iG%~oXO6%Ml=0K9pUfy+BsKdX=?!i5<{XUnyn(O|qR zd|V`IMiVEqTT-!oR)(-F)8PTBVK(JzrGV)`^f<(8Bfl!9Lk!&V4oCx5m9=1|G5~1im5u`N!A?iH`Gnqd&=J!5LfAS*tpc;ouDH-{hm$xldJ?sAu|BTaF_f z#`H!CWtmoC`vvATZ+9`30S%^!l1j&0$5h8&^nn97BzcAm7-7eMKua``&m8@4yh8(=nIXE!-id$Q6kQ`=Oo54Ikr&hdflbF<743EB@EK3ZF z9HVEvKHl%e9q5XTOkj)CsD3(qF?`IZn5>*Jtk&Q;O)MmbPnA9h#xGn<2s@4Etxa?~ z2nK9N-g=`{^BrwV(@d41FV}XC$l-))n7o2@hWM%o)PUiKAEe{M0=ghMQwne)CDAjwsL?4^dbB>VS5 z9AFzc<$z910^?2##pmx%iZ-zSjD0u=GFN9_VYDt@i&-Ti^Qu*h>88H=kJ&m!i zE$#9q+wXSl^#~6mPk^G=4|!EaMhD?v8mKGdr2#L%AVcvB_dEhsE_(NUIht@L8C{zkFJBS$JAgC?PW;_L0C*;?lyw(0UCX*e=!`cZTsF&lb4>hWjc* zupc19{f&ip4Buf)7-0l|@ehH&A9?+{S{=>yp~|0i9nGKv=^ij~?f?pRnxVH)195Eo zpAFpSYM=&mJ|4?(gXDo??69Yd5`+=)c^S`!)tIBvn05atgAmMrz2P4=>^Y{VI(D#! zjBLi>1TB*evld4NF!c{8PDEi_;Fwzm{ItbU!|Ok6E4+G&R}?z?uToVv_tjf^$dj~4 zHco0>)9~;|GXdoS&?e#_fs;`pOjL{w_anj?t@oh4eTGhXDHm43jx89LPBUN^sOvC>k(}&g)YY%@@Fjw3VY? z<%qC{T&vsDyQfr+MnDYg(H_xU^BN_#7HlU927HlWaP2X0TAziN8~`Uc8m?yGk3;>> z`oCWYcY27kzu$6g>;erD)i`o*Pr8~vi4wM}RW{%+x!hi2@%hvI>!-Nh81qg8IzY+! z7Z0WzrYSYUf3bO9n&H5q0Bf-)DLwb!SPvD6ldm7T8-9K(_{>KR{MVF9?5h!qlrt5{ zcmb{2o628R$jafoC3zuXl9H))^-@n&*01xV+mt@f_VVLYKp&&>pN}iU(V)TMVzheT zk751Kn|w!He8>}JPwbb2YX+UivUfakYVbf&p-tXBb-NyI@>jE5x))~DDxkv(>O-Yo zqwAYC{fq9o!i3x9)9_Munt-U3>@OW0avgzw$Z-@?>;=Jc`#%r(s$t+nc**H1<}juv z0fO_I_+CIx0s(Gy?|#GW0|$U$yo+`_}9(l))h= zu&#-jXz#{(L=`TqHztppj?nj!Ze#*P(lL+K%n{{Ep}au+=mL-9DT{Z~LbkhcxJm#M z47ltM|I~)XOXEXQ{7Xo+3otNVaBs{#wrS5s#jw(a-&i$d;d}Y10*F)k6NOKLSBrMm z5D;$vXE;OtytB8`*>dP}GPB#%=kFX|5>`a~-2HaF83_fnSWqDd5z6^`)*yvsc>R-K zO*0T<;bPUoaYDHSCNxR^4GeouIgG&{%4WD2rWV@>#u-1UNfU@@HdHVzyGG|E%@-WP zQcL}j_2vfhi+W2Q&9aRlI%cOM6!T{5$gQNWowyb9!`H?6M?%^o$cHyd&&#(=Y`t6ebKgbq zd0gLj&$X_{eYw(9dOK=gwx;vbWV;_%+P}5?-kL8j6G*&I#RC@`f6?Vj0~+c_5}P%K zdVOcq{W?=f1Qo|0A${j8H=1F8<7pbu-TIHwWRK`ubW|1ke9*r`+NizZD&lFRt(FL7}$>zZBHgr%wvzDjM+QAW$0 zNIh|w>a~9Gx@D5yc=Y&Qn2C&z*{HS2x8x9wbr{!X+qohXV2x9kodbV`9MxCa2Vfg+ zl#;@fVfl{;4>l14N_pg;&5{@_@v*+>IhOCm7Xzc4_Vh`&>+dgnwJ$!dR(w@3!;*&+ zUOq!?_!_Cc{T@AJ=Y<+zplX#|A3d{Fb zF4x$Md`5eK5xJ&QSpKh9n|NT)gM%BsOdSO|JPs1Z$zipv=>5Xqh^z~p0{QxIg8#54 zRN-@o3d0ePMxX8~T;5CgtST_Mkyf3l=wd`9{avN#tOTlYMw;ES){53@C@pPZ?oN-; zFIlOxlX=YiE6#K<@K-MQzS+L$hYu%w%8VU|?d-&E#vqzJ^m0wCsK`)iGv17nUWML zLFGZHC7n1kC2;>Omp^PUoQkYwtgPNUK$CMpN`O}~f8|W;-o-RB3PR-*r%z*JrcW^3 z{4}!jV7{pwzx|1xEK6?qDiwqvbaK5af0a^juqGqQ1FQm0#vl2C!fz`jnh zW*oQKOZ|0X?I?o?-{KY(zk?4tsa|22jgO(jL^Rz)8htI;(a&df({msS9Lr~a)xIU> zOPUVxi`9Afp;xu0HInDtknS-k8o1c9FddaGqrih0+Cbhw9OFHaX(eq9+#a75Eg2+E z&JEdadoqydB^K2{%M@{NoTPH+X>p%IP_Fj2X8t>VKqQw%hv(gFdz0(*Du zpajj{G|TzK$x6!2dxQ`hu8Hh#4^2^keJ-1ocDspW>j^R$<1 zWL^(}D>;ub{l{N>(Pm#4xRV-Qpl=KF+gQ`ob~pZ*7>V|$tQkCRo}{wVlyc;kdA32u z71IVB$^UC5vU3>`vCli1H$0WQkpqDv3ZH*fH{n2j9! zEX*5*$Sdmi^lF|5BUdg-tk(Hf_UWzoI7nrUN@_UrcW@L+Vp--FCVrxk;R#aP>>P!D z^9mXq5;*E2ujqtmkK<}u^O4600_<=0#m(QgyHJ|y%pb`B3{s}`a#AFfIpNJ~mcXiJ ze>r0(pV{GB1~U&2HyIhgKA*s|Jb5CUIQUz32qWp`ygoMFnI<;R8K_+6R9KEoZ(k9; zjv>Rju+l%!I?j%;>NGm>ZPM-BqIH$_>`M3rnc;U!p%G-S11EP7ka9_*7o?*3lFOB@ zf(tt;RdwiK+))5X)ap&Ig$tTr$>*ldC^PRG+YR#)W5bkf4*{4=CUF&(wriiWxEh0g z$1i5u&aWa%_lJab_cxRs)z|!^E*oF!@l`F~YqYIv{yKKQy|^{7+m6|;4$0^d4EQXj z)d2DQ!-%lEfiSx! z{+&UPt_>oxu-t!VVd>9v2Lo%GXv2UD67Ls2vkl}9)HSzq`S#9i(|WsCnvWePo{iy- z9e86Uin}Y$tVZe#roqPHw>sngko8fO2>`&E|8vVz{~gcoN?lwKM1~2TXo}2{)c>#l zJl>od$>NO3ffx)v84Ey}eV&0Qv_}7}c0^9nl+~p%zK6xI}!Yc9lE8ssdNHR+pwh;Mf1JkFgRWtEZJF!b`0`m0Dh-^th8nP5U%OP#7zxw$VxalT`vn8T!Ve+7 z^jQ;n0LL`mX_>Xs{_=yPwnUMjbzhKzRpr1HIRf?!KsfGy8^GFC0?2L?NpW?G6tF-m z)dZ$s&hPd-9Lug4=qH|Y{u#3~Fj{ycpS>Wa1&yP{L$**a$bhnOOgE**W*|lNfkX{> zo|`rzB7`9#w(9@PV1|+%BB(B4q138!n+Wbw-fbi;@j}L@bC){+c|mPA9By?gPF;}M zNvMx`Nv7#HUx~Q>(24J0jD1)6>3mL=g6UmI#tsAFg;i=wg=WrV+lf}k9{1I8gl?UP z`xXWOqdGv$?0sk(L z7l}+MO~%`%ff!L}ImxucYZw7WdGhO5O-OZ6gnJB@F$>l>+!a+HxU(;{`xxY@pZ9c) z_V0N8;Udhwige{8NMH#D2Z|+O6xgbxeni_S>lRUm=U^E!V>auleabbO;Jx+6$r!Jw zp3%ve=0w?*!WB_=(}RoApaxc7gUv2Hi}b`Fe>vguz>cCwOWsPag25N)Qg5p?Q>Ia2|B>xZ1oRKI$UZz#B7J}v`fx%&e%{!>#=~m*lvvv~`53{sStjgW{cv8! z`sph99{ghOceazM-l}2yc|m*BpC=S%>|D5M1>$;fXOI*f;!-#nJzSSjQwSo#h|!&@ z{O(N&t=on;xBfe*=$hiXq-Y>uU_anuRBL&vj2;hWg&V1P-TNX@8uk*VS2bO481#YZ z*bYBL_rSF!^#LH+?O(fVGyVr`Xds=9JhgQ4=yNRyI>%YMO&eKYt!Zs)-}sMtfOV=^ zTH8L_wurOcuE~c@@|FXBmvDX#byfhAE}gvZ_PYuFqP1zwgMaeRO0HHBWPEArTKzXT z3RR@`SGzT^eI2^9aIfYH$~}%9eil(vkra>?=`Lvy zX^`&jluo5X8tD`%>F#b2q`SL2B>k?<{k+Hb58Q6{T62y$#yKD#YfL@(UkIFR7I%J2 z%y-B_-_`&2Da4tGNEW&w;-$F4#V!lofz6>o30V8t0zkudk@HJeax0a2w)1eeocnS) zI7if6Vo~~BZ#v1h)PVhu~<{MEYyKl>_);7reu>_q+Q>q_ardLZXE>$5vl}{;- ztXOY3Ku3_`E$9ehIFRk&3we1kGvX2@*V9Cs1(wDH=fe?~vR_i``bpi;!FT5rQzLF~ zjFDz@U)gI|eXpw8zN8IBLhbu*q#q1ua*z#v^OZU-c;ZcYez7>gzd(x};*!`pPV~AR zwb}x#!T0p8dVf=B!Vci&rrEGA_!2&gDU0M$vS+nE_O-z6hx-wTIAl5JIZda5v_U+m z!5U?`R40p57&Ge7*KVjr>t`}SfRA2z&h~%tt$S#ipKLS)9Iv#omDv_cU6puD8*CBl zwG*73w6w5!T*qiJ@wdj7TjHn$i2vtJDm`jOlzoG*J*Bwl*G@T^m@4lQ58_@ho*~}c z@60v(=@M_A4t`?al%8Kvdo#a*gbdl(Py(%Mb%eOE{&`P@=Xfag`6q z=RP;!E;TMRJ&mNN6ltv$GWvGS0#foefkFHUR+g{3Op2#^5M#Qm+v*v7&5)Tp0nZL_S^PRK_J0o4a2<*(Z`xAA;V*aX}m6h}&HYFvXSf3-OV!tb6&iTxZsQIyG z&fDlz2EFXZb-a)Ho3>1Rb86w=np7?7K)bXnW{6Dl5l#Xu@9&S8vYKnc|0Vu0Bq|6n zrh!Eu;AV(S!#ga9WQohg3K!-{K&zyRGugYBtQ@SmjLma|gxAM9AFr5CGt2iwp}Q0} z+JoCHa&6nO@g%r@cayPGeLz8>5Sy=af{56NH1qEZOCFg@2UM~@Lc*W}Dgyzuu|=pp z_>5L9Q!itSW|?k$7rZK5LSEc2D%~DWyFRG4^1YNTFY5~U3O8KEoqsiK;`UfgFV=a! z2&)KvWffi~8SpG_e&M__;nI5&|5*3WBIEB4q>3br&Q_evVJ~7|!x54;^ba&J7hcEC zaHRYzU6$;d{_1WdbJk?>N4G22pL+&|3=HwPYLir`8#=uejALm7t-W(E^n=#KD-X@z zJG&R*ZYQoX-&WD@Nxtxbf~oZy_&z*s6o@59!a2YDm!Xu=mxuukD}GNht6oJB18x&w zU;Fsr(Qp5d7C*74YGws`KJ~h?LXU@Y0Ml1_XLAUV!Q)=C9I{5>K@VfcY@G6Pn zWFnWNNxIt#$z4Ex6U>MhrwxSAyUS!%aM)AFD4{P`rM5{8M>=YZWQ4~X3 zN!3>LFc?kh|5a~0T=sJbDh^@Cs+ag)pzSz1)W>IP4q~(>EKu8^R(1KkyS8C!d)@T# zhTMD66#;mQnz{gTDH*YwljOC-ITxoM&DY2wUA#H3?YS~_)ICga-EcBBXS!gVFtjK@ zzWwh`^r)l5Dda1bf{jno2t_2+l-gs|f&S|TWkI21WUrBM!P&?e>YHT$QcnDBUO zYa&nu9E9#nPCxg#v4Rinouu@bS!MbOE1itytsrI{2#eX>s*N@U>-BP!4dw%ZajN(= zR3d2sO{ZduUvB>S1%=ul_@APoKgb3YJVvNW`aFj&nd~21xP=99a{vp^OpobmTU9~c zB?IzT2MO^lExyjPF{e+O$3B_1@>^NBj~p!V{% z;cMqAJjfE|tFKJ^Q##y##01+jvf;1rI_E_BDcZj0l~B8kG`U~rUEa61jHWFEvWY|1 z8vA1Oxe~EiVNkI%mT>z-yM`;2WvD18GDW0=EVy&`Wy1wN>EsKY) zs0i|Jhfh93P$t(K3})_`=ZV&ILx|NfXKWl+%B^iQzt!4nM=}jGXhv@?t~p6~TcYHC z-TrR6d~Ydvt@PBp)XtZmM}oQ(L-#SSVELjY=-6-^su4W6E6R|j?>_bJMhQLJ42JVM zamcarVntrAI0#z}o0s5}DQk0uiQ=a%y=|$MG!HrwVh|OiB&-p`i*W1Vp~+83=oVcQ zBMbW!n)NFV2*v5~xS4k2+nej`Aipybqhmy&3y47t-s{hV&qb_oLUdMjG)apkK6qD} zp6#0xuO?kH3~Hyk)NOCt@p}{M4d05xKS97%ahmS&HRHwd4bb}QwmMIEyh`vN7ejUY z3Nw?q)1-)xaG(~U^l%-}&3;uCG+m+>&KJNX58jZH+u=p zFr7u(D-#<>he%JY`7_QdIzEoDw9-{BBEDGn!HH-}mi9M2Q0Q7_e>ouwnVxm1>)R2$$9WBYZ$X)9}`tr86cCB{2!ts(*J58XMUT**01;zOKko zAVpMfHRJK*17mEz9jtS;BzXH^N`R&S`kh>nI4;=@^H(cufgJ?r1QRmgP%Zp^&H{pM zIVXQ2B7~{0k)qk&x_2!j@D^xqES^ooon9(?NiVeEzei%!4pxFIs6Nh#K z?+fI!8ZQb!%shOhK-^{Tm%;tt8#94KEmz#)J0H9W&3CmMi&kc(9njKLCaoKLzKhyl zzyv1de(*1b?#}=<#-xKBOKV9w9ESkH^yS+dI{M{gL1DQpncF?<5l3ymO7k#3Ix2XD zS`3@&7bfu|m>>7y^NduHxL{}#fxS2n3J6ku2!Eon0SBkXxBK47;TFU6U+IoJR0*6W zerJgCr6fa&?qw(A7-ojU5$d{7UpL$IcLV*S>Q>fnN7v-Nk@nnT6*+RHef7Uz?16Pu zhp6~P%7197QD~IqCVl2*KHFTrATvR{qorWOv-(-67TxFc8McQE}g!f=rpO z`{Na*YtzE~t#re&=k+4(RC)U^`BC=K&y*9hD@~?46FZ=CZuZ7oN3S}j5k&!VLWz49 z0w-mKX5Z4&PI2$afuR+M1zIg0UJLWQGp802@$sIrGE-zFAKCLmwsYI6rv4xtr=GD+ z_wmQ;&Az+kcU(MGo=ti0_O5yE3;So1Q^S5xBI(<^tPvE^07R#X{D(+LMJXanrTvi#S0?eco_bvqWPHpjKEFNHS0rt zRW*I-W2pH6*)~cT1f@tfP$^L8?uYOK95R&}=mtv?CwDbFVL*Gyy zJJVHxE%~FzuaKO@?}A;?9`;VDR{|5U_CX@?#My$(pTK;%-&OhcUo1yXSOtaP>sQs& zdDH!|YI}7j#5a%MIqC|NFu~J?4^CLXLC8zTS={w8B}!YMB$Y$jd17=F<7aVOEb~Hx zy2n8o!b?2ChIr2$GEl=ZVz`?dk@<4|xl-lb*s`K?m-jL8K3en;4L4LzWy>_?DU4^- zyVqK1SQk>uJ4fqG4DgezMM=A{FYW5S_+Hp#_xak{R{HlduZ+2OOh3f1J^WNDAErC` z!M3?_$|!Y)OEZ7i%8jTMY!684-^v-A1S*BB*NIuY2j``NalXTXCZ909&@cwoMb9a` zH`xp3Xn6v;zu{S7lG1H5m%Kk4d;_y$kiw$m5+>*#lG}lC7Q;Goekp{9IQ(PBal-F# z&3QaFE`PaBlFmP6BI$1)a@G!){&rprdnh!%Hph6#?>lHyNW?ORggKnyiv~YFGmPjW z3p>%5H94qZUdmSKot20YK+5u_ZOy+sHko%+2m7;xJE+2t??2>QnYd-pn=H}M(8S%F zu@>MGGa|LdzA7c09Kxn_9!c+EZBo7&Ir2GZx}B4))nt0jY4%F`q>g>%X{uXs#zGvS z&kG6T0n!xUcce;@Y5` z3@!1GzzMPxY#S4CV&%m~95`U`ipzePa+c$2T%&2rwuTG;n{-sMlBK_Q%f`j?Xb5Vg^;^q> zvaxFvt}jk0^K-q7_0c$-WUN$9`&Na)6h2@pIa#GbU0L&4aOQ+{4f#b0-uPN|)L z(dH));|rmC7z_aR{XcD94=aL*a|9)tF_fmH@q*KUCQ%A|FcUG3SHPnY*wDpCVH z25FfqLw-wiagf3kPcXpq(?K`u9iI%hQ0vFu7-(5L-r&Duxk^@OT|vF}VZhTYs5{X( zg}-8L&A-r6pQzw9RNRD5GkfX#xMk%3w@5I?K)~;C-(b!4`u+AwrQ!Eid(>9Y_oZ`Z zi^l&s?hgbMh(*eF;l-5&Gv4S0-(w4sl@LXCfD9|n4{713cZ(ii5P(nk`z*8Ls}HYK zm>P$6+x@^6oyzG17mUi8qK7R``EbvZKWgLgWfzwRKPqI=K=b%&nzxzLO((6lMhMK8fD2$GT2M)0y02Sk!#cSAk*p)_|M&Yd^XKM zU9XlpL9qyvv%<1Sl%PQhasABpVq`S7QIf({jeCAZIOCN7q83 zO=^hjQ-Fa}bmuv3{VqMg88shUL|{<*N^!YSInbNtRa65-vZEg+>d5==x`d5f-M%sc z4w#lG#uav7{{`^S6l9#2g%Kj(h4G>);@2q6jViod5dIV1A4Lb4R0^{JFQ9<=x5t}` z2C^t3et36&+OO~K_K3NiD=6}I`2-;}5BXDno?BaPk@NO3!Xg6wOE-mEA2zaPxj8j4 z6r>xC2fOIgKRpw-#M55E{^)S{3HBH(WV}~nxHDQwYHP2N7jD@66PfE1cNgjWXEZQ> z#=Zcq&h$Vc3}l@0{~~gdw#gr#hL{U3a;|pn5_KzdIn|D@fnE$i~Cx!?Xybu^B6cBC+c68m5Z~DGsaW;4>*WiQB z&CK7$@`qHiUtt)_0K2aDD-d~qDE{2&u{yc_{GlievM)#s|3#rukI^u(zjxrVlC@nr z+QC!lk`glD)(KvbV<8}(9Q%iw8O+5kaDij5Pc<7?mU1c^#--e!6Zvl zSm?ju6#BKA+PC!d6MXpVl-Ybci;0G^|0LbUd%&9ku%8`p!tIZ z(*GEYxn6${I;019leEuK9UZ&yaTb{Pu`lN83jEhGAawfoR4u&v#Hq^J3RK8$yOezS zU(0KzZ&3IO4=E}Sd)nG7YGazhW5V@$W3JYqgtTwOaKuLG|=yeB1R2FmL6JRp(Sp~w3U47&`VgEv7#V= z&^1A-rZ~b5QxY(uT7{>O1>E7;W@m44-rc`Ou$`f|k>9rpg*IBQ637CCvYd7@+u=^g zEKL^XOfufPC(%yA43QR$Tqr_5eJ9KFkY+S*`L_isLDuc%mJkgE!4+!$T1j&b71j}; zaSCiUurfvFv|K|61KmvHgT;`6i4P^^}0 zy#d2M`8A154}~iWXKrX{;b}Tmir$w@)crp%ra-yQr@#A^il6FJ9-70E<OOJ?RK4=Bs%W8|7`&!L@&Dq8^Q1o~>yg65p{goLMqk;kwH1vY8 z$bKZ!ci3O`-v-pJVE>sfY<#2a5ANXUwUlWDMF+nNQTIb&0-VKHD|)De(WxF(KQHhaF%en8lLsk|tu!veY~I2tiAfPJYp>9?P9+55ff zknbn(11$&9s%28_R~PGAs{Pcic(N*`qj6R?uVfkY=Wfh@iLy^&kHiq!az=;p@r3?( z9CLN4tVp!amnfi8B%rbntAM0ElDYaH#U&4~h?D2H+k5dEt}2$Pk-ULY<_6`F7JQe19OHre>*E2oaWs>mL2{+VV>N58pJ4Z}B$|T+APYXji#eq{vw>G%0 zB;9OlP>%Z~%IiqDGPv+ZEmwggG+pjFfyf!`LRQO=Q-fQ7_|!7eOl7nP*=`N2e+OEp za#-Hv>O#0ZLaP8!;Y?R*bzw?}y*-hUfB=`EP@hlFLT)w87}bzrb8Z%uF5+T3$fy$T z!~`bdbz(KJdSuS!dmgnY zzU5m|6X`A$^|GJ(jTL%noDb2T-SCyejd^+1BaW`i+FBtTvVmNpfuS3gKPP&49?Q)M zw(qa7AFD@cTfCySex2C1Zri?(8rJYC3P`rYi-O~uUS{Iw?UcJp8E#y}Td{Wk&Vx*; zj4fN3pq890HJ_pesLrBDVa~%FG2$0)AZUz%3X!JwS70cfY^9p&|Dx6yICA-q6 zS<$f93HiI(p(;#E5XixsPcAbBO$o(knWSbINni1X@!1mkB^NXDa}^Wo^kjIEP@Ev1>(_3 z=y;UNK*$+eE}!!Omt2?rr71#GPDh-lgcZS$7Abre*ns>wA;ldmzTzEl6rzHzNwF8b z-Vud9C~R{|!KMI;f|Ui6v2}7HL-aFiw+!h(ji#uLWPrnb<*hmuJOJXrGQKUtX2E0! zh&~3V^qb$q5;@UI_-Q0TMi*=+m)LO7`Kws$#zev_TYBj!s?>1`8LH+Xr2g?WmhQX5 zF4^$Ng^(Jr(F%W&^^o0jn?~jSpvhbylsrcCs=0)5ZZ%1WWx9R#PQ=6Dn;y?R4-RI% zxT1MQLglmCWxvlGhE&+JPS5-Co!{5>G@J+X`BVEWd%w*LGDX;$1G<#S6T@d%`s&g7)@m_O6 z`}ZI6d#FqBTfn7H3-fZTT}rh;?3Srfk^S!lriXu%d6uQiYT-?9^lY1UopIA|S>*qA zPsWGgyctiK#s#?ZL%zHmVv+83Muy)O$=8Gs#LSg}=S$z7l&c8p4`aI@qJSZmY_ptckp#xm5Nm{cV{2g_+Z1%W=J zzlASPLK5r`CH!Pi?jOV7xLR})-U1HcW(chMb2T5yV0egl4h8F{zi{6`L)M9;xrq;( zd_<4CSLBUJg*M|jjd#2FkoOkw@MZB2BMU$Y)RtW&F8w;eN?dEwPUw%a_w~;h&Cuv8 z@Ww_5ualT8U0#9K(C-jjSzUTeQN)%=ZB2!3j6$NAw`P3^FWWJW7JwHm>JIUF1?2tFfzSo_UGp@*foK(`>&S9ve3 zoeRgQ8^%PmChfOv^JrQ`EpIx=*hg3U$R$ed)4PB#v}3+@{D?q}B&R#~>N_x&@hWbs zSer9>1Lx~Ojce+P?+QnQlgwb`1AxSCc*3F%mb z=d_U7B!70DF|X=ZW;c-Fb#pPd+PKXyNMTA|?=I94k4@qyjY(DF?G9$vb=N7~iw8o@ z4}PECfQi)_Is#nmAT4WQK9qryN3D8XDlcUn4F5mo0f$E)aEyR22 zyq-p?!twI8fZ_{|sMm27svLILVs`vD)eXFFK($1gy8gQy@REmJHkO3E15YKe*<8Ro zkb!GCy1}EQW8oy62FJxnxf!F!mD=0v6fcSU6W|CUwLUhu@wNqWtemAvr%k`^01p#R zb^${?MvLKC4B$b^q}KdcJpFTX*k5l^=^0W>7@Zp@787RnCezq)I&~0^vg6h5&_0cQ zv-_}Ur6MGX!{BK^ZHKsAuPPBUa>glfkYl7e_(d+@8}E1AUz!7(#ci6OEXs)4;IIJ) z`&R;m%lp{p4k#gQ!;X*?)ZUQ6V)s7$W62LaO{VPh@bMQmoS`O!Z+g%?1w+4=j zBO$hz+mg9*hJxecixemyXhtlOja{oP31o4fxM9*ZM5fC#Jg zEJc&#Isj6>2VqP)cMjW4np-tEAc?xbYSizHD)giOcB`8`Hi%~DgIaQych>w_6d1FJ zOzqy5+f$XDHQjDw0__G#7P*#}UGNm|!=5lsh{q7ErmF-kF_97(&)$wFNFMTQK=DJa z;kR|g>RWIKrfBUMDT^QFGHqcHy4Z-9|9<5eW|R?`Y`np0HpUCMgJ(-ul-Ar37E@sb znW~?~hT9T|78+xKzilOZ0s)O(*j{*T=zjhR4N3=jc=>o&EDGaj4b{aF5G41ynHzNp z`B=noHm5_s4rvu-@EyOsZgLt8Atz_%&gs-8WKqu+nL~n_-)9WM^W3^G8p{XsTJ!GLBRX>{vCh_xD0^!(Yo1;NN6g z(>VUhI4kk)7c;0J<7Z2oSAj_QlhCNVNL%h+KQQ;_jzzSFHOnJHY3vePU+Hgxq7087 zSww4dff?Py>hT$+BMH#-vz~^>c!>#) zww=M%$!7@9`v#S_9fVhc^MsAfUAuqljl)$+Cjq9>4^fw+dqiG*#RkOHY{h}!`)DE0Mo_CXE3qBb@W5Fd#niNDzL_uRiBLmz%%le6gq$?y3jIJzHlGY$G0;Z z=L4GK^u>c{?OZ?h?pu3wAbedc6szypXl5YfeJL}I$gt$Jy!eX>Fc$QpxghLdfrvWh*)jneAm~}<@``T0Xfrz$uNPp(2b9T8oZR@eNrA1cj z?-jJN=jSVE0fTmEPM7ygGu~wfyQ$()IYO*G9k?{`xcD{K=Rku(G$^hq!%MybzQUeZ zWMKcu@le`4bpHWsi8h=ZU87pFJj(Cu_T~2-XXq!WTyoSA)#)T%rjcD@7)O$x)&v@J zd-+R5WJ|0OlS~0&q>|=QGQARy>Alu;kAHzIq944t8BeNS?#HD={$3RHj5~f2qe=YI zPPvIRSlJaAZZcGn%Z00+vS&=)@YeMjLe|)vX`JusuF2Q#K)o+L|BiQgl(;PE1TI4; z>gOb916X<&wi|0`$oc(Tl-py>s9F;gkQW-#KHa3i7zLN5!bcVGpWbV!5H`@QmL!M6 z5?&vi>~zLk2pIyLZBYDlR0sK~;CFdvzhcu1#C<$6^w@E(7d1nD zi82Z5Y8}B~Lb~;wryjxx20BRO`&-aY85m_Px|0@n+oE2Vs(*5I!B3ym`07T6tFEW+ z1nmX+_G0(b`&S2nm>r?Lh&5wX5aru_wUa$vS`7%Exxs(?xz8zT7N2Dp|K-5X-7xFTPIBgvr?X}uVO5Q!6O26oQp zue&N*u|FrU94@OHJnXM1F%fW%O#^vcd?OMjN|SFxN}Y*QO)3W+9!+ImZ+v)ZQHL!D zfCo{bJ@-Bs!9klmZ{e8u>g=CU;H|b*HE$z@SEB&^)WK@g*;KhX^VL5V=C)mCQVxUn zQwPH#C(s=eu;f};OM zFu3^)I3>5=xjsPlQtpekoUCZ^z3WquWRFqHBYGIuZd9GGhgAu98fR<-Nn(w<%OXbV zpBefrw&Zt+gXZZRqKmYO!o8Z`n`LGeoc0(nEXUI)V^67n{}eac8=F(mn_}(EX7p_= ziY$p}G(s;+4qp9Om@ptlwpi1I|CzvQD%LHNk?~(g^%0Z2=A>W*Vc#!t{UGL`m~{23SytkAh2EDSh-~H|8;z%V3%%_ z3h()sTsrg2)hxQt%}&qb><9`IEWq0=RND<^^X=kt@u}0A-phOZAGjvimy#r4uC$IvhE8il`6YQUHDcgeUS#Q z+un5vYhj2Ok344K$nUh!U$E zHJ~Lwt@uvu6%7ihtBwSU!d#>`y)W$J<610hY;k7tf#tLsioS-}{~ccR@nKjNy(+J_ z`%@SA)Y{A2XBBS{bf?rv$K70|+|r3%6)zX@9% z^+66r6kLdL2v*;&a%6sA!zV9YwUIJwdPYQi7Qz9jAcxnf;~x2$h~zf?+d6^=a3f*X zC=?gGtN}JpHT4Wh%kG)u!$ID30?VVN4Z84?!E2LO*f_*{mA>rx1Y;^+&l&j{w6s#T?g(S@&w_S!%kU8yMCql8b^dkSu!vk;iyIp`(ZXTmsg{`p8f=D1kz|T~3 zC%@rF%hYk&mo3@tybiWz`}JpH2zUh5Y)Bzw5Vk;0?-`JW>xirMGkS(PU7g!=cA3#{ z(bIbE+`Z|qG;3AWH3LxS;^=g*ZRuuXPrS7(t30!oL)%-zdD@7OoG1BMa-|O7e}g5t z^Ft~^q&JE({cnpQ*KZWhf!tf!=rS=szju}`wlU-s53JrJ*WR`l9#Nb`v2plD_-Qt! z

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

a^&xx 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

w^(LiF`aY} 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ŸEPQ#EX(0oiqP*Z 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

lJm9|y;;JRTts8xti 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 tP8yC2D8pEC)rDvO$yat;B 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 <5EV59KKc2OpWZgbY_5xg?0D& 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

mPee1R>y7S?WQ20s5S7(XzsrsIO9L(qWb8 z<%QR{JYwBK&0)lVwv@5zmH+ee5r(&N{j9*pDQO{cCH5Xh{&(OWqwL%=iaE(pxD*@s zN}WE(h3F&j`lg9X9!u%b%+%gZcar85InaVyG2sC4y|k@d09)unBtm=C%e z%xc!Gy@laDbU(-09XV{w2p>97COE|h-Hz|%O9lUZpj$1EE0)E6zpIJtZ!0Pwd4?k< zc*`#n-~d7DaE5-&g7*zHOBIhtycMTQwiyjB;mS|s4_SMWNF{nm4O~cGbMhYUoL>Fk zvHVnqtmfLxXG&RjK5KBO=1wFRYyv+&(H)mI>y%#HnS@n<YQdknYR{ zC$tgBY5S(B2t05Xg4ncbFjBFnu0zDw+8Eg7<=)5RLB8`|@r3VpeAXL|GxH`hU^>a% zzj~zTp1er}^LU4kHm*~nVj6j9p05ZL9N4eEk|7zjxAI4W*|_U%)0YurcSEmuFvOy+ zMGT{biK`$rCBUwlt<%pN`sP-zH)UL9J5lh~q>~=xvf}3vo*P>tL7mqQ*uCn?*qE72 zsgN#MuA@Hu7%;o0^zzHu?4ac_;+YJIh!8K6DVv0#CZ@7$7I-j$pZj}xmP4#m2A~d^ zPM3(5A4TJn0(7xkmJ~VT(#_A(3v*_Z_j}-1AGK`@31FSg6mtZ}VbxwL#MFiI zph8(2oObGWZMMDF>RD=A&$d{e(}JwvE!#4kT3;kq&8D?+M_KM{2EtJaH7rh3)8Eb) znwDHiU}Q$Jx9I5PQ+LP;N{?|6Q*wXKI*`-Oxug|iqr||laAL$gr0xRl1Eq>C&nhR# zhF}$Tc+VWh3up+a+S0dA@GkVw6AtHyE>^4)Q%$z@2JYXg2ey@Cw-yWdI`(@5>Jj`6 z!|E!2?@H6MW|csDJ_`TG_VDJ?n**xGq051>FLv9TJf0mdDr@`_*SlHQEgR~eXN`Xf zem;;^lTe@``#A0YA*wYf{&P@MPtkZ+Ntn}Ol1A1`Ft1Xt37L>U^e&W8DL+QMlGWfD zI^2$6JwBcc48jE6xS9io*xE^()1zFx#H-0dlZWeH{pGQj@r@BS(fTOC z60c#!U^4IL72{bp(myAGrxD~vUkA!2S?@mUM)wnf6|~qx9yz78{@=h;`NHNy-X(+9 zE@!q~C%!kv^6V!b`CaUDE0X3o=)P{`aU6s%GRK`7or19_MwSLY>iTyHNee$N zoZefmRWLg;JsJkg?(c5LVukVZXN&GWfc0((ER)24>@i9)YiPtX`_B~*ByB^`j<-#) zfoR4pnXzI*&Dr$j=Z}wl?ulLtH!^n5rY+0yP=O4h2sQY%$6tY?GY}C*Z9Iq7xK zTY$|gJo+vVZiqZ__$=8hb72a^AAM0$+a+8XFOFW&A1i3tG))+FF=D|Zw;iQ z?r)_&F>LELGv1yJ z{w`WC#=gIPKX3U5DuZ7)y<)AAF{{tK!}+M?GIzq((FXPiNb)a3Hoo63l39n86paeb z&jX?WR7{x{?E5#3FL!FbB|w)zhyugrgvmi+0W#iEOswXm4v)Gf#fnx2$cSD*Tx}3m zSsTxry>)G+%gLZwMm-lPI6?O_d1N=}6mG~#NfF%wu&;c`cyk&p`4W!qMHRqkqs^S@ z6j)Hf?dC6RSvou_66sMLCF#c+Fmk`C8L*2Y+8;Ox zF1?TZyGSW)*_BynICmMcI0>kUEPiUC`RuclZ3OFqyN2T~p(M6X=PQf^P`t%&O6}_a#T)XrtP(`}Lyv)(YKhMA z{#u`n*KXjl6_|lJjBxF$(yH@njztZOY05o4(%zz z?|w4WzedB&G%MOgzSeKmRTwpOK9bO>}!K_dvV#r&2yIF zhhh_XL;#@x)XPhr0FOaBFNO5;+OdJT`i?ZBO2QyW8oM?=gY|dEz zF)c2Z#e4vx*DIC3PcDMM&#W=Y^j3UEFr60hFgxdFKj-CxP>%aqQc9No+o6ZR)jrKV zgHd)2QJ`5GR%0`ia&N~^#`}FFn{|WcaaT9`%&g^7yf=b;zje_dlW_%bjy5svIkXXw zY3x=E-@6&By}nm8IlkGr@={!8#%F~YqK4G?25J^tJ zKt#M-e}?%TUvmP*=-&TF^zlsnyUh~$CqpLqT?9aS9g=1yCNnXF8kI0{kW+Wt!O_%? zoWde^38@8;$5lPiPBPy3iA3Dmhq-&lW<$V}tKA(`H7E!NJs*tHl_plp17BSa5>9&# zJUoEujM-4=3%4oYM05=GO6m8lEG*D!6l3!{m2ND*0D6E4pt^cLt-$XuAqs zkF(#|c-uy;1{9JjRc6>nt?n#peFD0D5kHSStyyy3QkU-#+D|MUoT$cqoWEi6khT?( z-G$;lFuatdD-fQ+0-@O!mI_lMBhu+>+COOJQ8NaZTslsrSUccEeN~L7V^{sHIs{!> zof<@X4SufrN7^t7k0Gpt;AiJuuN#a9X05pO=g^zj?(}p9IMx~cO47C;1-04ITAjvm zf;3uM@n314qNSJb#tPG+s;$`SHN2B!{*q6hBIfP(LB#OkxbBdK*@<&=YbxbWZhuKjfV;BeOWcwcxe?Hsy?T%rPM~AaN zF?H$l0yQj@%(|8J!TJikoN$N&9FWPN7H=xQ=PYK=7?|2p2!5&1McW{aAzkTO{`E>6 zD0w;ge7^Q55q~70{Kk#GI%5rIQ*-P>dDBSfk>Y@4ReQ$Q-mW}Lc+%R{)^)wmyn^@K zJW}oAG$P>ul(R+2)Yos~(u*M4C9+c+j^BSfIexp+wi!pvS%sw)RapGB-!nby9{*Ek zTBBYoQr#AT^hZWsi=wZ|HtOhOqy=Q zU=c9PDD?X4O7`E*f|;Y2&*#sU zv=<(?qL0oU|Khjym_HDXVZ5@3j2 zgF{Ez(cqn^bNy0tk!UZ?wWDi4%t?ahtN5=p2v82oxYh(_8$ReK&VFub%&ObX$7Emm zxpM1DCDDqG5QuuStO4oAKxgMJH*BCTi)g`-!fgCa83PWxTFffN~14!kpg}HtfGbT z135&F^Y0SJed|QMw|Q)#PTvT3z>t2S=?S-cG?d#c#Hhu@2>$rc!0d^1AQx^-+EZNt zrostzZ&YPL(NM%X!&Wg(|ni;70Y{cazDsQudXH*fv+TTvqc!)LEpGH2n*?U9rZLKZE-WA3@YO{ z1UZ6q%Dk@=*txIM2r#jRfQfYk#b*gk9&A#`A-P{B~xq0=$>z${M z&Lg1vyq^&63vk&N`kTO#@?M2KG#^tjM(8*k=JGmw4;^7o{?o@S(<-aA)?tPLyuu#H zuxnlJIhN}K%0SS7P3aFeLeR5JKV^(((#>LD)*d{p=~=UM`H#KO`rrwtIMkpTKo6rs zSJSb<)c6C@si|O@O#d};Z3QBFCy1)0{oVnIhO(S7Z(;{4leo>6U2pWncSXP_RG zj);%@QA+x=%D*^zQe;UY1Q-A!6&B8I0F7?j<+oiD(Ng`cEqY(`1eo2gUbP`{{C$bctt6V|_kw>>N zMkcV~ERN*~Km52ga<^wbrS?_?XRf+agY!XF(WWdJ(>laGUdBuQ52Uv} z)Mt6#?Bc#tKFvBVo(oTpX2*C>438OCi!8deBAL($G#@SmyC(l0A5FYns1GX_Aq%i@ zHoYlhD`T@}+a0H+<_~&htCy?=c1T_%2Qs_TMS(DZbnPkXqHq~9oun2}8Be0!IeEg;U6vl#N{#;Md5<3F7`QZ%fBDwHUF&j<44uIDHjq0; zQX(E3Nl;38|5%@qu9a@jMC&CJQ%;azZ1A}VUW@peO`BdPzC>5NNlS;Q~h;B3RQ)p_8PEl{l1{`T&^>} zM^MP&YNBCId0?#zZfidAd945N5Lt2B@>y?jZ~uwGz%$LDr^jG^>4MuN_~ zNWVv&#j$x=O-s3a!bSKTHACn(1FJ>Jnm3k;g~WuX^(y>(;Xi;P_}*OpQ$b5dC`Uo3 zxPiHjp8WhkVq^W-ti6R;=w9Y`v{62b7Oim3`-wsNS<^$Y@DwqJ(ZRhOmUiJ}O!#k2 zUyb6zv`?-q#-=5xK*@ag_08)IjK}nq+bzNU@s+1~UBuH=e>syJ^@>3i$W6FVtQl5v(fZ~a zpHHdvIFDReLY_J*t;M7FPW^|X1fCn&Gy8F#{m4f$hzlzui4yhBzDb)PH&RT&OONrC z0PQC7#tfU@lbo37*x~g7u5+@WC&ohG1E=EWt#GQl<3G$)pRZ$tb4h-0W#{E zA}%n+9GD652ESr@b4k*#b6e(+Ps_TO@x#r+h*%Tyh_4R>PN>^uQ|~VFGvbmMKIU24l zCfSJRoiij+YfriAN{B{3)ka_QaYkjOq1nzC5l0kqa>iF{3NlR)&kdkKWa3t}q%z;r z3cxiivgW|$yD{7LVc=$?XCG78OZgimE_eR}`InHkojYBWYgCs|e=yHE*~8m|KM|Y+ zcvk~0@2KLM9dB!;n{IZ4H@%(HbO^)vwY1N`(^aY8(0zGlW%>T!09PY@d-)&={ITk6 zqX{MbJNJceilZ)-XXcBjev1pGy_wCHL;6Uv_xDrl-x?|GY7TIkIXVIE#|65b+xcJl--f)*ye8j&d`6z46zPi z=EAt_<}Nh|y*-&Z_64;?Wg5ITv*Kd6qV_b4nD6&|CQ7Mc2A~XhwE9rkzM#L$1<}4J_$;5D!#~njZ!Q90P5iiwO&+Cr`TvC2bn?tCv(>^jxwV z3h0WWEcWXA2m}u$9Qv?`Q!@tspI+c?kBoIErDp21v8#)F<^HXzkc=nGc5idDp+Zav z2Q@Y?(9Et0=N7kDsdFsxz3Bh$RH~g#XZgCV{$gjPNvZz0_!Sc>X&oz>H4I0)w|TVN zmi&b+W<|5x#mS-fKznX4Bip>o?elcT#B!&5A69Qp`lT+~7*wmb8VYXMN-I-LGJV&B zD#_dcV5>&J#T=h2GF#X3=FePxxk`t)8>d5lBs}6;(Gty^&=s|69dgE%tqQPJCswzV z^bV2gyhjiv0WUFQIB~%TQ}FLUOH#$43>`nK4JQ=EPhBw!kbPxmZeoew-BUU<%-Frc zc3^$SVw2&t#aTqy4nMIHT54qS&y|8hAReAZ%&V^cMf=VcYrQ{{Ywn(rjl1+GW1oc8 zHnO0oK!%z37{0f1)iL|5s&PgA3(qqg`00|}&Q<^JRno%=2%DXXh11B23PFpS36i+u zMID}oL|D*JD|JoLKQm!LKm|mZyhHN>sO3dS(1(dK*AnVeb%Y4X5@AZP9*o*xhNXJU zhxRuE|IqhNCCB1|mc>s32x#1mTB8SbHiQzly|Q7jH%*c*5?mk0E_f;wbDCX_*_Hz4QaCuhk!kCM;!wX4LWKb zfpSdbujoZtm}_C&QQqh_lfIM@^MeKHZhuFRx*>HWu#E~0_9U~{pR|VcbDX4E#WBTt zLe%>FbXlOkG#$vA|47(On;qTtcbOCdE3FulaIu27&!BRYbFcK!$y?RSuuC$#=SwaB z48NMIwoVWdgi*H7aGY0`0jm5aN%=?!W1Y5dPU(vDdpPS-1Xe* z$S0!!pZLL5(2Xlg=b0@{28tM3!a=@#1h=yo%OC7$0e|%>9cqIM-WO63%Ztq5IhxFMAc8E-Qh}mq*aFY%R_Z2 zACa72&HN0QH4sIAxa6&EqY;{s)%3=0$?+>in5LoKRC*#vgghl`PPe882Z&{M@3RBO_Aj#<*$%d|$m z36SOTx7=9?H_6LCUjF|v_4^W1e=oH+Ioxn<&u{KxbQDJQlFf2m;@{acCwvDxLMp@H ztF4VY0m9~uWViBGOe^rQta0q&$9SKA5!s`1m8hE<^~<3Eqs z6ADZ}OU(m*=ep3Id()bByZmN(;hzyjG?j{1`*?_{?agNhrivw>QbBc!liXw}@hd=wYmXZF%R{Q92>x00@-Ka%Rk5L}m z-lR~dt`}MljK_Hpl3aSCH~UINMO|#G_lMuu6C^4V5aTaS_P6{>Dii@lQ&!XruSV; zjU#kQLk-T!$ye(u8u?Mexgul16H8OZtBUZ=r>9)#adFig{Kc%6@NM}fp=PBp>o~y^ z(S>M6_4y;b+$SyuAHw0zB)qdPWI3?iCXwXoh@IO;BffI zo%~{(L%Y@@8&088|LUdS$JXYRKco2Dzvy(vUbDA8?F3Nun%##KpAt7rU$z+ulPG_! z`>G0MT)_tC*yjVrU6||d6Q#MtCjUnEN>RZ*0au^i-dcsNg&y{w#)#Uw>p$O;9cv#G z*y8?-vl%u@i3-x#9x~s38ZV#jC$JLq80gBT8{YFvbwn+#8GegM3!@kh94 zeJ$zm!4%tid;hBKs(hV8;0BRkCrp0Lfw zh3^0C50V!-zz!)Kx4qnPkq;jP*%D$huGt|38BEh8yCLpdVC zZNby*8w{dNW%5wHIW`*hcYrhLlm4rHF{kqZ0 z^Iccq)#o#hRAxbBys7FV6gM*3wG@1Vp9H{}lVavTEoSz`he>SJ`6aB)htye;@sU)= z$gG60wX}O0+BC#c;lqN=XfP)qXlDuu%uZP$K>_l=U zoS6e?{y(a`NNA;0Y_&chMdWG7!bsK7X!c--GOi1ZhMA}C{HwTURltUUJWWq*>x^;0 z@ar$u0wrTee|O$v^$9mZF%igBt((;K`}o=lpI@k!>(d>$6nA`!@z4NtF@IvE*85>C z!HI&Aj_KkRysfiPG%nRwDfjozq|W1+({GKsK_1PkOBaEit;=`f)!IGM7Xz{l zsBR>n;muv;c{|E;N$knCw3)m5JoxAMo5MgzT-amzBFLgVz+ZBlmVniKO7Li(oKC9w zzT8AHD*Cmy8PCW=thYRh_DBZTZ}H6+Gdcn@ptxxx-yR)BX)EK}bqZ@*ezU$1P?dy2 z+tuizSXvokY%bSTNWQ=EemR3I92`j^y9ZvLTNNrCQ~%wVQ!mu5B@i%>@#|-=A7k(? zxi4qS7hlIAz=L{y$Yv5X{`FOmk8{u^qI7vi*(IXxvd-1t@8x8zR~(A%xlUoj`ntxh zLY<))qYPYIuU`!)X@R<67galYGrLpf%q^kO*bD3xY9|>CzP8pQ*pN@Qe12n8=a}Hu zxWbIlyTqP|Kp0o7aZ(Ru4WJWcM=PBVKFMBSIO+9{XSSpy%km1c1XAMT#|y?typE0( zv7j0uOzPo?do^x))czUvFdw<|ufYd6L_6pVDt35}V>pu7S;5z!nWR9hU=3aj;1eB6 z8y9dy@RLIT^ImE*6DkvQ`d2DUYCoxLEj6{3M!~fG$FH;|t_;dop+FU6{LKW}+lj#* zKA575Z;pflPxdKRmc_AFYFwpORmz+SlaiiC&#bTCLwPyh+j3Sf#@BB31-7)`X(!>% zS5Hj84BlMo96Ekc;H97x#56=IX@fUibCm2RWegFH(MPZ)#Z5t z3*p9Y&1O-%7tBm6ry%KANgPPZur2%wzRoZd;w7G(usD(Lg@c>ntmRi~5ytAR*|ZGA zrk|4&KNm~{)IZRfGWXQ@EYcjb=EY2w&!v$!x57Q$mW^W96;S^jLKat+Z^n~p_pXrk z9mrJob(Ome>3~~+5_w8*#ki}ldA}`LCA+k<)L8SD?KOqrJL;SxFIkcG`aDTsrV?GZ zDy-}qtToQlWCa#b^G4UtFW+u2Ixtu%9znE=rfa{rNeEAVfG{#SGs`c}4XR>d&bQ_K zW%^cbtB6DvdJ1saU(-svJ7$M^0rqH#>WA=3OWVjdJm{BDV1E+(SaGG}FSPJ4e&@1x z{AcA`66DL*538^D54bvyb-In`-oEZ?-#vNe^Jf3E8b7t$H5m2n2Yw!REDD4)uM9}@ zyC>3()fW$r8`z}{1W9xUMpsF!JF+xftNxo5yn&r8wJey*KkBYbF{x{wEA77>R)O^$ zNr(;+l_54SHr-eM>O6(-5;Vw9D&*Ii*JdT!i%?2I%L2KmmczH;9Q^PQPbPm~3?bN! z%6e1Q%6r-0K&6OVY<`avZ{i<$6%*+NtCMr})k)_QDQfxmx~rzoFB$h;&{iUok`xI} zpDbEOc5`2?fvhJX`Xv{p`Cu$SIgAba@RCFM;nzVNX$2U3uv2z$r$?O{mUX1BoDdM8 zM=#9rYt6c}t-ivLGF!I=bbb2vBBobw&P)mc#)`^|mB;nzJ?r0NZ0n3oGmNJW9Lm6x zD4qV#z9lQ22B>Bfej;<1RZOgu4`~cPAxag62OLd;LR%F^`kMux*c8hRzQs&Et!g5HQ7CLURT+k6v97 zdLjU!0K?k!U0Ug0&}v!SPnnF#tDh)vZYx>q31VCpJQo89?MH1_kDG_wdZpDNBMZHg z4@r>v`=g*s`8s?j%V|EGVx`c)kPO`-j37`JMnk}FX&5`vwk2?zWc+~AK4 z%1jViY^7z;oXR%oJcnR$jQM*77mx3SyR;d{3Ih$280jDeEuI|1@LR52YxQcBLAYP7 zV?Qa1tQq~sr;7i0j?UkE^2M7xOzLuaL)Hvdc@-$4oWX?YwZbozAwZ%AwyNDPglMy9 z)o&h2yW8}g{zm%kJ;infaQPawSkJcuUNW37P2<`Rs~jVb^g=3-U65sG+0VRg31@jAz$;2b zg7thzi9|1Q35*5+(dtS0xMZpM@@bVd5r*j|x;a_%g46JyZQprow>FJt_Y0UC4*mqA zQ(WGylgu3Dawg*5|3|eN2lF+N{Xq4*sR|R1XBwYb3+YRP>Ym}6emZx9NoST+OTC?s zj>tflii9@`s4FOS1^m7G7!k}OqXV1De)a|YyC3)7=V4Ww*o)*zto6LSZQ#n;0-X@W zDYZIfx?+m{jw17;48$tFiymjc$yAX}sU0QTj8*4(M7pwUAtp2M!c4|YY5suU0Q~ic zFr?Ds=7J;ADyj#+z8O;GhrYRbV^%f0zcb=`HPA9r*qpgwHiOZ|pFv!i-1r|beJ?Mi?u}{AiyH6j^`b9yeQGGuI#bc3L7XtXs-H z6#84koXH)*VNE8O_>IGCA~`9k@Y~!4yvoIAWKcgN#jep5r7?-NwdEHv0{@aEI%`Qk zcYp^9sEZARNZf`|SOV%c3`LiCvR7HAo5^13o$www3)74N-h@Ns9?^mG49evUwXs%y zGc&$V`Bbg{mm;Zcr5Pd|VgxnJ$!FAg_Emm^mCBD1pD052zlC`iSz7265f@2xlJj+5 zkLgb9JS>4YLO+mTSG-5sZks)=fGAobzioAr=31~spwGZ^fz~Bk02TbjkTuRxP38TM z!-w9=HhPgHz>NJ_7Z6&-sR{l}i5@&mEDQuJ&%)VOp~9XvUuJDLc5EnSGk5ZHuO~sL zu|3YWPtzwn-R*1P3Mfz4mwtBZY&*?-zRX&W$=UV$=P30ZET|f2bHxQ{Jpk(p4`P5Q zVz_M&mgc1#ROPn_P*>en>+S=hWhqVw7-PhGg*arbMyT1WE{`vQ;H^*ggjtDG#Ui4| zUfjS5RI}jZJEJZF_<%^oZ1P-_&7$mXu1f)T3Z^8hzrSJdpmuR$CWFAm>Pw_F3Ze)| z!d)v#xkk#N0>mXc0af!u-9PYM(Ra-z;|Ol38U2$8#`ck&r{wixVcPC5m0?DxEf3#HHO7XOLSq6Ey)PM(mzu;a zF5RB62U{B_UsMUfu@*mpS!W6}yH9l{WT5-_&2lsHvj4-*jq>r~FHt`r@zIzfXg*?b zW_qhWL%QJKwza9ffzW2$!(-yMJUf1Dutdd4$qy#!M<1#tcQ!4o7!=Ol&m262^-Z#* z=Ub25L|SZn;mc?t?Q0t~?apH4`!Ks|mrH(hco0JcCvB+V<4zq>aP2xh5TQr84CaE* zf;$_GZP1x&X2@XdIJ-DmA4zzT^V!iV$sg$y96SD89PuDKFtWq36jj`YuKgLav_=U< zrGr0Ci31Sd&OiO%S|qn`eI|WpWJ=?D`8_|h2=IH!^Ov5cADTcsZ6{(VnfkmW@*IIY z>0Qn3H!1ORZ&Q)sdHRx=0Da|G`(CkWtq;GN@|)hJ2P2h_{CozJT>d zH*Z3CW3potSEGpNe_yM?;Qzi>tC7V^EcKhD+4Yoaf1Zk;WTmGE3>+o*#NcPZMLG1l zP*T8kOusOq|ChmY=mEtSrxrMk!rRW@D;IEJxhJ?$`lsJ z*<%~V9lok*6rQI8gd#w#Q~gJ+^XL9ACc8!w4{OG}BGl622fvh!u=vXr@`(C(a@4y1 zHXw9;#C0m~9g7HXzpv*3)c?TIn4`gtRa;ryhhq>4^m#~GZMU`_`F&7svI~SYNMEgN zWV^!QIS@WW)><3h!R@vc@5i1*6vCwip1&LqOVtL=75nX=q zO3Ao^?1fQWN$eaM-tm6taP|{qmT@AGw9aT3renS=VS+h{tgFOA70{o7Gl5BaPu!UEjW?Qy z-zm@fAF;diFr;b%`F;?hq)ZqeqbkP0NSNtA^62jj#}$ex3}_3aV{MbbUDvgH9|zae zve||1KZizp-U{bO29L%9JvxjN&(U~W!4A`+3oMX4qssE$&v@{WVA8IMQv?~|)?Yzs zRtytak|bx4%3@UyfGw zDgOP|QQdK!*1td|J0dFI2B8eSHUAU@5x$!72hqLNfY>@(wk$n07jGgdSD_gE_Pf3* zeVFH_5_?M7abmf)>JBLR?5>=~#Q*a5iSvXT!f%99t235Rf?mcRzFjHy(+@XqAZ3;? zy33x&(T`N|kJSIx`=4-z(Q02466=u*z`1JuUeh}2GN1%8L`L=LMqL%FQ(4AiX}3M!nW_2|Y{OrMhM>e?~` z7{3&6wWNAkk$-Q!mk!J-S@y@@6mM`ltxLg(^7XyHN!L|uDqL?EA#)#_T+>Xg$$F8| zy8#h|98UZ|%On%!U4BMv_$dw!HHv}^nW@*(Rr@jrsHYQ?d%bZgw!VsQ1{H=q9#WYT z84esCmID~y8lt_0y-}*)Qlm-KLHdY^K4n$DQEF=5tNxTxpfO#$N0!*AFPT_E`G#p{ zV17>9W@p4no-!a5gAVbf=|7QT^k-cS5)uUGa4cbr*d`t*sTL(<<59BIEpH)b+NXW9Q5C6NuTMuEQU~2(-yd%0>N|ODGSb0iqwGj!P98j z1Zp;nA`{4kABoTS@>&8*J%SMkpz_GRpRu~5l~bRFvjas}X5|;Hw29ZJTXIO0UtKyd zbbiN%Ie|Q(4P3Qr`JdCHpQ(C2Y5XiOJM8rsxPj>P$yd{S6X$YZ>pu~e9Qp%{I-{)= z{gV9veXWGg<{cQGzr54_ZW9z3Z^JIW_WG2+5CBtOX`-^GwVTFxxuGuy0Bi5BRVrUk zw%y~gpo_Y3T;&=>E5p%lpetWe7u#5I5LG-$!b ze*o17)FIj*Q1yjaElLF+e+kl&87s-GOs&JpfSaWvGphI#1*Y`POK2g-k(zB?bh>w~ zai#HQQ2@Ce&$CweYSE>G2B#I^k{&&(wt!HVriq`ios8#_w7WUezwyNCoR^1N7Vsbc z(eft(>2@3wNf>GLVb$RBJLa}(cRRiwM9l4inUbG> zfZZNEt{Q<(m6K~%ahgJe#EA4uvw7i; zj1#FTghEdPRb+r65N(l_p_Qc82^mMwiDW1;BLDFCX6R_^{LQ|&wgWK;Y?T!p$X$AY zlv*-}3e;MH3m>_mn15LufMh6}Wf8ZC#lDgGgPO%ngTWNC*V^59oI_ zB?tH@+Fw)X`L1s$rGe)!0Y;!}Lq$bn*Xr(jTbH(Ebn6F>oX`fwZup2t^2pfRp)bTZq zSlmXk`-KVm=j$K-R^y3H2v`-x?b~Y$57EBz;Trnvyt7b`g}%w@MVtip)M^sXun3p< z^%!{7i7J;na~HRsqQ2--nyesldSIhbW&`Jqs0gEF>9^KK<**l)`r0@52Fr{N&|O}< z7N^ozFS9B#2)I2iYOuafa%06SMC;Niel1WK)=6(+d7r8=%awhYdoVl6h71jYF&%p{ zEdJ3^XwC!i1~AZr{}up+=@r^IZ@su-{b!|})!xa_W7msCQ2{lc8hD-c=bb6ghp89N2)Vp=m6DhlI%~J{ym61>VFe_J3 z#|X1Sz`~oWX{5oC1wH>7+A2P_o!Fy3*Cm2J5(AE9C~z#?8!?er`YubKvQLo>?9ES^na;uv%@YEn4_;yG@bu zEe@7=^tCQr0)Lu{Drm0#w^_x;)9$OP%aTuG}>hu9^0szJX?tc0UnQg z=i*@7F7dYIfr!F;6~GQRr68`WzDNXW753Bixl|LEdc8X7fO><&7>Wc*w~y9=Fl%l0 zuoMM(T5bRKW3|dVTcwVVp%d_R! zuKddJn+#8|kt4BYcEB~7GdQ`li=`s70jaZolC$=_SU*-~j?oRZsuk;d)j9D`1fMd! zHx1vfI!>a^#!?|3=(o499Xs7fwC989kTP=}L#M|HoYHW<%PnpZk5V>qOEGMxpPF+B zI=b+0xhI-e%N)J2DiWO8@PrGRpmEE2w%QK7awWYz5r9g))=_I1b|AqUE9 zIO$9BW><9XOVO}KOAV3sG7?zD! z=;%8#uq-pOSIyjzl%-mXPXr#C=kgl;iAR(d`N2c3`OL_3cOG#91gWVfc@uW=f9DCB zQV&>{^B(H%9|dXN3nvoux3hr}Rt|B9G_-`8FvqJ6xX_>@rafRy1IW{G1@pRzuJ5x9 zrO4p&lX^2@{&I+)1nFhLqB*Tm>9;4drq!0KDwA9}n}Kk|NF%TswfxBABG00*%RASk zKAgS%jzEWh%^gPyqkUlXJ9bonWEU4%S^PHonR6JTolgSypMQWHDc<*^=Vf?J|Id{`qB}WJvSFtZ9u`(Q{z$G@1gPYgRbzy$NtGDxq8Z9@n14t|yVmi*Ybq9uF zW3jUDh%?Xo8VcrEXy7+&>ye7G5l=t|ip=ckewQreWWuf26t=@#=+0Z*ZK-s<2g_gH zEiq#mm9z=mp@852h9oG^RfZo*mG`j-6TY+?8}jNaxw7fSx8>a6+!Cx){vV~*L3#A7 z7lUzJ1?)=(DhvVlfjQB8>{p!=hK{k|`Um?$D*KMkKap36Iqxy1nT$Lrb?xnI2jIcH zP;?ZY)x1?y@b~0Tg9BeD%cWGhH@BeSE0z_6>4GmyhLWyKP%d`4Pc%je-I`IPaJX8a z@dsw>_=}8gJ;zH5B(%H4o0RFFlX8xw%{3TY$n+I>mhGhx=nj-@PX;Y9DW{^py z_-2y*h(VY9ipzV<54Vp!Z*5c&|9RJqJsz``i>Yi43LNJGMJ(`L=+=uzoB|!0dN%op-AhNb@X6u;0u{0;OW_vP-BpH4?+5OWpY~5GdE&(ZD~1o^Jeh znZno)E^D2JA*r@q)K~h8q^_%UX$l2?WTj+B?|Jh&To#HJ#3BBO&_}7@{2eNyC;2FI z$4R~W2kMSfVOHm;rGf4ID&@(3)VGCpqJhvEu#J@1ze*uUseci1!TG1=eW8U|HPBtA zxc?fXIV5E#Re!3Yd8`zGl~c*9v_rJ4ga)(Q5AI)Cd26C^SH5RjT^rlJkF?oK>+-0- z+&^=&C_?XAb+RC_8}Z{3<4RzF4Sly{oqP@mnwuhSf=JANrvYu{E7G{upug~|r=L!1 z4zGYVy`h3SJp3(wbMsG zFJRx+HHyd!<;3Bx|BJ%)rsV-`o^beA{k!?0#k8hIxY{TQCwF#nJJvh9PxXJ!U86~6 zVpQLKAW|?UDyr`M3uqk(ag7)srkzxj=RcvR`R5p7;bDl1#w#Bo()l5ZF z2jbAyrD3;JcNp&KsK2dC`WH7%JSo$LCQ_+`bnfk+p1IY}iLCSXVheRTtl#*uag_Eh zmwSn1D&IH@naQ`|pIw{2hCLocB|xL*&{mih;vUlPlA}6+LnWPR=FM$?!T9zx&e&bLILn3r(P3Q%e7Ig^_I_wnMzzK9blT&FHnHXd@J z6nQ%BjeF;9D^7jC{_Qp4JY?=`#kb`(^A}^6XUm*1`-5LTZ^la__IOeJJdUh9j?jI| zWn=dEf7=6U_V`0b28?lH8=AO=|Hsx@K2+I-U7qePk?w9J1Ze@0knRQnX{4k(Bn2d- zL%JL3?vn13lJ1V#$7kM|`7r;%fphMCU;A2X{nm`S{?_#eV)q4?OXIdL8F9wve@fl0 z(^%VbNB*)ILUE8Q%-XlwuDwDxzg`x!Mf_?;WZ8pYNO<$F+tKT*YxR$$VcU;Y*Ne&8 zg})Bmt*pHK2F5@?WxhK3>Z(h_irnbrXE%BYPx(XJf3k;t^rMZ=CVSxkg@FOj$u-rd zh*xh+eQXWw;)N2?XxlL&y`h_f+WR@NI@>W9X42x>jTqlw;^ao*?vNCFXhLbRfi+OU zNUbjSE@%q8(i&D`lK*_pMZS9vO|HQAwQNeUF~t4IsZYi!Qj0@se8kKe7W6cz{2+?m zZ78WlabM&mT?tVFgyX?4 znQr^8ZiBd^n;1<+Ikp4NF>^WP=tg%XDNRIX7-^7L-uDN+rZ4zb=aTyLe()EKB%`WY zEV6cSY{uDiPQ8BK-+HH`N~UZLW0@J67W7IQBo1(HRfXx`77YfyB;6t#!umQ$Re)jk zFLN;Djy6)*2b^|hWNph8jVSrhRpMavI z@*!GM>aJq7%jCcAxlb)J4(vri$1WO{KU#1W7+DP_F6W($B`cEh-X#F}_E8kKk{C>kw{7bS`K84ZBvolQ;R=|6R^ zTN3j7oQl^7d<&z|VsxQon&}gqd2=slrQH$X-$L|2?4*fn!QFe{+@VT;epzc^@N(1E z=Dp7tua8ikWYzadD)r&N-gNM>L*^1b1U8L$SRw^;DqHvWzkUceA09jel^>WYiU55I zqV3D;FRxfLbxt&9a6@Gy*KihV4E$Rf7kA}-Tou;A4c9Wo-e8QVrCBx#yyAq?h_wX^ zCF!E)w z3c+;>i9U;Nr!&{e2yr=xSU=wto21A2ToEOaBOQ7T;Fro5seSTHP#f0Y=l$A)DG)x_ zwASo@T+V?a+h?m2&GWG-DLG7!*+c6_DC4h0T$*Bu9*|Y zSkikO80VI=3dyhv{(M?~VombWm(`ERiZ|OjH~SGa*I);M(ncRfk_32sUNaf#jm{fW!B9Mpu@z$n@6Ksy1R#R0_iG#@MUi$#+CCd=W$Ye zwN_8IW8WLF*$mS!Nl);YZXP4o81OP#zM#YaTUas^<^y^`4al-agxFx&zN}H0s`{CP zH{&m)r=~NAFXiH6Oi9%g9QrDqJE(o#`h}nPozYpdMcm-T{;{zMSW6DC!%{xCqP}q& z4xlQLVfI(a916$|j`O_|(+0n-(94;6FZz%9Zy5gJ6XcxU(Pb^28t?ubhA-u5d6t_c zwsiCvL%nMAWSDT8Cc(#PL?KRv{rKlviS3e$>eBZdTURSs{rx?f>zfYeZ0jaj)VOMO z*75=^ZS(6DD)~g#<|#Dwj+~~lIWh77u+BKa1YX~}I_?TP={5Q#w)i>XOxskp|fAxd?_1I^X9eABfA-{5D_01H>;_0aNaL5{w zTBfV$3(rqekThH;d)!-835Q5*$x9Bh$yynAV@MZVma_&b;GOv4EUKWZ{7649hyY+Yrg1F@QypR<84I^##6i z(ga(n5!}ZbbZV8L?>ng|R0X@#xRv^(xWR;WV>96;hOR_mMn11*-bEm71{6yXS-rNF zeXaeMx*clIn~JjX#17R_;go)Y7gzgmnV?%ywl*tvW^ZfO)UnM_Bu4V7<#tQp1msH1 z>+4P);p^)-a$dwobbUdJugMR6qyG_($3<61&y;Fr&)CZL9gHEQ>_K|no3;t0&w}^( z44f~DAgQW+MHMu&qY_Bs_hH|FHi}X3Bqw*i}7`PS(Y*)J5Gau6f9&lC!2| zVmUX4aXZ_y?Uu_ct-Qwduh;xpYc1E}y|gA_@UTzTqjoDF4=Dd?58RK_;VP zgRve14NZer3lTtvv~$cT(MKzn6BI-AM?TudGWr>KE2ENp`PO+o;%%AJw~>G9+&ZxI zI(NDpK2p5$wJd)xV^}gW>7y}tw?+9KQCv=Y0L~^io|cbQWyoL&g~^EU7H}W8YG7=u z{@Dqzx(NPqeyO-1v<(wPFlsTA8amcUGpSBF{2W)pqFvG=e<7SNdD`_d`|vS`X#%Ea zpVhs@<`T&U6XW_N=T;fWjG^kxFs?ZKPk}?dR+loC^hr09hWm3VF_h4!KnWG5{GYGv z3$jpuVESp(LKYn8-rpJmj`9HE6=|cuK%h0)7B4}V<^@o}epVnx&^b5cFL?0mb#xck z_b-2Ef{!5waTBs|Vr*?6RBnN*eTN`8B{}g(@hE5l>G1(NKEf>CNemV)F)Ov|k16Pc zpui^zm5NtG#yvEv%tYNHD;8i1RAglBs>hGt)B4_F(oXRWx{s_kj>WlLTe{Qtc-lt| zyu4Hf;ZFU#n7XGHuZ)toaoI&tP9(fmGL!Is z5DuMZxb;SCOQ1|Qi~hYn%8gH|$cf}Car)xa&o7Yfn9og5x~5~QnfvHoRe9lI#XKi= z&_Bdi6%%kI9p>tOTi(WMk@Pl(5A%=A8gImUTE8fw+G zC$b|AtVsk)#mT_}Sm1gxt`ypTsgMB)O(2YANd)YaELD3Ie}fHwt})8g*x=#p0(%nP zId#w1=2t;`TUOImxR!6B!K$nzaYG-j2Y4v(6Jk<}_R3fsC@Kq-3P0>|a&#Sd^)Xb; z-r;H8AI*Fz$F@T+CbovZm8;zFMF!JPZ&7fol2#ME#ka+r9R}|jMqF{eh07kQE`FBf7 zp1#FAW^;4O_ot2l53~8zoKTK|Gw!a+?bje~kX21?{Itp$C>O|){vJ;a9zM_MDSE(i z46Q^R66YN_i3S)5;wLwykb+CExsb!X!`qGw^5T%aJNxPis_3UU4(A2jAKW3e!Vs zfgMZPK@fOH(mr}LF5?YMFxM5U^^(lU=^uSEfs>>M0KBzoLQo#l7*bX4)9iuhhNyD0Fl3)biRMaR$BHjK^a}Cx>a9ByEfbKB!-&vksLD?Hb%@1&L zXc!$Ffnru66yS7&^Gj%6pcnV zp~(ZhSI%924ICAY*sc6|BMNuYF%8=7Y#!M?S7UQPqnOExD=+2&5N6T>tjwPZJC7`6#!V3*+K5~VTZVNTTsdQb(_&A zeaA4dsAtbtlIwT~+7B;8D?ZTJ_xOOb&BDISNs`mzSoc&7V>(DD4x9{}>>@=`U4} zGE^yGBIA=%_gzvfPy!Iarhm&IxV}dwj7ea-9fP?5mQnZIkXc#Ta;K8B_u*6plD>uC zYm3~@)821P)62KbJlmd^q_Y}LZxDfM75e9wztj11s$;QFA&#YxE8l1q>XRTISB%qzM1c2=RPXYQjLB}^f~@Fn6)_)D%Y}O!z<-TXIIUn z7`vb0tWX+*`{{Hzv~^?fEog?D-!d*i!!~!qz$nxg$Fd-PSud|?e}RZmnpF2B8pe>R zN_+VlRd-N3a*1c^Rt($nspS{qH)DEX5*15-e5&uHKS6aR7G)>FlZfZW>+Zd~}6eJ?!D=}r~Re_r?%w6>vk^nzLYb1boq_jdm_}IAl z%U4EebL8)ZR*IT1zo4E}Io!%8YSD!R>hb!95G2P1L0Cj}$zrsiFaG!uI{r|WWum6L zuRrT>uwB~Joq|nnE!XlEW5xUMO!?c`3Z8X+s^Q%TbAvY~05~SzF%E+gEFmUlyCWFv zCjzUte@GSMw!*X)J#tzW=im9#e5rm6Ujs@6Ty&VQ=g0NZM9$S#!vl5VgLKWWC0mzx z8F8-GS$R02q_IjF3N_pyxddm*Y+xz zWmv{feLEicliU~SwBy#rSWXQK;G!NWUqfoJvV^U%v3mpH1Ajyw6JA7)BF!;=7zWWu z!mrS`G{-)K!}sYsHrX9>n@^Lh6Sz9Vq>Ib9SI+CWJ^pItvd5Z=1Y$LBy>|)x8KqR9 zYWvxv{Jl&NH8vrrd+6WF_BA_)&S7O@|E%*NUITFbuW!&FT0oj1N2eIgVF>lY0r0%1 z=dL8?7m<)ZgUACRY@~agD|{nYH%U`4$exsCA@orsHmFN9WpkdHY`@CsLcW9kh*$zN zjkoVuuqa=mVSfgS1`P>~v^~eW8>@tp2rYjgXmB#}vW~AoFNTnyGp(%RVx?9KrLpfO zi#S@zOMWaTo+XEOq)5;H0szo#G>1R*z(yLY-Q8V2QhYX8tR9gg{~Hi$YR0uVI?hIe zvym*nDyt4^qslaoz0mN<2|hIwv*TeM6nqC5RtMbJE>z09SLlC|jQx>}^bp7^D6&Ah z4)#y*jJ#F0NKwXTs`pAbJbh&Nb?PD_bknUVk@#_LEjMc=Nm2;!0bk;hG*$v)40SST zS&|yW)ZJ8f>=ISVFXY z^vw;11@B#7|CYX4AuslJZr>bt#7b(;^49lwfND~``L)Qt%T(`2N$t$#wlE_Z;kJp- zq3Qkcc2*T31XJQ{19$(va;_Rxknxep2Vy6{976X3BX~1Hk?!r{@&qhvq8aLuP)^q8Bv3LwkFI~ z6|HSu_|wYQD~Yf4hCDrH$OKhhms|RI`>s$gPr7v^ICZ)LZn>-Bz)2p}$_h+9(ublp zNx>a5sNZmd!^%P~9`P*IA<}tp&_e&b<||7Su$k$_ zOv(D1U7JAJ6dkUEiCTYvc+OgJpO&88RKt)=Y)sw-h})^#8bu7fqKVrftYxelsiS4A z0hWbc_m~A6v^bJV(~5L9rNQ30Gl2_@dWwnO#35yNs=!PzE$@KqybR0)1e5q1$kmM*%|G;yJH4wO1=5)WUfSC zm~VrwyFb(JPb)4M zWKj?wuQ=AM@q)0|Vn{0j2!s~b?1dHu@*Nbsv){C>4tnpCN zSo-PP8_e(BzWHdCZjpA>p31t{Ei#L;qJb3(%Z-Gl<5+(JX?M41@i6vKL`JG9TC*XP zWG*d}gFHH*i0P|nYYEQVQhqLuhPyHbj243mI;~$4t8lwHAh1O^u2~OyJV;=&aHOxGo*jc%zCT=MK@sCZlwe5vr z5{We%B=Z>Frt;cD+qxiPgue*^3_S=^JHDdhjWmHEr{++?irhg^c)gLz%W3eBggSLY zl*+(Wbn)pL=pkMAg=n|n>KcYngKNbv4`(Vn%O4*1xU_t55?~n_{+{6@EGa$q zt34(p!1#8>XM7wLEpy5mU-{@f*(h=A&b@gL+AO}=wbjfum~gg}`t z&U%We)Udd< z-z@p>eOQvxqX)v}<>9wf@SRwTWx^lJdMQU!*qfg=1^KxK{DgMdS#M&g>a(tn!7frI zb^-xszLW<>o48{{x$nck#JM+Gxwvqf%>IymX&!JZT(X;C8Z%jKio7rCiR#bzRgTfi zyXF{q9c>@NCY5@ZD1@&w_rXCy=ZHY$UrRs;w$P0ZBRWF@u%g_TPah~_TaE1C3oYy) ztSqWYpUvd6QF6Tv1!OT;rlX&>qCGE30~(c?k;9yg79F&END9^c4PiD9M)EK?o5@3nDmYZ${J=5J4Ye!pUJ!=60x%)zzR zR^e5U2#WnEN_I3gSZqwO<$#;sY5zZx3+-rWagsI?k2e}a_xj#XuOA){Xu%v{1@;5K z&3kzmm;SB>oY`^`m)J`=|8&{3fz{q)=KEFgpP1E9+Yg zjBgdF?u?^_f+J{|-HW?pIatn01#x-`Qnw(>sG}CI8J5x6>vPX|mc>^aJUFkdW_D>i zhYC|OT*F(XzX+N-mf=S%K#LRXND}b0Lb=A=gQzwtT4M$`q<*eMA^yQV4nnrCsX~ z?l`(lIY#Ke-fwHIck}8yACgL@m{ao$*?aWT_;TXBD*NUQE5<=X`mDKWWk269IOwQ_ z*>e!}qmX)QZr(IlZU+ao1-YUnE33`24;{F({gGlLv^Dl|kT1!u3qvmpuFE*M3Z zL>KBWx2QaBB5MnB}92sR-T8*dQ?d7Z4#Axx5-$;USYI;fvu?@8$V4y zA52Ii^)`H;^g#^sdc2h+H< zC7{IaR-J9$2WuU8*6=@B1)n8J!Q6=mBo90jM%FlALUUnr$(6o}mDMhesfTBVGAu-< z9d%?mMyJjI`R8PH{tqrCz#!b^)}7s$h^D^ORDDiL-I75Gf0BT*?IXVy4MH;E7x!8A zDK6&}8;G?oHh>E>+3VWH>+Ie4!r9;Zxn+f>xam+C^TFEFvtItrt>3?89ObOVYaPM& z!{N#z-&0kGJEbhEzx`egzg)~9aMZTY_Y&y?WQ}jRsw`Hpc1X3PsYdE#=lUD}_u8+} zyY2n)RM~=)YzcYKc_ztwdI#SW327z}fSXLnp!_b149*Ha>~2Ej#w|G;<2XotLR)&^=s zptLvh25lLJKj;bXM!=JRY{s>5gBzUGNcNdSt;DG#Fyau%eolfhg^&2sE=$sPd40^H zd&%%AI)4+eEa>tsU`ZCOR;HF{v;AFM#vkrm%%8s%Wb`GirnFy_sY*x*VOmZRtlq^z znLw_xQkAwbv(^P7~YrT&h`RQL=*?!#KdNJ>XqR74RC)44{BA@tX)IB5{0=Xx;= zmM;)10?Kc%fvZ_=f1!NITJO`s5(&0az$O0Mu#=XmV~^?@EN;!;_=#8dMe6=u^ptn z`8nGbrQXfT8$qzrQ=tL;5ZD)P_c`vmH#za3U|3nRd6L4torkn|yGvTA<*1mzR)GU8LW#-;;`c)`aJ z>`cr86fMVtosin0FDq<(^IomP;k}k&$e?`#!N0Q%j)Gx$ci4xXtP=eFzJ_mE9$ZZs zC>pA-NliNR9d|Dtr>&OIN-5X>V{yGV2ZGh?^#xs<*6y;KyROAx(Im@nOg5ImW!fQt zk(y8#Kbbw$<8r!X`Jw8w>#|jSkztc*1maLo;vYM!1;a#?axmx7gvaNvl&q{s}DTJK<`G zv^OgJj#sf;CA?T~`)T+ux4!_d#cz`S%imLtL0{)HqiM&kfsA#~dPc3sc78mPHU<3^ z*esJCFKjC%{QtYz;-InU`ga(zbxd@+qQUtD>o%=!pAT!w4AHyI%2evp$i7ss`KiK- zKVhlP0ozvo*Yl&Vw}-P^fHxx;C(dn+q@xYhHxcHp4JER!7ZE+yLOdCR$Y5OBqkYVe zC7xJW)!kyOC+H}~ztRR(MA%?`@GJXH6-aThn70=Xj!!Hjy?JX5`Ok;)OzM!@0yAw@ z{*KSm;eHg+Lz-4f`#<&-BDcf;z@@726v zR0Umc3_e7k^?s8cvvm+%>0%RS9~tt5X@|lkO?AYHxW;mjV!wMiEjSq=d+62NhkV;KG;YJ}C=;~<8pnBrSazrM731?+hGIhba<<-Z^5rcPNKXCo}o zqeG{Zm>-mqSMuA;h9uudn{F&y)8%sQt;s)ip%u4+4%%rne)kP`Sr z_KAJ&zJGKP{{DWE3=*MzwDrmlzv5}p$X`)YW-uH2RxzA`7KM4(rP5a`{L78j{=c&gLpvhPO`E@4^u+N1BiVY&F8?Rz+eXuhBY$t{ zC)kB|VrcWqGAz(g-;d-PL}ek2+6~PIku9CS8{7FUzV@wG=!4Fyd`gxojK#n?buhjgov6 zuK-siYp3N63=zgEbEdsZI-zb1^Z~@b@np*|?OYW#wOo{ET{CYXi&~1nth!n&^ZGog z(0}Qry{@_9r`?T@1C_#l$O{+|Tq_;ChTjz#&(@vnWCgcOw{;Pvbhu3#{eQ1tPVzb= z%7tckgij~)Q^;p0P+5ZjkQTY*(qlh1oyfiRor9a`KYHVd>W?zb&yfn`FZ8m;N0 z$GPyX%n|gqx#b|Zb10{N&igb<5e0mx&Q%$E8tYtik;$_ExSyj2|2#N4f)Saw3;G#T ze_C3iFV1W9Ly%6N7ngIFySG+9jV~p?KVV|ipP25&qPCNy%hSou$9heV*W{yjZJvj> z|1CLV$=@Q3lZQrIfHPFa!_xaIRtsx(k$a{+9erj$sT}z~tHC>2EpCRvOydtfzSnNo z1iX1QtlQoIpAp!Ah`o6^Oxdf3vxfEQxZ5vC0mX5FdkGX25+JcBBUR$Z!xbS#BLlu} z;@?=tKaR?HZs&s1yRaZiVuRP(mKg~W++S{K=^T$yw?B(;2+)L#Sg-Y#f zQeGdOC(UwPTpDI`w+N1dPxE1nXvt>;JXRO#FZ)63WQEQ=qv+Z7MbmY8^OqvyDgoPj z4}EKb75L={$(Xh0rMWJ?gAYYde@Q)2OWljxylxSoK9J%URx4_CzUg=8gSDmzMUtp8 zC$cxYF$aeloH%RN9fKHF!YU(#z^3bhl=ZS!4J#0}5qe5Cyb~Zgr2;YOiJ!ix$)e@_ z86qGSV=bLO5Pc(dwi`mJ5)rOloMaHb*`p&;`zt^c2O=%ea57KP3qoQqS*?GvLm3Xe z`WnjhmnH(D6=bhhl{SV)Tz<)@6MW^i!+p8$(-_MsJ9qonH%3tX@~QP?t#L`a^Vjp= z2?gJi4cq<4#&<`-pb}bHgscOXnWo`+20b(L;Qdi2j=H}n7d$r4D|aly11<7pF$yo_ z+B&67SU;23>b?+jcnk@1R?+s2YlX#F)fST=4? zYk_ps1vxyC0m;d9~b!VrK(CZM|Vk*F8t40xR00y8bdOiYiu+Gg01S?CSE5fzCm#3slFc+D5$wkb3+W|2u=fw;F64#&KG)dd^%!)z!|i5U1Y9E-x~Q>1KaIcR zz>JY$D7WNtMdaunb9wDiA8y@J=mTGj#)t=QPh3Bfq2H8+BEc`fJw)}}l9Z9c?&k=t zMvBv;d-CZ{Xy<#f4*J|3fBGqU-ON znr)V5mM3`K?x~@o_b%B$z7yq`aNc{FW5q`SxmHM_cg1{NyRYVM1YofokLuy{mJsVd zk3Z;`%{&w5{}`*B(GEkB>T?(-@1Ve+hruTiqAR0R;!KUPdg1Z~y>_2D8aQb~zRC;R z0DHRk46#8?C=RR$q^a`BhS`_l-=hQFP51-a*hV25%EA0mFgT=z4i#fpqIp0=B%+5J zB1_y-9=@~F<2OdZD<V&WpP_8@ryuv7esRUFY2O|6*wBIQN?bjEe@oeFXn5(zV zNb;uSS`AkG=@IvMc3}D^GTqebpZy@DgmI4MOUl|;D%sAI!QOBSFQPz&1ypDa+uL3a zqrl+K)ETyJQHV{Cv*9D2mnxjnRPw`Hx*a2#tjoPOrgD;P`~nt=kT?xmPzzGKV$yF1 zPq+MRvCO6xr=6|3kl?QUd>bR&mS(J9w#lE7KvucYZ9Xg)$*{Lj9B_+Gbk@b@wIJUr zCYi<|65qpec1Is{ECOP->#v5ClyQo*4M;bZ5Wy5qlPK6k;;6Q?zMx538X3c_Tl0|q z?V>N1ub)F%{626l^wD@?fwdp(BC_2b2lYwVA)Z(Hq7d5;#~RsQh! zz+3gcm8aYS(-Ttp^8N8!zP6vpJO}{|U_1o*y?g+D97s%T@0$wW+g;Y%UBdI@|M9NcoW0PPafsL@Pe30Hc6{J61O#_N z!mwV8uWy>o77{|C@Q)h`X}LJgaHmzUZi2d4Z+$7mf!<_7RxbC}r3#Yhb)KU_#==a1 z>zDWJYq!NB5|v=jJ^Hrl{JFh97s?xWRivd76`m)=MI=&Z-!7JbHjamDxq9a(^IzM7 zFyE;~c~lZ>2G=Zg#`i0PNZxLDw~a@4dYu(`IPt-8V^L*V<#XuY{}6?Q!wc}NJK&fY zT+zMp=&VcsJ|?pyF7>(gJ*^B}twy4=oneEy_Ew3gqeGdSvs+-~Ex`+X2Za}Ih_J=E zchZvR7+qi4caZRCm8paB#AhunN?it6&!IT_2rbqRaO)}Gy5DaECqQUPEJ{YEekeIv zij>?Bqye2qlTX??ttn1F%7*`Xc_v)@c~2l*8>y&j)QXDeivXg6bX}efwEh34eqt|` zsxK1xH;JatznG_JTdr?4NL|h=cD|~3-K6PG9_M+lF~lOWzH|HRt*JE6_St=bh*Hdi z{M&f+2Q7BjNvgU<-l*8SV)+Rqs#p?irIfYCqW+9`Pe0 zgvQ7p%8KHDY6#!4wBj0p@PP^S1hc5`vwkbe#-jZBQ##2_JJB_Q7(hid`pII!c zd1trEdWZh^QR`^eQ*zb`#y#V+<>1RlTl{Fu&`ZS@1jmp|&_Xza4zRlR2Ty&#$Oav%8~t0J8v$K=?cFzFjyqkHs~5ZVWE&O>fE zzs^Tnv7X?8^kG=b3MscAkf7aTR>9{&}_FXYe-E>RF-23@)E zwwW|vb6+DpK?)Ba>yXshf1@5P)*^bdXb362SS?ug6B3}mS2y})OZJqT$!_>bN|XGl zry}5~9i)Nzk!t;Fl@?&R|1iA(jxZkr^iw-6zAC3NlL}qhAN?<}?0>QZtzS+tL6OJ@da5+lz*&p?+Ci^fc>idbY75lcz)GuVN(6{*e~NFeMx7BkoK}0 zy8TU+Qz!E@)=!IQs9h5#(Z1po6qv$Yb}W{^3@2;j6kG*~^PsXJoVlJ0%s~W=NIX}i z*>^xf$8U?Bgw#V-gtIKU|F*Xk3NsLpbe{hb>C<$6{^)wDx2IOTCLlb}q_;W7o`+$- z&|k(F^PyT?WS7l^Sa9_q!OPsaY=n%dS%<3qOBgVjxWgem)MvbLg?k4cCg`uuKRmPG zVIaA`+RxZvmWVv0lF4g+4_AAo{r2>9@z)mxh7%nKU^{ivTG#v>-|oucFOEV04Z!7C zy7r(?AA;?p6;1yI?j7MLtw(M1(OZbm_C2i>oQV#UmF+>M47&ZCqJ91LzMI1ETnFD5Zm+4b@)e|tb^SuX%FMad zcJdIm5A2>5?9YIK2AzCRK22m&lJrx$2D8cps8?EBZF?me@D2r0f|%h;rKilS`K(Ng zP1R1z(_Fh)`UbzqPYWkR|8et@O79k8FH)pfuk->zEE)>}*t8#{un0_Wkmi@(!KW`g z_hFC7E-=2F97(g<)TQ?i4)IHTyv1U8Z$YwnPP!I5J5wLg9nEx<+9H?dj2dM#-<)#8 zf2L?VEg&E!9_VP-6rKdpkr4v4IR4G(d@G=D7V+FTzI7#MJN!)w9cLN!I6A*W zes@RI&ik>Nrh~`y>k85kl(;=g%`U4yQth@CB&UwF*P33`Qqvy@TJc5#{WT%8QIc0V zpq`hzs2uClnWZpGBet61Q3Dw3c4(T%$3Dmz`R+w9!H7U-76obj zA}MU6lH;|2^NyFkqLYcJ6L?c|x_QsnAYI_#W>mZTr9&;FF3;R%>t328I2Fk{qP__k zZkeG9L)WI?J_W#1$XM;edtgQ+|=c$Jf8T4axtyZPs zz^69hr|$Rxet&3vHMlSa$7%Zobj^jXwqM|F+HuGjwflC5I)4>hGBxhk^%9jnZcM#G zfR-{w)2;}-R>rY~Uo$m_e0-=77VX3A4(&rO!DUwOd&ho-rc%lUyK^_Qi$?I}#!N z%1*;MDj-Q(C3(hLT9gL!qE1joxiF!P-@D>GyTpjo>x)^&>-?Y`p)3g9dugaw+dBiZ z|J6}JL6EtP#&Wtuf@k{4%8R!k^pemn|C^-1b5G>}!n73d_U1GoW_8xFN6-t(Lec?m zjDMR3pv{;D5Z^_Kt$eEdJFhnJlw4BfR5(^(rS`s9Ka)PRFYMFKR`&5UXot|kQXe&^ z`5jIXTw2TmMgtBs=jCE5)Ij>tPj(VpfW{OVcEa)F?dL#H&J=bco+Vu0t0wh9*yMN9 zSX?AGH*16#XvfuII?A?{g@i!`^AafNgeJda1nO(&&)uTDNcR)_2hX_t4&9fG(z&}G zDj2kq#DgD84Y2}shqGETZFE>N36$49p6~3HdN@ei_`N1~4$ z{#=^A^;*}~cKCsRasAgJ=FNVLA?B$zL-ee_jCBAsCJ>kK7+A|J6!Laf#W{K|+C&kb zU_t|Co*u>+|VTI4?#{|&TZN0oBM6!pcT)^*hS>e!NG;*&u6B=6=xFK;7Ikq>g3*1}u) zCT!;3U2lJkAyADE|E0H92j^lR<^?PJS=1*%5X$9(wz?maIuie|3|U)+`QHl@liB^I ze&WlAr2@vJZ?#gYopS5jBFGgGz4C#6WQ}xkh%m?d9NC+$Mb){7W6Dtl+p6~LJX$1f zr&}k#{A*5IvuW|RMij*fK=3k0wxcWzjH&?N&NznF&BeH(aEq|}hVUaAp8E?|N8E`V zl@g+L%Wx(+hH`mgU3$KiW;N8M=LRRCLgFz$_8-*3>h&)akbhGPV;u;!jfO_I23Bst z`}NjfD8y~_F+tuTpVw>G2T=DodEGuJ<^OD^2nI^yjFYGPcMT!5TFDxUiUxP!P=vRY zR+Q9<-Biqt%0{!?BP0s5h`GMq*t1h5-ygXpL2i}+_Zd%kY+f2&vA~yl9YO=^kUPy$ zPdim0YVi4=5y4(}iS1ov`|?Tg1@_zJv|n;LsXau-o`N?6wy8blMU#rHZTU2<{&wL! zJ()uSlx+s}t}ir$#g9#MB=T*t3AK+iY^IH%rYgdpH-LIo8F zl>j=9Sm++#K~Z0K_JVrqWL11YIpj#1;w7}8dKIXQoJE8Up~y|9Bs{Xe16xSDua)gU zP~mL-gM!TQn~8>k;6@>7va$Ut)R`;w?b#?xHlbzhi|$OYh?@{n!$SnNZ|+Ro)>f$9 zz?W&4ZCD>5Uy3h=&RernL%;b6Ti1xc-eon-De`w!hL^~_{Qx32iN&^!R4*c&QKgj%Jzwqlj+EuEY*YXm)>ZG=+W-IspSN<|V>W_>OjaJJhhR zpHp3vOE!j!21rCIlDlX;&z8W7XIHfb&t$jv3wxy4DVNJnq>}?hQkT_Uq*RjFSUfKc zu4mz=5bAqV2ZepJ`mW+UwTW~Q=rdz<5Tkid0kk|R{Z!V!><#taOm>hz?=1^SJ7oK7y!_M zc^7AsZO-|PD&<=i2HL_ViOW65WtD>T1P zn3vEmxl(9JaBk*V(f0^N%1xWG!s0x;R*e|NiUB=c#-Yymafi%qI-+lXF#t_0;oM(F zk@ZCt%g)xs4AGxDTGD<9WB~o-Cbv1)SezWYw6DUs3r)j`zd~Ib*H;#QVv02YateS< zlwfv3ZzB>67J#2=@atQl&A*2HDA9TeN;x+=v`sivSN{Q1i9B1CyA{(w@!$+3aNex@Vwr78lAOcZhLW%yq*~ zA(*yon2JyMJxWj3c;ec)R(}T6!}kFOV8x%=2To&&Fe`-v2`Lw^#g3DG}M@+!%O zSBmCFVC>$xsqw=C|C4XwxCAI9#X7OAuRMQkaFy0jKABW;ohriD=|_`JmD%Ul?t{A7 z@JIA6Rx8ki)WhIjpX6vpoetq?{D#xW2WCq_L_!4v*bQ4A1x-GVDw}7JpLl`Q8mgc- zF-BP;*522yzAT5AVw_fO)bG=r@<030ZJ&rt7^gjbp?17YWl=fK&}xo$I$aMiyCGD;l>VuFgMvo?bR+PV+cSUnOt7>K(cK%&;1~ zq>Jde_uiK6_Wu5B&w=GRA>RwVtCqLr@Fuez`)Yb;Pvth1WUZIKzu%~Y)+Pd{&LR8X z1KKI~S?qUxe;3gQw4s${fR;<=g+s;U`)RKc560l`Q(DF4Kf7e)$g3-_49qe!_lwlS z7A{M65mKdL(rPa4t9dw6|IKMP1ozi;#*cdR|BSG#<(qKbp_rrfDV18=`f4~*?{>Q3 zc-y|k%H-$9Cnsf#e8ppo$TN_n(;`;e)YjZwOaOrMV2b-&jyixcmq*ZU<_{TlT6d>&uuqr^H2Cs#chD}rZ1vaP!lPizrr zSx(RRn=nc~7j|4S6Zy%SWMQU5NA&08Q85WG|JillYcxUw_y9Y^lJJQnUHgRzkpw<iDC@Q>1wu6M6P?tSW_$Jfk$?+=@Inhsp`Jig%%66=x0oq zI^*`?l;t)jwrBVG1Orjf2mt*iV?-|Q(JO|>RpN;1v?SGDD6^ZnXFEbL4C{@Kje z%y`qcS)w+&=s6ftd@0I#T3Kr&;XjpaL zPhkyH^p`&d`^(cG3lvF0@JI6O+ z$Jdt$zlpX+biMjk6A7kkG`iFYJ~+Gy^1G^w3SAZ0j{#DTf2M-DK~7x-gZ4K$OY_~A z%-?lEGmb--Ae8*K?B-rYwBDf7+DpDg>vQ)Hu9n)E62K4fdU;qEn(oI0Ck(3^ckkuQ z_Mepqsqy#sDKX!MEnK;cxp*_j>WP)AbQ_(RD4--g`PZ4THQu32UDAFf(4YcikZ==q zL9X+$IS2CAym>ZB(TY5sWvRZmrZViY_lG_|%$v0b!B5TbU%B1y;-`Ar5!rPJ#fVu^ z8kU&}3cl33-)L91TN$+Y{3hRj@Nm>Hg9!d>X}ZDusv`GAaT@V{6(w&_V;^^kt0}DF z+?(SjQ`GDE&Za4r4FphveIV_y=?(wdVP_9OWWq(K1nn{q;m8h`=iBF?boVDOpT$*o z?$@g)(`jX^7oBY~EyX`IiP+X%bid7NTqW8^&`mpK=^5+}Knso^`8aM}l`*D;l_7Em zh|42KI5S4W1qkVsTMbe}V!r$nJi`_SUel=r@P&b3+Q?`l{*dW^_**fk2N-KAUKHnl z)X~QyuX^Q0dEy~1saan1(&(oN)nVD+o3Wha3;Ll$+hNmXQ65q&buTPvVUpR)Ih6Z> z(SIl%HYkG4Wy1o`KECs1&UC@bums3LJmMj0tK^CTBV~h5BA|h1Rg?K5;XiPy9-LxP zcStZ4N|GunmWwr3%<#oj7ybXQzxitUVIf;oJWo{iPM+i9I&3on2Gsp>wlrfHe}jIlKh@kDds`LxCkcm9+{lo7ISVe0_39aLKVyAX3>lFRY&&H?+8O+ZJ|( zcXVcQq`l!QWIVl8bTutt#UOpuH7$;G^{CT77_4&95*W#%FtQJ8Fi?@&d`?J%R5WK& z{1N6!Xzi8|>%f6?ihvDa@%|JE!&+@tcJ80v_Ecr|{rDL9v9kGxdF!^viri515ABL^ zqGPd)pqLt(RcpB0UcgAUgMt}5zM_%Dgxc@Ll8>XR>;>YL!a^|T)w z*~>ZnhTj}V`oCDZ#(+NmubpiyFD)$BvaMy?cFVSF*|zOkE!(!1ZR5H7{h#-}_}qOD zuj@MJlmk!QB4{w1g@(4AUGy4rj@hRZY;t^<_)DU0EV@YugtgeJ1@rO+ITN zLD{Y7i<4K`&SS3ElLn`Hp4Xew%x=ZVhD&6~5~pZBpabu|gXquFXkdn|_-+K)&3bO$ zPU7qV{|^p45WRA7`p@;>)~AQ->dwzFs7Q`sPq88f+3dyO6q{3==Kp*K8b1K9`2qhKa}j25E1gfe%XOYuOs@JV0h0BUBtb#5r7k2A_jx8wX+4quJ9oR3J-3&IX<pq#S}UbUR+-k$dL?Ja`mu~!`KT@dforPec7Et#b2 z^E?`lI~{D`eHW6nJu?}nyQK+eFVarm=V7sa;YIHXYP6IhQ6;+11+b3lzcCnqcm8-D zyifHue30s9|D+e7>WS+Nsc<0FisQ6Vjo+B5aHKNA6I(J6yUwG^=A$}j1!It_s5lI0 zYfjle2UoX4MJ~{p)Gp#PQ7^Fj5QiIAaQnQ(Z+51a4hw+OeUx<}A!C`mn5k>7$B<(T z=a!thIJkWm$v(aI(VnIU(R)2I;^$1%hsaZ;9j?xP`@C8!`5a)Df1RqMwkc{6bGRON z5Nos&8>i5QMVg6#g{t9BbH#yu1p#2X_h<`KYNLPn;Nsx_Tka{r_`Nm?Xa_{0?%%2< znl{!BB+}{Xd@r{HbMY4?U?2?cE$|n?M#3DtRWcFC#iwUvkat@W8mZLjkKQ_SbW2(_ z(Dpk?&gnSp2?eK`=-DZ_6h0es4kOTmDLuQYhQ0N?*5qvJ{tI9mY!)Nw2EcUj+FYE+ z3967iciqA6i7I`|gas^ITyrb*sdz3g-*#$6*C4zz{i zkrZm%1PhC2ztk-;Z+;DX+E1v4qksTYQq=vf{cZm{z~~&|`NR41wq5(#>94^p>zE8K z<8GT`#NWK>KYtuzT>N~_*DfMJfL#2oa+fPoZD#CvcY2^Z@~;iN1E7;CNY7hkjqlGS$pQM z$Yuuw%SBU>_&&QwoW~udZSn;#44PPt@uPaMxW`J9VFA#jrwj7;nS)!bVvq_#5l|ol z#aabD8-)NOnV)l}-Ce*Sc-KRmQ-;99j3rd&e((bFA%HTx+8Tg(x0_olp5AK@aLU$N zBE6lD^0ZPcy@doBm#02{&5ZXdKP^itvkd?ff`d?Z4GmP}o6GHj3A);tJ_-Gt^q-=L ztzz6__x>XOxx(yDSA+On;G}6Wd#Kl#{5LbXZRJ@dMFZbK`Z!Z27r8(;$|W!2EEC8bz@GrNQ9$BZ zEFKPWh&MZXe>7EiP&PwDsQrbxK*`|)?MXdvuy5rl>s8E_@&lcZ)!X!%#F+=qukvp} z;~H{!k}BrKfdH5tf^#5+nhlxsnN%r&pw{(t9DC1>fw8Xqtyl+`@^--{vQYYE?oJzvK7V-jq*+z_J z;u^vG{w$LJ97%w63;K(eN27!n=RG#_5k~EsZFQJy$bLQx-Al^)sJ(k2syqHgutYqL}^WS%l8KRBkPR54!?N+Tvt*QG|>tt(JTvD|o~=AoXq z*@63FD)&OG){t*T6rVKCA(lF`LIjj$!M({U*MN7x?lGcb=KrRPhyI%`7U%*>W!n%w z3M2`ST)?KFfP4cF_xj#ce`oURU0BuG0a9Tp*Mvla!TpYwgrZBIc(OEj0Ctb@Nt`( zwE80RmD%Sk#~WBg-I`ua-5OiK20$IgkzV{g&UVDu?^vc|8y;zA*xv$H;B>y4p`JpL zLm2_bM6MnZJ%D@G{m6s97yo}K-Pk?SRH)(CRXR^kfLdC**d=ivm#gOb-ot$*URRff z@6^|Wej3LDitz{(FoG>^V5=>#{959MrlJg(y4Oh%{N%4*X5z!9baco9H4GJ~Oe;k? z)J-Nggqp72rQ(&t9%gpEV<$S?+D5YQG*uA(TNFxlE-r5AQd2SROQtU0# z54vGEFZ+xYdvJ#1=2sF~X+vCIAoF36AK~o_=$0bhR( zRXC3v9FN%J;3*_lX8w3D-MrLen2(?QBEN>qh&bYSOf?z=pkOkE%YwZ@+Zv%5iIu4I*bZKwaylfOl0F!vo;5wqhRL3>y zj8$}va0k{w)RJ&^{933r$0$TkjXA@DLOn`rr`Tt%V?6b zH&S`TAYg{ZS=jHuVM%*L`x2{h`mEQ|T;31!0>Hwh|B|%P$4Mzo_QZq{ zFNgY6?OqPw#-xUxM+fNSFRHeJT5O^iKrUf{gw$*WdGo)`%PCl-KgK?D>ApR%xPJ&Q zQ>~g*S0_TMBVGD^E?jFlrMy^6-`A>xMfZh|Th~_h?+MQVCRSkpMfErNV8v6}+NJ<& zexhSv;Zy*l7j)+#=yRH>k@gb=x_9re1WTXcH2a`iXJYyZ1~=Ih;PUhxm76{-952P_ z+>2=v{p|S1;6}Ssb0z6X-o=ZmUB$s~L6ASk!^vZ*jxKAN=pIfo*;t4xd9>1_d2D3; zXHO@{atUOyEogrv%%gdrRW7iEor1ZEE`E+y z4vOOR-~tbSX0TM4k+k803UD7y&WlwmY3Ud*&&5G~gn-6hzdW`bj?ajCe2w z_}zXnj#zc}>Q_yP)~l8&^^|^pP+DC3p8M zbE|vNK+KfhQJNb2G5WUu$t8)eOn!^6&XdPs;)oT&pzFg!yLbFRh31acjhmk{`(z4)WLqZ7W=grwn%M-m?y ze6f158*(gm@V{TpbAi4}^s&)O=3cP^tYCb_0%rptoaX!!2f3)pNffJ|LAE%hvrlDf zo(nvgjQ-s!gil^dcd^;iU(V4p3a_&e>Tv)?BY*cm3D+OFNVM0FbZudA68p|aY=+BvLz?~4fq`-+>OL62>( zZEYM^qQo(P>+l2_cX#SZ+9!eyWw{CSuY9qRu5_M#R9Y`g(w}02f`UC-fX!rzA zGB4^cCVbj5+meu)k+||mJ4}e~p__Svj%{^k-<791t^R4B^+8KSMiCxDR+`K+bOtBP z($y67+EHjxCq}Wasmw5|$CAvu@Q!MEwNzic=%*P3yy|?z369{vy1|M=KJ~)Q6*8~_u z%}W%Xy+!Sj8j3_oy6$TY; z@lZdkv}}i8xaOz6qTMiI@GP$1m3A6)cL(R6wWzar@QJaYG=p}1-pT~8e`x$${)epS zCTk)`&*1AWU@K>9dAthgak7E?@4fJOva)HarKm-0*OXfEd%eVS5{_hY_TWcOVK5Ht zn=9q^X6N2v%ef48hNT2H?R4yazKxZ8#n`qW% z3ni8gQ&>5MTCc(a+Bb9%ZswAYf)OrD46giZ<+SMtlP8&PzflkdF}ccvPWh2brK8%< z{`IT|{hJeWurrme8Z@e$8zCHiwh?Xo#iIKvb%Q)MDCN^}G`Py`QERpxDF+i!8HXg^ zM8T=I$CH}Nvr7{HyS0Q($Jm$oEUzP;WVKw~_R1rRhVaZUvuaE5-kqneJ=OX;5pDS_ zGhA!DpGWh)ms>Hlv{1I2{)36c7%KfyK^%P!$jC_1}h}WbH42U<9gi#OP0O-Q3V7#k!125FGBwMB++QP`@ICy0C~w5$%-tXy zs{YwHROKw~RC`z=Y-XHkA38w3xzk8*dSIP=O55GZsb)<5y6+?B?=gdU>v|!^sa<5z z)vW6U{b$M0#(ugu_yE)#wY}{a zwe7-RW0Xf~$C1j^?FTZC+{K1-v{xYSz+rb5K91{cKOp?&e7sD{+I4bg(=>@V)!)En zzx`KRzPktCi^78R(etxpuYUyMdEdC>%Q@D!crfm{pd;m1vdl7QsIb`Fq5>?4%7%`` z$y?WojCq9jXzMavUjwj!MsSnMoejYsj7UnU-dO@BKnRxjvHspTgN>qs`LpTGVxhF? z(hMHF`bdn`iT5B(nQt8g>I5&GmB%l88Vv&@v*0>wEN9C{AZxQIIk@et-SCS0YEhi3+KYLObH;~ zbIk$MAZXHXC_4J}uC&^cH`L3ZHt5?rZpWwx1Yf!6BMQ-PO7`$?i-*O;vGBjds#5T^ z^0SD{3fFTWP^K1cMR1piZzBfX{I)cSN3zDc69$rIWWTgzunQJ)UEtHzLb zi@^ZC!qL4y@(wK8+-hxtY%q3Mh*>>t7t>qrZ;MF4Ig|}cTa>9m!-4|sq6PbpRvQpd zAs>I9zbh$?`R^)s(iP%JmvYS=ix~Iw$+c@163L|riT8K9M;3$Iahl9pq&mWS?CXF2 zRtm-qDHr7_$hjqsSN25$Rmt{2dhS#so?QNKmMbac2K|Jv)j|JNuCrp^^_otqV9A! zFWuPR!_s;|;s-Jpw#YD!g60L=e+e%VC5LCvw#39~sDu%1IhG$PRZGm?P$KsVrj)xr9I`>K9M3LAlsm>Z9_Ejj2 z*gko-@@~azjS-qy!uQ{<0m-o+zos{BOD^%jDEKDS&msDDe=Q%X!#LDMLCfp!Gc=_by z`xFk9QDRb<{q`v`Gvd{SUjrkJg`B3t-|1?$zk-PN1ImoU)^Y6~~VqLaIfciUjfmA>HjlU*k zPixlUGGS?!)e_H1d~*{KEu*_>LZ!b>h5wRj_-2=p$G2J#+iZWky=>YsN+)?l_YduR zgjCJueRF5JSBpe)`P18T?^DlHoKZU8iC%a4lXey@t5!a%CNvSb;pQUq8H~`3KX^<> zAZiChnZbykZ;mkBr5qNk%C+jQeh$m{&z!2lKi;`o`K4YoA0Z`2sz0`SQzfeUk-@Oo`)H5sPE#~Hz(*nCXPAl+6NWB9*Zp~?~?|4 z(Z2e{M(EYd&(Lv>VEge;KT%x_AwZx7r0LFRj@yEQX$<(jnLNJ*eW?Fb{=0Z`>y|`w zSGnelp82;pLgcxuFZB3Zm+!{|Q**tQUzMbfs;vi?M_?gsZ`Wwygu0mu)b)#tL&6~{ zu_S^t|IX76hqhOaoPB2&-&x`?FXU9)+#GGmpz+u zS7>U@TttX0mc=gZmn_igQ9VdjUnZ_g0nOlqiqcfOw(4AcV#p8?}s-wQM-S9d+1KP81|Ab)soEmhVF>v*#){A ztEecLa5#bZXW(|?G7dIRRax0x`Ns44c>{BIv;YJd@#ijDG`B=lNKs!htOocc1WQ7a z5uH3lK;wb!Bb@G(%;|vSnJ^Tux%b4dd2y;NXPh>VD{O-HjMR|iI0lCM(syz}dzb*H zIn|T6eba`4lODn{AV6<@Wu&|&>cDhs$a;OKpWXf2^gV0#PGgso8dzB(F_C=wWZ!9} zFn)5>)-arW2y?bxmzg;pZYwH@w~wlG z4+QEzYV*m>9BdlagRnn}41lC5^hL&i2@RYFkq=i~9U7P@2a)|6kul$#*Y}`bpZI|gsgw>4)c?n?9lyZDk)>cPdYCtuVD#IaFr?2~tOiMc zvMWM0bFn*c^-8zUt2a+q`$&?cYcrQ_-abL9G4;mw z_Bv|AIYWR$Ux$5uZN%V`Vh;!5)A-TT(ogcChy+-Vp)RMvNmTX8G?sSCq%feK|05kj zZ)r36Gd~WW@aWgWdED#9mxb2Yiypl*{Au^IM;zMTwn~Fw<^7G{>>A#T{YE}t8Gp7+ zw2pnN3U+gG6ZMH&wR%2YBS)@?(5rh=&o1hZ5`yTpZ%vBI$vX4}!X4Dz?{d#(ytJg` zc#9E__}!b2@?KYl;nuOFQ7BZ+(;GfYQ0}7_EXCKq~`P>-0jTj zeGNSqMG9nDjGBH?rLlJ17O1lNp#~3dNA{_H11}8L=>EFongz&t=EH7}v@hg}-ymJh zhQ`Q!zQMYb{y5_wkzTsvI?8cpNnwe=J&&apHY3nSThiA2$xpMGUuf(`> zh=t9~uodgCP#V?#IMCh>3X%y%MOZkLJ}LQU+OS}f%m?@YPF{09RWk_q29x7S;c!); zVYS!F-o^0Q8Mpm}$ojbCqYc~iQ(7nUj`o5+_wq}7S<6sFCRs#1q~3FBxD2vi(>uJg3OSUYJSABi;y*lDs+;)DB1vhtf8jUs zw@B&scv1*U3^FBLK#-V@RVkLsQ1CeO2Oc zfEQtK&x%#hKkr6qBc2$In~G0Ie^)cupQ69-VY2_Vc*;q|->skKfMgPh3G=w^O7MO2 zCyea2 z{Ab1U*nf+*y`*}*g(wi@S&@bl#r|j{8aNhMF*jc3fxTu=v*VLfaHos`2?1rv&5BQ3 zcj)?=Z3h{q|J9CUAYG~H$F24oesI(VH*X^03!<@$7Be5PUpanlhWbXai07o_G+A9I zWH@=Vo4MM@DCGD{Mj?W(xf>dPGp8#DY=QJeC27Gdy2HqyTZt^+mZQ`7-yDCe6w>8X z&S_of5G5HiF&#?dOw+l6mI{s|yQ4PtZ)!k|eB>u%fHgR{=;j8J$$V;MshNQIONDB; zld`?U!z)cz{jjmg;#r9ifO80IP&?5H%7NH*nR$TMz;^S}<1%T@wfgR$@ZDi^mJ7~+ zc?*f018ewNo6Y3Y-!PD(KBgoBi*my8v->h`|!;e9q2*q8L3PP8F_Bk3rESj873pRu`3YE zlePl0r<(|o9cPiX=g9)?`oaF#TmusfY~!&yMAYN^g>vS)0+7}acNNFvc7ZSmO>n~> z&&ol&rVT1=-GrYX7o+2QCtl4|EK~q}-)UU1C{&kGV3B8y{bQw(m2d&Joh&jwa07xl4EHwK8Q;zW<9Mt36598~=AxV#h{nu+Si(kunmT1vA z>3u2`VRe6p<&+nBsEwY$N#@1iruuM8%iBy8R4j~GD$nhcxF;;j3ke~BHcVzmrmSi_ zCT&an(<|mY1GqW=Hgj{Dq^v?(R8!0=+^1~>#1{&@9oytN+_ahPq((duCg`P}-es~N zP_rh{Oe|O#Q$MUdoeexO|Fn6b)4vM@nRpNt#c+JtY=at76wyV7o0J-*Fi;^l$Y&g& ziopuX`ulLG;m-}gG41+|*^^r`$oRvb86VG0q?@wreuMei-M3&~CwkMSvbTD=xy|6vJ)4885=DiyfM4yiBYj4oBEzaXzs{TXrv8)Cec@=6&$I|YJ6mxSS zf936)_I5XkiU<5?=b#03y>x^r@`lZ#c+!p_lQWOBx;4hL(S>#6K+rAO+&+o%6UnBO z4oZo2Ybttus{sJ=^(NAj*kY*kRx+U~A<)mv(d+z`lc;dsW+>;CSt4angEnjQ%6P=F z{>NVwKO`hisGjFE?EI|y(_ulRomrmTtWm?Jwccf~;R~HPez%<#Y@R5QoMRq?S}{m+$gKQ9Hl>(6Z9q^Nw)>_H+JWKh)Rb4=*__Sb z@D_IdPnm?-!S^6a+b1%C3~LTal$QPd@FzKCXufyL$*~}JE&f(+_Zn5nO8Z1Y<8KLd zYY9B#Mrht&`ZWX20rm5k$Kse>iez{Qic37coN3pTB-}mDL0_b1M5$Uq4t_XXam+e$ z_>}qFz^ubSS)Sq7>J-N%9xDoTDX+`J9@|AlE>McFy`yp)e zoi0?Hj8ka(Tswx6CfMVWbt~-`>LhTW$A80o|4!Y6^}-~BY2B_)Wn6g1^HGyy+NaLL zdi98k|H7bF{DQdQ;9Qn3vpE%^zg}2om7i@K3LR`&B;~EyQ<#1gYW+d^!}c} zZ!5d13VY65E3#?Wp16G0M46v5VOoIr?d!`3*l!p}9m6`n?7zWy8JkXmrcl>Vpnu|b zm6c@nknwdh1}f^q&IGx*%InYG0HD&UVj;jSrx3_Zmj924dw8(Cu(pAqF8DieHK(*_ z<9EMD_L`}(B?c6b*CN^QIqD9TK0Ww~JHP}}$99~G6Xx{YP2tu}RpLF)3{;14v~{B* z-RSZu^h1E7g4)AJ4EqAM$*IZTxKi#brc@SpQF$uvZsulsPJ6k7gQHjs_J#=glFf_e z<~Z+K!RY*}_uIDTwx>khcs4B~xn_QsUgUHN1TF^lMMuv)B?FS05v`oa0t#c7pTESo zbcNby0_^)DKq=r4_FYNH(vPzNxEy1Uv_C;OS66h8#EUNi7z^I$Mc|LR*Mx;DLS2fBbM)HYeS+oNl~7wn?Ln4@!$JRR5>Zk47NS z?{%_Le7172ZrKQ``(rKSGAd%QYp<}!s}`?4s`P#f0QG9(TADb#BBX_riBdoPgQU%< zuT^YpNHZm2-q{KC*HVxp-*|S$q?-btVHV16j~>B1K}KKU6tEw^v+Or1Q%lUHgK(Pq zQpl|GPr6d|&NsM~d^8n{z2v9fvDCsNe+!d3PpyIp>m-)TXHiO+s;Q0!(iR`5WXsj_ft?y61iJB_g;(z^G$%1tInYjQ_0m-``>Un_ z$|sy(YEC_jLtxwD_x0GskA&z@MD?^`Z86R@V>G$mmwuL{-U(GO)c2Cf_A|)?dBkL1 z^FW$Wy&Tb|r%Tt_$5#EwFK-Gc4i$=zbN*IpK(VXr-=?zlXwL$nG3f1ptO*`)UEr$>)50aC(WU1SKK$pcC37TF(b-CcP?*UJ@ZcbP8B2`)IO z1Lrws_9upfEOh<8$xfVEV zOfqM(MCZ^*%LLMkw)Vp1Su9-jK$FfxOl>RFt>R{}HPbzq9ekhReRka!wgSQep5$hy ze~8a$3%mU0mZ*#pODA1IJ?=)EnnxDYIulNt{u|F15?2CkkvWt=9F7p5M=>8b_A0?{pVe~=0V|mNWT6N~3 zc6{Q6vc54d^ozhi(qbitv1A(5-G9^R&Im z_**zS_*4fAC7kjh01G~nd`Ovn;oRO@&ljG!srW3_we@sOtSuEUGVJk0o6RTRTD4&7 z?c()Br_Uh>5go=9K_6*9w}vyM!*mtEul$vRzlwW+38za)TTO9Vx7t9A$2PFfSt*`+ z5~6}RUpKz}ws*f(-`^9Z^(#WtKtnpjlLjR+2AW%J5nj3kShhOUCgaKO_MlK%qBjFc zoW?Khg|F!K3iN-cZI8T?_|7nHEO@oSjBkRZ=jmX@VFDVHSBPS(>!o<7uc$6Y5H50; zh$yu(=ZJSa>hI6;c;|#zv%gWTaW=zaR)sQFOP%$QbMVdd3r0aIi^m+2bk!}o>>zp? zaB+I*|Lk;VYZyFI-~;x*^jr>*jkWt48XJd*A+`8fQF8(D2ll=;?nkA)?@|@23K2R4 zH#1G~=nz&r2urR$&>$h`7DPZvjoaY&*tO+u3z9K9mum&~KER*q5=tvVyv0%ncwz8* zna;6#^f>BbK5Pvn_}@rhSqN}$h-6olP5ufY zjUB4J~A&QfZWM*r2vBrQs4PZ|P3I<^k$B(@)!vuiNjljC~D) zqM6XQrJ2wK-(-5_s)g!Mm7puDDY<616Kj^^$J&&g`UZUX0ZEP(~&j8UFXp# zcc(zC7?Y2g?+rHrA^?TT=xzK+aGiqO^f>==W4)E7Ee%c1wnRY6?40P-DX`@h6{Z8E z=}7Q`K=)kGxqti2RYzS+0NmLt*kO@aB?Xh1qux~rWg%TkwgRtZ24=9im9PpIa^Hdj zuzi&_?n8*tNN0#S=>s@WL&?fGM`pSyC5gvR&EvB--6DZKlZ)gX;79hC`s^YN6zuQ8DZ8fQWD^BiFKs=%BE$Q9clEEHi$UGb z12eGIEvVQS1QkH??b0&?f$H7p(!;7;vCDpQ=MZ1A;fg+TtQx-xkeIkoFXb$E?hm2s zmVNdPnAwyrt9o7kH|<4%+*Dfcp>~@IHUI%L(mB^eCwMUsrS>(pZH5#^9-dC{9?ilY zoU9OvwWM+PfVrVX_%jU;HMoaE_II=DKw-w?nYA!C(P1a;J>1+GI{P4NbMtDLEQIt0 z0bKg^>Ne8}R~6(&nd#PGnT*X62+FksE*1%5PVRtBkL#|4l2QO%YDpqho9yFgeX_B2 z;kQsd?21GMc!(z)T2O)M{|q0-9mn1%h0HcO3k#!GX{k zyQueUEw*Cq_Ex=V=hn1pLDS_zGm9?7aT68-ldd#aV@E~-{JV;<6wGdX^e3ae% zPhgpW0r3H60Lpk^;6%;s>fLV7J07>%86m)}A69)46-oJV|JMl-f)W{A(-ej&uGTD) zhYaTSUkT&M4oShVgI`f%uwBf%7Nus)Kg3%{2vVTT<)o*22ct22uQu{lYK3I7(b5`M0G3DN`&T)Zu)o^4-d(lkQGyldQnKu{Y5rT_ZU z2}Tu+-RkiWPo_iz(Aj=?Zg3H6Uz93-c5IJA03}q!7m4|Xv^`TsiE``fCd~|O$0hhs z_}*cIKDNY2iN=nl%M9PQll+}k1(C2@Fj82ga&u6D8Og-gIAa=8i`9`fb4UqaQbH)p zwIx^CoXrs`elQ~} z5Pz|*W8uq3pBE-pA=kw7HD7IMD)%9kdPq#-N6Q=%l}E?R1nU6-TZ{=FO|qVFRG$B66Yuc3c)3CH9% zr?#u+uh;)zp)If){(i?yn$YAS(67h)oTSg1 zDz;2BRlzG#R#Ya9JaqNH_Kq4lama6xCINMm$6{Bgtt5_pkmlY=ga9rQ-vLBo-4_b1 zFX*5*{*;#F@r?>UK9csS-K*)Y`n`-)&sN}$-Ff}GpV9Ki2e(Zd=EEfHT0SuaFM)#S zQKfxH+~n^>vh6L^lUApHm3(F_ls7Ki1TReUe8o6q+f(+nj5&A;#`*QfK5`)7FfARy z;4dONGI^{Qy^1fX_8(NU#02yi20A$pd!$U~{%`{~T`~Jq+ew?(64$8^1xbL&wsg&n zLpf)s&%{_ReWB@={M?wh(H?z`Kkla9s7&0~J4cy($$v*T37`=ZNcA3ULWNo|Mc1M11J zhC=cWR?y3>j^!WVoKrWps(ME7Zzh7MFV9aYH` zW$=J>wr8bkid=K-Vbh5Cr(R!M1aeWOB=_G#7$NKL%N~Gta)|zI-%ZB!DU2&FAE?VC zM?3)om~}oMqvajM`DJ-p2zERD8l+rAnMS!1GEo@npJz~)jL11j`@ANq3TDOn+olGr zy^hiKyY@Po#BZUoaiaIa-zKR#LlNTc;gIvgf4TGp86l6Bh47=cGriOVcgR#~Gt!-OS{KUqG zaHHi^d<)=%85yZ7DeOBlb>A~JCL>Py=E8wdh|25yKMV)}>fNHoV+VbV6Zl?x^@5a> z<)r1jG+{glQK>Y=MiO-3m}wfZLKW7F-D~Gh$2D#LX%`!AP>8b~8@NR-pcmemfgL_{ z*!R`x({gqSjW@!lJfqd z{OFg)tvKK!fgF0Nlqv26clal!8n%Igqfebg98*8Txv`7$QdM<|SP)XesNZXkGnAGR z_1&1?6Z88jf58LzVPUK6Z%bo3bRozFc?s(IYq7e{boopziZAv)So+u%n7`P2Jf`)5 z7o*e?U~YTqCu;^<@$4=%3hUkRv`gPKE)YW3r%kV2@T^HFI;gS)nTx2e(=YG#CJq)gDN(Gim?kA9)nMaS166oGGs|V z%I;{eQaQsNCiowd&s`Tb<+p*XV;dA4%5Q+I3uETdy$e%kI7n_moZOU!XmxDyJ~;p- zgkkBJ^y5VJQ@E*7_}wSzQ=n=%#6rnZDZ|O=lJZebUgA~6_c)9D`zQkGTlGcLzAx=_ zR;CKxnEm%t;GRyjJ+tV@{RZ#J_f`CHKwv7j+e$Ta-y|sE6jiMDnXSzx2*T32k9)*{ z{4u+nv4Uw30Ib$FQ{drOJv72Dab#iuaeU2)pOv^_!rs5cd|7g3RJx6m)F@5n+mD=_ zcnTolJUq>`wXsEx0pm7Qf*0b(wsMN!6jx>gpeaAD?$%F>T@!(dohWG*H-&CB_bzTV zKZ}Rar9(q$hg!ET=2A2+BJb+zbW$GGC7)aQOeBgp;JZeVL#Zm{h_uFta{&j71C zv&cQ$%ylsLJAEcZm<>A$N6|dT--Ecj#hw!ns6Y%bQdGQU4BHmu$e~@$7?8H@ z`qafzVW`ICw4{Gv{3#a!R;P0v?DtwM3P;N~t+>g7Ap`$kTy<|vEos5QuN{Iv8NZSJRp2IMX-?0~Ic# z3RGSUG1Ffy(Kp0(8SLOeG@t;wllq^ z9-N~`Wf%Crz>Q`YAwmafEH%`p_{R;VmbL-7x@n%LvvW9C3iyqtyy7|FEik$u1*ol0 z$P#4-JiW_})cL$%#ZtQL+OAdwNm0ASkNn>+ro?YNIe(6@lbaOsZtUJJ)EY3Z0b1v? z-(Gpe(f)L{hO zw+cgHetFH<|MS)=hdm49jz3Bm~Tg}Bb0SQ=u6K7)6 zfEiS!74dPSCGm%D!d z&9HUD&5?gd?{k5#GM4<0$La6j$J2e9BCO0&_D|uYe10!8sSm{;NQ&*)r+-oIOXx$% zvBf0a(U0P-cb>InP7f8^3i15% zv{w`JPOee3kQ9@ps)>M~k9rfG<2^!5ct%SlKTT@P;x)Nr&7_);em~m$e2tX~LhS3k z9y{G0ASTZX_{6kvBN2AGfR&Y{sI@C^M#dcF+xv% zJ05u{bx9Vk*&FDZxaiuqQ?*E?3IAln4F$&%f1x+LE$ZhQ@ zYDPG8&#!&?d6&J~>!!MFk-26`;IV365xX=Qpj$#WH*3Epp}UDX=Rwuf&lxuDMC;{w z!#(TU;SnEmZkufx=%}qPo=o(k1^RFO4aZCB{wR&9Zw1tCebfdC51-Cqo6WyNS|G}- zmuNh2&=9NZOGGEcj8XZ(0W$C+Ha9_8L7R2O9x)r3-XpMfK|J};*ZfgN9-W}RCImOB zG0CVkWm|6JlRJ`3jbr0eNCy059o%iM{}p+g1gfl?3o*^`mpwA|Pa7Ghah{#`OKaTT0Azbd{zUpvn;}CGC)PeE?aLwQj;(pw4af)Z2S4Mi z-zx&%JNIrVsD|d-Fo4?4$fSn;tD&yq+)rsBQocb0br*xuJt;qVurfobc~XKf!lfLA ziSnaqg2( z<@w-oK=1vT0Vq*K$j8RzZNK(_Av7RB$VP5P3xZdI$BgIN=}$vIe~qaRv(EweRuMN~ z*^7ze@Pk#S27))3Ppm`huutbg*>a%?1od!wK#C4mdN1!Y8r+MPvH3S9%BbCg2Kf$R zfV5;*LrbI&@WMSeAvY@IC@gURp4b%v*-dJ3fPg=kkkYKcYTS?G zA*pL~aGXN`GSNq~;8^lQu(L%Lnm#tXM>LI>;6qaNe!^_moe@x1^PMjqczUlzF0j8o z{ufUG%*~3=rBNG6pk62kT)en0Gj2_A8%~os1s*EC66Jjj5g17O$s#>ojyBP)8_Xnk%{qZunX+R zx&4Ddg}7CklQ?keU&UiP6@o~*KnlmAXT9&-<;P_uPw_UT+WH^}{_vHrIM%}! z#B0rmv!HAU-(x2o=I>h^9TO%r`7a)|K@xeUcv4MC!Ksm#@9+fvB@&_nkoehn>1{t_% z>0*b0#<-^w?jr>gJmN4}-AvaB0~-)00vcR>!d~qeCHLkOK2;y|_#8T7VuU7gXIGmf zL0b7k=n==+t}Wai;74x6@R7!7MwL(@q>l`@oJ3}35vQ5&;>|@i#OTrU!r5l+(iUyO zu@3qLS^SB4UmoE3^8IDIR84tJirw78_X=757v;C@)Z{r|{8}q9p&VCjGHfsn@#XkY z6T=d_t7lvR7S5&f|JXXm_Pn}i3nvX4HnyF{NrT2sW81cEH@2F_wr!)aZ8f&7p8fPa z=iB)Ky{_ijd#^R;m}A^CG@zZov97M@tki{mtv1A}!+ssTL>~BO%%VX_f6M*g`f+~T z=7vh?k-WZ#-IzOZ9#bM)!6A4r+-t8+jX$&ptjTNY4e5NRuMUZ>QcgS>-Ua#&%nu?) zLgcp$7LoKo{9D`9q%;xSO6!aw|K_8?f!2~f0t*&&Zb`cjV|}$CHxAK zm^HV6OdNLVEU(J^dTD?iEy)|Tm3?Riny-DV5nv%cr^l%-)4Qtbe*fpEW7?|>1dC9g zDB2ZXL!O9ykqvptueyMHFs`ns`&@2`@JQFQb^!0lbf5~m+&IDiF!i7cF|PdVnj+X} z7rDkPAMEs-sc#(bsy0b(D7X~%eJ{3B;5VC(48#bZ34A{(pbuCzi124^M}F1;!zd2s zk?x8r3QX-5c1ZGB;;Cz1rc!AKPpW;^U#AY&tNwIip;>wLWo5uZijBD;Jm))Gh*^tE z-%6NP%BswwW7M#EN#zb2{IulD-EaYyyr88~tnm6nFfUOIzP`z+Eolx4hLXHnInF&=tJmUB~V^Vv~khafq zbkJpxKN%LdMvs0(edKHAj8fQ1;lzLkC*<-MQzQN~ckMt;#z$!pbz@i~wm5OKf3(ae z8$OK>$fyrnjXh7i%{Uc;yoIUqyKQjuUMy5vyg%WYd(}G*J@LWn zS9fwB;t;gaRAXdR0kZ);TxPvdvW~btjNn$|^aazut0494XWse6up()xA$1N1FxFkC z|2h8Kin$3X1(o23V&ybSsHagIx93WQ)n3!fiA4sTEk^`PWF5E%$L6?SCY42Muwk5f z>GQEmmmMM<^^3|Xlo1ZDkl{0te4>J!B@Qb?0WiLo3yhnQTuhdpoY)O701gNw7M0^& zs3H6|M$i%O%6gcaIIn8L%eLT+@1vS#*8MO6gIkK z@J;^Q(^ATjtE}=)JMW$wx_8M&QxYK%C6RjPSMz3{8+3U_9 zxWHmzMlA%lewQ#r~!6) zO^zS@z`#evj|7;h;r`9Xr>Dhv8tcKnZ)Iin=t+^)`EXi03`V^w7PPu1qv&%_i#(e7 zC#prAg{|^1fF-Uj>N5B67wB@siVLf&<|-NWUnL;7z+m$^WDTe~>pr)gEg?kfB|k_< z$!EWWJAPCF@>Jo0F=xkge#-PcTRe-u#!}hTU(V_{G0D%xc0Z91l@CL|PD~s`YU~&% ze)+KghK$?G=M->-?PM8QLQ9PrE8uc;g$eA5N9CpxV3`GI@2(W@Yn|S+ zSCUs|U-S|ohJe(lF4dlZiJFXEAxQRh@Dr%8n$oPGQ@c)-UlT7lc=L>(bS91-xAz%S zwZKF-HXz*gl{*h4@o6LM(l)km-PjEBcH^!QfvNUX-w%g>pnFZR94l2iccLwjfYm+*%*au_*$PCBu1I+OoEa4|4?y}!~7cJg5Vs`aQp#Ts3Q!0U% zz%gmNxBRd2F_qW*Xs)f!YJv>;*xO4>6>aJd8(AH)CiZap%!-`POG!@n9npn~(X z@UZ%m7OfJhC$l`8;(1m~k*_hUO#N>cFCJpU0vaEBmQxqMcOLEWqzP>o-z*I+3axEG zxg_M6{-*<#3PUfu$lETv=%r{5Snx8-ErcU^%`$BkM$bmpA6Kq**7^NQZT#h5w%piEZ84^f)stWDVqw)`6#^^LK%XBY4g|oz z!^r&6PQV~EDLY`H=lN1SiVWaTM|!HgxfE?W1Bmxb z;(f#R`;2XG=NcIf! z%_6SEOBL5DR8#Ru7Q2N3VIfw|(heANDz5tZ1fwW07uOG3slub(SEV($VaXF;otmeQ zNi9j-Af17LpJX?2>A(NS}$0PUN;z~&d24iBmgYl9g<%#8e1 zp|bfpz-S$q080S|6Q9m_>lOMn4iTc7%Qoxu&SUDqlTY<~=i3PP5Qix@S6U6l=IXSH zNmHgR)<(5Y;?>eaLNiiJGv_&AtIh^PNr0H*fcbUhhzmI)M~nt!r_HjZ)_TG=eJBhh zDau{ylzNR^uAuJO5 z06Q(np%3GtOh26ZVBK{1@?XXXTPQ+Ai%yEtU*e8--^!Mv{^dJ`{Z#tRy!-#g4fYzM zN{Cv(5f%pOHov0*ZsOkUSC>-3 zAgAyf`f;KINl&q6+e5m5z!@m6t4oTeSzw4e>ALiHT67e5Bf<%qTDV$+%*z59E4h>w2fIrCro>U}xzHis+||-OoV=UKhW5+~iB? z&-Pkpc~dOhwZ@-%!BWj9;tizZ$MP$b#xK&^29+Hi#2OqE=uS*uQ2KB?bD`;fasLsm ztV&LXj61f(!FJ1k;zaZ(7kw?scUi{b&U1%V;)0ha0S<9X#a^39XB3b}-ZrN+_BB$b z^A`!6GTgG~+<9_WEdFSb`cib5T1hlkRIl?Ak|7W!&>CFN=^KOK*^c$TG(M=LgRoI& zb~lr9MaQ2&i3?GoRIXaq*%N(bd(jJiPL*bqIn$|~Y?(VM4wyT-|M1zpmZuu(C+!z0 z|BcP<^SHv{sipk4CbzKY+8lk;DX?^g7a!;IaNhbY*3dx)Ttj6(r=jg-={9jp;FTu6 zR+^6A$6TQN^Gi7nx-9Y#B4IL6739ZjBDt|Y|CwOXHnXg2=Gi<=dC=N zb}Wqj@G||B2zGj4VYQ45tXzaW}kCmGpHN~}* zjyjgIqbvLLtxg5tq`G+D;;q!8>|IO8tcL1<)Rl(Ze!A!7@j}^D35N!pJEslPC)5nL zEY<3ox)1~9HiKO9$@oDhHp|~Xb>_Fgb14;*H9hPC_gtL*KXdLnp3-8QfYGUkp{($r zw6*?J@=}c(EE#MmG>jxP8|!7xr6Vq$5-E@&CV%|y$&05nnQ%o6(JqIpL}Ond&>`{u zWiv%~)Y9q)(5P(TYQ9<@Yfhd4e~BsZmn2yAd8l#M?`>}sojw2E+v_;?Z%bUw!^i-fXtA@12{~Kci1&O9t8yT@ z*xe`Ff@{8AvC??1;!ute6^e(|&6%Qs{b#wS^sE-8U4i!d&vL(R+Z!u+6`WuagasUb z!KM-K+0oFvy)zi5h2zB4I+0XvomUjhGBUKSax^9a zZ{i%wZRu??!QElmsz$r%IID^Hx1Xd=+P(nks6fZZ^Nq}10{4*IfcH!eqO)9PsO#i} z{QfmseNE<%qIwK2_%P}_o01K&Wr2o{0(MvGCTAV1_7ZK;iNc*JfE;o8zCW7Uea^2%Vs$*(r95pS}q z=6aM^IVBIt85EV#(Os*;aps%PIMG%2dI>?+Z1R_EbbJ`&{h@WhdX*rdBZu1sDo&uR zwcEAp^>2w(LszUO8%0r*&29`zgCfmF5c1$TU&_$)!ZOh;-V@7u=)4(EtSjJR2vpev2#* zL%1|u8IIrb#Ff=E_Df9iw8}T4662g&eX~yiLBgVukkHFmhzLWvWZ%hH$cVXr7~|ND z!ZB{!=XZsu?mM|5GBT*2ZS*k8&?&y8@yVvi*jHxlpQPyJ+B>8~pNTa7=y~(VGgqvY zOsL=u&VKmj z6HJ$eplKZ6Vck6@m*|5hd@=7+JDho7tvQS)*gI6tksT)+C9H z0ssLsUT~dgeN1O;nQ7Li@{4F)zi(kij&z`DJe87Gyrwt`{@$0|QxGRxT37ujGyL^U9PQDZ=j~+>s{4^xT}l7~|2zYb*)hXV=qM*rb_`Ya#!{7EJBw_`p0rs-y$T+DuKw0H ziDPsm4z^6wt`Lz1RZ!=4Kuj%YKaOR%=i3^zcn;sO^bw$`pl>^aQ5U$0LN3WPMzdrz95 zd_uNK_=(I$j9+T~1Xik^XWgP}eL)v5RFH%)t=E%gm0>eG3(wvePNGj` zJvvUDvt7iWlFTD#2eWk3MS` zxz-ss4iVC@swR>!6MwwUWnTEf$7pp569{zr->PRiKTQ`Rg8E-)eGLrXky86R(aL-Y z`Pt$qaSd}VO>1)OEtnoXYklscWfdfF|6l|BvSvnTbI0YbU|dm4vJ^78#Y2FfS(3GR z{p4`A=H;d+FR74-ZHQf7MVaB$%zO((VyAMT(L6PU6%q|>xNV}%SV$@%5?;Jto0HY`T;tI0u z{+`)}l}kdQCmd2YzZj`^Q@sH|8cdq2(;|9|F8b9C9s#pE9VJB(rQ;=|ysrp94<9+Z z%00F%c)l|Pz!kw_)G2V&rc*Y#H@?n(XAC3i)yv>5DtG|G=Ya!4rXVeeHCXLd?c-o+ zybJ@^s<}c&bDGu(VXH60eh7gc`L~K>W4Yt<59VB?HPFrz?4O-*PD@NG9Eq+LXr2z( zH;$uYF(l$$b>6L+b&EiO!KZTtvRmkSUAm?fA~KBS#)~$Asrm|~tDmsFaYf&4-&|3J zK`siaWpVVta@OconOsE9C~a*2+{P3M=- zwDYyc0-h<;y2Xte&whA-mL_l#2)+SR7ZwdFW0UDwFSCO>+^679))@3&oD3jY*^Z&Q zCb7ox&02>_to)+8)#aIz>x4Jqp{3yM7E3-_^Wg57$7P4ImMEa2C5tWNc5FRL2 z@3CV5np9j_IT?PT;5U6)VF#dcl@=oAiCWAJvwBAyc%k$ZN_9JeB38Dns+*PNqo004#z%&(%t7Y}v>nWC@a5y)3^iw>u zfMI^F?6o&~Ulc?o$kM{6&~h3Ip1yOy>bNW}1RP#RwSs?O!o11aAxEI&Vb#rlok+fis-43nE&x)e`38bEyB6s<2v!9mzvQ%u7|U5{5kw>foF6gdwF4n)DiH z41L&RK(Zco^r)v5 zA@$5y3HYilTy}b=?S8nFIe}?4t;^}*!PYfe*B^YMq{VzOAchcE6EZlYNXER&fs|RB zBo%uARjOqB9U&H*qsTs40`SKb!|zZ%(K^UUMgDGnQ}sae^y3thoh`ApCvpHL zP-2m*5FvfQc!G?1YOs4y!n+Upd1#!I)4SZBGqkjo0_{80PkBz-glpS0s%LnjR=13p z<+l#)*EvHU>MB3msLfABS!?ge40_`oh-xg5@DOx0Sl-|bWsd6gnSjEDhD3fma7&a=MS*64_%vF<7tYRT=lD8 z*YQzxs1RP4(c;YXbG*QLSzmdxX#M{1t!aV>ml;gE+ASgAugrBQ)CtL@ER0bjL5DzN_G_r}5+*kZ)p0d(}t! z#4RD|RW~%e$~5=(+GxJn+@V4d%HNR*LCcu?e5y)vZp(kD$`}x?`ZI*~0`AVKM4Tf! z7X<^rZ&vt7CD#C`6<3MONiuN8seJ9p0=$A_msz%QU;jL)e4U1RKWU=)qx+cE@XJ9p zKH!nY+j_22PVzgQW;Pnkqlmz3AEx&K@dCs*ckv)=-S7{P!G;{zoP}05KKa zV=%ch+8A^s?0ejiqxa!*aZ#EVRJ?sOwGmiU`C>FFVb}?c8>filar%!t_f1&#<0&h}-tZ{%dv6`gt;G|i^ ztB_smh$ojY&k`*Bl`YkR`wf?NzNB^1u|Xm`emOX3;!O*#9|1j2yAp8Em9yw&CCm&W7_Qp_l; zv&!;%93ghp#mNpadL0r1mRLD)ku-Td!h405h+d5OI8;Zr?){Tdqq3_Wp)hP z(GNeYwiiX4sEn?&4HcACcAW7<2N0%G!@QR@rf{=^~Y#;7;~`_hOH88MAxit-B&0 zlL11CTaELvy0TwLWr%+DywLk%l?5qajy^~AR|J`arUW|$qICg0jljl-k$Sj0AEL%( zE6<5e*&Crvj}Mfbs^Xog6!7vwOW21;uioKoTwymd%M+ly-up;HODbi}g1LuH@t_r- zh&;Tx2N3!G9xOq#ypQn|6zs&=Id~g^1r(328;g3ui=joYK-B7%GDql){DE+ugr^(07@RfO- zRu}!BO|HL^nl{ydJ!Q#$Yg^B{fbo9eSekz&@xRFnO3F*P)*lcb8RDb{BQG=B*h zqyQ-ffe4qla$*HZ7pcAS`Vwx;NX`2q8TP*=)@r;lE0pYNcnf63v&Ir(A5@o{n%x8M z$$!mM=LPZq+zlDP)thIRFGq+!Axhy{kjPiNtMp1fEs7^EUf&g3c~xt(0Hh@-I2ayE z35HIvwwDp^lO;MpS_p#qj96}o42LFVLBe%1z@iTv@g7QEJf-_z#D(Qc2EXCw=`Jt4 zXBWl#kfoE#S!#X=(*_`LVS5if95KgSD)6}B;^iaLmYFTgD1Bv0=`dM z*u))|xA?U)MBu^AUmX*}xXLNm-qDB(AflmMbLokO@Wssa@)&R!Jfze_e`5p7;=f;K zUI60@OvN$=I|OCsA$Zwe{Wqftf8Fb^I1Tg zR_Bcz{Dm3>eoQ5Jo7`}{bu!J>3jv$h$rC& zv=@u3`g21o4jd1bTIG5-D6pc$S??2eslf+;z!2v%ss#cWg`kcR*z_YOA}^r-4|0=upXY@q<<@Cv6m|3XwP=jZtF z74BoGr^-0)t(%`3zw@mdAcnuK&Fo-Evs|AVAI%L~+@g2uoe>j8lgT=jgC2#2y-{}@ z{$21K9Ni3q0(Z$;8&G8P2ce9k;?kPPvo>lK+@F~`CsfZY;{EESyw%JJH1eF>{Pfef znig(&skY0(JFwT&B%Uf{8lWPIf8&3%aKrSBYB>P~!+B&=s1}=9a(yIF9gIP4duhHV zh6p`>l^s@^tjL}(&k=L7g1sm}B${d%Q3qMxj2uopA)?@Pmd)-cvz-sOa7aA8B^4eb zp-KUz?3BU^(F8}#zqlE*`m~)>HVUCdI-#1nUN|#lC z7Rw1lRl&>dO(nnmorvM+@uBWHbn<~2Kxt-|hCO~GGn}Kh&mh=8QU8p{oJDU*Af{gO z6KmMQ$MwgHnqtTEaH`K%D-f^ThBm4|!!H3o=~&&++o39!gE^LMzK7+~L_uGAOd zbz{}6f4 zC!%fjD9=Zq{BqBzp-h&=*7F2Fr}t9TeppGC>CNq9iWLWhtEt3V5p)$LRAK<%(&3Yn z>sFU9yX?^+Rx}0C*(neu4@479tI%}9xW3w!r41=#@)HLnqQ9n7mVk+tB~Mc$Z*o5Z zH7a#m>Pkp}=SNz1yLYxp%%hdu(|JTe>~j6gMnow7Jc?v0E_q;#(!+y_`}MK6Q;#tD z)_Amd@Ik8}nJ&J>Y|l4Jn}QbWKI(mFav&ENr<;=~|0983 z3BdrcGoZ~$%ub+Bi_L_q5Udy*s95Cvcp@+QOWT&VcXvTSeF=-O03(O@XV0|0-<9gC zI$#wh{T7hVJ)=28p!PQrWvgl?xe?m^y}e`;c!O57@m*gq}wN~&qXId3aUg4byDtcU?K>O)9F z1LD0_8aI>pHRfx z(?2E^l|9Y00Nlyh=hmYZB@SK&?)-s%p)`h(Ni$kK+OL2OJ0%BLPznj%q2JB$p>c3Z zs=PDY){Xv9Ab_EdJcSRR%N%y6 zHf22#-wVXmbWTg2zcnm&bTE7tCPxF5aiiohq99bEV(}o;S{02AqG7KF7aMpJILQSA zbYTDj!n7n#>Ltx2ri|v9T>Pj2Z6UwVrL!POV<$QfN1T`bA+}M0vxyUGdHXJGC9FVO zr35b)Kz)wTGx-PP{-bE%lP?i_M7;P1Oj>_geQVe}VsbDjiHRJ1%#dm5Lf?^0tA=b4&SL=obNvX1NFmBg)h)01Fgl@rpumvWpnA)8BQ?5 zWOTJM%8cvAwaJ^NPYzkOrv8ul;_Qux3@}1Lq}uQ-{L!hN`yl*ZOz9gDEw8Dx#zdo) z?>_@X?6Sgp=m|D$yg-mWMK7*NM2q))aL5|KYq?0nga^RT1OA%U2=+}K^lm5i>2T_K zbwT;R#8#I{`$RJ6vrB}n6UZ5YB(17dhW~hIgn~ZhVC1RnH|+C@m!*Y?CWH^3ThsBo zCk z>6*pd_X(6x^3jT)B&k%A)?t&l)nKiuHn0P8N_Wb>x}@Pt@Wa^ zgM{0-nS&bJQ1*8LzMj*Ren0LBDBOcg%PpU?lntlAR8r%d03B%=9zmdq{(|P*7Q9Jjc1sMH(vvW&K{Lai=n!D^kTH5m#nC0jnu3oi5 z8hdqjRZD$BiPogR0c1$aZs${a8S9_|6Yst;gux&zESIc|!T~+u2z(DXEf8Kp_JDSx z*Rge?=SG-fAwT^BU(HNhj+mnyYC{2pxc7%rCD2wj^QgQPQftJyZ) zQ>1@ng|g~y@vsO5K0>=gD|zW)vleX|GV0r4$nIUhBXAL2I;JwK5vL$;<@j+CZMg;Z z>&0&R%*St+ba*XBJl%v?saJ0-98|!3u*g}`v(yIN-n78&jStfr%BwqE$P#Q^2nXvDqlx;HawDCW4>d}5eU3a@XY@ERCPrU%B_gCw`H}7tKzSo%0iI_rO_99if z?)+pnd{BjUBEw>1Tn+*_Kw+^nEi9q({X&3TQf!z-JlYA)$6A*Wf?3gx-3N zg5y#S0FI{2aj8|wNuHwUrkHM}?xtPG%g8Y!@sTQY+(Nk`lpxTk#lUHlq$GGL((1Ba z@ghNcB4zPy{>qxcTtZ7P1)#>=8#Qb?h5*>FdQnnFS5j$YKdWvff18lUH3ipk zDYzQrXBF>359jJkuAah`>K@1kff&TdfyiX#vn4?rcqoEXig@IZ^}_MR`;(S9Dd@{7 z=3NQl?bJ`w%}HSz=K7OKF%k9phKg8q4Cl#eWL;#T_x=V3+cb>iXUb4}@2zfZXB*WAQ5A+6k*})nFy= zfZU}g`}hG;noUo(Mcg^Q@6&4Og+w3@57MfWM7gxGf`a zWLB~E-IL~lf1`B-;_^=z7(;4(SmbH%ZgQ71AmaeDbjF+s;pLYV{~!JUNOYDP5)$UC zm5OfJ*!X7r>ZHbqOQXcgoWDD2(XjD_)v>-i2~TJ}r`enQ>;0D<`} zR*KK=j64*}r8QtpLY6}zJ@#H6m*&UQ@*tJb(YvgddX5pc2XG+Q)loCg8l=RfGH zz~@*0I7aj2vh!fDUX|3PlQ#0MO@S`wTKCF}E3!(!RXb5~od5Yd{qD!sFj6>i4{-su zuEg7_ga#g;g+ESzsyaWjmz~qMoTorJsYc`f*z~xVUl_i{= zmkNNqkS6U^Wm`EzB`3dmK~5p=IkWZVc(IFTP`!D%3%Lopp%`ZOZA?a>eynkHmU%Gq zM9ruS5OiaBr8D@N5O}+hwTwfwlIcp@Z zN!39OaBF%X1*Y9WS>1!D907m5C9Db0FW2;B9fY_q;iW>4?>SKdTbqqhF>Kg&+~X~+ zp6QH9<^c?LKsXc@f=1;qU&Uzk=?O@Lo_jWk5qx`O^R&0wpPg%wDBA0GD+wvbA?*7T zg%|Z^cUsyzMAFgP=7}lJ&7%fn>T0m4<8Sahb&eIUSd{311toJqdkOCtWrd54T=8M* z=I&Lx#nc@NN)|sE1g36459dkWL7)I#+EGeU>7NOa=Uq}m_*SzNsJ_?GevBKTL8Q|yIY(+9D zwq0N4R&Gl=FVkVEzw>(W&qCC0aOIV}K7jVa(O%9xeIsz*T~j@;Sn9nfSz{}H6ee-1 z6f7czZKv#~WpgHsg$*){R8Dfihkj{CUX|nqe!;k^)8o0dtwmEMQqblNh^78r{&~)kk`O4s3jKu6qVHGg~8Blm^ErRC;>Eup1D(@9TKsh|CO2^yA&ML@# z46Ia|2kjkjvEgfXPs0AX!Na*|zU?(J3z13gwz9jw>%joLTYDu{)k}z_yka3X!7M)- zag!#ISy68&EVy!iB+t{N7EVs2hKF9E%<}&d_Q&CcwyIVh?(xh$?abkm*WL$IJs{B* zSGC$@kcw>Vc|L@uyXXE{sWVM!3aEO97fKw{c+~J*wnG478IZ5Y0TJdJscWIKLBB3R zH|W<5;&4Che@^pqRtVvEVvwk)^7!0%l-mjUyf72{3sbun6FjvWBp9padoDj9k*V zw~tK`3{N!zGQTv@N!qrJFWjb8dssS*YUq9azx`9s>AX7V%}nVwTOD#LfpYofn0V!6 zx|1Uosf74Z&F!D+TCD*_YryB>qFaf^`WV|_VC9r^yZ7OOfUU$)oJFjQnd<=U>Ce z7NRjKkkPSSf-)a$7~@;0idH6}zbZDV?cu@@S{(z{OQ;NK|KK&s@?HM?&tit}fK($e z)WK5nJHi92LZ%AZHe|{|uVcaajnbVru$N$MzJS(AIJ&W;tV)0VA;Lox>+YFX!O*NZ zYEY;@4R0IlA`fN(+zBw)Pztai-eIp$3V|3}f*ZqcC`l2YMT!XWSCxkX*8$WLwH%x$&lMO$7fnd;94ez##2v{hs?!tFq~FPMxkbZ8>@Cj0e*? znwdo}mQiy8vPbrZm{_>aPEy~$nD5_PdT|=2_=*iq^zLe%{DzGl(}Xif`^w_INWqj| zNp^F_ef-&5r0<*T6KByA0b5H!U80zQ@LqwOH2+LXbaPCxH7hT`6g#HuLW{o0ru{^M z!WXv;waoeNXK@pcK|DXaGS{8OyukXp`|W zis2GBcho{bPuS1+kF&-4HZv(;tFPJ_dPqCytplpffzB$X+q0|e#q0hM&~F3rLE*$g zpVG7-OFfv4Hy9C?pX%bAH0~f!peMGvq=zc* z*UG$$6(Pkcd8JJd(ZQ&!cZd85T$jjBz!tUVcPDU;2z*(T-f?<}RprZD`-I%6KtGDm zow!Ki;!G^9B@s~M+V0H^EL6#M|7*ZC&sfOsK*7V>%1D{e@Z7lZJvSr**b=bwY~|p} zr2kbLOvtG4n+w7y%T^-B#$2A5uVU30XHD8OzsF}?{>JhL#$ktq@TEPCwopk`CNsvG zX~=0;s`R#?Nxk_8Za424y^x8NzjOsPcu=!Q?{^?w=eBrPaR=HMq=)w;mPE|$6r1ma zZBxvZi`E>I1|slWzNQbv<$^#B#V<^he-~X#r==LEKck8C*DJcax(W;~Md?)sr)gYp z^XHv?kerg-ex_;W6mqQ1Nlr zxaKY8M32>jlmZ@0@ZYKL-6iwJw@>#j>TJjoV0CkjFLBV2^F}=5>G33i!B0a$=MzJz^g@J{f^@-S%lnvaq;? zdN5N572G4+TUvJAuVsTD1RE99qIoPTfxlJXUQTh>q5f9%8zM(@szryueZ8I3mV~!; z(e;O&sh}RNg)clCyT*o7k=}T~oZ9w8uSu%e6jHW4GqE(3sdE4dtrs%NMGNqUpWjj8!*pU~R%m z-OI6wxeszk4_{PItviVR=@t2_W&d}z;nP2!U#;P?d!N9Rge2Xev@MPRg4*I_cW1=; z7D``*gGkM_{~4YgDgX?Y3dZ8`MEZKdcC#IE*!A7jQ(`C_I6J39JAgc z#YcV*o6rF2`%5Ge*_gkj@m!EUxCJ*EU|vm&3Yb-`J>S?PoNHMRC!2w=oGJgbAVC;w>zFbeuXQgr10J!tCp z%3#2BEQNMud-b8lB@?oaf`$ryakP#BTq*K;Y8`=1=^573m#ayjNl)b;4mi=c<{!fG z8Hfrhzq_$$!kQRd9@O7sWis3|)mf{5mxrM=+Ujw*`QNL2LAfeRGiw<-CTFdC#fd8| zWYi~JR90aop~bi%RUg0j#6{N&wYPIa>03E-mu7bf#Sq-HLbfhmkN^T(fris|S)%`h z3dtrSwUhtLFgCJ&+=>ypnpslqs&ejDya)f5HWoWBQHBCUfs>j=F&hR-IH3Uq+I zVz7zCizV|us_h;|x40rkz=GE!5- zB7<^IyCJOK#w08>rU9}KXgp04r)_H}k<0w``}Tb0Y|cq_1!DSq0Qxe1qwLJupK7-C zg=LSnLr>#$*vk0z)V~Lo_uFe@MJ0|2GMgSmCz6}(c#A}{e`8q)7#-4F?LUKt6k5`& z$9?ps6FUM%K(ZM6)=N#1@<${P4vIl#Ij zstGrh_nlxalA~;KR-IG5sqQkGBAz>oT+x@z^oXQ#yCknmN4pfE4V zwb5cWeE0U%u87||GszM0raW&+yI||qdCF7##*3du+_BE61#!d%=ER3?OlvGHehW-+$u(6Vb^#^iD~n;PluzdZ zdoH011a`T$i(pcStutD`Pj-0yr@-@Q1?C#YvhI0s9su!RphHM!_>d} z2IoW)fey~7i~NLsYxOGUh#Z=<%$xAsZan`x-_M>}+i^x8mksQREB@-4b2ib{gt z&84WF^q+m!_Coxs)Y^sIpO)cZRD?Q;$>|B<&jX8TMYGQ%p`l0tcjJLCXDw;49C`G& zRA0qFS_;1bawi3^h^?u$>Y~pH#i)$`Uk#c1(fBhc!llJ%{=;KB%oVVMA4sYS5V>kb81ZxJO$*DebD$aIUj2+C>wt{Jb>!niENct2Ui@a> z88aU4j@@b5%B#X`usnQnRA(TRbzC@JK}NQ<_6ap;oog|7A07%bM>xAt#M~S;mXhYe z&0J@cB(@&53>&Ma8QHx-?)Ai7W&y_!7F^RKeOQ8UN^vBka-{(a9Ffe*eaQocwk}zE zrnFIm)JpGkmu@=V=@O8HQumZYSO=Uuq08MoP4Fx4S$wdUU#DCSk<1X*-!pkAG)#Ds zg>qJRyjrC2zHtyRW*P+9WUrE~Vh7pu*Ir=Ycq4C<9EOw|D_;rPX5HB$0juRHsbP39 z{GeFu!U0YGHy;Qo`={Lr@CEad0>0qv7{C{7T61&udVMk1tz-08+|iV6^!l#y(?edx zCUA`{tX!vU4-IlL46K)$p>N9-}C=V9UAn|E9WRM7C)dVAE7n}RtL2>LCXNv=tsfKl(TJD;q4nInX?Tcm^Dx%BML#Q&KkTzIh6?&2U zgfK*CKICSh+iNz}6XDei0AR8l2r??&Wp5rbCFmcz}Z)t}*}HNQz2*Nj+>B z+PsG6hfJz#ZNo_|g1<^>LAEbp8>1Jni-VK-I7bxduV5zo;4h57h6_k_)>F#dnPU#M5q+1XKBqgQ0 z8>B(HySuyLTbuj&j`ufzHpkxAy4DO`3ME)zryzP}2tnmC@AX#Mj7ss>Y zrVg=qf{6{o?t;TNOxuTY0@jXQS z;4Ie>?wh;f!!$0kA)f3sq3Sl-3m#=H=U`rJ*lpvfVsw#9vdmDBz9VK zIbI=Fh2%9kozG7L#xke#SaAiK3biA~n!NJyaARxLmlq3AFU)in3Bm=-*3>>P_W2h! z^IJM>P4;fiWRy?50@je7WDSH*^7PJWk( zv(wCk)o{!^DG7Ex-L@OsIL|;nEL;qy#8|*be^f)nND~EAS1k()|kmd{z)T% zoOTgT8G0zfV*%Zsiao|`OWpiu8!I|Qttbktv>Zk(I;k2kNqz&b-mEFyOA!i)OJ2=I z>s@0}n+-mWbD}ixdiO%2_hdXiVANr@>2MAA05@G`O5Lq! z{$H-U$P58KMh$+zfbEiyjld7QGszSru4m^j)iL0;ZkR*3Jk%-jS3WRJsR_-Bl}L2;R^fMSYq zrr~}UsMR2^!IovL!!L^EJ`MsI5}{-q{N>7A`ecMZwZ=c46?Yt`usqi}i9v87Nv2s^ z!~qpHpYv27;7EM+sjCYrSPIQIBJV2eWHycAzW9v{dKdVOh;Brw`iy!kg?rY5-N|w- zt9vg_h{L#TRM`O@`NafhQ%8AqAf3@)R0;2~HPt&PbnMv8;~W zry|}VGqZyOD~5c&ZId2oOOBQWvA_KDeM71Z%EXFe|J*>QT1c>>*aN;wB!`2@kpmoo z?JznPzz3wOkF-I~)w#~HcXN<)^`N!6Cj5YNAj6_1xk}U~q+}Wxbf&BkKKpI;nA)sjZ3}E)E(c3xq9Xf#7S{B*upMGm};3rE8p*xYiKec{MZ225XIGiiknd8#s%?dLs zXDALrRqK3v;`Elxm)IQkK*WFIEk?HHP}*VC@3CQ@)&4B->31d_#ERK%`}@;0T*Sw% zoAz+2LTe1v`cK=DL>SbP6s&IE^JO|^;g*?NXVrQ~K=4?z;w2U7*PH1d zub^+Js!ob(Gmcj`W~3fQ_rGO}l((r6HhjEdgmKDX+o_fH*!Jujtvj+I=ZVr`boH;ty$@WFx1Ins z_D;3{2I1K7gCDqyoKp*%e@$oH{8w<)6?P9sc86Kies4h3b;G~5BMO0Yat(@9V?mFr zE*mq(lvk%#t}s=%{JKP3h!)FCx&3a`ih^Ah+#TOH4yXCE?icyupt$x!m5h;c2Xt$z zMNHwXdnQu2DH;H9v9?i(xkpaO8klM~*o%#PWEmEJ9_(1Q#ofo^%gtty{)s|O^4Dp~ zwF{sI0E+jIR0HS`A}Z^v~g1C)t(~% zx2~ykMSxZhB>q)!9LrG`*I&rG5rUu1aSQZ39~K+s?V!LVGa3xz>HL)SNJ z=B~DB3Uid;-e$Tk0@%@bs0e?i{yaPWNenni$b(~MfKFgnq&r|xELl2Y$#Rmq# zu=%h2^sA5-0Fd~H@VPw&1tNsYqRc8&m%r#!2-4&c_LXtST7K}jVLXh64+sX<>$jjQ zxNT+jbMPRfPsMiF|78guRbz^$4KBvwxnNL^uRkr>>O-}Qc2VU8UMEeEZ<|O(D9YR0 z7+{gUmI6#A`qEtN?K`pC)qAdfqKV)mBK77}jx9$bgbn;BcWv0~x=eeViOC&Y0uigP zEgq!;A-V9(HYdt1>w}DSlqqiTwYQDJf65T!=R{7z zb_{T|$z?0x4HMO^YO>J#M$0n2r*=9ufX-dAx|c-0q5CT&>Yg% z^~#sZSTd4tMCC&*`$*4_c>O;)TrbeJkP>$KWAdl$N=`{0IlUN!Jm1n=Ytb%sy7wd( z6QoQ^lz@r)JR`3zu$^>^s{hP2hF7o$2nOVt@g;iv9#slU?N_1I^x=kgobI#5=1%BO z|6@Y6xBSqaJs-Gg$4|Vg34Q}jh(3Jewes{iVODcUJltm9_8-C6#~B&eNSBCDc>oFM zPa@a3zwm~1l19v6{tjXf7ZMa+{qAAcf{Q8&_nsQ{bZVXMq11J;O}Ia6f*nntUHvCm z6Yj&8or>~6W$!?RnyJ;{N7S;Oe@XrWaK}|xaLBl4zb||;h!_rY(*!8|p=0dfav;ge zW!(3Ez8vG4ZEw<&oE3EGcgEiw68?O>*S%7e2g^&-d)LtB!5?%XsOn+TUY-}nrM3w~ z?@>(Ap;R+gG(WEqJooWZ(=^?Ac0xp;dI+o+crXrxZSUS8{*Xoj9%~jygXZ_z&~Guz zXK_E1vUA&{ruv|UO^m5`DB{&ny|p~pJH~blP&5$!D;{tk7?OQn5+9`dI!_jXgw#yG zBqWRBBXw1Inh950t6M7lo~}4dTq_2%I0|9uM$|T>ml5F(26h_v9Pv(rqNN_c(xkQ= zQ$Y%uW2+`ZvYN@}@4@&@G!L7(!1|u~?)po|4$t57vO`}wGme5w7gE;;NcK z`@ejD+O)~R2FAe;UR9he8y#vdgTkLn!n1N1@azT*!bkN5{z*1SC);erd*@vK@|run zNTvF1%;__12x0*D>_@Umc4FO9o|**8S}Ycj_kt*pVI{a$2j= z0)Ycm@b(D{r?H6>&p|lESPUgx8>C9#a@GIc(mqQI zny8v1(>@?5VcuC|zpp`|E6QMhu*iAe__LJ9Y?(}4-E%@h<*dQa4ezeY$wy2%2DLkY zhE@r)Zr7k_@>lA2EtUaIe)TW$0FhO7#^fsd^m%;!bn6&bYFIZwYyp^$B+t0rd z@PEn{m$sfi2_|`nNA`E9ExirtQ3~pdU)3uIc2;$C${*@*Gp^5jvShlQ zy^;-(5?|~Kb64%hJ(Ddk`W{=hO4YlgTp=--^}S56-uF?|t3pDxkNW1&-{B{=TC zaX{~e)&Q+zaAHcojE?=-lu2&uV#Ho#ll+1URfoQK;wPoj_|l}h)7ww-vD6R_CPA`L zXh0yDk;$&T>g$@(VBMk3tG#m6r)&Nv+bYz$y#|O?qcO&JN<$A*2@6y1?IV5`<{=bS z{_Ug^7V{g4YwHO-OyQ#DKP|C_6}*{MPE5kqD1I04rrYGTHk>;R6Mo9hrUaz;Ck}}m z%#jaCAJdViN)H(Y3RueVwFAPC0k`W%o($=#iDP;+_uPAz8g|n0(NFKRuTh1UC^Xw02IP|0+V2JOxj= z^XZXFB+Q9^r9i#>waDmPV_^T}ux#1@ew0REBLmoNhQ+6ma0&>XO-|tjA3LPV-%;JU) zgyb$8`@W8(;nIiX78$nhd@;i53sKnrND@;FJ&h&J$#Q|^?Lt+*^O9Mf%12U*>2lnz zx2FG9Lxi{104|>uCkZ@?IsB#V=TcN&y+tdD!^6xS6~6+pWhw$e#t1@^x>dcbE(JJW z74t9DZQ|E9KPye8jzkU(85RRr~ zAH#VyBlPf!JcI<#vMPE>LYW$n;u+zPiG%+k^~ma}Bg~ioz2o@u4sqe3k#lGKaI4Aj zHhOW0>|*0UcZskP>dtw(A>Z#&7sL<#3Mg4WUP!Ax(jVPtBgg)xCmQW!R{vQoUsPT| znX}LNZa&R6d}JC`dCE?3>nNkBdddz!=-|Z{UKLic*WGw_KRdj5m)9a;B>p6kiw^?m z*}8GY>BbigKHM=USOBUB?5;_~ck4s>e!0raBGrR9EH^^&CnGj)UQN2kJhrj_lN*zD z#ZCdREbQB}fk~O;!KJNqvt@JUgZ5NpBBI@EFi4)H-R6ffepd=tZ?9~}=a-AH=vN>; zv)H{|VNfWr5u#VZvzfqAnR&yW_7#d%Eocz21lny(DxPv|W+|fKv$FIY3VT$QBI8#U z^9p7w`E=0|(B;-`yj(XI&k#xnMZqLR%oXzdbIaULmGG&X()4i^d%%5~FiUWq8+Z#* zoMt)g!4-B!I;ql`m=PF?i<0&q5O#J!8|0ws($Y8>%f-O(hhKQRI4$6ORJ_#evzUgQ z8GQ8tHOL09VPp{irB+_jr?Z*9qQ3jcQjA|Pw5rHl_8PK+iJ~M*S1?s2@9MBbyFab; z@=7FH1J>{US&0xe)cKmv5?VzV?~>KFU6e-?HG;v?@yEohO~bARACeH>{@S!3U_quig16AW(F}!UV_-71Jlt)BR|beyY4{$W^rD`^yDXm65hY<_m%nz}-q>c4;tAtW>g3 zu2q7%a61kCSWN`;Cai*7JQB3_*ogOpyON@#Oe=8}C)l1xBCpPQt0H~KU`6`yK}BV^Q=!J1E9qAeVIR0~zZG(kR@BXR zSYouJjyP@^otWjN#HmF`p?Ha~G(LJ2B1s#RZpH0fbuQ-oj+@*vTXC^;@Ez*uy>?ua zOwgMB!h~u+gP^2FumFbEcWr6~28(=|5Lnd)=yAe>ZRU%QZO(W!ZX-?>al6 zRVMdY4#SKRDA>QbCB}&L4^XITqpaipB)rE&?N&2f{+N=@+_kaQ`gDC%>ul-arv=Nbc4c`;)El zjw&deJ?!%#f7<=vUN7UYWpkc^(u6P-B9bHUMvP%vh|klQn=iZQQQg-;c`+9M7l;Vg zOM$(a-OtH8{fF&rA{85fpAcvcS<=ttchdHtAtYZS`&fX^AMdyqXFE&jI__YH#zZRB zbYEDBV%}lD1MUo-$kxLzk2VC@YQ{H$QgK=2;`MzfF4W>HeyaCD$Zv-(P;>=qV|Tynq4i%kpxUkFwnE1vOSF*_P^3 zM~n9AvN&Y}K95bZ69jp}K{b{PBmM9z2I{Y$r97LJXu#hK2AD{@Z(?N?j{II!xqaepZ?d<2w z!sH%)jyjH(YI_8d@7Jp2!N54I4vfR(nmL-CTI77X>McF5s!>S**WLnt z8tppt#=eze9lBD)r|0dOUN{fxi}1uzD1e01^C!WMv^gWly7l~R@NAOLkK$I1gDT1s zgh4J?(G9sDDo6NuE(H1=EZA7YS$+^vX62B^y~`DIdEzu1ba^MCv9{yp?@r*hlRsCd zq>d_w$CzsP3c;ddN+Qgbq=Vu=%6{{7YZ30%=A^rIL;Pu^j%mi6pCiO-@p4x$+QEr! zAg)*N=ctL+Ee_}wf#td(Na?UvwKM^{5#^%g1(D0BBDUhB4=f!GgRGm-^B`o%?juj)?YG2d#~VQ>hRW@ZcvP~4$I+~>73{K)>7+Dul}N$^%qXYaEpyVmbGgNk zisq<5Y~X@TrYY&)FpO5woE*S>2&kbY~zT>wVCNkn8MIQ^s9I5atRv9Zi$o!R>L8m^Gg{<{Vsi0#kEy8mw*e8Z0I>Win?r{QVO>jM@4NxAK9LIG#}f^209R9R#AFkQfg0i!n9M0rZXTplxQ2gq zM+UIj$mzZiOT~*c>oXTvm0Y_bQ-vWz;AQ1T=FzL&YxwwKw(rM^KLHK zT7fmb2+t=g|FYXlTC6k#K_OyGA(ak3gtvp7+^8&x7C9#*Ke@`}S86e=IqhWeQ&aRy zlhIVwR&ax)zfuaBbk`>PZ?$i3Bc$2Za?+GOMyF);25D{?TwF;w{Ti+-5b|l=EVK#C zEYM+LXGM*NM4{(AmI@83At0HCy)E^`&k+MTWMAjn__$P+)Xz5VX+KW{+l7WBE7WM5 zJy4!sdNWIP0GX56-%yz?ZkV`Z7Cs;p^!~`>PAc8k6sjpOt=?l{AS?BmU zGIKmX=Ryh#76V|0g$iepENY-^3L^B=8og205Z|c~LBbFN;bLzh6B5{d^=jrN#n7&w-xhfiC$1o6q@5Vr23d0^{8NDib?0uJft6 z9zhl2jBxoH%C?HvZB(A?Uys!7sIXF?M(Qni9!pj+b(IbG9#}X2p)HtP$N5;^cN?!+ByRMfMZy>~yjrMEcYkYc{612MpE$~;e!9|8I#ll44+*F_S1T0H6h@pc@fTT%1{}0_zOEmyr0C8mlJp+4RkCQ>_JW>!!QpQ zjv+ZsQ`QmEbS324gDNv`udmAm>mM+p(`rt>*iTuqPL``!uRdBXq}abca3>*ATzjz5h6TyXvS4ei z4qt9Hb$j$1uj%OoP@587)+Zh>Q2`aB1HBm$CzOB$#AYrvf0FMwg5*9_5{2Z07fwgL z6=BvQz{AT@IF_i8ga+-Tr=1=d440l?pmP=uwMdg(t8z<1*D^*!_$@>uFBaysliOW= zk{#!*vdFsb85I!p`^=!;7+Il?cGAV>Sx z_zk%;*ePdi4>2G*$L@38U}$GA@stmw@H7=!2Anl$WAvs1ItjOyx$XUYU0w8WVA&pt_r~$fI zL9#R{c9_{0P+8@_vg^*eHFGF)yPzC2mu4|=+w|UYj0HKsf1Z`?FysvVt2Q&7QHNP? zT`cglYlinPn|-*3raXd$mIhL>LNqy3Q89>li#&8thvz8_prHK^mT+()-4IocIQRoB z!B4=BNGHa-k4x91ul$-=Y8{5``s|;hh3M5*28%03TVio6`aMGLfrm=)CxGXnK`P&k zYOi<>9nPG&G$A%RM`LPR7ZD%5T`lq(LCh-_LxJY{LZ8$EKSV7}T-3czpacu`eunKoWX5=$ z7~Ftu+P2^nUSsLJ(go_{W|x@Q;TKgngs}2<+k?_u3Hd+uFJa`#8UWBdXP#l3p|8r4 zJaLobSH7}#Z=E;7AZC?_*6sV>3w)(z&7f@#|H2u4`Dx0AZLaI}(SMW=!3IG2SbEih zbCC`h(t@YAvQgSPmQ?D=Jfq4>7S?IoPl2|jwu$|)Obc` z1FUtNgAFCf)B4Sb^+gq8YU3}CJqJ|Kn1e=HKHZ7MC4H^GUb1kw7vt8)?nV?Y!eJHo z7T;?CB(Z)^FP%?#wMVhWFi?JMiz?a&*30$ouMM=v+ko9BwLWKtA#O4P;*CXs|E3nl zR`RJbwYWw-VD4Z3M8J_N=vS&L@`HNWB#a)aY`56TPk+NPfTVh>D(R==4j0iuJ8-?A z+Q%+mh<2(&I*wJCvNbT~0RH52)UH<$bm6~Qv0;Du5X%G860tr;RS^6;n2S^I?DU`q$vfCl>1-CC8 zQ~+=wdRuh}UOZR+W0#LDI-{4hf(x>@i7Y)ccg#S4?UFW%kR|1 zPcQ#io;;m)G}+wThlH9`(TTA8U)jKmR@xK=W)fn_e`f9~gZUW9{{6CzKq?E8+VNyl znc0ATLxVyW769V7s~4D$3k6?h2we^0e|L4mFsTr1O5Nh?{c(-^6PEG2jdKX6N`~=d z4cItN%g6b{G>e4wl_GTFE18&vCA|jo%(6q~=-+j&jyibV#Wpr0HAtr1i?);kBWGo% zYW4Yj0I7eQ3dK!?k`rh*3Xr``E#E1(k;m#D;$Vqo-eij)Jv0S7k}9wxG2ejfNDh_C zO?lLxxO&+IX7mbT?&8?4TFm5^SfO`jXV{s?qs9E zwe9rU_KNO3nJ<)gkL9=hH_uYBwf_3ZTlgRcVV-cRn0!@R$R6Z{7lUEc{LXrZeNF@+ zjy6Tu`VcAZKdU0$A08p!>86H@OqC07Q`u>ot-W`!TAN zlM45|A`DUkgcz)qU7kHWswi&AUWsnM_!ulKYfggqrYu#wI+nsld;f zp|`FV^Nv+mO%;U#BWR16Tx9U-xHnEedezBzsr zoSw1_`4#`p{TA|Ej1cn4lyt`^Yryx9y^6-*UWs>;z1PzoYE>ebN2S```!&?~+ir?v z_()#q1GE9zTVDG5;m_-9R4ljNnW>42dNbsEe!nKn>wocaT%A>&i6zpg+RWbgnB{zu z0gc(WH_ZOR;937pkj^u51DWj(ToLj{b!_rR^{zDo-J6)n;$Q1mMIb!M*en;E>jWW! zxq-gdVwO0C0E|ikf-`$uX7=YA`#Y9hI90v@PvW}C-X=Gh1USwr)LV6#NX7ld5wM97& z$G!0k!E@H*F4mD)&Mt?psmTl2QX0-hT69j0h+ou)Tc+$ze<<9LR1NsD`q*xTnS^SU zY-5`M9M+!fCllT5(8bql3TFac({E$MLrxlr&A*?3b4zDAuUtCF6g$|63Cu>!>B5RJ zS(j-H=+p;WksSR~=D&<21qA^LFnz)CWg+|?KM6Y8xUglBh;^honT!Pc2mF~>a_g6h zD(1!k=dJkxWKHA1RmW&a%`Ok*G3bWrGzHgr&CJuS>YHL~u7MtlIk_ui+4O-Jv}sTs z7sj2i`>RN)hi>($X+Bf&_EFZi=F{}Vj8$2_c7i6PJI-xbKpW}kUwyQ0N>V$QumAC( zkdg0Eb<4%Ve!EP)*1*ve(ID<%Jn7uMI^u3G4DFM{GqCcHO22)4nUOm>3z=kckZ&nt z)5k`CmRBfBW~T#r`?P&Sh7imdbf)o1aF}bau>1ibUarHMjs1&5m86@*zfCMW`vuy3 zBuRS3kq=M^d;BxYMwbC@25cWBFD&zFHhvVC?0o((Aq(<{RL(IWX@4is?KpB{)ec|A zb|g^`9exn}kqx|(vS?GoijJw^8rbg9jonC#;@w|*lofq3Xd{yHt z(x8Kgo2hgZ!HWJk%->9UefYKJa`h3Y8~K0!5E@B}(IVj1S_#)&o*9d_{jrME0Tshq z`0^Lu-i}G`Bb4>EaU-E>K53XC?Ps84Q0$mVOy~Y=Ky(HO!6I3-nKVUP$mfT3_A-_C zL%*ENyRY8h-Kc3=U%%kju^Fk@-gNrGn%6QhX(qn7WH*(;qIubLtAcW4)M=-p9k$5- z8+TV=srjuP?C@45GPzy1#IZ`&MH!^y?VIuU;Az$%eP7m^(r|@SLucUo7PlDNOqEH77@!f5NXVd~mb|kq zjC-mY3bRf|93)!s=4Qh`P~ya0$57Sjw5mmHuJus-S7T_R#;n?4gv7x$uDfFt>J^!p*GXk~IIq~2DB8kFAK1F}WDpDd;{=PaHhdX<3@0Y)z!VMhC` z0&pyMo=&R;Va(mO>|^4aJ!R?<6kKpWEyAbt)1o*NvADa4=?boB=hA$(EIH!Wj-dh} z&GFA;(1-Mz@a~Jj7Esndx8MX-HK#~_EABOC#W}^&xn(kA0o&NTU23^HN9-p6@|qH@0ByN({UuyT`GHH@c&>Og=(je zSt?MwxG)aoh4Q>nVP@kGs%rF9+dmK@A<@}@cpL*8y;8F|ln*^L`Upx5HK1F!>j-p= z%{epwSdoVTmP=uEi_9F~oTly%@b%CYmRv`wmDMi>|CC8lf{DEx;!JXn;bCL0^4S9Y zu`*V;O{o?c0{IarDa6Qr76h@{KYx=Q?v5lbkIb-Q^Y?>DMX z&+m=l*4W&woLZXps@Qxc@5Ke7lK+Re4>Xo0dr-do(5>M(&Uu=QR-bYS8@0AHK1?iom-8hs4rt z;HMGK{ZqaICy@CJNI@X*^vf+@(v+`jg+DOpGNb2lWcgK={UH)a^^>gA0TP2`4Qec{ zVRy_V_&PsnhLNStXy?Z8wQ%IH7(z4p+o8KW7rwn0?08+1aoMH%iN#&#rSt$~>+0#G zTiu0aR=vO;B@NuC$4DbFllSJFL<}L+R!1^jNIHpC^;e*qtTrVod*W|kTFSIopH~Ac z)-76EJi>%n$J?9Lc|@5AdU3U)h&#zwD&9IvRd2gM*13;e&$DEk7~X? z2sC}p@i3@kW={n0xs59Ou7!Q=SziG3L zjao0wqC5cuxQ#c|AA(^g3h?d@_33D)IZIvg4)_%rs%A#Kq6s1F{cI&eV+H2Ksdu{E%BWwbJ97}&SDw?QH%hpz!GSksR zbo`ejk~%ze90M()>ssyb!&tD#L~Wn|*0y|#Fs;VlOZ?}x6%jQzsoA0xoqF;@`9#qh zxBqW5Oe!0~B!{_O?CFWAc`C9<6X<`T=jb;)9nmGO4J|GI@)ty1^cZ@{)#-tQDya>* z0O-#Q<<}d%xCfyV@{2^4`D>Cocj>9>LG(AEE0qG}`bAN=pW1{uEIMp!_rQ%)6%(Ev zv>Mnu_2w!KN*3M64aHk*Z3=zT`0^$O>>&KR5B!8&=D`D&x-AdB-QZ)CMrQ#Vod(#X zMW((zpF|tH(6|PXa@Sw9o4ca*1Ev~E7LNXh)kd@pu}|(un$isF*KHRwZ+}ODmR|;S z|BQ#LZk(7lDYbYMvd{0Bf>y(s-}w?Xhs7T*ht7_Tt%HYExH9~|C3ko$Br zy5H){QOy$(#C4h-iIWX&8=O5Ovt_F}8Aq?7m<>Zr@oM_ycz&kN7jL1uMfF$JO^w^5X?E=!fDdE4zSLt5|W+ zeER2HRQA4JntSD>UMPvzuF zBm1*XqAKqo$M_C@RZr#&JkJA9@8)kffr27BsO?{R?y=h5O z?R^dh%z1|u(>5cg?QAbP@&6i5&9h}@1$g5*E*&5g63NtNq)vBM5BDG<&tAB?vhvcn zBOChT0=x~j36^35i0tMpp6QP5P;#tDX~;*uUCcwR^TwS)&0VE(M;fpW7CfbC8AJ1V z`$^Iw-|*AQC<-3jtpaHmIQZJ)s*fU8et>H8dLO(M?h$p!_q26`(5Bi_vrLV515rtP zo%+6;`gIt|yw=P7W_fg765KV}=}kct%5%-a{wj*Y{F8V}=8{I`-Smw6K8Th~zYLB} zEzCAm8%TEiLgYU9nd#^^x(3TIlmxZR`qjX~S|~wx&7UvBbCZKw2-fR=K`T_5#<5k- z?|gezBl+-wA+y8MJ#~%&p1vQ2yRq>wIjOVxs`G7J{f^b1 zs^J|d<$<4#wgjQtVy?F5v2D~9Aqq@~FRJ~Pt>_zF4_2xZV~c;Etw&+i`f;j)Sc!g3 z4d)c1+SOE{ee5yeTwGoA3TwFIj?*;RK$8_91WJ!bmWEcH z#kCEWw7MV*ABsLZ-H@nEZkN(1nNRs*8*z2t5Qji)q54AKkBA;&1%2hLQI-5nKDAcw zK`rZ{vuspDSE~8Ke-nfs$|W^D<`nQnS4~ml7eb%yW7jplbFv2g zt-g6^B43fkbac8QQnF3543XWINZqcc{Nl$_^r09utV=AZJ3r=1Pt*;RXFk!C3r*lz zoDfcZ^Bl!lsSYT<4%EQ%bzJWxy(G-!1s0VxVkL#K8-##j5R+dghm=hSRl8A$Pb!AS z3(QnAF;ZLY{bvPLul}MFRdC~oJmVDJT{X2V6lx!(TZOMUpt%JzQ7(Y)+T|CM#iFbwAx6 z7>y?wGc1x2F`kHSyc*Et`-BxyioDw(jdONKqdOR*g0V;AmKZReHBYR&1ji=ov-E2P zPUo-M!B6chdA(&#kp83WvZGKz%Y-`tB*-|@$weTUo#sN?%ovd zTGpN2E}^J31lszIQcVcFmzt1o?+zSL&$nKT5D9#F$9J8QGBh*9towxn)|iDjZT?QR zflTCI;mhw`snO%?=L}}a*^g+>#Kz{Qxs?6 zkn`=FKV_L9_b9-A`t#;6q5*Dt!mt(+dKB{I@%HbmR-PjI23lJ*OOB%N-=P#l1ktzh zqD;#El)Z%>_jL;p?RvlK$JEKbrU#|XT!b1bmbIJt$v_GkpW5lf;<;1!ND+K$N z%|XDcbY*#+vhB8zr36cyf@^x)TYkUNmE{7~CSB>}{*27Wv7iZ!>;Riwi4=sZa=)iw z^@a2^UmvKRUI@w@7;xwgmCKWa11n$zMN3%z37|-Q-_8~Mfc3)~KT1yE{azI-&Nwo@ zvZr6+L`}GnL}WmdMtzTye(B}MSKU4|oQhz^(668V2Fr060qbhgsoCX}LcUYA=w^BO zQ&uMNyVchJ;PWG}U(mQxT4c-k*-YttAUyD#gT5oIp6?jDGxgi6Ww?=cXcQ$Rld(+!Rxx+eB64h!w=5&T7ar7M#pO+Da=}UChdjLK7(Ho#~8zU*iRS7Iuah zV`A{jNqhv}=?rUX#erp=f_6@b3v8UueQMEUqGdy1749f@Jxz0MkjPR2{cctD>(e5& z37y(UR8hlqizE#=>z7!r;BviQCvK*WdJH<-;dNd@Sivi~D#Mgf$7^N=deZ;Q`|FLF ztM~O+8UWvMQYq{lm{`sV89Y1i;PdAj+JdX^CdJ00U#@>Il(Yl{h=}_{UT*oDX`u3gSqhmD{P8E#j|8&AN{@}=d?nRbz1|RnZ-DZU87?b6HsO4NIPHo$l)W(!`c^S)rN4^*p9@sv^Jx!-hd?s<&a95g@j zs6IY|hwePHe8wtX|A$p<)%|w93|Un^-07>gQGzioBP*Vqf2-&c`%_q{d|t4#u_*H_y(v{?yas)R(ZfTFkBkJ@2TD@ z4SUHyY+i~u?%Kecc9})R9twjei@)t-k3g!VEf{E?IbUH<5busiLh5|HQ&0JcgWBng z2_TScX_9_CT$B2?sn8?tYm;++h78t?J*~aC7n|#Q#NWC0-gA|>(-Q$4li6AW04mg| z*Sp|2aeRXPCO&m1c>7rF;n~?dmZiQhhie>!kC{*h49INnEpqI<3sv3>VKnlb}ISqwqN`co$xp+To0-KHDfKvLq zGDg&$@|nI#W{#@~;{%+E=FMu%QfFh>E0U_)Nbr9^Gb4rCCC{b>%wtvpJF0uWtKk$8 ziOfE31MRs|CJ>VMF|qsKF^Q*dZ7~;wof`qGc;LVM7h+oanbL6BLBz4;1aLU0FH_m% zh9=8cgkSr%aaR8sNZB%}jDSl}G>BAs+U@>vFjb>7Suo|4eepIinGYbqok7r)k?rEs zgBzFYWg?CF-k-g0yg*D~uX=u7-;p*8Xa_CfzN3-$>bE`a;9PocmlW{?pa0gZIh6&< zGxfU^=(-mBWdlFQsad9caIF%}{S4`gxcNsJTVj6RNoJ}ft3Kn~)C0F?<-ON16O`mw zm$+2ImrS2bFHwC{fp&Y>nB|?QF8b;-swr*+50fatQR-F=`r$>p1fDAu$!v1_zscax zPRPh9{OVCjajv&2mMMe55JP2l;H`swOzKGo1$ceDUzA1qx7)_~C#t8tIaIlXBlC(r z>j##Z!^5@Fhum>2g^vYC1TU){4U3EhI=1ytw>i@(@hA^LwbMFj}seMspJ~)ivh}|Ko>J%~v#vCQO{f+I*FdrnUNw9?~}RriF< z3${v2*C)0XPy?lp==tRLP@!rgUZhTEnU2D~9Rd-t5NoxS-M zt|jpaO(rcK+!akr*!C^9r3G9I8PntrUK18JQKgU$PIZ1`?EFTlco~fUN3zCyU_VC^ zx1&gD$Ywkh>~?m`#Kolm8k z%SQ+igW4X}x2Jiy8>1gIW%XR;cU+N$;S)p^0SE(`SREvGA=GId0+ru;saqW_-62Ws zn$R@=rG$unGZL$>DO*H6(8dn3sU^D^P%0wj%haY+r6d>CVYxU)N}GqOSAW$vqj>C7 z8!K5)J!1U5kw$$A(bnrttF14T>~k{-tZkVOCjH?+2;!G|bdIF0&N ze=Q9?c)~wnRS&TN0b(n(8ePh6Rz$Fd^ScOAboT+pWZ2N?%V;y*y3SA#9A4}xIb6_Z(ne%N zhkRUX$majACxg(~@pkowvzYgJ66FK#qe+oYorUqZ$6%PQy3>jEFGUjFjF^He*38Xx zwF{o?uJudLXSAzSvV$8NQ=`|Ekt8h=_VDysSC8^SlO0}=%o-Djm-f8$RA$|?^?w0T zh_t7zXO^b&ROrx=?S6bujP6r6Yj}p0SLp{v;5L9G=#RT8Q$UK2=)`Di9QsB{c6>9< ziEhxxgk%f-KKOH+?CQ1uwUX~gog?b#XXU;FRRauPJViR$&y@x==RS|uzsq=ZnwS<^ zkL-xIk0|#ojO}ytj93Ph+qCh!CN#Dzp!Ra){IoIzvG>L1?-k3D7h6&!I7`e;EIT#&r4{#Em@m zYkrB?ezFM}Jbs?tLZl(H+gBEP8RzC9?>}|hoHqZgG8@vQREL*_ytBrP^Xc4X#5TXG zp8q$*siXDJp=*pux&CMTqG9XzZLBY}lc317XV0n43d;18y1n$S;@8cs4btTs8ck01 z@i5og$5_&1A|Jskc#$Hs?^!sL+oUYx%rDw(b`6}BZU#x5B-Sy4sdu{0$kzNyG)R-_SyuHPL zey`ZS6y>7h-!<=k0WtZY7nU}g#~59Ehk25?b0oi6=(WQkSKRv2xr`R)PV+UYk}{7g zWyPEk&s@X1u!c4f>vY$b!I$W>JSok-V@=@&b0F2oe9B4>V(F|9!+PQsX_r2?L^e-6|IFr_v?e-QC?O zDBT^>DALm1CEeZKE!`lsXgG8E?(bZC|Mv&WIp;IRb7!i4Tl)snMt^_lo}N3iuii?l zKA5awFS0mYR&?&5s*0iW2Dv<_qB>r_%UCNn0>tX$fLJ|5fQIYfgs?ri=3DvTb+g)r z=+726S?=}=Q~rUiC9Q&xSx3=;v<-KF5bV)T_2k2kPWT3Rt^|usN885pD}HCdeLXCq z5_)#&a!DYQ{l)@Ve-0YbB3Ldpnj11j5-h+%zd{u>GWU=^5kMi8NFp4v15)`BSj$2x z=IXDh_nNBD34bCXb^3I2nZ9Lgpe2wjaR7$PQwF|O{*KXX>lpHC_|#(YbHV22Pa-#) z(>$9CJJs<+W+6RBhh0RW6zFk6+RLfo51&MwtMqPK=9a4$m!4(RY4`6@lDT&+Tlk)4 zS;gt}dAI?j-Uui57{zVW<2;1@a2gIeW?+SFV9)!^p99)bQ$xFD9OXs{tv9{Y!>+A-bzEDiV3%Ovt&p-IngQqxJFohM zqLxz{Uc9Pic-XWYKJ05DIxa1Y&i1^8k7cG>!`r7xm3E<*|5}c9oL1dybGj- zun|x|uKYgse^0k^+xfWGsF z^b(f(KEnVFx~gWa3#z%=D~#{Q)NWE8+|I%~i%>jeRiwgaf8pi_e!|#h)!ur2SKL(9 zE5Db19tz%qUiZ$0(gb#(KS-2NcZPF#f9Qd2FQsaB?4W^lGx=ei!E*+(!!*gcW_U4; zX5?cV-sPL&Q30)|uT+2|ED(nmYH@ZPkpSNMRGk&2u4H0c2V4N)L>M2jRSI$>E2tTli%$rPga0j*-7#P-pm zfU^RVR)lF|kU=Tw)30BC!p7B#n8ay6Ez2_SP4=jv39<$JCaOv^y5XZ_Y&m-|Wp^6=5pzE8R|$Qsuq+-bFov=u*# z7=7jc1T?>H!R0bFP?7+^PE$f#d%{=?&gvvk$9>tZU%~iS@^kRy8iWIjr0n1Qr}IFw zMa(vEMe1$o^!Hj%4zfF7KWC4tq)h-?x3fK?rNn#kD+}-7KG2Wv0Fl!Zv#=99n7ziI z@#_0tpQGKjRy0Xf-j_y>hrxG~R0&d;68OWg(&IP{>V1)V%MtXzpPujhT?-x|yF!5vJgs z#x)9zA^n9WZ zm!ANiAnrE=@sP6-Pima0`F&H3nPE!ci;_VR&AnyJ|EYe2hnD-wYN-3E#`= z#Hr&uXZ;vc_xOi;?&|S-q=Dl%22V@(elVJg+-Cxi9T950S4cFL1vTqGj81EJ8KL^9 zu1u;qf3H&wEQ*K7Gxuh&T}ySF$P*%)DvWMOVWgj>$8*WPud$8NbcTg zZlM3N91i=V4%Qz)Qs#ySfa~D9DsmhNpg^g!i;S>8r9R93OaGU}1+)k9?9}M$nwQ7Y zx9V~(>dQ4T6j=i8jGti;IxTM;dqs(P^_O(4+_w>q^aRNsm-}e&FWGd)F6w-m2c2mC zDtFfyYi&fW5!t%)JIbrG?xDk2XGK_!s-Xd3n2_kmmvwYk(tqVr)%FAn0(C$TQ&>}) zzJI!yMS(%AZvX|5q7LDBI1|SOgCbf!M$Pe!7U=a>6p8to%eDPO-9ohZ<|x-mbJJwQ zTEDjcxd_HgfCj*f4Mjgor)Et@NQUJfA2ZnGJ9eQ>OxpN(@|YG-X=^eMj^;Rdlm8&S zK<1L`G-qhM1>^5%qgGts{IKS_U_2MCAe%LRR!9@Il_0Et}t#|0){N&*Oe6T&48WT1j zPU#bP^Q$)v>vTJ!?z&<>c1AVMb*{$~-`?5RD@yEnGEV2oZf;Jur?cj7^rl^4mq7KI zY!mIqu@baudyaz4W;j@j0LG9UvxF>9#Mf|j&+}hpOn^#?ZNAdS0NKJ%KyM|L5mnj4 zdiQNw+OCVv>iZ{1NuapO>~n-+BaW9NB0(`uZ3RTMXQuYsqct+t4hBZ6k4sIma8ZKZ zv7xtvI_3_L6&~3-rzIWDv%l3{#WYx+U>-uWEC9synYHn;Iy}| z<~)BEEFH+mnr6CUz{c_xUsf;T+00SsAA@Kqc^XpZ;J|;tG*l!W<(%eNevo85^VupV zX>2CYe3Vg1h70DrKMlFB?(oZ{)5IlgSUj(DKyUNM;iS82JikV8TJYiKI%(Aj=6wS) z{WK}zF0LL5zjqXsv)X6=yp&6IdLP%9q@Nt$-Bsc+A zHp|$@#a(LVheKT@6|M5A@r)Nn5#JhvdjTQet_`(6UNqlZ8m+&{APpY@7XVTHqFlxI ze{V$!#nAzUr=W)yPonawtmLs3I-)XxejGR<%f^|@}^>g;}DTz zrS!iI&|zWq*;{ryszo|v6pfn-bdKWc7_P>{36cXX6tb2%>2rcl>-!a1-yG7UyzFHv zgy)X=JVb0YOykQ**AbL~Cf`jTVNSEENB6gjXWNCdF=MTu(fo>6kEA1oGkgyj^zJXm zSqj*F7bC+-Oq49mx|n)-6VL`y%t$K+e6e`UZesYcasth(Y1JJ10n+CC!fx3AfD-*l zsDu;Gsm0s2rnq_^zKepqWSfnaKZA^+gZ^W9bw5e;k}3pe)=%aBV`ni1Lk+=yY;6e}7v*Dn3rFXU_suAM(+;rc zW8a;&W3vU#l_JN|Y1{`K%Cn~`pioM(z~m5=F8Mi-;{NJHk2aK(@=vmF+l8;rd_2>qF+kqzmO74Oj@_Q2&>vm^N}^hM9yk3EG{7J)6PlC?A8M2 z1cS`Iv{34X^!udUMk5rtfqD76k0@}5+t>Rxa^A)m$y7@*0RKy1)0yxb&4fJ@RhI8; zp^G1E$0KwwcQc(L5icrMqk6?g_klX0R+YAl=lzNK(VW)Ew|jsYr|v|GB`gH~7vVj? zizw8;Bjx@RN&4Er&W6KIE4_Lv-c|W5;&oY4@Lt$2`>bp8B>oSMQ!(7j`4<<5k7L}+ zB*x?Jik}k7>Tl`{hKI@y^BBfZ`Zt$|cC_b-XsJ>-03sRy0Jkybi3>cnS{_qv>3)I( zKT@=He~6YGiNiT*rfotEON%zb%P49ugmp!cB{a5Z zrvhVyu+={9>^F8qE}tnrju|6H&0Aaq)aX{bx2|t2kGdVX^O9kW-JNk3nWoJMDRTa% z9eHGt^7Dw^W>tkzO8FX1*f<=PEFWK1nMP1Z%34?RAGW4_l$9{(XM)p1U?LR%duF8e z{ouT%gQMB^1E4I3@J=EclJn~Et0HN$=7KC4mTNuhm3nYfVyWkMnpv0Q=j(GOotmFH zN~evbSz`Mbcz|n2gUCd9dKtWDLWO-NfzkvrDj_%R{YQnrOf7t4w3yR(#2ve(wPPUC9cbwICK2oC7gkht50-B`zGixQ{O|zn2~U|gXaS#TwL1#d0FGSSOI?qJ0EFje z=?fYoLZ$#7?1_13PBTq|ZbW-ZF*hh}r#r3w1*$l|#F@~n)deQLM)gBkj!7is!T-rL z_L*b4G~pIupaZH#0bN3O*SuLbkY-Y2Y;vL}8PuL{WT#rbdX4{SsJ3IH+;ytj6ic{hJisJrwsXN&hd|?49z0bftm$u zXVl!gC)zdqTQ{fj_o(118FS1q2SQ4yh6IO&|h5%Vg0*tXKmT7re~0}2-! zPGzUelJ~eCzv3YZu+2p>)m$8TGE(Z_H8xm^m2(abNo#h#-v?v&cgD>+6a0t00i7 zBVZuWGE5zffLfx0bp}%Hi_YJW?r!hlSbn+mC6`$2(qE&eHRk>Pb`L6#AL#G0#*Pr{ zcr^T(#t$vRS*?)I1(5f&tw-WEA&=q*;B4GEyhm6a|JPwnKmIpF1b_c=qmZ>(>NdE9 zUrNJHnM`x8WFy*@gJ5nFh?<+#vz=&g{lutQ|IQEZfBn~o7eN0t-y74LPVa-(aR17~ ztK<+gbk9W=ca~&w-qs&dL`NW^YK>J@^R<@YK>#6u`WZ;kWdS87b}E>)-`2gX3DZCU zRSB`GqC{m8=WGuj6;AIq1>Y_fuP-Jp{M&P2K@=txS$7fs|FwX-wfp*H-D=#N$*_jU zzT)ymemg0teM?j8o$CvNDlTTl#l|Klz~~K#w=)qbR%$%q*=qsv#=Lmm3q&8v0~0F@ zp0Zpj1lW!!M62Hz&3d|1we)&I>)-Wm9=PXvZ7<~Z0Lz{_VH*kpyQ@zeTzZ!XK@mvA z%0-Ooa24ZC-{E*4@xy!2B?&@{3 zGIn@dP1K+^!Njc$_NRU4z~pLs!2%&Pawz8yDRb{)6QqIOy~x$&I4S+d1a;VXd%+m9 zi!fgcOLraB`^(~YDx9(>gOlGb`dPFGT^=g_{@Pgw8G6ksqLEwFir6(5a?YZ_Do^Ux zOKj1hi}4vue86f_mGh@MX(bSMJ_xkN_`6hKTCIu%e+m$#7u4$sGS2Rcl{xde_Ff){S&OHe68{BQ#4U9C( z`8OVC9W~FDR&O=wle)6#=Oiv&mwk9g6v684hc0TjuZ~$IUcQjc^p6&XuRIs%V;?jRk*9!w3?DdG zn(T91zhtW@l*Rtq73YcfXIrdSgWAJ=@(QMN+*sf?0*CxvZo3WIsfkLk&CAt9i`rkZ zNH>IhOLzJP4oJz2vE_t}W6hsfNTQB|r$i2JKXLfu5a>8^RASQ;-V%9J{%hcc9)W=T zYfJGy)4QPaN2VaL&Cso;a|%foC6|2QJqq^B5g~9`(!+6hVyQ|#ZM7W`=Ym|in8Mo# zi16g9i6JYWeDn5Z)kYFe!AqCJy#*vuO@9GC;Rv`XlP0dy>ycP)BIDq8enp{L5=1fz zgzK$2iD{RPf%A2I>#rUN1_T!3rukQ|oEN?to#eJ;SOD7Q@e^4_ARrA@o6N3Y{zX*f z57WzV<)=kgC?LMnxgY^m`?ibB+VXwtM?YzCWQUKywB}8_tIFEX7imhn{(vP;JsvQk z8v_SO68)0tZ9SDDfQ-M#%$~EL)}k-$D-?TJ@Bh_lkh7BQQMP}-!dd7rkWYEj_4Hgk zqA;*MVT;t6SUj~#XhBvwAO+iAsG5Qp0VwB(o6o3BCT-l2?LwIM-%`m^5|M4f^&x0j zhyPm)BRrUBe{Drbhey|^H~N&c47kU;vaDk%Q-F8k z8*{9%4F{6+#Kfo6w-bbOO3pAo>523iCf37Ru{Uhn!5Z|0j7NZj5h zDEcmv(>wR0$hyNtqem%f0TjA426=D?G2l4+bWRtb+^T(T>h-QBh-symYTb*4-UU=q|W6SsagtLH(HHOQA%N%{10))E;8~QZB z5CAIe(@<#(g!G~|J>_zbf6CWFxzN1gm54dIY2v=}-+?GkxE_XodX3L02!0uOmc`Ru zsk?57x!e;8lgBKRSUeV=@K3aziiw}YUVEHhy z;3Ps5M@CMFxZg-ayyL60ur8~;ws?+=;hbO2fCA1=WWe&0N{2Po)vaD1KhWZ zmJV>1>)%TQ4#a+o_?CO7g!&mmqyOs2K1kbRZb`5r7ZGi(A6o`|6>8Bzq6SrEJ|E;m z?V0yzemtN~RBosp2O+J~0Zn4RXW&WxDa$PX#@D}F=x`Oi?5T#|`>pQkM0Cr*-}=2dpx*LR$S)!(C~y4#B`035zm-Z(qBCGj7NQJBliyRm z=QvMC0=637(x$O$$AF_Ip7CvK=zrFkk>Eh7oFjL{=(=|FL zgMIaY)0*R?36Fzht9GTbl=zykMott;^?RX%MU6pW*nJOj^(S-a<9F-9;!sh>l?TAX zUqCF8a0KX^pyr@naALaGH42^f^9G%E!+xs;#G;L#LEM(U8S{ptP(lIxyN3ON1fVaf z6iUi)WWncdxBh&%45JlL(eVGX@jhWRva*u`I28Y;nx=4CJVPTtSn4S0(|!3DQ(+I_nZ0GK)eBNGqPsC)XOR9@jg7CKPKCb=Y?p<}po6<1= z2_}P2AE8$rh_k=Xp;(;^n0^RZx-(adn2hNYM3$L{`pP-FjB4$9mC(`-nF2;8D-#`} z#en!;)<&WUbRe<7p-9uZsEi87k>t8!Rld=Gp2HPWmQK%Q%Mhr{G<{8}vtKlzTnBq0 z(mYLeSg5{&f6$iUf0Zm0BwFn2Pvcqs9SzYKeB)x4Tls}xg%lyy~>}Lm^-ky&2 z@A0McN_7qeU^VEiKM)2QWAbd<;6J|bY*&vos>p!!rs%f?>;mIyJlT%JyMO{R>zK;VySm9Wqk z;IEIS{ioc5DYD!6@pf0D4h_@qa%|C|2le2MD7D?FIrG-K0=&AK` zvqm7J0>B~gG7-iS8l`Kcyv(EdJJ`Kpj$o|uDr%&>z-mhq3-92Z_)M_=IJ>=)ZYipd zSkcuu4nfyO0Zp|yfFvf=A^nD{|LbAzmyv+DBRWxse0gEwY@I(4ytatJ-&GGYcqPf!O;lF#JvNmyeQEX&OR9SNmHxS=g`?*Q>KkmqsQ zGM|(h%ntGdL&Sq!OIC>nXt|n%8&$&wk0#e`a=9N5ov%+VbXIR#`cQzhGskalGtKi6AmE|8BQ23KU<71Y1yG zt}}S9AV1F|2`&gwUAr3oy}Yom(=E8;MQ_U3*SFx|#943<$*s7KZ|}syzSliHK1I;< zbw^Hv=(6*2Sv*>|mvJ0JOB^v0?gN^jDeKU-Sjo+})ay9&pqR+)8Y~|%2Nueij;+W3 zSnYlJ4z}qH)XKhn++tFi_9D5$e(c}2i?cYzQE z!ji2GkH-efc7xxIN95^M)be+$F1(ANy#SeshqKQOnoqYsJ(#xrm3y3LfFp3^SFJ(@ zb@ib)uTkE|b=$Qm=;=^W{l3~zmU@yA7Ds&awI)p{z^x*v>V2&%>N2o^)%qsneX+34 z9h)E3abeWWiFQy@K>=ZSYtF|`UspCe>p7D-q4p#Z)nFZEp>w0G+G5c83L&!07D3;g zu71{TXJV;JMjiqciT3qDl;)j>^%|i8)p<}suao?MErS--%};EQ+nkgMMDJy8vnpxL z393MRJt|)OmcfAQGCM?*E({&eKbz1*Ul7$!P1A3I|Rl9!rYQ3%j#l^iI z&8c&W50Sfq2Fxu1?szCGhpO*sw~YiN3EqX*&`6; z@d<4!!Lu20=!Ji%&@1Vdvn0P#--|K(z0@xat`HJu!5e;dN<(c0UcyzG?-DA6N{?ux z`@*qg0J#eoj#1p?K8xe;kTc=>qqvHnL$A7enV4#R+_hWf7)^&k^~Fa$u{43*hYl}k zp=D>0LM~+)GS_sVOZpb482J zq-g>>keHu-rs`Iv!whKC!FYd?3Ko(|ZlI#~@SFh=$q= z?PD*V_;Y|B-+8F>bWXe{$Zi<`l6jaTU1m9Ex8`l+xhNn<6?MQ2MOQg$F-eXqe7HE$Lbj5 zH-tA47)GFA9f47>E+b>(e8Kk);?oU8B&NN+84z6px_K!nI-SLk#IRj20$y{m8!1JJ z6-+{7Nk7H(Y{H}n2ok~%Vv*=NCtiNn^$WM^9kNe)%(M4TN;FM{3!jW%7=Z)o^MmhP z1*1@&-6olu^yv@YP#0#Ejl!lc#u@L)rsTM<_R|{EzW#pxzP46GWQRtM>Ps3%iF_9s zs}B4QGW1k+yE)q1)LuC2A~o!LXK6t}RCu?atM1JP4u_nF_9bFLRagWV*XyfBCj#qE)gp67oNp$HLZV(HAmIXJ05p zw}m}9u0y=KX6%O(NQInSx38C>$4h+B6%z*iAfRa4SSs7el`gaXB@P@A#oZ>0l^R3| zwKE%j^tJN?&AgslBOXV?CW|q_o-EI}=RKEv4QIdEzi9}bZC%jz+7&ia@}(JnEy6!z zq}FV$VNPD&k?FAAjDmXdgYPw2SBr+oIh5A`_H%f&s9((-_ryEhkluF<1HPLHCnpT7 zUA|RV85a+2#^<#{i9<@npFj`(z;QTF`0~>Od+(L*hTd?Y;hjHe)7SaEo{T7%2Oz3eJLf54r}oIg;MeTKD97*~~(l3e7dM zd<~U2V|T;s6s-u#M9f7X3AR-D48EmC*O*8sMKL9C8;1C{`Ha}`L8d2uHFB;} zIVZiwc9*CDCIxe2Q)kVJ&&-9XTU40AtO_OE@VX@_c*`H17w#NaESEkONs*%vm9s;7 zl@M|TnE_VT^#p?VeB~4d)dTB6HARM4e_>rl4XAqT8xf_=oPS-I9%QhJJ3pY6qANVV zX3DaV940BIQgp!SSEQL~hZ=tO-jh_@ob~vVOZQh-ORr1L5G3vVr4ih2b3#-~D>pf9` z!^P=-7$RfUdRPl%*L|ju(aCb+sLq6^s(vSqWA6x(5?)+lM<*?`c2|R9mB}(t;Of3Y z-0Rmp=UgN$(~Tz~Xq({%M0nbdre z^Mi0p&js4BS2{z6h0Ytw@AwZAgX1NE(!1d-?-yQr;dg)tdtesgPjdZH2f^*AGsSog z(p4>vwN`%6=wM{~EC7?f^NTT=;Do{+Y1b!%QmG?=WcWqbT=sn<8hpoglT=H|Y`*?= z)qA_dr1ljJ5f81D>U_K1k6ZW@#jf)}pHx`xk{S+fgQJF>%B`$9ApIFQb2OPRz|AlJ z9hBT^tJV4^DNf*BuQ-9I){M9%ReV&*bH{hqI&uuZ~Z&O>WZ zoctVhUY?ufb~4dTp~7KYIA;DCq*z7jvM=cG#_(7wyb;SAD7 z{EjvyV1OiugesS{?Sb7u^;49aJq9n^F$-73%~%vnY=C|j#tXPzv_76a#O;y?MlS9a z!E_r4^8<@t*}`!5?%$)M}yKk~F*0BO> zpHkNBr`w9mqzUm_VI}wrRyp7c&!_Iut0)b0(8F7=+8ig(lnT)w$U*4f(-WL&H>8qi z7$yOEnW=DITB4{VCGm_mdX+YJDOdbuDM@m4V#iX{A z$SbdNk3g%OJS$pMxaF=<^`9|~Jw{m&m_!3sg>KCXkv%IHlzX4-C6EBlpC_f6F-gy? z*S=(IEo)&?0Pq$NVrWcHhmk88T^#rIafs%}N0nob$<91f2cJu~)sS<&y$|;-g**>; zDz4Qp-`B?3iAR7Dc0ln^0_i17h($b>(9xM}e1f$)dqiArLu$`C9NB6=mGCa=T?LR1 zqmK23rk(t4Q9{zO^2WU!p^@dKJFbW%m7@M){PqP@9NixBb-bikcSl@@8hH04Z=K0> z(h&@PB@XM@T=}gEPBD*Jhc=GdJ0~z7Ico5}!RQJatgFfIVuTyY5u<#`pm{(S ztr9!2-n$d8%$X~U5=o``i>Ru(Nsw7gWjIvTsW-<(CfvE)#}3*1D}kC)=&X#h%Qh7fOL0D2eM|S z61ErhlJM5ttN2H%sGDN3UG`Cj@U{(7RWuX^jc67%%iONRhvmU~%5#cgmkJxY7gWGi zrtPnV=g4!p?o|M8sP#7K*Npn|<^f1@7VU7o!7@9Xe}_i3p|vpAd(?qXYf|pZ{%Ad{ zgSW|NBrt{!GlLSfGgd3@iY^_y*R7i5%K>k9i1#qma1q0HBtrP+Z{`u8`T|a3vu1HIVzVu)fp)58e`>#B}1%Cn65FM1H`YAxm2QN_Y2VemVh1wpcXCduI*YtD6Csks(yNX1JMqqsH}yOU0(`WT5-sj ziq@AS)>p8!t<|5YE=x4F2{9K~II{d`=%4!d49vAaAj4{XR6bsXpaZJ_joag-` zByu>;U)yg}#fm`NXX23?WqwF(c0!>RteztafIs}yg3%b_oE#{Uc7|}p_SdVQZmRjm_ z!KXsoQeo!shTKw`1+M!V*AHcB#>CJ?fRmgkM=o+5#2*OO-?eEaiobl~;ql4fkZ=dJ z(U7b1g>)wU?qSS(5tIZ6qYZkL(*U6iz%gDcRw=?=FIXaFFZJ1Hu*(5Lkk8`n+d03J zmdy8;D%3|HVXyI&+@Rpt3CW@+v=UphBLMP#)i$lIgJeknv|9Z+<5i{7HuUwiV}q*f zTUgJ%T(nn(qt6iB2~j~Q(`kUK73@+ityP&s6u zTJwh~IeNr!FkL69Pn8OI$q&eeJ~Jw4V&iUFmCe^(+YJD9RU@r67rkFX1O=vRO3#Op zA8N#fKDTk=Bi;r2Uf@2w@R*|#!#(jjfnM4@M#PyK5ch$B>*=(aYqgaAdQqEcvb}g0 ze8<*MFl*OPh_k{sd2uzq;Hs8C;GO)i(AEd)6(WKVGEwQ5Ic!H+9O)+YdFy-NeqcEo z*lE0wn}>dW5Zp{|LwyC^eqrn~I-FpMIEL&p>@srZqyGWWVTBpDwA)juu^X{6IyN?) zd!uWf!w&C=RzEclU&o{Ms!)m)=F$~o|N6Aixph06-Ayc#Ann7v#buPS1J|{46@8CCmNk14fGfQ3K z4NEv{*OZWJB8)jNvkqp71d>K8o|%pt60@dR*H&%vE^g)iTFW@_2PpzOY)!@A!XC}z zeT@zo_s?9R_4q3XdPL$pj$V1MQ}lbGwKD%TR6U_n*`yX|OTV$K8A*OH zV8rOASw$0Bbc!xcR52CeZEt@ALc}B)nKTPDF)F>=0_uX&XD8kcB*8q_%Wt-XSMrlW z&}Ysy#aA}gIbD5anKFgX-E{1cxcKP(K>uf9(&oEC_3rUQe5fEziXfFadRTtM3J%8t z`{B!RAc$bt-(nF)gYQ7Eb~(TQV+P;U*aF4Lq!`P4N_gyF;8jLAo0I_kgA~;MbG!C) z?Ds!p$lj$64a5?G{^p|+vXeU7`VKU_(b}n}J~>v@Io_Ye+M``yT1q7zk76!c25&8$ zT0C?%5UC86`BQjFf0&khKxHjEYQLW%la{BM-+dy!-O&5B1P|plKk|vYn@JtT_L4MG z#;yg&V;C7r-7!G-_JyG7wZ)Rb`Jc6AT6g(}44I_gFKF9tqdwOzjXFIS%r_Ki;2k?d zpL>Mz4hzc89zsg&Z(pBgAmS^Mno^p5hQ>IF)9L5Is#BHeG>@12$e_&ZE-T$UOnrjA3A96xulqq9wZM_)0*$qZqm$*ok3wN&L7M zNw2evfNyUBao4CYXPKh{i6R?!`-Ht(z7T(}gFmQVovI|@|E6&YOjiDb*Ea(FgyE&0 z7^Xo5<8cV@tseL@(XxIfZ-lKUOaK|oFefuNA$pAO&qkPZl!9FY_ zX%F(b6n%6p7S-7itqx$^2n(OwyV(GGusJf!#BJ*4Nh-){DW zOFB0zf9#Ho(AFp0x-c--YC7Snxq!Q@7N3q=|5wwJ0)FHPD-5m7t&46et(qNsDkrMMtJE~?rHPo946WC zE>z4q%yr9I&8PeE_5;dO}^nHT7_# zzuS_~SucgBM}8TvRsTTK1{5nC)K%e<+B>137Xiyg7{60$cKJCM+cN`yP2W;|FdQIu zm}_|gHOE@^l7xG5^DzHMuy9x*lS8T26x*ETeGMr(px)uq1l>EMVE;^a4nfp?5%^we z$sf_zh-nC~K{vEpJ~t+icTMBJ7V52sQ!uCkC=+XZIy|W}tb&_LFTG z_mfc*9^xaTE}1uSV)D06oa3|22zRe@9O&t;S*0})5pow_KLUQ7a1ix}Mz=@pN;|2S zA2>I7N3pMlu3L|GbGcAadM;B$i3m(S*Zq3i!dOjswH!{^N(PR{5+9rJU^-S;CV^Ba z6J})f=!x}ifgR+J3ytDnQqQOSK#8ipgSUJT=%gz)x}zd&ICByM`lKa13k)gb&q_w# z?3H)BCm-ZaEVwZ?g*{m3QfN!^UAg0474bm&J2!7IfPpN#9){#OdLnK2ing?cR?Jum zIe?g;vMaBTGlPO}&Q8>b`90Htgj@3GPb<~uqx=V_X|7c^kbmPFBEs!M{r;}sI#?AU zls{!|EY_-}!&D&s5#&nq@;JtzKEF0|G|KuM^|T~c>`R?FGtPzk9k#v}Q>9BR4`e6i zL4i=}w*NfHWd>{PJld=Fp!pQ>50kpzlR3iDbbe zlztOmZHsI`BK%ukpGKio+7nrHfZUj?SsaZq=HY>~RW!ADgkVmHxdoz2_Lk!la&Gl` z0fKkJ_7D)4$`F71Pu-&-;D#TGvfJ)vuRPlqBm)2hVR5&l7<-FLDpXr*vP?UVR6nI> zLovD4b@Qu9l+&grst8x+qj{t#3QKe=L>MbfSO_{!D=ga=_$%j?u*H;hoKXOIt2pM$ zjQ4^GmxtzbLIE6W)6^4_>V?$s8P>imV42?*}=rSD(P_4eQxY>YqgVcCZy$59R zQ=*~-Ynoz*hY!4Q1!<;Ty=@^JczwFk2~Gh_&D4_zIxDgtUg&`AG={i(j8iP)V&J4P z&T>R20Kr8g--*A3!&*PBdS5qQJlxiIz&HKc^I0}Dq77}~7EeXOza&+cdCf<C^*Tl>Y{N^WnVm%k|7Z8-VYXePG&FAdAvaAvWhBzc8 z+`FkTy_JCRD$8FTCUABP#;2R(ZL_{TZk2k_;rmITlQH%pHGP_KWA&&6k6wpv zHTmU}{iR!%Y~;zqM3`$QnOQ;XxvH8G(KPlEuO1HCU|t>ZToVm>~Qis zz?G55s8&>L$6gcV`KXR(m-0OSaaB!JFlda7)W_<;`IVhf)APIiOy(9T$DQy7_JdmV z{J206Dx&YQoaHx<9Jbz#0Hv6$*_N0fFmRoc#Q8(gYu?3{%(B4Z){vt82Coca)fQ*@ zwg;lun0R>}vkZ9c&o8>MumAkrfVA7=+c+V;K$u8G*+BAvD#Y`rYindbC5GxSoPBFS zy?9Og{MsfLW&Xh_Tcc|oAnhBTQ?Utkg)APzW0!S0gqazA9E}>?(tgtG1-4Z^tOSyj z@Va$w{CN3BEAB%JFM(wr_K>vv*{~cGKMs95oXe6VKMBo`M83)25&6#7_M={&FbGrf z4zn~R^ScNk5Q9UExYjHR1AcDEg%6l^qjK4bSD2*{nI{T@DKqw@zvN0+OPn2WbdW?z zVePn!6^a4BJ2ISzn96SRNXXoR{7}9W*kp>3imL$L zu+Mv3-M21ve``1(efTVp-{rc<$3fgnDod+%NnKE3Zs4K(F*DV)EqFUlnQ%OpBmMK7 zyr|!4RH^1=;FXZ`ha)`r`$^B2kT1$EYrrT74z7WObm7N`bg{YP8wlqvj`bD3~b364NyY45T zIMF|JcZf^89!^cNCAV}k5Gcz}`cYrDRA zW4e~+0foO}lG}$H$V*=!*6#2=pBaD~f`mh#224muMK~1*jLIYEL}p~qo>MAo!?n(! zt+Lpy-WIe4zF!QmXqQT0y~PZk^Y={2c(cNP#tc>nZ$LM!d#W_wTDb|-B^&1|caffQg{qwJH#6moaqDN{M?xB z+DCnJxVtgR&WDiui8bv|S>}m*n@pCUbj|81bSzeSkW+T`cO^uorRa?^27ztEE|Swr zW<59~L-177w`%;bjuVcPt{aDf;a$E%_X(Wg+J**r+ZEBj__6WTw=z+vFB#mCoV7ca zF1`&-r;y6@P0z;Aor(dcYKWPEXYxTSiFsDxIt^vf9RayP()F2eJ)?5FOUle%eS2?v4LVziBv&&&5vn!uh9 z;$uJ~se2|C>x6UyQIWJ6K6>e^vQWt;m3{hak$}%3Ki8z3+H4ho7+Q4!gIT#8i%%uL z(c3t#=YFczHAbFOR<-aKY9=!t%*|5${ZbV_HS#ieTCNS4!I}j4-pP!Ip`x;>&;zpV zv+##42p?$^FBJ(zK%G@+i?_R0r5L784j5>p z;k1JSrBd)6@3vJlgC6!tHp!S%2lXhNLTXr{KvgAh*A`WR zX0!<3pOw;HK)g1flK8$>bRvQ0*A)e;Vh}{5;Xhg_OUc&l+v@0B$K5Qeb#m(F?9>2w zHy%Kffop-6fd3BqsG8L7ZJqF`CRv%1XyJ+0Rlmf}&YTk5BsJa6kR;Jc=2%eEuD|!N z)}i6J`^2)OyK;%-;vPxRcOFN>Qr(do z|K7(W*8!Ro@UQCXwH;7NdvH+6=8|qTtW<4$;{JQL`^YPYtn1PS;Ee^LG|oyfP_8B3 zwRd-_<$6C?O+WK2)m~%@IalB9-_DoYg?CUq*{r4Yntc{A;P205!{CN?ZU~=$O8x(HDba&l@$b;ApWbd$M@cZTC*ttoV_>ueo>&j~s5{nhw#E z;Xr|TkGO7c)MYm>`o-fG`z;@ku%sA&eZn`OW=?2S71{)$ukA7NTbAv+<3{%YT^W3% z9x$!BJ7Cy|Ff+P9fn(RENf=_^wP6at52 z_MfSkGIm2%>g(k(_*HHH z{3W#2{OXW_2}sw}$F40DRm95NJ_p8$;>WV!0Fry~*z@mW|AOol%mZswqtuB0x0vwO zPsx$4d^$iVrLXvrWaCwwgK1@+wP6VFu!z;MyP^Nv<5H<+_Ql1CLT$?i(|q-0-;?`1 z^i71Va5aX|<_Vqy1gK@tMsm(8L@mgbn_1NG>5$ob7`c^7Q)hZ>lz#o66{0U~^U<}Z zybY78{8KjPkNw5tkpZ_kD`*q@>iRriY_(58ZhQrOO`C0E1yD{cOD zszMLW3nOp~J^?~PstizV{C{knQ+OW#7wuy;Nn_i#(bx?dn~m)@YHX*mZQFKZ+h$|; z%=`PF=Uknu-u0QuJM*2r*Z!=vQ;tGlFo|~z?Y;=}Y>0M%zx;Lkz2}~VojQ`N-s{dX z%F7)8%+^S4O3F8!<>d#o44i9=C$6n!f|PQfDaNJ0)}1S$xPMP4=Wr&#k`LpT7;7mf zHfrwdj_M3d>kv*o-Bg1P{#m9%f(|agL3J<7A_C<8=g)qMt({%(lyS<_@FS$QjT7QD zmw%v*_Um1oClp44p)u2BCjY51&aJXlX38U?jwzzrS0rnhjCu+Zel*)GVA`RMN`Q-B zcGc9I?Rj$h)c*EwyQ2NdvJDH`vVE*Ap|hKMYR!68uXoW~v7H^her&hg{$r(&99uMI z(m_@}8Vx>}$4N#fM)x@$_d&ow=I0D)&V-ox07E)n57x z3Fqu!9Cv#J(KQl5LPL#Qm+FJp~M^8K0W84J96yc{;@jis@Rkq>C^%N+2db8 zGmh{+jIMZtUV6qP1CY%_cAfoxfD?j19nE*}s*u>DOyJx5d56v`e`^jawH#HlKL&V1f){uOgI{>;zA%77&;FMAlp2pY4H3+-EU zdAtUOeXPne8!^8(2uAjS?gNITKaAOkZ+f4DotB>Qj{Ai^kume$JNLlLi*wyRba8s~3a7=vtm86Dz z^esM~k`1VjAt9aH|q)So#N$7 zefNOS&eePG?m}AYWouzS)9D*?- zBP78;lxotgL8};OUH|IxqmpgqnK9ph>RlyleZGpX0MZ^P^HxKt@7yKew;wEdUnS$K z`E~87ihuncUz&0Mf14nC^`rTlaZ&b~-O?@f-u#LwnqW}aAG zi(d20AzK~ae&%PV)QUrIf3asYm~Dsh%Wn;egt5Z?60J|acsNu!DC0K|(*LI7^~oYO zJj}a2SFuH{-gY$A04H~36+zi@zjpuygO38eW*8Z0IrFzQ+#L(DLzV+mrCaj6=@cG< zRq^V2%1?A0O`FT^0HRgN-JQ^Oe`xNKK?Ii;mRFOd#O3C(4VPw_K_tyE2buaiG5ndb zT_?llM#{W?NojH9CK-#jf}#(Y`6RMfSCT22sW*jRG!~hYTU3?r&{xZgzcC}SD0}c0XJdzDI^lII z_Y(shC;D2M$)AFao`l~=4cB2jT%|&Ai)65kt8^IStgGs8rhpQW_I82cCIHz^?-TSH-{lsodEJr;fF8oK>yJJ6q(>Z6@+2_^t0>bM zu}j0(#-aJu+8rS6k^g;wLJ1oT2V>>dS)03qNJK*ZY6nA5mP{Z`)Du8t!n2CUmwKWJ zSK_frfMu(}^XjX&>}_K;SOlej2EhW1DTxUYC5e$FyG=Njt^Mz}Yt!vho3^7B948ZA z-J*hA*SYGTJwyXyw46L9lDw|Sl_%|Iqz1^)ZvCO(EoA2z4|b93T6ZYfBLyh22&fbD zI2y?S+XL*hEJYerygFH01_G6R;b7<3B^JJ?F@B^YV!u(V4PKsbS!$?gf>FFzg~N8} zSgC{KS_uW5wzp!dO!!)}ptw(K?&G1U$%Z&k}c|-pTiVM-+6Z$dwXSgc7f}YC(8c?ZfNl8-?w{ySzDL-b`tgqXtLw6@8?Tf3m*>f=V$_rYbM)XG}T z_6g6+W`19HJhN?DDGX{Pjqb;o?03*iHIhtGbZG(AGhU(IVuZ)#ihOk+y*ng;4pXlE z`TB~CR{Y`%-AK$tZi~H)-&h&+d4Job(+%Z|sLy8?^J1CSbN+L7xh*cqAIl53oJ#39 z7qo2WsQQ6s%MoWnU4-soHTU@>pu+i^ZMkbVTx`>9laHpIJG|B)SEIQ1KorVOoR{R!w8~ndEN5YTgMh>P#k+cTUm26l>OO4K*9w+qfn( z9gWUb*y@G7P0vf6((zkid(VR3XwCW0AhxJ92R$#MNYe6e3k_r1*{& zp6S(ra*B;w;3i;jfba27`ZC1~Yt(8pLx3~X1S+6X`Np$^o>C~Eet?=s31|gKzXT#V zy`CmS)8^qL$FDAZo7>(>;1m>GHI4>U=?>}aRnu$Kj{xl>!%+lp@b)7o>*A%F8bAOK z^Sr#N2=i3%T?eg1r}F(%rA1(7$2UOPnMjphJL`VvPRc8rk2xipI7Hj3sVeFy342$ zFyFtVe!w+kOem(icqxAA15V$t1z9NTQ^9d~+w3%_Uo#frL zo#cXJHX;mR-*xbGF0k3fB8cOVanP-!kYrDiJBCcpoc@TayHh^hKv)1P=X*fo)Xxs& zqgglUYCvf6>;hlEg$?lhGv*%o7`#7YjdadL+ce`=6eu&9yuag^PaCO}#~<@AN7jg0 zF9+MV*{q#U?{`EOwgg9@E7nFdPRVW2z>*7p-lF{! z5n3~u1OZ)Ob4XDOCG>I>h10#&fhW*XA$f}%-Z2{0&>Odf17tX$B7p~@r(4>`gE%IOGhm2HL`&Jz+ zVNbqF2J!Qa`fqb{m`j0yUrONabxV(lT#r%@4le_XUhZ4>seU2X^GL;Tmo2j z-lK>nXr*|jkw(I}g@K^UEusDK9c_N}jhd6VHu{Vs=-8i75->{>)G0b0;73XitGX?)@#~7!LwMz51e*5k$vpE`_?Ax!HB)(l z6e+u!sb<(g7vuEXl@D@IQuz zkmJ})oIC|m@fQ|6s6hX%5xJxmDt5K*f?SlNn32;*;6&q3wjR$bYqzV4M^zae(WiVy za!8KuLZBBP2BG?a?wY+zv+?eqZg#x~Z`Zm=H< zVA=3ppGq-}GBlwS!|LR<}CBP07HZlRR3S&4rSJF=N@sQtf<47jMC`ahYh!M#8q}L=v6ymU!fYC z##P5;7v9pUFEj4hu%*so ztVHC0A3Rn;#+iZov(JNo+%mw-c*sb|2pD5{HeEWEX;~3O6UFdwuivkoS6@CPr$Vm_X*MVv{g)5N`89mBQ6>-j&VJ z!JAQu+L)UuDkt4oO7#^?<+vSCEnx(g;SKkqm!QPU0KS4St-+-66d8>RM_T7%?de2l zR1?3@b6&NfBUUC()ON?rPc_(AF8M51*Q*wjrN&oz(cYYKe>E0aSDphzJ6udAD$t;b z5JL_!xcWTu*g?Y3Vni*`8Gvep-n*G~nlx}rD{M)ZdUh91t9nQ;nQ;y8%-zIY2=b%~CgbVduHoSEC_ea-c#x!hI zLGVYHMc;E=6u~r!Ij~V73Cp_dw=)kN^`sb=ePtn$iZT~LlEx|=O1Oe1aLW4v0pvPo zNQ;e4F?ZbwB5jLhFR8Aojh_17-B--W=~62t{oHReBGP|$$tIDdeNkx$bzv9>2~Dfb)q+%|#3AwHl>QcqT=c5kww4UQfmtNWxbQ=9 zQj7ovi_5$V*qf?EY^M3`y2D9XJzqk}kv`nWK$rxLVd>cml>JjDyrAz9ZBU9%W!4D;0l z$vhe$+ysA^;ut-n05}PJiC9UF$pcXD5)V5}Qn)F^46Ip}SSqg!fLxQ0QgLU-+m{0R zJBiJk__arLEFZ;7`Xild<~7QvixGWt`6*o?s_*~O4dFp2TcDSzyYly*?A|HMl`^{j zVw7fbf)g}%|IEdjv(VCCSPBLZk!&*G7PJ&UxLSihK!8}8jk!9@YxcGvPk!hqFU1wP ziJT|E+2MjnNw?Hy zFaPSDLwgtTRXd6Q?}?;RdeW%S5_;K-890o=7MTD)va)#mav7hg*~WkS6JSmhoydp~ zfP&x`P(;G0U|~kfE3GKdidCHdW>q-3fRnYTGpmOL zm*y7nQ28KcW*z8vO0!1^xrdGDzx?CUENsgKLzo?Un#&pZnk6TijR~bO$tE|Xf@Nm` z|GZkTtJT{A(X=Rlc~ugtJN&^Fez@*1Hrt#y>MTNVxks}Ygar^Mk)o!=YgOyGhnS6B zU!j1}>G6WcsC}ketUQ-qeReWSf2H!etHT} zcaf?wLfXJ<=EpsN9E;q!Kz$FlC40Nh>VZ!ZR^`rw+5cf~u*t^avib4#<{>Kw&)TOc zhrTOWF2(SRrvUu69C77mUdFggO$cDnB6IxRe_%Np zTV#QF*Xh|+*}_~ZJ<>Y{_y$rHM`hfw^9{RwC3aMm0>cc7M8t^Co{MKa@O7OPL$69q z{ff}2Oh{)@sO%#b{u*fYUA_AXhqZ73Xe_<=yS?>@pK%HOcxSYLq6g(qs_M`pHKEE? zy;k*4rw!Pz-KN^{7<_}R+WVhl&U81PM9~@UpFh)0%hyUOUS9yrJ$Jj>mdgIv^WpWy z1Q}Uf6xH$MZIN`qWuBmJjg&h`uzwya)3Dj5-8phW`5O;3UwD~*Uv(`;#&aco&#h$* zn1#ICUtAnNPWT&36V3igbSV&GMOoXK1@Hg~D}}}PslZDV?445rM~i;gMjs;RAYm(h zAQt;o%T=xR>v|eKd}BpKx_}XaEaO}mFAT67G@w_VSE?c$lduA$HW+>f1JCb8*)~~Z zWgn|p`pp~QzkJzal%KXdE^+hyVrdR@KvsVfooRiczv?9KYOn?=!l=-8jB)JyI76qy z=}xKCyq3qn6^UF-*Z1JsYMa=ZuFs`vxeVi>XdrV+{fE_iUu%qh>`H3D zDa!B+S|KEY{j7xS2Si^oy9zQ5Ntj5?w+uJHMg+nh$&*>e@QN)p=~FT$kXU{D4+-TQ z&(U!zk|;b`kp=!ebP#fb4WuI`nQ)5()#8lq<~g_Y=4+K6^|JIByWnE_b&BQ6xq z2?-5Y4W)fXZ+|AasqYLzE1Z!9l@AXvCrD_osS^b4MFC)9 zyvcC1u2mocgxZ$Zwhr2iCmL4HAymXopuN=I&}0-z`w`0QC039fbl!P#1Lv zKqV+;piYhFUS5SR*w7uR3N&-etaSHPjm>=W$AQtIAGOc3qXa+q<Xd4K_^_(vhOMrQRFHz zgY$4sWme%5twq9pDsHteuzsxQ7cQl?wN@9YUM_XZP&jv$(Zu6ylv5YMUzyQLhPG9R zU9rH052Ff6uP=7;cK>;9l@lZX*fBUO&_DpO@^4amw8h&LAd-Y?pOqDeX=~>2 zcH!dP->+=CJtRUEX90etmWNr!9Na|{y0BO|Rf*P%-Yj|7AvkTz<^ILh)IR_wII3aJ z<~-AQri%|qu_#YrlWIVP*K<|Fx8$au;rK;!Whv68 ztgRde#No4c{=`unm=w?lFkg5$&JC*S4|mVkFits%+4Jo)9M76H0iVqq{8-t9kd z7I!ux&M)FKQqWzB-WAU2eVPGxPRP}N%pBh{Feo|7d#j`CDR#TtiT#%Y@eI`5fzQgz zt0#J`m;C3}S~f;AO!?x07U5o%Q&XNQjV4iWCxCc#TQk->n-x4Yc0>&tBr~CAGqbny zk$nNy#E%N8kn z%VUS#u)U5BjIt$6DhnXogI>?RBBKABv?B(7h4XDo_0++kBYPWN9ST9we4 zQ8w0H1m}{{c{__{``Xil!v~j-tdzx9m#(sQHgS_I5&Bg?0-Vvb{M`<1LhLb7%Rk?9 z_V`vBMX!MGn%L1zJei<3(3oT06{54&y0gjA&Mo4<6DC*vGBf{~^S;68IJi=0rBAM8 z;$Bou(DwDMXy^m^d<>+OWO!qTz6PH!9tx0e@s`t3U{Myc18lJPCiK zORDvZCe}sN-!~K0A#eI<3S^GHiP$3Yq(BB2!t>gLpO2RMS;Cu_nMQ)p*`zQzGXa1( zZOOOTI=G|TNowfx^oD_CpGQ{iT(0R;Lg$?O{#X~cU**4MzkxlF(Pp82gRDc?r8jT1 z{!vRka@w&M1ik6$OW4WXah$Ug#5)pE+{J&taM^{@s8}43{3n(ewXnUqQKm5m%h?nJ z)|rMPQN^W@s++5(W-NS3G=10xnU7*Pv{);e71W(02;2yu0Fg?|7Un^ALRC@+w)&0N zuoBqezFtQAZp5ZecM$TuQ$A_3jsZ-2Em=J_w2TtJ;) z_H8(JTW)&{ZU+51n}-^+GN}mhbBpUXHh}%GcDBwduNMu+mnVx+|HA@p*FNw|k(~3!+a3p}a zKLU_dgYh3`8%yGZgtrRR(HggPF#-EerEk9ob9*IueXxHzQX_tLPdcF1%Qdh{gay`0 zE=)neBG{i|Ei_?(qTZQ)J0@gU6gcC&+~vD!1>??QqVPEOUjMVhBON z&*RgDSpB-QZnWjwO7<(ph~`?F@Xe#-T0Si@WY^6NnHU^^gA7+tchxY%K_L%_?0zXA zmwSHYf$QItz9%qfT3V7JCDXb@JO_|@>Pc7#Cxx*+1Jg)h)PMo34Hko&@ z%(tWn(%N__v@-Bl8AUSv{ajkN%rZ1NILV0{fyZ1wt*8ClQD)*sAEE zOkG_|YV5}L&lHuaqg%7>{B$|@a$Ax6RO$SRGL#J_MOid?Kf;itaNaNpL0-r0EPLOF zw>=n7NSD?`m&s#f@Q)`e+*v3+3OkFfYiSqiJ9sO8AA9SKqz`_u9oEOJA-cu(Di*lPD(S%4)5g)R?bmmtxZ&UNA0W}qP_cX~oJ~Gxx zVQ`npyu0dvNA}_ESMhk|`>R?RTT-I1r_Yi>KWNv~@M9lIN5gfauK&!weDSu6T?FV3 zAtuTOatqO~HH7~UT<$g0fQ)sI+rW5s8mGKnS-5?vz)lD$9#Jt7!07zoSu+7v!{Q>y zl-w0I*o9e}%MStv)JsiKe7EsLinjXzG;R4i4KoJr=V!D2JahFwjBtR-(3*Jc*w)eA z>crDk;5xe`X~^{OV*oP&{sbdoRI4;aH}x59`L$<-TTx?0%!KluCNgBF=J!0@6|me7 zsJwnmahKd&!A(MLOpB>@>JxbA|W@2|?I~R<6R4pjTSF_hZ{hW02X^xZ4P+1*+SAp$A`W#p{ z<@su9I*mxeRw+(e^=NXu{K-P=j^E!nE!b}lehF@31RJgn@S5Rv3Vy5X0KDhz(QS9* z@Ah32r{;qNM59RXh{MOo7zCi!YkS9tbK!y<`R!yR{^JV+dTcukIH0<2CBW*9R^xq; zW|}JjAma2@(fW!d_*s`q`|-Ezz|}(Nb7vsb1^&aMgfpET5c}RVSC$}KsgN*U{JcR^ z>U`7=r9b4s-W_mOAIX|?b9>DVIY$?m4~d)DhXgJ}P2=)z3Cy>Lx^3Wpfe<>bq&2K9 z@mzPDkp>PI^1>v%0*D*uXeBv$)*PX~gJB3A7*;s32->A3Tj4g1j#Uba?G$Q=)!guLQ~h|3P0t7V)C(pGuy2FZu?_X$n}WQOVF5a>3>seUUjhWxGXEo^HPA zRAyxw)K65MNjY;H?zggNN`*CMS@}q6d^7I-Z&Lpz0dqhyV|YNq&kh7roN=-{^f1{= z)QvSE^Y9j=9`GKQaM7JU?8{28KJeh$1B(I)<0=j= z^;y~V1NV0!07dZs3tp0TKFTh*>$EY6N!vg^fw zZApLY^K}4YrhYwVR4(!7%f(czRXr|}A47R8)kn_5EtD$tdX7>(Pd&P9gR<0wjkZRw zyT}0afq<&K!zq&Q{0(I(w7l9f?Kd+zi~vWO`@k@ISn9sSw@>k;O#Nk6)W4?DB|g70 z$(&Mk>rirIflX4fEKAup`tbMuo+KrhQ^KH0Z$eU75$MpyTlz7Opmbh8=g6gk3jlLx zT{>$^=cMn0>Wt)DfE2?hwQqw(2m(KR@o$jW9#0cq0_`XTPOv(Vrt_M~UECBd;z~T4 zASMmtZ}Au2)Lx1?`N-S!ZEm1Fdd-(?Gyp;>VimH1$mwq^5B5|h34IC`xu^x?tdf8P zUo2KL^^ytTKgqKxo>40_5ksem2NU2RONPFoE?DgvtQm_7)3gMqw3Wk87bXUlz_?CZ zy}jrtjqxC3@bL=VPF?d^B8*E55?EoZ7vHGS?MEamVTBK(`tQ_0yh5wN zF6C#XGsL!`+;>#fZ+GZq-O-_+XgP3QNGv!XpLU!Qh zj>JPiDhw13UcppQK;hIqii9AYdS^tz542$Fa%eP`@z$2qqw?>iR7&6c1Pr9IDl~J8 z5msS=MzY^-=W((XiT_BJ(3^`Boz(Y>d-%+68aXQy?!HPv?`yQA>V5k9c_djY;AO6x zhmQxX9hh0eRupiAA!PRVsEe<*&X2=R*Pz~FR{Zqho!0&W=LifrYF5#-eI%Pls^`ai zQ7V+iMz*Q?03NT9Ljn1^Pllu`{93u>m@=XMkV^UFaJ^{=f7lKzpwj>5wUnL)01=3D zwjDs&2pDR)=u)tWb;1inE)AsNUWKDoXGG!;I{JxuQYB$ zJYm&g8?1#nkSu`=*WwF1}45iWVsUSq8fRA|LZRAs1w` zN8TnoP|6Hr!nJ){esv;H)@|-75^3)eVuvC1Ke`x)mOUjX9*qy?uPyR z!R}I$zaKs8im0XKeuJh3Be$NEp(?{pf*@!9V5BUYCA_fA;`FFck{0c^ z9;(y^*12t#O#Vsl0TJ_^`ju5n*6uBV??zV1MU5ju46oFemR5H7#OR~(x5TF2>dKslIT0M&!h zGtxXG1CXV*4BK`B4RBg5{LAi7Z7X2UgYg3V^5*PRHig>y2k9;vp|&#FIKTi@3hw=X zuhKC#&U`yeKw`W9!WGUFlC;ti-p%_+Qp9f}Vs%Q^8IkU>??+>q6Y3&95#HkF3uzBmN>u|599jBCX`IwAqU+k z1z=qVu!Q*C7HoBKdJ62oJGB1beuOK0Qr;OOP`f!ws%}vbRk%oXA9|oK|D*ZG<@j-w zC4ZmC)*W=cOSp5~mttGrjW6&z>e8fIImzni0MPf+gVj)xpjTO@&!|K3c=jkMt)R+> z8jh&A5$E3I^>v9FTPDu7E~Il&Q`~B+!bl3(1){AYT4Yy3A?cW(Be=!_!sYEsT#{YX z6aV9sPw8vvrN0}iYcKyQ1j5J@CC-%L%@cBFsQwm{Lo1d?c;D&;~^(trq|yAE`1797H%PI z{3!UEibbZmj2e=8_ulE-8Q)js%lVHS_nhfOWF3Gl)w=#%;c*0CSFtq0%wW(Gx}b`d z2&$Se8`<*2(Vebh##pPw8~vAZL6xW{uu}#;F`}DVkofRTob{aJF|;KPa5RRUhx}_Q3=+23`2AUyg&x8?^^m0M*0USDjm>NvAK=gR*<^Dt!B79|2Znndk2? zwTrf8$c>j;YMWgCIqiI%0cu-k>aWza$T{6SS#1{K3zn{=j*q`s*5DX`zxuP?)Scl( zC5^QQeG*U>QMI9e|AYIyEBr?meQb7Nt}iQx2N4n{dI?{Hj^aVrG>DVU*YzzUUqyOP zbP;|@PLnDCugIBmVPUIf(qQclyX0>zUGcSapka-gl8=~|bwZb>98?I11b2|~5^O1- zIB5=o>gU?XYZr+>4bElyNTGaj(f}9^y~8OhS$-sE)V6;`g10#A;wT7}zH~xUr=--;m3W{F4pvJMUo& zYX)#pITl8FrCVlUN!}_SfC>fw?XFAP(+PsgrVhT!g->!Fc3zj4W z{b1a675<#NY}1-FQwO^EqKLPfN$Yec6Rn(foYbX*;s*Mq&+6B29sW*6ji#GS>F&4_aol9Bhc5#_Yset*+O`bg;RE)HLYa!X=RTsjz2f4cg=agt(E)`Gc0Q;$@VHZ-6J z$-gV$?O@?o9i_yyetHB~{a%YbKui(VcH47xa4#YQ07+3+-I@ZciHA6{cEmGWh9h#u z4#Qj3F*wIl|1U-~%dSq=u94QxMesocuZL5SZ=`KK24oiP_@$9esVv@*1VDZBnKV#W ze3wy*X&d{lL@xN3qfub_+3jJ6SXF2WU46JSW=$0Px54?kul}(KPQ`+1Is@=OgokT7 z41nf9-aOMLU8@;Hq{N!9(coL(O!wcj?3d2&)I%QK<}&^nrCicZUEoKf>h-fOpb0ht zS-9@*ZQfch(y7;F&_7#RC4;exmTi zR*y={AqE>;n*a3P%EUKJ>!igjtt22##>znDUYmu;1X$os_;?XyR003tIWsDpDin^m z+XcLhb22J#*k1?uMk8{H68xyV8?q`N(@K^ulhA`rex~*W-%p#n~LiVe1<#<~6lJUbk8ORI%bg*_8yY zafUlUk9{hu8SH?#{Zf5QY$l=@OG`==@PjB{QB4JKEiHF-;{d&}3_8Zp}jw`5+dc1a6DnY+hX0+J$HXLroMeC&^^wrvm_sfx1)Ec<6OKM@{7yi6rT34g6NfP zP%y!1@1tTyOv2{`Dqlqre;b`$)U1~MF{I)zS!AZ}D=cn%562+L>G&#bER_ug9XAOc zsFf3uSCYaJ2P#B-$4%QDiL^e^TG=qyJ=3-8*km{#Dp}gtv%(wW*j(5OReX=CF)YpY z!!D~abf=UKsmPuP7dXYVE^3qlLeL1`MLBN*3n^^E13y}@8N&q~Q2GonA}G1Dh~EY2gD0vX?b zM-%dOMP;V~g`@PtW6bH_UzamR`tAj=VXUvhxM+rejKB%Mq?g>fL^d`W!rdbmB_*HZ za6EZ|+Ju;7$;xn=c{kNfJ3B09gw?mAogq}eUOvNeMgqWpuGU1)1M>fqw)SuuPCLi6 z*gQ7(@-HIv=t^aElWCo_>-A6^S>HHhVx@E8C}^~k8st%f!SeI#C5>ylb&Vj%f2yz7 zL8sm-o;qBPZt2t3^Z&EkdYzd$^*q&}c>pbDjpUHi@hY)*&D5u1$3jW;t_Y3j&3&iM z{{&)!95Qn&_iTQyN#;sZ0b6(f9AfuE$>2Ndk84G$~#&DRT@*9ZP&x2hBH^L4!*QNcW=L;(FcPW2`Zy|=%5d*EE}wo(RaFy z#~vEquJmDdR^WsM_F;3o4gwNRViWa$fMBk0;8$7K8NW25GZs;VV;TSC z#cee;4?=;2sxLYQy5fCMU?q#6zVrYVu&C3lgaf{<={;Lw()?fuAlQHu zzf;$wIF0o0@AEP8-`0^iX@>`RaXkIPD%Ie|>ZfL%`sCf6jP$PfXGKzZC@^Q%BcT#_ z{{N+jt^(nwQM1eL5f2}%9`0)j{mny^1V}i<9(#uuK`?Ewx zcGA>YBi9`e_1#4=m|s+%1_K=o9E}(>dc8T3?(NFPJ>JSI^e|tIbbv6yyUg}MD0B$^ zdjYM*m*dMbaU`RhDFj&fG%`xD`YV%P*^GvtAc3HXE{zxzb$SmZB@&@xJ(r1uQ82)| zFcALX!PzgnD?{T3b+c9tvsB`n=+?NZxmlOSjR-Kzw)EZbRT<6p+pwphaN(+2zr5hf zx7GV5EWPP*^(mvQ{$O^RKoxdjHb@Ot%#Ybm{i66h`chcGYSL6UEh_}@hF#GP?b}u4 z>ycG-KcPXjLH@hCw)=XV*6W9U1-y({n} zFZZ`Fkt`PY;;6ZpJi+W$3?y6j#z@CA9|DlUkXJt_nx9CsR}eIGooQhM9150HYriVj z0~`jJ>3YmFB@WPmd$1Nl`iw{Rr6^uxyIj|sX7<>`Ruo&IYe%gvE`d2q8bM$n)=r~V zZm>dieCaeguq->so%zA2Ci+%V*0jQV9d!&nGw;;ykCOf!R_OStbGdW$cr~{$mw^-~ zKK8Rm!n&27d%GnlWApj2f>VBf?%=PC!Is8T)A}NivH7ZBKl8`k9B$2b9y~;4Yhl1D z|3QK80S#eoSJRYy&GQ70tIXJlr52d^*Lu0!e^(O2CJfcE#AiNHJRQ<%y3oNBhw672 zu;Wvbj(qD;quJlioI_S6^-i7BbPfZ1rsJ&Jw_Fs)5(#@V9Y2&Lo*I+4b04}L7TplZH#7eI(;W$$$R4oR0Yzvku+S0Wo0H|=gjGAgF z6Bh*20)Pe+`z!Ks)l2iTli8VEqjLJ&K`aE$W`q{z`wM%H`R6y;7IP>pyu|52nto~`$6k-wx63-Y z#{Fu1$xV2hSr@%{BvkUc1#{5hY20qS*{ts6PUSZ{UQgwx3@&`@MgN29^`OBizg0!F zA+eh16fAWn`4393^nqkQjMf2Q-O&F8`lF*F83=@(60xp)Scgfd4#c* z`Ss$(TGo#OQSFd*%CzKa5N4jr7yU~z=!$r0B#zT6!$tCBt}h2mX)4XUm3k`ok%30`ws%W21`^HG0kHW zgVrP~4j-!0Bnx;E`oKjH`gtI(u&F?)d7T)=2>(Jk_m0D~NH{7CNDK=t1-1s0h|uVw z4{@!46w~FjL7yL8X(SDqRKfZM2yRW(e`-z1i1dl0+OtU%)kDk3Cyi!-^k(b4)nR~^ z=~_{xLJ9wASkonV*Oy`fwer6oXe4-XAYKy;jT3$fd`5nNh zPs0pwmk^n9JHxOWrHk#O@k*H!K*3+KSM{S|N8NSFYxN*_ss`GO}q^YJ8YAv-=C^&5XA*%cfh_ zJ3Yt6G9Ku{>U0!Cq{^*7$pgGNfPgE@0+F`_6OQ<+PHpL)f%5s`TekuBT6_Ql4S9R4 zJ_A-^l&`b*;)1jhKT_lAOi;Kc;t-k8^$MQS_{^Uz|{f8miw(cts69%dF6-Elj=?v__3$b zM_qN#-Vb$MKw3+U!sx86DQ>#6BaXPBd)k$hrHH^N@cJmgDzx@1DYhEFpli&6iC&~Y z`q5+F%0YOfnz>^!hW1Z~^lCFV>hl6~3-NCM|FD0m0T}V_A1rxW!xej0vk@Y7J8ks1 zw$mf`Y)0Ev^6RQ=BWhjZ%q`V6du>eE-o;R?e!q+#Cfs~KKdWFXdYhtf-2t29up3~! z09F*^b&SNueL@!>;!7BC3o|LI0q`O7-^oh8g*>HQ)4O$LdOyK(7A;VvoxL4)1+7u` z0O3OD{2tCrnMp9Dm&q%K(hUu$m-SS@b3?yy52TNcSB!@*cs=K3buYV;xXGaO84nJ~PZ{^%*j-tV>oRvJI19DF~Ke3N@ysN}&V zwsQItTt|L7pI%SAI?A=Rg8dYOLasCT!{WT(4^e?1pw`?h)FE}_aL{Tiz42!=bI9bV zkGenxG1h25x!y1@J(v8pA&UglmPiLO>{@+1;Mq&r)Q7|*u-VX_TbvF*09?4)_XGa~ zt&6xap3o5BTw~;8n`dV)y?)J~3vqK*;tT?+)>CzIRT|P?;(YSI3sv2h$`YS-8OyuL zlwAwDU4f5{%g?;7$%98$J=4#CbN8w+J-O+#`q;^!2w1-nWdz>NmziGB)A{%lrez8r zU|sgM7%yM1z?E;>#Jsy}71l&6)WCg!595FNOVciQ%CqsubkrF1I2`WM$JN1T|1S0> ztDml7oa~F6+Y`4$4AD_&m_6&s3j1d;IhklOJp9l;c6`q{N3lL?LEXVi8Atg8XXJ!s zw-TsZ<*<9s6C&N6POI{Y18Oz%vw4HNS52@Uo^Zg7So@B_!Uf@*lajJ6T$%y{77Nhw z;g-_l0RWdZ3At~o)EUjfO22T^d;$61#lO9zN&L=&Y*e!-#dx>}5cAJa<{g%chB`{F&|rMtqu8gvbY%43(z!^8xbq>gYAUR{3)nR z3zK{%G~6dWQj3J-FIe7~xj8+G3b#f+K@-Sy^ABK_H(si_^!z_WodsJ|Z@jgY?ruaHm5`DUB&DUL zJEcpyQyK~B5|Hk0hVJeT32BgSIM4V$?|DDKT-WS9v!DHoweBU_$4wC>&6%?^~@-3x%mWc`q>PU=8i}FrFN84bs*p_1OFoRMNhr(rZ}V-KbqB9g@Q^mt6!z4%^AW*A@+at!~4+uQxVT|Lu!?(&xp2KuD zsJ};dX{^oht~!>&G{+jczL=%D0gGMrsXH72B>nQ~0Wa=15r5NnM4&hON*K185F_xa zvFz@8n?l-$ESmKv;khqMw z|Gss*`$59zJ2l_(^TsiDA^S32$n*FgitCy+GQZ?8SyjAeQ>bW1bp`LsYkp$tbX+@3 z%a2k-fi2UtJ8T2A68crkNx?>iu7lvHqm4duC+3)_L-#UOH2Ljek`7io7}U$lk@AD* z9reN~RFbN=@Z4&3=aL9-vi@1f8ZtIDpG>D_RFxt-@q-!+y=(Na>in|7M(W~}hhAho z3zR?WX(QST{k572iRA^v{aFQC0dtpiHEP!jD)qBN<=6;~I==a_&@@{}Ap)!#BzYC) zQGTV@I%pH+MA@#ETpxsXpzE>;`G@Y({o12C1m+}oeZJMkjdYb^Sd*?e=m@7SKym0i z&+JQgK=HdG@_ftF8pr3f7<@#$E}5T>OyTn% zl_XnMs?JlJEN*Aoc}s(LCePet?YF`WF#|siu&{KvLI?fP#3SsxalA%FOCuIMkFG`{ zUQ>`Tl-Gs3?hfD2-j8m}sWZ?CXyP%B+Ur zA0v7g3!wU|ESCI_K0DNT)EV*bT^fv2eez2d3)0*lBJeee1CBs{IC-5R~7b9e_E zzhBI0D}$ow#Vdn^s(AC%P>q6IzjgGYCW&AzIDf}=9p-~|F&{aHO6UO9Bi+|@o-Q7{uL*R`&c|7vH=sR0muHpBi#ILJ*{a>#OPZgZP{OY4bkz$3Vc-X3vx7*0@mDo?_h?x1;82BUVd__^BH@~QPaQYl~ilF z6D9%NKM_bZ`~+TNv%y&Jro#5=$3BZ=qLQz*xtYgIi2F&thScu3xv~f`IG*2K{_&ED zi>5ag8VwZ{)&(JOhnJ*fzCr(u%VDuQ5b$5rNb*s&r!^b{Vy)o*EB=x+)k`nK;Ybd_ zs9`%uPPgYJ9qcc&;MrMMc(AedgH@m1p6vZ9V@Sje*YnXJd>eq8vKR5!7qWNah`#R> zvF6(?;^x=3**-UjtuqgV%<$vx6D2{JZHX84k6nbSMy6VH6lOUg&CP&*L3TI5oTEEh zyEKl91jG-`bm-VGCgl=7aTTwyqFwu4zdt-fMo^KpFa2xV5$8FWEpPt;x44wBb!mF- z&)|W{Lax{gaimT?&z3P9_!IWVue-9q`iSDQX@s;8S*S6;|x#Ev|z!zt0!Nmc*nMnzA?<$103FHJuV zo4uZe*Oq_(;4S*sa2uc(QpK^JqqUI;_S|AYRQasQqsnm^Pq|&43<8G4XM6LQPw#r|((B!*&R2L= zR+>v*Y8kHz*zwEqOE>=RuQJb25QgaOMZf7V?;~`Kb|I`t%^kZ^qOI=yyu~_59}mP- zZPNpmDiV5)y~ ziofdnj_G;!@o^Y2ajl~p;vghJZHF=={BEt4goVca)?g89gYUCV*d-Bbdgk0`PIA-H zD9c$7L8xa)8Ux>ZT?(xzkSZxe{ZQ3cCmTMDop8UdrZ%FaDAEqezs8a8S&UI`3X$kQ zGC5x2JMoQICktjHsa(zG12wEDuhO%#;#VD}hkI#?RCGP3OA_MOyxr>eL;|E6h2O(_S%4`W3Y z!)D`47h%FY6y&#Gww>JsPxE?0Lp*=B>5+|)m1(K`^FjH$*cFSr)V%MVIX-wI3wTpz zxUeA>N3h*(U&K$eAdET>(=wy3RVDhAY)tS~3U^V@5_xnCh#HEAnttV4j)pD5q>G-Q z!PBU)iaX3UW|^_)3qq&sN`bhR^KCEzB|T<$f$~nWnBiKOAOOZ(nzfT#WrdU{tobFx zfHSN$3pu8GViHa-sVi>bhI)R9u~>OBLJRom!ka_CLk&Rk!|Z)6X9$BW`#Ce~cl9*R z)a7JPVo#Wkn>Dnv6_&o~!ewoa_lTNjX}k4i?V{)(6WbtB8u+FjyW>w&%M4T#JcyV& z!X*r)lQ`kaM4=Q=HWlkWlkGcfO(hx4*HM)dS?P7_Wz<@S@ra8g~yd*<^79f#2;l{;5Ak58mVS{f0biTeA878(@elNe{1x!`} zsVrZ%uTT49tsdrc*o2(grb5oYeO(u?5~nK5vHwZQNifbjL+VQvD89Lw^CmRD>T7d9 zbZiek(ZG)U#^{5$fY=R3x;|vHYTc&zsp3;q-q=K+pd?UqxsnE{e%@IB>voc)h307R zLFvj|HSYW%w{O;Bo9CxM>vewEeSxcE6k!0Eo$vJ@XP2e{0LTkpzh6*B0C!iZ&{!@1 z?p#*wDq`OtY4G~>EI^YXrP<;KK$WLpxqrqvu0Aid zr0e>k>AlE#a8wlSyY?WH!CnW?uhDq(bnbJjY>fB*G87r&=UC;Q&k>s8UJon56CF0C z)v%OO2?6aAi7K81MMmy2v4n=1Rx4d(@pY}t!7QpBkdSGUwYGz)W><-!zsBJ=$z4(M zs~G>Oe$$SIb6`Q+q4`m%NLz7sc+e@3&vRNW=(M*h4vZsG)mrZ0!s=Dw{*e~vwuv+N zZCJ+Ys`kkIA(Rc5++DK@Nj>uy9!-ofqRIT+CJQSB)AJ+U!!kM_jBLJ3Y?y0lv;8y= zNvF^|{qm##^!)c0saj@x)qcsDU9=V^*{jQdZw(MGRsaF>-hW)1XJ}-wa8+Biot=8)=Wa#J^wF#2_<&k2P~6;3waVh}LS=?tlLc5Wsfn z;B79rVi=#w-ON3zTifkyR zAtYo`LR6Rt7BYu9H2p~1A+qY=G3P!m-{XH-^&Pe)p(Pi_De{Kp&3g~*tt39KR3Ev4N-~pzj(%>NbPj0F5VZzzpmJ{x z#UeuNep>mWy&Pc`jj2JVyWd3)g_SmWf5cekNIrY9YxRpChj`|gXUQwO@GJKB{w-90 zpp7;+VWEuK{4A3o04#V;GYtGMD_z}N?Zc^wiVa(+XS|WVLsj*O%t+^nfJ-E|!iV76 z2=57NbanA^=OKMXe(smAA4|W!$juD4c6QN8TyqN{javCbs^YbS2|WB0@KGlAI4sFmwxJKf z14DS^OCUjzP&fP7fcB=S%S8YQ7T}i5IboeM;!BIdXE0=MUFvy4g2N5vw)+gB{w0ts zXx9-V#pQk}-ZaHWjt$p|-T3!E^&Gc2+S&_Zv=LwAW1>;?sCq8>njV{Ze~iiTHzTf% z8r$X*e8%SlfJ*=7%IJ9ZS7T9ktr~;fGQa3w{MmNm^$uw0gv||`_hH0clnv*g!;$=b!<-NAaY7zEeD*N@ z^c9G7WAL9sx(&gA{`tl*8|e7nEw!JX=cgSL+-hGW|9k~0a>TeLiK+L{G&*;>G+kwr zQOzn+%XoEvCA@iBuX&R;&~a78W}XtXExd9yG&bG!D7O&}PhX|={g zrr?dDl>r=pJb9q%`K&$9K#yBW`rER!iEqN80`fss6}2Yw~QmG zMg5$7iHcDi6PVtr76|8xJ@w;LMPts{*5}JM9tp*F63qLDJh$*jh%9P%*)`XZKgY2j zasOH8|LPh&d&+7b(`8m-QWcMHcW#g*C+w%6yqtAOllU#f?>(?^J~w83)(=*-e@k>Z zo!wO5KIqgaj3oTxQ*Rtz#AC&+7mxVlv4z8DVZYXBGtj{F`z26)G`Fd8?i1yNc19R| z1-`hUBw>d#$7d!=t!Ca9aRSSpVVbciLd3c#~wP)*xFAOOvInk*8H9w5c4Zf!Z z#>{=DY`Y8>7SGD0L(apyvJH0+v=j!opol{uQ*$vxoBqcM;9GYb10Hw_wlknz*z z*~5K%#%fW^G0{DGQvWQ;?E{E*B-;Z?o9w_FguB|^cwOr89JaYmX4)1g$sk1}%hP6x zZ*RY!58SBW4G*`twtNi<+ zU}+EJrHyR)oMYN0i)%EU+GuXMLc5J=iM8k?)ghf25Cno#YtjM6CWdo}< zEd?9g3)Idf?_`ecUunJ4Nvw8~oCtP}-(39PjqzodS_-J4RnOL10!8|p1)ow&x$;eS&Dvb6c@5i|3` zb<AW6xNA{O3pF|DNAblSM z<#-wP)v|YSvYOu1Tn@Lq77_%RPNnz!dov)@$>Y59berny?DG)>#Ow;E{Q|FcR%YU)f1d=xo>^D`+NmT#cZKoO}hHy2ur|w z+VMsq!F`R}^6=6>LH?dFlQQ%bsj zz+c+k?1u}jfX2?ympmW!jvx~w&S)2b2P2Cld)l<3m#sY6h(A&>!;Cm)$KNtMxbaLF zccZklHKQ-i?hac|J4?m?IpRw(M@KklE;zPWZ@{**v#2C+L56pFt@Qq~XUC$uI3KFm zNK9{0n=$w}Ig8R&{4R4dr(*i4t$WW(wWw0+l#oEtBE6fi=Pg=oV9iei)rd8nf_$Xe zeZC^wQ9%VL$t^#ZD@tMpSN>O?^Z-fzRg95_+tp=v^Kcmz_Vg!CHGlpRYrq<@fb{$X z^#GdCs?gS{FVH)mJ>V1Fc+oi9TX~U7f90=K>dWzjXP%%Gx`Am4aQQh`D!aXv)x$l8 z@<%(J19<~Q51If_ALl+28rFSLD$fm~;XdOWiCQl~WJtgXfqaSi{mAcM+~9udMoeP( z+*=?sUA(4z^JiYWa$!qA{rXQ9fZVSx?WB!MMTq#ucy~vlzlJotw=!=FnibpVF?A8{ zqOEI&Gv8z&If`?mRL>*I@IF0Nnf8SIPKdfZbpJL!fL~HD2yhC2&T5+1PwbL-W*3Kh3bn>j^|-%?^j72G zW=TIIdo_L}U&EG|!NbWuPzL*kq2{zEc;@Yhlm}tEZ8)-{Ulr6s9*7zxgo)OKr=tvzl;jwK*Eqm>JC-FKNm%W>UNQc4Ef-S zhu`PU)IE^|aNGEFEXWORUx4m(P#q7BA3ts^^4kw)z^i^Pv`fy2gk8YUJ#@Hg+RDl$aC1(>GU z@r8Wbs?)71SL!e){8XuxOS)}$_qR__PhY`Eh{a+yc4;-9t1Z6YQ+h`V)}x;% zp3S~V`Z!f!!bo{ne{E<|`BG0mfY_Ui3}X<93nnyYf@)M*TdVxJ5SG9;Qk=@YCbg>C z^W8dWlA7PM&m4o}Ih!HY$!8wREts;r z;$EW76w`pgUHQIP<0|^4CatwnOy!Qm^(HFO)E?b=o(S@bEB#*2nzzdY3^T?>kd2f2)AIM-SR@RR)c(A!>eZ4=>7)pwU>a|R>`mpqYom_PhOL)X@9 z`|jTYoh|RtzWv|tDdWV%sNRXtlgGIa{o=Zmf46=|&Fcj|{A%8f)~XC4-T3Op&-rHj z>92r>Nv#uII)>ZzX?{d@yUCFWRk)IBmZDh`*Lel#7l|V4JJxmlhTJUMoSpc$@#afU z{e;R9eB`A5C^ECKhvxwmMF0?+mAtOL1pL_Ujx2ju}cC`KBr+_hE?PMJDm?7_S z)7SAUl(nyq8HWzbZ-kQ}BtlpsB^KULOkubA9)z{+Wi-?`Hk-fD!G~2nkq>d2DMyX` z%^j@IZIFscAEM2rvLa9)&fzQd)&9FIZA6Q!5Fe@>o!`QRzf=Qj-y(;nnP{W57Kr~# z|4O=X4vmMqDO(GNF1Ri~tY%b{dN)Tndf)eQ%sdF&>m3Y#p$7vHR? ztD-&nwAq4sT(CCTYx&ug>*sZgJr941p2N;YU?jj3Q`?e8Mz6@T*A} zd)_h|g7L7L9+QQhQuTdE9U{#9t#v=4B&~Gt+p4zrmdE?syK;$_FL#?#s|+TwFUW;e ztpy{7rd|ywu5yQ8Id0VEK)~g1BK9fIE!s(Ws^7Um&oTakl7q5cTUL%zso8K{f8>R+ zWyRcqMc3yo+w<96e4k1^H6&K;O*ClD(9CFlBuHud!_Eg^VK2Y{bRng%&x2=ELSy`!vyo@(2TuCe$k5HkOgf^`bcSYWf_S9hLd) z00Tb#zXhex8c4yjxQ#7nDlWjL=(tBzE)?j8dAPnSb-v@#t^~p!7fqqIKid3M@k~d* z-zffQhI>rs9U-{^S_PI6SXy1N{kAfEU9s0cV1dEqlzKvpJo$qFooS7+XI7TWNfis` zAoI=PVF;Oa;PE<9;6?;Y!fnV-Mu#``#T}83K*X(Q04_5Qectz@B*2PFU5%$eH1X8k z+nzo5O^?G2JGkW3RaZI1d7)2a8RsB^VEUf~1@0Ch?&YK2x0lQ_t%hjaf+Iic8H>&W z+Ms4koWiM(?GEv0Oi3n#Ii3Y&WuH)Dnf0Dw5H1QwVCYh##F?@z&+QsEl;ZPbSHAfd z-3a$BB2?%tiNhYP#18p~5NW;NN1CgQvZWK#JWb1~sZ43il8}e0AIVr@2(8crYpnDb zpJZ};H8gE5Q*9hzDx-uLer8tpld)j*OoEC9i-gN*HQ*$R#@DG^1WTMn+vNJ)gd*%E z%boraf&R1`&VrIgr>}l;f*ZxIENYy}&ejE=qvUg)HFif=vC8g|c>3AuYqSYM6XgJlIOX6zd|@|5LGmAZPq+plxKJp3XSuGTAZcDi zm@#NC0}Z~HKFCXL` z_Yl&RFJkhaCmBE96}|#)KPTwA+&QVDxi#Z81hi)YLP!OB|M#-%2*5J_)H{juj z#+VfEJ)ao}V#^-*vi-GBCUjolwukz)Ctk?}VbkV?zwKl6^k%;Pi^1vWh90Jo*$LfK zN;`*b3PoTJPoN3>Oo9E_D!bkU8)$0KMRxrsjH@k>Y?d$~cuf3raWVTz#kP|Vl+!f# z@i$g_=N}h&kaTLgbZfBB!j4-#G4Ys8h}l2!8}~NFu$@H=KxDeD0^x;tEAkHB_Hy-N z#ikI&l4w%43*k?Vl^x1;b@ybwrHcC$nz#GbIsI*t;sm>ag2D@N&=u_UdApb9XV--q zv@1YQ@Mk#wp$2SfqIPE6AVc^g4&r6lvxs@)1%#NI12!v|eu8VvKH~+r=%-)w(v3Oa z--Z!Y@X|)(++}i`M?Qcl-)kjz4H(!1;7yEppn)n#!h5knYnjFf=$COl8n00ATs4+9 z`+Fee0WRQmN<9eZWJch1Y6wwefDKSmSTEf%PBw&O;!h^(_x!kioXWt2D^VIeUQD^; zQ0_^nR^=T=TLM4gEhpQ{%rPfPik?6we&7h z=GlEZzlFT+;3hD(@hJz#7I?#Jp7R}+DW8;U|HQ)6)&Fn-8{rV{V5)mQIr|ht zV!UfPsx4w`obBv?mZ%gUp*Y3X<*8-9@~InKcAsOqPjAT!a+#=HJ1)s20El6@RBQ+A^h@5z$8Q9jt*Xbxwy!%GE}e8Ew_({9%Pk`)OdP z9?WN{x?x6+Ht5$5D<9?;-OcY) z+Mu2YCe2xt{WNWxw8*ecw;ei)3!VXOTr3-d&HhF2eFSbfg&ckHzkX_OvA#O;dD{hO zoC$V<%^G!dNAoR$W7B;q!5{nvHe@jGy_E)W40a(1%zlM&7ZQBubl=?LMH?Z69eNhJ zH)Kk)5*?KbJ%A4p!)0JL}6YNq2v;z0LLk(feC?F;U>D#cf$XMn|P>-B3d zQA5?##fzw2&l7!o4-of@P|(|xz_W>U)s0Zk{1WBL*Y}v{@*??Ho)d&zN;B#nqAahv ziZ4z>~I5G(Ht1a znYr`sBTvL0jmCw5Lb&Ayrlv#dGgA_`dHcJAf|9=pMjXtNYzID>q`$y03igAWW>nf& zs?9=cdW8CNd#_CF^V7rQU?uWyUu|>>qf_O=b(?d)82;AF=M}~C6c9xJ5`Oa&JzbEJ z7*og#QWCo|P+t%iqiV^?2tFR~?0S-kdXqXMHe_#~2}uwwt9xVJ;P7R(&k|7Xf8C-U zJ|nG{4327DZIskPMp`a7mfODnc$X}*IFoRHEqhx~?~W{xaUm%8ktjeh>X&*0NrxJs3x zZ8rB0{i@O&$2;UjH}KsNz^2dqdL#NeGf}7wh?tP@&q}V^D+L(|(3Pl_kd)eFkBp`x=3aV?S-C*6F z5!k+oKvr$SxWkIS`A(0&6X!@3adeXS#e+#_kRx`)20L389y2TYSZ!V$9exOhpc(O^ zYBgvLYB30WQsb+vU4kXEZ?Ivb3DUJlbgq#QNn@v{h#aKg^Z<8;QmGYUquEF{j-KX>rjsd zE8(qxoU11q(yn;pthb>97l~q+LBo|YyKWN_Ti>^w|!S>x# z!Ba6@UBt3yNX#983HUYV9ju=;1FJ5p`~?@OhznSz`mVLntKYy!?@>GN#(m0|;R-}i zFZoU!#>DI0tmM;dd#m0i7_hS%hd$$FVilVJyqU48w#Cp3_C+FIYXgQHUy4K!8LwAn z<_!z)s^0yByHZ2Q_n&|__R+k~bUF|Tj85UyK$)*K;vLJ&+p=6@0gu%BXKIgq9Yz~o z!e&KKIP)hG4i%nEIWpaS6l2w5v)bXH^DtEld`s&pqsk3iYmv5UcvE9ddo<OtVo5R!VUW29FBu7{D+&KSHcZ$q#@Jza7Xk;!V=#q%?NBOzs; zC_mBRhv9YTcAfkn8xFe4nnf{-vK!(w;r=uO159^%o?l~vtblhc+)Ztob21$$EGd~x z!R$v8pRK53{=ewEujKC_eSa8&Nq@3aj4KIM$Wakl;>WHkXbasCd%k|%4HQi#i(0RK&)XVzh5pxKh3Cm*Yp>3B@F)JB^8K#7 zqJ_yfe)x>cP!m0PRk=PP&JB!Ek8x9v5|?or)Xyj?S3Tze62nJR#Y3{Uod#oN1Y3K; z;>TWsL)j&Wjqzsx=qb6n+}+rctBV;GW<^lGyN}`RR3fvM`8k!{+-_mh^sZ5n5Ab=_ z7Z&4A|3FmR_}phN?%%yhs5Y|f3)S+}<{BJ%Ja1^{TgG3RL{7$v#^12nJ?G{9dG^z+ zVj#@u2WLa^Ag>jD>0X4SmS+$7rub*oxWBjt;mfr&rCXrX5|P50EmdPr!O3!G0~>Gg z1%F(#dac!Wywyf~n9ET1E594!NQ(yj`xlL&oSf#Qtj)5V$Q)vhZdg_FhWXU?_4H~S z7Nk85!2m;ORc@CTJLec3dhx{;rOW>@4$u5oZVxdH$hqSgEZ;h&X<-4RzL;OC+^vtY zIK|CAr1>-g+x1El0p~nXB9NPwSuZkVl~u@l&uV%rNjz||u8lwQ1>Gv=-F+hkUl#BtByOr^Nf`u@$gYCH$<4S$U`Y+VvIM2 zu-fxbemjSKWjeX6P6zAY2_s#0HhHgtjRjn*NO@L|1EW!iL#NDBW7bDpdS8y|SH%pD z%rG-PZFUs}qv*uMbg#Dd(e{wX&)R6u=OOp_fuP`0UbL z!Qzh_Y}iXP_?@<8Evum~NZJ8Q1>~~J@>ZO%Wmf2>AixlX>iBQ{k}b3)rMXrRqfV5u zlMN>{AENtFKVj+BXLH1LzIoWU>}3a`?fx=a-Z&C3uzD}m$q;V&`V{PFGSfNt21ldj z<&BI#>T>FR`N*&;CiW8x!}z27PQ2@Ijxu>I{6jPo;Tt}Y5c`It9Y!AzNnIgdvtuc_t-mzK`wGN)6UdlM~ZVTInXnac|(;#Srnum&uJMt_Q|Xnyt& zbwp4;eN5k*`aCyfCPc_LaktxsCJG(D=DvTZVp+D|Nj=DmkGi+1+?GL&T4Ionh~?_0 z4;{b~KS^QvZqpezIdKjVlL?6g6HLOaXV{)h8wPILpaJ0AQO^uZ5TLvKP}M+kULzV>aDmuY9=BP%8@jFlx(mR zyl%?Kwu30ghx*xaL50J+tfYm_o{k=7#~hRc8AJuYVtxT?+D~V*XvUg2@w=pv*#Hjp z6{K{QO$?!X#JI%P$7>4 zRmT)oq-3mxCNmFOebL4@TW<4Ys3lw>&gr-3$~GKmrQ25_eXeQ#meP$j@JglYdKu|g1C(&z_H$=($)-NSxN|8*npxE#q2zy_&=m)Wr=OG( zT4s8hgegrG`<=Gc{GDk|03h*|!UdrY3mC=B^UOS%LtkaTqPl`OTHzFMSk5f7jBDsc+$WA76I>4?O0LDznK=g`F`rFW5ny-FY}-dKuhhZ@U_S|! z{E@5`(RHyMu61%#ExlWjFXmiC!3+H$-P48z{~2fRgTKO*P^UVe)`fb02sat~u>R*C z-Y68s>W3BxbnLl;eIQmd;ToZmNf>%u*>o=2%ze*BGw1(1*wc@Lm<$SI-u+Gmyxc*C4uNTzBEqnXE3eqdcX-KxE{>}o-9*DOfg_DvRkI)dvr7> zK(-9~W&!C$H8XOBOwTFF=_SU2`^l?Rcn*5B=e`Uw#}+{iXAUCHiTBnD`nTkXIxf+K&XQ&G-@wXI=BVr2rD z+}?i76ZT(LsN@pyr-FKEoGe6t$XmK`plb>ZNlm)fHtOb<9kK$L2+9YxZO)g(IJba? zGUI$+Tf)2`Nws9-ZsG31o$tqKW*gDPq~$2h4lp96od+zF|1iPS?=Xn(0R3PSfMJ+-t`cbhTu*tBYGYbT z{Eg|1;P&h>`r1qE^_DTX{WK=>$%}qbMWd7h{o{Q0cK4sE=Qb66b^8Nf_!(n@#2fuU z7FTjCLDT2a6e`uv8V62mSHHlUC^DdsWW+A{xST}x-vYw2;BTZF`!BVjnOq@P3WFT< z2gjzbG1E&oj!6PJ-BqxM&dD3RIEaAf4l(2*cD;a9KPAztKfp)p3S_6@a)kB+mDeD- zJk@%+JPW*w=t64Us!7Y?ysa9K8NvbFHq=_E7ZfE_AmOPPId;UlPcnCr%;GZcn9aq^ zreN4%o|qu>mH$CnC95Ftg8Vs9%g+Et=jTs(7PWbku}tRSyNp7M+xGTje`br=oMm~g zN+L_2lQjKnEw{2N2#mbP^!hLIhzjly?-Vv&-9t2C*Z|;NA19xL(NQ#WvAiWl1O*7c zYUNHfRLoVH6!8jDD5f6V(4@5XdQN)P^$92e2Z>Tcch^ zOw(Nu`@(ZiFumO8cq6A}O>2rjMpEz~=IuJ$@ESz%m^Yb;)sPMZe9&&OP8o>M4U-O; zz0~qAb2*Iss#~(h`Dl3O-Y0d$_^~{gMUhoHx3n^2w%6`1;DZbDr@qcYEJhSGG-j?m z(dFzgV=5p7D^3Zg^UW?mtb20fd8rblyBaIA!W?r~TrqrsT_a;zUfZxl!2JUngN1lB z6%ChOSoB48HYU(ml=^j!>ljCrppexN$KNSF4$U8txFU`*=s}KrtT29A)KJ+C)(1wI zgtUrd0;HA8w!Y3Tg*&Yp@G%v=qasVwqy_r3S*(ZN_73z>SV ziAVkT-ZuVv&=3zZozF^?JVKr{i#a!XP8HY3K5ZKQTjf$}YoRRFyWazrKx6Fs&GYl6 zjcw;LzRlj59wbC6unRnCv^O%g-zorzD^cls11bZ#>_CvFcVVH6o49vEYeCQ({c*k4 z_|XWR%ywJ!@z2|dhC7+dTb(qUS<7+fSg71Tac{ar3ub?*z- z>mO`Qrw^Rp+z|`Y{E7mjpAw*ZF896k1>>&D91RH=pa3Pd47eBhr-|NlR%4pJJ!wRb z!g!@Wx=->O5P6wcI-=A@JNDvgk{i z{dgUBVrOL$V+57g7Cy;3FSWPvtk4ob^G+s3mqwLl8+^dL$)8z3TfyJm z^#@+vOdyx-1~7&v4DNVxNR@PzHe#=Fr|-~@;1Ohe4DDivQf`TBDMEmY8E z3MY(z)|nD;))CPl(3TmM$IMQwJBPy~N_6jI9M$Z_+f`_9d29RC&4eL za<#WUAAjEmf|P{<%9i?OEvKE$jRt#&M}n*rZsv=*Y&d!Y$EPmxbTZlly$I*VBEJyb zMHjY`aQ1m`Z&%ai=y9qsBD$DT$Z8x#4rm&xPLvC#A!7=wYHZku)-F_Ec2Ud%WSFM0 z70(BOU-qee)l;a^g{DZPOM2Ju$*R4Hg%n5~zFpGH`|Y`-ApuvF374pBcZEYlWFJ{x&QTb_ZB0-*uqlUacAfVGY6iClHQXPe&np%dT`-+5EpqRO>l5E zm<0R1y2lbi+F?5d;mb|T+%7=!#$wf1yBU1*XYe>gSb$n`n(I|~a@gnwiSbk+gt(V; za>%Bi&G9jA3*dG=>hxMW6X96Y_FvcGr`zT*&(U#1)kN)_Gv=C_d%rQ^7o7;23<1~b z-nsP^s;3-k;$|x0=y{|b*<|-^C`SJs`k02WH&?8Sm0aOHLfN=B*i#iAzwt!>e0wm! zlQG{YUiK&@Y`AKFwUsf$4F!lHIm^5ha8CcHm?Q3rpzHh2`wcu3q7{s;FG=9%y1sf6 z6fo>lA|At!v{klSPen(947$A{!!MwO z{6yS0x&Jtm(!Wc-weB<*-O)956NNXZ74dS|R10L>BR#}OPE%Lyhn;YemOsZ)s>``A z8|)R;7_*ljidfXC|CgGpwuO#nhjn;osh-t!N?R4R0V$k$B;kg=d0%py(oi7{=H@$x zqO9q9lIZ0NeVnn#8Axst1Rl*CHgY!l~XYmT}qUCE}?D6@Gv<^1%QfZSn17 z*k07dE>OJvArX!aG|@K9nLHJ1soj<(`w{n`%(*Si`sRNh?o~amI_X^pkzV|R`{KIH z_``1(Oti9TNFc&}=hvnN^|>ec2>}K)arX!>1sQ?wO8U5#V>GEh?E?g2BhGQ6B`GAG z6r7O}?TUu4`(wJVXRnx()Clk{-nIh~@Rg~Rzpa;;_?0Qp6BEPEOBN4+>EaSsjP+|5 zUePJ8N}fEg<4be$ldB^x_Nl9***nEL=i_dQ{wW-lZ%1ce_?dprT3BJ_rf#Kb>u!@e z;)zYFYdPn|myQj_@qDvNqbuKWr*lN)vUb%D*Cv#5BfH9_Nxv=3kO|(k(a@~@28wgM zHMQ>gg>5QAevaKqzxv_pOvaMM%Asr_s@3O_LD zLf{1Zgt>Xg4DXHl-=-!^4)`=!h5|dVCu&{sxSs_f8o3plSk z2joSY-7Wm$4Tjri;j?Lq%R8m3fJECM5r#+!n?+fWSsJVk5tP&R`LTbq+o(0Qcl1En zk0SGIk@4YVavNbcvNWncIRhD+m@d6H*~?_x{*j$Y<($w4Okdp@-p&p$CdHC{E2u%v zlaO>E6E)TK(qC0b1l|bA{CBO|3dEd;Yfy;cySJ{v?-=&i z36a2hL6SC%L}E5jyerFH!$w`D4=8CH%I!!|>W2D%!iLG!V0vPdTh(eg+xdL~r<+1F z2-*~605xZmi~n?!yu~W(z<$k)@n5Z8G2cYpswOLq%{`1xrjM*3i1dyA3cR7U^B^S1 zaA8_xQGx8}cHSZ%F5I1#l{Iz|XMC5YEY1~<_C2GhhbvK! zit^8tve;*J2IV-CL|*e!qV36$vnagT!9VZ$10KBr=02zePn1hl=HMp1GHU;UEA|e( z<__7|Pi1ebY%p75TlVJDt>UQh!(fO$_oc3EBkHK9>L|jV+2NIbjLMVs(K^%Nq1z5r z)Zp~>iiPr5z_TBHXnqGYD#mS03>Ym$G!kO|v=Wy%ZtrW~!qR0XjEdf9DtOlC`cGiK8rmT^-))!b1OpAVp>}KV z4^eG(PaKZ`^vDRCH17^N|M9C0B82@4zjwli1{=Pv)u@Y@^mhn1+UB!U` za!PoIUkM+Gu!%5G(KKGuF88+EU80r6dR{fbvjQkS2fy~_Xn$pM{yRC$GoXFnkSSO$ zplz4pJbc2cd3Rq@{aF&M?xg-d5Tl{0pIjFy+pFS!_?(!q#zqd0#Q^gQHd6Hb^Le3v z2Zf6-hV}z|BWGSOs>3$rVKE4%-o>6(CevyDjrsdgR_1uA^^io{;%K?ajE*))3WuER z#4yb7Bg1;H_RnKZjv!t8+XRi}oWVU^vo>z7lK|%v+<+`(g8BE4oRA^wGlQB|_Q>&B zOz|PVXhCOeOwU$FN6O{^oi0z~*`>=I*5N~L6zHl)%y@|!xAfguIJHl|y65ivvh&WU zxl;lc=gP}dkdi`}KF(m^L_)mI11m0PbT0F2p|i-?KcBO3RcGjfi1eIP&3%lerTy0s zQbVHebF6Um#4efi8gme_edY_&T{$gD^&%cxXptG}XtMR;%@HMW9X{Wi6Ii0+I0py* zLPbedWU9D$1ca4OUKnLLJ;k1g#aUfxwr?ep;LM3Fl={qRm+dZ=$DS6mJjRR{b`~tC zpC0xX`T($%QPoG#=!>A!X(8KMJibmlwmtpM(Hh9<(&=y}Ed0*A{!s<%E7zgy*+5wg z)t&CL6)D}gP3#Ao09E_Wx2XJ2LR*zgx`N(|kI^Hl1&uwn$1Y;5=YEXBX5d`Zz%Xf5^!4Cb%s}>Fv}!Hhp2mQc#(dAV=)sQ+7`#dE&m<- zF(StRVTz;(ugWnkR;m>4pdu%0mq$}@1-7faxjEKVmGTlJmm&_x z*DYQCRsN?3!@*m)YlSibHVq7IzpKJ;#L~}{ST^(qo3{{X-B8CIgxUrlZ0kC~6hUw6 zYOA(C&Hu1<&JTIM|KHDU8LMU2;;OZ{Y%klk?Pa%Y+jh&gwQOtoKCit$Kiofj|AXu5 zIy=te^?KrQ{ZHGm?LGc`@AX3qDe}=HZhQL4+^Tzn%)0~JWm4IpVxx(tQvP8IYx8DM zL#v9B1%W$hm6G2AQ(KSKsisf>-%b1FY1Ygq01(beCaVILui_^mKz|uD8=9PYv=GYo z2w)DjFQbVaXPlVJ2X=Xn#^c1qhX%gfMkI}XqQO9u(39%pSxhO}Yj{Y5yy!?oGbx;t z>r|}^XQ65+@`6Ok-Tvj5Cpn3TolFbOcL51AE${Kb@|MI)R)xgW&={0n=I4)F2k1d} zjTbvOJ_O~DA1GCStL9uW1Fj&Y8;#Dfj71&EpYuR341IYsaB);s<6Wbda5cgvMomGB zA?W$1b*b!k{~7p%X=0UxLWNvGVzYgH|A;bplD$y_Ezsw%r9}fTcsrv-xnnM zL9G!Qr76nOrkL>n8Yts5XlD$LG3;M``d<`$)UEBF5L=?UsBbQBxcOu`2=7im@RmX# z9t>L5jZU!P-%c!Ge=KC48$rz zf)nW1IO}SW)6m30O`i+8JPGrths8p`3i$r6fk)ZfLqqxY>*VA0HY)J3Yo%j0WvC3A zIzz)`o@%tI9>0-hurgSF9FNSEAqHvDW;{ss8gVsRDO_jM>bR1@b3Tw%CcWC z49DsK$`|fAR0d@9SYjl1KUGPaCA&Wfu)m51H&;3ib}A=NwHdzNs?cnk$c+W)QtWVv zqBn3Bom4aR2ENrp`8|gSu_YI!U(8;7QLA{i0XWI@CVlSq(LGW*9bb|3bTJ)>hGTq8 zI}nG<%;<|J{PkDOOue_X^-TQPPMID3KTss~lO(-@s@67;AvbtDo3jFl1O~e*$CUQ- z74o7(r62iu#?f(qi+>*QO0CBOCfRRY^G~@ei#f#mJc3s3(;fK>xH)|P1;}4(jx7kD z0DM{@wyF{LN|t!%2l4^mA|tqdw& zD6fe((sjksOxmv7Ph)O>1{Be$J<_+QtRk;~{##7w%Gz>=h^V;#y2S}7TFOm;%o>u; zk1+{JS_x>+?DticjMe*u2;eR7(XZn+!4l$5TdDpW+eV*JMTmkRZxqSL!t(A3$bHv5V@|43^#v<~jWAny|RH1}>e= zDq(@ibU0%rrcIztgw4ww>tJ1{nY>!I@w;sHMdRAyQ5^kq)YHi0dLA#gaOOZA&Q>;C zjm0DSz_0AvOjnpA&zJNCP580uFlZndYNomakG42`rC!*?{F)x3z>^Fx)xIB zCZrNS2uMfX)wg&8i`pK-S*cU^JLw3SBDZGqBiZsHR{kN0g7W7(OAi=Spg=uKoAEY9 zL`>E(7Z_*--FX+tI)H0w?8Zc@3*!Ab>>=b-?8CX`)%S~86G?(pkCX#X*;%L3KnDq? zq8|I&riXsU3e>l1CR|LSp=EW zRAqW7P1TFhv|3D$pA`e=gYf(|8~MC|yN$h;(m}>lx61EHvn@J1!4xO}b2*zM#@e&p zj0;fai}M7OQzzZW7A8FP`H%pTch(F0@qRoI=<|c2rie-ig&O)Ax^NvICCP|&wd}er z0a5=_Se80OUiPDZG&qp7*{CEYCOv7hA}(z|1riN#p%2)dGZ6ER>fC7T?%wSvu?u+SLV_mWZA8t0bZ!^wc38?zgZ4!W<&B($olKlz z&qvC#!eD<*pkXPyOH26NspXgpf|cJFSY2P#__~h-zigd-4T>tbFc14-@O^=&!>Uz} zwg`UnNA&1B&}hgu4zWToyEf4Gz9CR#)t zw^m6qJS-ZCJPtMn&zx8shZeGa_~bj2Xl#~WH@*xYcc*Iwf98iQ)iuLp!G>f<+?zCKta+KEOQ#`3Yr8bA0`2lgz8MNPE5 zv(iISi0-sv}kL2sLA4th*af9(wx2fi! zSG};-TfKIzJ)bzTTf~;@Cg+i@MXx@}ty%ayjO}}tdRFvNy4Fao57@BF?Js(KJoU6Z zhq8m6hjI+9Y`GWvtWW;Dq)1j1Qh$c|0~psj-0AMZ`oobv6Y>=qA@Tpg51d?$15ukI>q|hTk%(?~6keB_2TNP;qNw7jux5^kx$9~5g3Wz{ zQ|718Z7>)Or%&tF~#nr3jP@j>&#V6tP~;i8y(!uoKnl z|Ka1GWr%pXx6o*4)TL%xXll&H{^I>gVdDp3z#<3*TdKZv@6~IyQ>+g-gI@>av3OB@ zw!`BO0YfbC?ks!|ydF}GT)yCY&1f=Yr{ui{>>{0cUqARvOPI_5(5>cSj5d-DN5h=0 zFB0a4CtvSn+vNtj&DUQ*)EqBoK(ebTpB`WUT9@xf?gWMm0+EFOwE!C);$PxF2VCJN z8Fv}za#(U|dF(d*i;iPJvy}b0Fv`7Yq3%lId7FJa+NHaNeAfmEzzi=F4hj=Vf}Lfj zAM7)EE7;BWWzSn%Z<=_}Bm9U26d6;uRpDO_C*?dIhyX=y2TYU}!$OX?XYvT_FX&!y zr>8UTBS{F}x}9hYL`v3eOPYTv-#68(7EMlgCP_Uc5!VuI$G2F?D~VJso!AT#(K^p z=uK-`w=9*+J~!lFrwnxrZlCe6ZOyU@)EqtPC*q3A2N9gEgVj6Ej(NS_b=CvPw*&^^ zUD}^l8U%Ya06wPs_kq0%&;owfk()b7&K;;0hoU?~s2JaT!LtnU9CU@$?>ABo1Cyfz z5Gm!-{t+p2*jYpSlz%0Cr+;Rc!kt%tc_5()^SleE=MM_^1RB@qx-wez_Dme39+Rz~ z__K4nPr`bOXtue2yplI6VMo0-<=Bgn7rxHB02n-r$vJ@aDr7|0V~SCZnw717`B0noQ(_S^rR*i1+@HpNvJ-vz;IX0Tn5`e00zS3UmTe_c?V z355Gt_zmc&=WKvA3%Mlv!Jm5i%5%r?oCjQaAQl>~H@(IeKP<^>8SB_EYi>)Ib_sKd z5&}&o;hz=OQyxgv{-I;?8qkJfr?IXJhqCmI$Rd1Wybzii>Hwa~Pq?rr`V&*UZKr>t zoKYkz z7E7!tp>5FiU!_rE=OFraduv}51ajCv|FkI+EA>4xY}wuV@=H{YZdHpXi;g>AK_^k2 zVFCTUulU4c<5E4svA&j^N~=F1+MBwe1a~vlg-3sYLu1*jh3XAoR6;-d44y*1ThLm` zh56I$KqY?Txg|I-8xG7(S$J#j{Kc~S$AQU>X^@#PKv!NFM7hnbtiuN&-I6eCytTVU zh)*3yNjB#Lh^m16c60Vg(O$bGCHb$IQ^jGWX|bNxIUGO*=#-$;EMlo^B?0h2h391s z^opYE)V4r!e8PJqC_*m%&=BOP-qsHoS#zx((X5_Z*KeLbOmSOhX=JTh?GOvQBb}Zz zsi#|0`aF%8yQ*@|3)HPLuG1f&^e!lHeyA=q{n~xr>F3{|0qpRxJtPuW>{7LxYow5X z=gN>CSGF0-h3o(xqjqK+!QuREX@+j+?!L0-k)rQLm*X>)1ct3DEtRnpDZ-f$jG4+>;Z)*5-87ms%hgx5g1JmcdFgVO9R4IK->iBe~)+7g4^lc8jp z=+EJE42?I^0Y*008RHLp_P~)TOAqV1eG(>Pl74`|BLbKMTu8SxuU@E3eF5{{;wf zy2yV9cGS=^K+IpTPt0PoWP-*=S}su=Z?xkUe4jD?2AIYGWr7YH6OqA=Q!+p)pYOVK zOVO-_#>Kju@>EuFoA7luj0+Exbq$BDvBhYBjqF1%+tNm0X{kB}?u81mx{ z4hQEao45>zrEc=YxjD3julaWCMj|#q;{%g|9myfphm#k-`A<-gue%5JWjO@e-yXWi z6pYBX`mpH8x?a^kK>Vs!_{bPP&#ktCV-d)3rB^M(HAM>;Wyw&fImH0g$gg|J*NK8K z!qLd&luN`9Qtr&@pto&kF>O~_vZ6L^U@1{izDeT?Rc58N^8LMb%!XhK#XxO3cB0=( z`4AfeHyQ0O*{pGSLc1U=+}nM_-M)Z}Q_l&X!hTxDI398fm7iCWX{>4#d?gjeo9*I# z?5Xai$22AP#qbf@9WwN`+L#lnTU{d^=(x=)&EL+}=|DkOgGBv44D!$rJC@=l1)#~7 zhGL?r4&^;N@s?Xp%}a&qL|D1H&xPwD3V5O|iTFHft&xc*7sS`=p4LBa6>pOSB2KgTVeYK1sFdIMW=%@dq+sCTu*t=6}>hY~CK zye`))d#mWTL*T}~Q;c2;?*X&_3us6|QXvI`OFve^TfeF?_~H>rjukAFeH;pN%&16D zd%0(C@bw-8-)gWeyX<7uJ8?>ca^3WK+SS+!pzYCCL$@1p%-udfJev&RhOvbx6Dia!l@MTMbs0d}F7?-` z>Wb8;B-v}{fJQtGWV`FmoK-qFsg2XmYMI!MR&>;^&K*v?3~?tpbe!CJBUu;H5$>fR zKiw`B%7iLEAFwEN2_us}K;k29cB&+54^&s?Q{eBq4~oU+Z~P8oz0VPAaP%lU#R7t- z*Q>H&*?8Ka%}3+Ww{`ALY!3#c1@J%G2;^zmoeE!>5%iVB-JZGU@}{H}8HryrFw6@n zuQ2o1P8Iak9{3@kdiD0Q@c8+rQ$Q2SlN*dC!-lRVgAJ1R;NOelnYTA>ZX{?Ow~X>r!~kPDh#w)zeYoeaiL{zm6FTIspd3*QhQzgJZ{QNBONcRWN(L1u3d5>yU}?dn5r}Q2W9)wVd`)KaI)bfvp%eA`w3ZbKxu#>lbi3 z=|i_N)Q>&dKtbOgH<*aAoRE;G(ND8yh!1I;*MdqSK#UZ!DfJpTrdEOAqtECtqR*)C z^~KoZ(8x*}9i@^4kPLC?`;9!E1NxO_NGxMURkG$xScsC(qU5!zmOa-4nr?uDYf}_I?U)i({RHa$V0bPL?{L$urq9aF>i8 zT6>H&Jdrk_3xnMLt!pLRkUsK)6pBUvE`Th3($yY$7zuDCmbj!*4iuj0Pervo9?SAdf-EnRWP)N1w z`p;@NOO~ZFP{eEIY;}{FGqgNSbwxs_B7WM`Wj-~<^5*s5_R`45s>t2!dk`#%ff(|n zvRI6`2lk;n!1bP_hmi@dM??ZWP%tvm5M5N5R2{7?lBwvz;MszzZyT^2uJ0m|^0`UYU9UoFI_S67Y>rZR~wy`+E z3nn4oTYWdw-^32+q<>y+z>>hBb9c{N$otDgQX5BZi<^%YDt}H8+kEiNsZAw6Zn>hed1`t67Fbiz{rdwYRTw=&mrQm94vb86MPo4xT4Cw zJNA}IuNVv2^kv2p$lyL2>A2P*HlA|XHEw8^KL1*A?1pTrz?bO|>rEpVu%2s;z|)2( zr=WFM>5N#Jv7(CwTqWMmYA5FAl-32zuZ>WC94F5#X=lvRsx(dp;m7Di0A^Nxuquy% z4Kql)1Gl}1-4(VnXMpFDQoDnFpnNSHUcDl%!M^Iiv1Kd^uZ$Am1rQ%uN3UA9LP68! z&%cwtQq%YmQZ+b)XYa3csHd7UWK`E@Druy3;uA*qmzVbl3(eK)IK@efQy7$*bzVTT zgVE+IC8hNB#<3m41Xf|Gi40tJb7kz?7FI1Fa&V)gd-kHkJe#ib+ zZzHJ@iCOi7=}u#x3&Yj+xD^!DrmF7Fcx}Fnk<=~T!jzC)v|q*_WU{~bt1Ej8^rtc{riTqmH8xRCYg~X@y@4OiFZvJoE9mK0ChFPn&Fh{I zMst>a1K;<1k<0bz=vf?XGyl-3Q|=Am+?=eC-^4dJ6n8J&z4OxRwATR)*2CD|RI_%c zQ&~##PNDB`ndk&>h^^f|;JrSvMG~v0VInm-zpz5V2=U^}$oACFIlm6ul^BErEj*$L};#UzjS@M=_rcWj-{S1ROUHXzrZY z_{F8xvm*Uup!{W&d0u-V|Hc5doNX%*VHNbt1V_02Dd?wr%JtK)ms0#S^1YmHQ3r5U zuMD{Fl`jZ$CckH=krK4!m$03VbV?oYrKmk$+r?u4=m~e*E7V`qLlIWNm1dq!(0{f& zJnw0zZzBbk8y=limNknjWTx}t-x5G#O)pgVdz6eQAwQ)N8|4^4O^}5CeA9E9EWOgm zg2=rXwB?@#UGEDZyJ0MaFb zEceuE0P6yw7^meMfvy0k?enS*3K~_8GF&~87|TV`)>L$D=Ltl>?bvJjZO5Fd?5vT; zUzkgc^joeV7iJOLdjhSrSZxeugv1Xa52g1dtm+d~D&3D)p zW>-23J$XY)_@7CHB0f05Ry8vjd2p_Grz$633dUjKeSr8PyHzxa%pG(tH0PP39UplO zwe|nU@_GVI%Gw;i$tL~^xuW2iO}jO&8A*D~FdG-M_1~cjEDFKHF*@N9(>Du;0kzu< z=7fddlR!>}>!K6oV`OQTG#GWOenxODMzNrKl3b9o@};W8g+Tz&qr8Rw%6O|px2iK) zNC%uPb?gl};ed~e!2gAvBbu16U}wq>m|2OH*c3fbO{X#KT?=--#eXo#&A7`3LjwA5 zsoP@$PjxM)Nk?|lqm#+G#kM}szJVJiqYi9@yHU{~QS?AwW>m26gUy%4tyllG&>aFT zbfam|N^g7>HAD+&mP0s)1w^Ai&yF3n7|es--u~Ad3JHcB2VK>f*2^ag^;Rw4ae0Dc z?fW<1&EHv1@3b~in=sQ|Xx(Pn;lbz2iTCI&1?DYu&I~k%zysFTL{PEM7nP|jsBPV} z$_E6Dx|vGvVF%}+wVVze?KZ6!{pGFC*GxzY_l~#5p9}o;PfG}VVN%LLFk!iy`|qy) zeI-k`3Wppv2+L0-Z<&)v@2%4FV%0_wstsa{rk89&n(gH;gyfCL==h{Pmm`t59!2=H z>ppP8R%%i}(v^uo=`5+n?;$#CmVM?Y1Zbmm70}~~F5$j@JW~}@hn#K@vDe<;J(d>o`eq-JE4diJL2a@lC4l!Fr{^I;RC!3lo~|sr#8!PB zu4rU3{5t-airFgl9cy4V5q4C2Qw95vU`y33#pf5o3xc(09F``C26FWa9n9@&rxYeY zQ+<(JUN7L;uPYvj0J%~JZr^g?MN=#S?||kA1NTQE;c143k!T*ksM7DsRS-dze~c%N zw898j24rZ)dAzsC6TrB&AdP8F3)Ho-$`y$(dzTuZqE&q|hdO&uyC6U8-_5(JIcEOT zzx@108F9zt3b8Pfib3IslI5f$cMz zGr+kTK`FEn;%FBzm9RolP!uKe=e&fRN&5bk%m@z{-IB9r{Q$QnjD*2`)Cq-!&bv(Aa2b_8U+c-1r zu4-MxGNc!Sx2CL2#%93;r`mWt18o2gCLjoBk=eujGmUSz{glp|?tI^_!tgEBdl3W06Dh3Y-Q$NNukA`$sW(2BCd1h}Z^ zjWE8K=m=n1D!r#%w|`edm{Cjg|AxTr*dT;XUOXzNo2#rNb6s@u@|bjU%1f^;&Onca83ZWz z*V_0!->0`g_gJbXY!Y4biB?Rc7Mg6bP-&a?6N|*t+Jp5C`!+LJ_cr~k^ z&ko-SCcHMez+a_tynKiBQEBh@{fFM)7>CzHKf(iz=x*nfcKxhR9FfC2A7U{A_#Q9p z5sQe!s$%$rV=HBrkgwj7S2>}VC8;596P$jZAy;6bXn^vltc@9weH-5+Goa<^&Q2{z zjJ-WhmXrej5QhO#t1qii;OCgLWP}RT#x7ogY5Lt;PIa*wOv$!)qAX@}YyN?~(G7+R zY5C1YXV%vZ!X@aERSp{YNKs3|s{dN?dwqiU;0#4N4Zt|WI*Av5oHNk|PKFzHO3f4Y zB*F(=Q@H>3tAY;z=+_tCJawm5a=3@<{&SX%j30sa-xnr1C8TGVk7_UJ&KY>5 zDM)~jtKq%{Klt`Jp1=POU_v=Ns~rD?*hztM3&sA>0#yT48jtU}$ThXRL`?J$)1lmJ zsR&~SAX(GAq(^lFh!VAD@+HxlKc!c>#yLlybvjfnhUi-MIfg0V@753rp#a6l!6Dr zvU-B|Feq&XZskAE#?%BNa;k6OApSN1@pSaf#a+xEsNe#%Oae^$pqjhOvA`Ou-10Ri z{8VCd6Jup{O1kDVU+W>)5)4wWq+8~oeBJyBRaewuuiml(w;AwEsBIYA z)?HrUNYZ}ODRuoeJ3=(i#UJD!aq2oX)d22Pi-hGPS=PcR_R`RxOaSl)tEy# z%P@gHfv*Rua9uBE8;6J#38tPstv}p)YSLM+g7diFO2=%ZF>ZjJh`ZY@xb8~XYQt$m zxk&iaME%P5@e5y#2cT_Cxh53B3@m?CfF`K$>z`2!q_jH#+Op2Ne$YV!~G zTnU!%>#AR0nE=JGGbCbhR@$)=WchdP>z)*axw-lEv(q5v>*q(Hl;pvqwvb9Z{Kk1U zebSA$D7ap@bt7|2a(^|RVH#!4gP{qO7`2G_TWQAyj%UlrJn8fe~i8$>mrs3+xlPKm@Vna`ZSe7iD$Fwv@#yhNS z=qEo5n=rb=+KXvbj9aQ#;YNm5dU;(|VUkzbNQjPXNK7#umb?d9BP%lIL$8rZGbP=g z^0I%etqVZY%k~(zHq87I4sdO1)$WX2|1bF3qGh!F$FjPi>;?O;w~ChmK+g4+v!Qt* zDvljLeE1zo1>=R+V3@0HZY19K^1BVTMzu@<5r-KX z3F?-?XX9Mlm(LTtqt8O#K=jbMZ8Xs<*t_w^sEu+pT?IwN_B>({gEGsx9^cxH(JIS1 zi1>HvLAxp8^0QHXgewu4T<|s*VB*D2;ph0j1M_grYiiYb`W=h3PvH&0!v+}-t4u5( z)#yIuS2&1^3ygf(kE^(|W=W+uQm~^4q~eUYtZK5b~&Zj#S90*nFpm;w<2%n?i?$l3Q#uw=;(sI`}h1I zs(T?2?Bch7V3l5O75tf$c5BBUlz)fYDdRYCqp8?fHV_Q{elagsv-|4BcA(mIdU~5$ zVHt{|Qg)m*(ipe1c(D&QO%_i(t_F`Ph~enk=qa^Gg(DtoRU6C`Vu3?b>AgKwRF`F} zM8HVT$<1;XQz#s~n40|&&}o;ddP6hu4AkxfP(j^KZ2A#YOQmesa2jSIRoBuhr6>?# z21o%;lnW&FhuL8tgZ)NgdC=|tE=fFIJCH7p19i)lmeLfA@l8)}*Kj4}K5`XOUmI^d zabba~%j0kQkClg}pf%zLlv3%zvb_sj(huE}i!?@(c`O??HvCctO6_q?54*T)N>{uy z!kgi)cipneW+tMm!FhC272-hY5Y`_=_|W?we2Km&z{ll9P%>)Qx-+y`$^V)F4}9Pn zWAs?~#^Vu~IOWti^PRGP)bGY(zfn?U>x`@2WUx&cW@eRD1!Q=9YDzw!pmjDunmWCC z+X9Xe<{U3q28~-bDGfn3d{&jQ1B?Wq5p}C~0I+o>bkcuAB?*uIA6W8$NATz3?bmN& z*4YCXOY%J-LHL&*iA`o>g*Olq+BRTNO>`7UYmA>S!LS|YU0`*;`7C+zf6|f1$UB?F zMxV5j-Uh%OIn%?73bFZMY5D(u+nU32$jL=EUuxWkevLBb~#lQ9gW!d_RKBKqa_EIgn!x&cuND% zC5#vor+wDuELgi2`u+a7e~%AiCJS1T1T;91zqcQC)|Wj9b`F7dDA6XPYX+H%ws@=6w^DPOJj9T-9~>Y|*om9)RxyGqC{92hm~ zY>%{s!Jc($Gwf)-4_=p(zUG{4D;2K zfqySbLr-LX;Q2@TcU9>$gO71(05*BI+Ee0F{5oz@zD#tZOdT;FBlUwvz|Tb;1&Ku^ zW%@^E>!3c+RUi1`UaIobn^ngAq0LP^fHB|-7R#E<(xsC=adIM>JL_w7IW#i}=Pd30 z)u|0|o8ql7XY^4kG_E5fImTr{;;D5Swp$v6u9m4v zjnL%Q`s(_~1<8her&%Oymb;eTM|N26t-0vJO3F<}^UXpWZGlM3?1(%P$VM%1nN=Zo zV>8gp@&j?~MphsCZ)Ac4>umVqGxQ@J2|qwStaHe~4iaYPK>+-nJ=*kV419SODF@^!U{&V&aE&j=E+FM;A0f^Tn~M`n75mYjI zlOq~X`m0jDto%tz-_A1$hkv|Lfrie?BGQmdW1W10;MIf8rCx3fux^CzH7R_p0q)Ow zMDtRZtvRKC+uKMtMHssM=4V(3qkj{UJIh+6-Ga7JH^c%E8W}(&S$tyyR)kMQL~ybzU5BJ`xyxWb{__(0cqk zpVKr(m=2I(U-+?1kXz&*N8BV95E0))W!r(WzW3q3ckS7kOW_HalS{-7(SRZTSnZuH zmadpD){y8@0a%TaBKLohO_D3cGW%M z5^?Kw-hah^S1amcFj>4kHIgJiU6Xe3)+$U(>(`L~>T+uq&~?q`4jw4p(looe-g?2! z=ak^o|%oOfx?$Tp41phUu+pIP<^V{>jlJ^tkGeF-~fX##RR=+@AN{j ze5P6{8qeThYn9cviQGE#*LwBBz(XfwB8GIk#LLzVSgxL>iw90hfbHl7IKa=0hAn%AT!E2 zzXboXu%QYnk*MdW#O*#JHInKyR~Z3S4)%IW{(pE4>p~%A(#Z1Q;{^>vw&q24Cw9=;@gG;}U+K32QdT zg(~XM>AnET&p!N3<4r2;b`o0-RTNlgPy>rs_HcY>QibHFry>FlJnA9GnTL>4%RC+%$(!29tzXm0Oe~2`h;wpHOf+^wEa411i47m zZ%-N#3_!>!i7y0e|0TF!jn43{JK=Hg{JAd>fJPlDyYh&WpWe;U`Ktp?KtT|-y#W>m z9!to{wS)SzatJ66nA{NaMvmUgt&PCegn(5)Q~dKkXUF|5OIJ&Z_wS7aHsv7i;O@pyZ${fe%N%bFZ}d?=DefPg0j zFiFroaCf1g{%7Oji|P@Mc6{ikH*2Xod-Dw@{*T&So{)W1G6xnD!@-wW1B&J%G3e)y z)Jr%qKyy5BV7Ap1nLDj?vd+*tApE<)8%d(2*aG~HV^Y8b+gKmRth8XrZCti*rq~BE zht3wd(}Y_>Tubx|eIAu^LNQwpco4&!rQRb>x1Hx@LHof-0!)nkeT+#lTG#v^ceShz zu$N&80pm`mZ^UA-%Da@Dvp#5tp&_(^JXh!QEvR#V!yWwCzqHJG6 zAx+@KT&bUqXcr%+oPOW1Ygk%Wd$4BS$OOhim{spgYq2e>594;E|!nUR)Wc|fv;=Q8A4LL66x2@)W1N{D~ z8C6xxoGDdJ@fPYqdbaaQ-F1JwD&a8Jp4_}FgL#GbxhIf8aLl-Vuuay*)nrrT4*Cv0 zhd&v%TTz-h{NZm9_B#9To>r^do%QFNKJ>rd+Q0^QKp@gS(Pj9}s>b|RKTarLF&N(+ zHjiExQk3((>iILwn`L)aXSK|9_b49R(-r14&BFD0kT~Xr(lA>=G$TY#y{dt^C~Zv`nS#=&KEs{-l z@aJ5q{z`mJ70dnlBSA!1x~08A-CgUF@^rO-piQru$tMtMuD_j4iG08hCEx~mAo+@F z;t-B%WTO%IacsBkzQIZQPBBZIvK`27NO?R=W+<@x=$;H!tIwMaQMnP#Y*!+lMCm)7Ag&1VEv!G16%KhV8LL3F{_G7kpQjFI!<0gYrCH?Dsb(@^v#!!0(SqnQKOrdK?{Z# zKklTQP3aqTWussXWMS&om{svv^klm&2(D^8)z=8w1LeLq*e5;&y_35Pm{YQ2?_GDq z)U5TUOdu@XMy6Mhe9NkROogPAyq!R)eANvb!n6oYHXwqnXfy97{esz-!#>6(;6Nw! z1GEXNZ>+4S_&(+i_zOD*HXfDsMdn1mt>x2?kPb5LESXX9*T`_KK6skBe*4JJX2nQF zoeJkGL*Z9yZBKIIbi+)~zQNKlzG0Q69WUE4;69AX>)-QjXjL)`hmM2Vqo~xRHXvXS zYnMLKr^$7SsJ5lj7nbX8(`(rJ<2AFdKyqJ9?+(VZK39OiZa80Yw!j?>;3fCZIzH`O zyRCSvEO?$I+?O}AxyKtLdmh7gNgl*b2?}Kw=B@s-fpJhT>Shn>gks4UPO%n-|8Yv4 zRI?HBcGA@K-eUa?g#`Ccb%P2}fU!REVW*&x4Y^O?lc$wv$9U_k+I?P3z8*BB zK_i{C?;zI~wt4h>ZL8TNcF7;JX$y*w6@;5#Yy5IbAD)&~dE^C9kp>Ggl`m!Q&6Oq% zVc)BR!ckE6w>=twg-tiO!mWGs(;IhI8aRp6H81vKtFU_}&3>8sMg&Zi!u`kT-#t7y zL!G4oSx2W)Hpd~*IIw8uG??{>4{t9u{LPC==qwnlBnW_2Hut~Wz4x`??8wlI%Ie8|S6RV8;-8CZIGDO*cXa`f6v(}QTvUV@-X3;|PL zDh>ylCM^Qmoa-yo^rCwVXYd!*{kW(8k};N$I5-%Uo6qUR))_(Y8Tx}6&LZ9&4`PgZ zTVyJ-&-u{gjMq$1KU)&+imzfW`-6U@+ZzgNWcPbR{2s?b&l6ky!%{n>fpt(X_5+un zfIby3*3}QK!j*U?TK3R1;p znHta#wgzo-$h`d7^^hOGBU|9_LHizDv^K@Re0aU~W zTJ2@TK={N320IvL#F)n)yIf}9lU;rAX6ltAgME4 zPVy_cNO3Os=U9bxT58+s&MRHv0?}z8b5E*gZ;ugf3uJ`+I7)95@#xDx^$EVgO8{(Dlm7x;AlB}3F z(N+NKb?S~j;ro*M%`=HctA>_;E)~b5gb4eiYh{1B+0%>pzoX-(|Ej~m)}a%l_NW0)+rU6<3KyX6sf`!tHj9B@tkBbe z+@Bq7*L|P%=j<8sDqYUO*;N5*X@1^x9UUnj_~5jMsh z%!zt)OxX7el>h*I;*{ck=?&~x6yhT(V}yg9D7|(R5^TMunp9|E)r~v;L1b#_4)&a8 zN7dm<>Fv32<{8+@33qtQoE_ix&8+Rh^*Qno)zYWYnBqI6=f5n2*O6JMZScI(aFz(Q z``8icsA1MajE$&m43fSs_{VR|jf%B+$_m?b>uIL1_cZdc&?+Y8e`C)QTJ&b^?@1VN z|B={7&^)n3iu8*@Y!pa#{UMt$GXamSiUWE|jQyhdLib9gTn#XjU=ZZk*vcB+zlABq=IvQ%;?L zD-wE=JffyZ@Nc66vvcg^E&kL9M5{oNbN=Ppo8}tu0*?bb*o9K9o8hL$onIx^Z_Q;z z&*i$u+GF^aN_woq;B|~E`k~1}9#q8^HBdT%IFfy>`l0tm^`(o-W_qu36d=kmB0lk; zy*lv3{?4o-OiXd9JCUegv9=C-c`j`!plF9?v9mehc4s~dHzrL#3^QB3)@!~^`ozzM z!bd96K#l?4xjd!k8`2=rV!`^sv&BU?k!^7>MhF+i#Ou`W{WrqH@J9Y|=&7wv1pNxy zmZCLbD6Dvv;&!Kunj{}%M02$C6>mX*9*J*huopO%kDNi4%IQ>m)wx-0=6Y|Yjb_2# zi?L>bGhDRCz2}$Th|JO}E*J;lW46BfS}g7!lurY2(a&2uhg0g z>H$wHPApv-1x=9^CDCv{d*)N4WchT=DG?3|?Lxt-UAI^(Dp=TO7NHGLpk z_D%y&5mWoV?iSnKrsxmGeZ9)}4I1F9F^WZy3rNDxPbW4S;PG~9x7 zDr~cWTg*GihH5lY>0Bh+t;b>fj`@1?VI4mqdLJdBLvbEsnO{(U3k6uILq1cdcaz;w zT?~@AcB!ULk!0;??UpIwi(n~oN$fotySk=S)&H^Wy4xTaigI*D)OZ^T_0UqtX1YPu zehw9WVehkh{!6c8h#ki%eROC==~apjVwk24b7tih=tN7ZS&&sVwnw`bbmVI^f4&q|m9u$eU8lRCdmPmcnrUxxH9%!EN9o$$7e(qQ$d?+U3blI5GT+k6OY2PxmlP6w zWB-luxo9xa2=2%CWxt}%>m8i&c7`P*y>T1l^fFo>O)gOlGy!I$iBg($VL53%5tRb0 zxW!U;N-kS$RUwUlp4! zw%OiO*C)KpO;-r?iJGE+0w*;!rK;pKo5)~@5a@*>)Q&A3;{Voz3b&`QfY;BdQ-(p$ zXLJu7(+R#{Ma(lGCQwj(-9A7FqAt9Hfb`>-&x1G&0 z%(Zx%R)*x<8E@z7@fY%Y;#$OFFm3w3N}JB2l^l zH^WZZq}szG0tCUrm_p;=O#2N4@7lV-b>RQk1}J2inICsngEkPDS#{Twa%;0zI3hkl z_p4a(?Rfi*Jf%5kH@%y>jBLz`(j zcy#PHB5RyHU3pN_F;)COs@}mZ)9-r&O%oZ;Ywqjj zm^0T#!eZKZ?>^m9=x2uA0ACa(F7^gSiXP|{{Im>Cw(BjvMHc1F#+`>mYuSDiX1cuW zdXDK5c4etX%@y1z{S-YsoN9#MyK`=hmwj(mnyp-Lfjviz%U?1Tn^zcnYVuRM?AX3E zJc87zy5=p%!QqOJ#MvM~+s?+gkTPr+Mmhhy_`SWxqQ)Nd7&995*tqjRL)U69qrG$n?Z7Jr+;}G@=^Gg$CJg`Gv0h~f2FVOr;jXe zOTE&xEYapAXQU;SVIkMgrCW+Wqop4)J-3FM|2%BKW219QtUw?ZK6IHqk#ofS5QjrF zMbx65K7qg<4*~GAOvp&4(0E~Q0jdpiy11v3RLCQ(i5dZRCn<0NxjOdfPAxRE=J<$z z*+hy}>oi{xANB|H1X)BGq8B?z{?xi;;&eybZva;uO6W|kcGRyOP!l$x`dl4y#-J7e zP_SvlmXg|MlX_L(FnV!N9X#^v5$|#4VXZu z*W94wF#CyL&hgOF;~*#Q#WR|mCnToYQ^o&nrC0h`Hai4HJ_4CIWP9~FEnp%_-M}dV z4287@-D4HCPbYKN%R*ZHoY)66vkm`dwX{r>tH`FUaiaDg)R}=hyFm@DCc#N2lb_-= z1XImb%OVf^u!KJqXn1altA||S8PN_13U0_RUzns(&uk*rmS_0c?g$$#+LvZr_|8Bs z9qpzimf0e9E0J;Gq{2acc!#l?Ul@D}-+!W4pai)Qs}?ya#}TmW8nOXGfPR3tCt&h$ zt1WTqmwC?P1pE5NR?7}I!eBt{cfKiDp?p4Gop!?INh0 ze|GVwPNdZvd3}Qw6GLw;4&M)Ltj!*bm{XeZYJ=NagLjy9&BCBnj)tqXre?{{6tfn{ zt#j68+u(s~%klQLYWxodm69o+g(x^Xa5oa380G7$}NHn8SSSH)7 z<1a?MP}d&|&GSAb!@=L9Q}yel5o?8?yGN18Dyp}M3e_=D)B&pEFKf-Xu;pfJJKIoD z5~$?frC!JLEPOsv(*?I9aj<|i%E(FK=q!-38Ep@`%dGuN|32bYTy;82E=F+>JqvXS z1aoSOhL|C3j7Qwz5QV@Xxjqz=!S70h;SH`ZT};YYoUY_969AtEez6OLy!r0Xh5pa& zBh(4Rq9-(02X9ZhW2%IAu6aB+O7FPcmFnL=O>DnjPG-r;_CDD#%>chW1m|%?Hr4X+ z;Lutp9$~K8|IUD-B)EeqeQ0u7K@Lo}R|Fj6y~Q zfr$;Tr*Zfa+#I6r#-0XxHI}BX659{Q^F#&dL@h%CgehPm*z9V z;Fq6t)yT`tpOh}c&_r2zDI|84pj0p|+`x~bzCFO{6^lZs zr-deihW&0B6EI?R17{QVyg;sRPMrk*vymXq>QS(x|hg`2%!AI`4OWL-_T_OqwXeiSlE`Fpj|7@fF;c8Sj= z%YY>ZuZ^erH)k%AF??JAmP4dyC6`H5nR zGPMe*A+EC`ARyIL(B%}>WbDOUj(-dN?_uu@v(xhdrkRm**NqUFf((8>a85sESX(16 z;;UWiQ2homZrZ2L96^D{_ck?FeFNrB_4SRjF+L8eX2}IB#Y3Isuul_xXaJrAa_7AI zuFd;&o5A8RH9!!SWKJmhse}S2-*&49_U28i!D)d*nl`5jS6wKF2W*^{snRTbzo%x& zmX*$*#Y^)kHdSFY6bbZ>z2zYhZ0~P_aGY4DekF-rN(UI@0(1SALx(Bd{j~Mc>AW+-TYL1q0U$IZpx^RsE$y4QZo{HvSmme#XXgXSYW_6XSCNMB&%y&W z5r3R4%@Xe_bDS(-Q=iywg*^P(@q&UjNVTwKGPJGfvm*tJzErXQ$z_372zKwNgXgG( zoTt)^{j$p(5&i)iJ726af zSgE^q3XJux(fup1x}G^63a(PUe=h3vXZK$=Pl%*n+)tzsnJxPX z#OI8nnhv^^(J8C51L{VRs6K-aZjA%`wE9yRCatB`!qtH`Vz}!0OCRNrbxmbh5GyN2 zBe=W!md_Qlb#0nR<}-W=Ypag>4HA@c4Qrw9b<2XZFal^QSJz|3o&GPb0TaO-4+VRl z%V%lTN_}RBY6s$khqkuY7gnG!XiVMk0}Os8@JS#@KoK7n`b7JLAi6~w9$+J2{&j0@ zS)NbHbX86bhP=@K?24Cos_ZEIVs_e5xm7?z`sejNRdXhuC&GKJ-}_G<)GWcHg)H~@VoE(#0)YQFv#>Dpe` z=mN0fh5f>uXc_aBgGvl9=0Ct0E0s+Dn7v(f zuq@;#&Yvi-*Qszr2joZ9uYRE$lc-jo3?}Z5TbYT6N2<|T{ghio^zgG&d5J^Yq-PZB zSwhUXM>Beh4T6vo%LyWWdx$->Cld1SMTr+llw0?tPT*%%?mX}4oG;tGN-m{$sqeGc8X2W*pkMfx0?g=q^ zNPP26#KZQn)Tk~EO$A=uI1K1edO(^gbTKLWC?J>audEV}lqpa1?`P@yzwX@9q2SD! z_<6wjvl@r*=f4*dCt^@uLaE@!MU3qQzs4CtA}t+^kZehI{1f%dpbk+r4oRCbND2Rm zmDe&K|EH3V=(mQJa&K}0vv8*GM8rtT7jix=t<3n}=dW7v8~nOwQWP((W>(_m+x%HP z<2_7$f{3LSGqsLu!*PcogSya z*ZQUSYtpI!o*p{|QQOvtCC$#|2!dru86w#AyXK$!P>5RALfg8LWHbpsj8A-QU*qx; zz!!oq2+5_yY48!`7?5+R7Z(HkU4BkiztEn5+HAvTqFj5P{QfO&h8AP~*tjZ`^XPKg zxft4hwbXCA@oC>MlgLCN9&Sgz$A0C#_1qnPbeU;cL#8mD*k$qRL#SHq-}0)jM_lSA zZ6jq1wNZ}HO}zlxM>!=TNVWVd3GXD{QhVO2rtJ3(phC-%HhF|Oq!MFcpE*7b+QA)e zYz;U0!(U|O3UhV@%=Dta1hAvpmC4H=2As|= zO!hZ_5m;F2xLHMu0kfd>d8(YU&xhWB!}160oK7QNMS~-Cf;k9z4*~mb-~Lg*RV}QX zFH!rnD{3N|at)sig3WwO;yN$&d^L6b!a=XoJ{pIqrl7oiKz69KnToMR8)h*)S0?Si z8XHZcAb|Jm_8kXbF)x_ZYYSd3jb^9KfEZH)2SQpLZxhFQq{us^u4;A?SlGo7mNIrP zX|;iQr&?6N@N`Ct&x4b7{fQrtZa*t1qU@WmwN#rRdFgry1wjK1;Gj)p1agi^OW}!3f6UY8QS+l>Eu!#7m?ntyg ze`tU$toC1O>joh)@(T94H4B7&x6I^dFoR^(t>-(TgJ}%I`33m%=isr&!~2l zD2{fUGzPDH0DcX4DBI21P!NCIb_SALP0z}_kN;C#8`c3ekIH9S$NW5<_W^*C!LRJR zOWJ)r?xF$zCcAz9jYY!=y**nRtnlbR3u_`96EKw2wEhXWX)y zCoMzzYnTwQs-mSZcn~`|l%Nj~NI&tSR&nGk&6vCiB3yMIx#86T%rks@Wh{trP>fpu zUvd3TDVYUmmq>6w`kU(vxE9TqmYN@K+VMc$N5_`N{{SG6sqMKHDR9*w*$)P3$=lbZ zJz_mCeEN}U)9)1{RfKdo_sm_u6-Q)fv;6u~sz$IqdXt(ED8j6~*Pofvrq+MOE@8oi z^zKyDm~tN_ciI3j+gR+EE=&+W42XwQAsyqAywN848qQ~CN}Oi1$fMr47d+bjUHM3* za9R@fm{Pp*JA|x@Xd^`DiB?z;*DTF5WdC!z{bn zcLbD1Y1vQ%t8s~g+6X$4*Zf3?eVO)WgB?bB2UwYs%1}baZ-yV`{MEf2Vbj`bp>m>E z#>U+}v7=gkT7=o8`kMic?>5xO_!Zq-r0SK7Z7rvyUMIlH_yN-VN)@<|sI1bA-gQ)B zkiGMR9!L=3X4}uYuQb^fP;c#?oPomJL(jgrzwGd_P~?=2hfXafAAPtD@szd=lns=( zNuoy@X_^l*b!TfTTD0sM)}Ph8C$DU-9k&HH(O-u;U1n)iV?f6&2u`*^*jgd^!h}Tn z=S(WVaXl?9(|nRTAM6fF13lb7ewaC5liDT}*xV-#+-*I#rI^$_rHX@Q;%G&MO;!tq zchzwP#pGo?J4UF`>?4#LGO3}L-2`!v*@AAxn%y*qM=ifceySO#efulA8O~Z*DPu4e z4al5CD~L?^mtnzN8|Eopx<#p3YAM^>(O1#Q2-AI(S2Q_jZEh?_n^J+8X$oB;hII~o zpT2RkJi4D%C%!vwuPndDU)J1K3$=Ir(S&xRk$*MaaR{>8A$oZ$e_Z%wG7qy`zR&K! z=}UM3SRxb>n~(50LY#d_NB~2GD!#23yUwGYtC*L|`;!a1f|?G`$VgAO$ViXT1TIJk z+^!5CvbjHhZE$L-nfzvoo3-#y@~T6Fo(APbNi!vmsfKhf>!+&1+2W!T`l!%s0cyqP z&&-z94hBp(@mrcDKLgGiFbsaGc6l}H2y%nxAQs?ZEs3}cqz3Vb$iA#Tzn38>!5WlK z2q^yH?}eq%-%f9AlQ93ZedQrw`f8VsS+>?&aL!|%i_IjtF_Lkn9jNHL%=4Iw%)5wl zXe~OR&=hb3A|Y6Sr67Fvku;KeS2e{bDce62QzUAE zvsprX8>-^4{B=#-GBLHs4cGt|;9glHjh&jOO>q*=lQ7|U7ga{JXv+awS9Evxevvzo zES=Qr%s?5H3o}yeDSimucqBTO1Qj=HGfWbMX?d5Q0{;OGTxM|ex>kZeeF_|S%$DCJ{m z@`GF_Q1y3Rz}qc79MVlifxlmI!!Tm%N3X-jA#fSn{_#mru**vlu+k!Yix$4!Wfs zywBOucff>3lDA~NaxIpb3&&lUv3<_^NxLPM-Hz?Q4{w|9%{naI4qMqQU5eJ-uZ;xl zusAgu4q0jP{i-r|+N)(ko1Yok#f+1V8yeO%#mBZyiv1qMk^#cRxnuF`RAWB&N6IR$ zng3&DKO=XH_V7r>LN+=9t;Ml_MGpSXaJGyIA=r5Mc&bx!R_58lKntyeO$h|x+WXsN zks=A`+4-c6B>_K(^`GJ*O7>I9_}>LlE;@;G1aJTfx`$Ws9owWhE+LKks4^QCl@vn-%ba zH8-n6F^Wu*-|V(#aUkcDEK7+tP4y%=Iuj+zokG1JSHv}IqT^T2=8AuG|EM7bU02Cu z7F*x4*H$kH>yO#LQ1c&CruJ%B6+W{=u>8Tch$Bi*48z86X#75>h9}P2)3KOx zluId9=U?=m}DiWXS;W zPES;hU-_CnLbS}|tmv=Ndbs}e^4Mk&G;uuoTM{xmY%G`eUQ7)d*|F)4tu7nLasDI@ z9!`C1AU<4$XjMp}Z^Q`x)rHO$bi>h@6@9>f>qdz{2H2W9Fr1qFvl@8b<%~Z#s?j?v zL{)IAksyW981Uunz3KdUi(sF17IHR{%Y>-v|m_JhHfP@E;$gf?u0Svm=7 z(M8(4>gT)x@=hz96Nu%nQ}9>-DJVJVG9trHjzLC`(+F<55N%KwRjaL!ETj}+ZOv$< zFcN3N`k9~=-Y&W8B%m{-mOzkpyxtlE((%$~WzzeN)G7Zq2>KBaHh&S2d1fAhft&U7 zgLl4TBa}gd$NRs32TNPYR3cc}H1O#H+jR<7x}O8sPz7y{GlBU=53ALjdFZFd=-5zz zEQB33M54Bn4v_hzYxZ7EjU6uAEjCCT=aq8-EBoC}GNKkLNUe_lLTv+|f0%`do}NWq zuV*e}*KoH1d1*F0UDOQPj3R*#lM0IOf;c)CsZ@xikn_B*91DFWCozJ2-RE2;sZ^zcnx z(F_hEQUaYAj}gJqazh~Od)MKv`^C3s^ZKXX%nb7f8!)#I99=BYj_3cJ9{bYQNa&WY z;P(CegjTg71qAXtw_Pkwyw2k2X-Qar$plH?Py7ygco$+kul`SnAtAQU_R>6SSb#xN zF_G&jEDO#_vrEL=+nB*Goam9Ju4I_DzOqexpXijzlB=L36stfLs?&1^@jOq0Xoe#Q zdFA(Ze#EY9>@)e;ulqrlA)tM97IS?d!S>v(_735&41=1z>N=XxCey)^C@ z#H^C?dGS}g#G&8T+$N`Iexmluo!?_ib=PlTUgqM11QaOoA3cXh{2k%?+ka`7ENlhL zPb*J~=nPU&*>W@IDaN`#L~)1%iZW_}H%AQPWF2cM$TF-9@c0vn#8PGtx)jlV zEW~Clfwg5c^*(&~(?wtu(|WKM+$e&LLWyf;EIIPsxwIT%zJ9-@XOdG9Okg0Nsh%PA zv-jfjfO+-Oykc~R&(-INl+_L0(n_y(n2j{1OTu|+KRF}b8i80Wi=-}tcLY7$OCCmu zge?YZHOpopSl-zcP!wNYCE5%HY}tbjt8_1c3)9Ky7Jm^z#-;~fAz**LR%O!~^>7ag z{Xgxn94?fb&VShu-$*3=C#vp;5W|37SW=~Z;?DmWhu%7bE)h%NGxr85rQ3V`5E@Gm z<{Nh6#6uNI_}yx; zC$7t}g=PIK@yz^yp+Ifi3Y{S1?{@c#i7%TDjc6U;+%8Fc#d96O*S;Y3@?7#$MDdu|h{d*8^P~U3rLw_I`>A`tv zkhaX@x(b_7o3~(ykESdGjDvoz2!mAmLk#peD_W;A3+L%#AZ#^~=;tq=D_0%6978Xv z%_XdGfB4|a_9!Wg@ifBDISo&xhl+RG5nTBPOGKi$#sjR6?$Pj}zJ1JSyI-o;{SPEm zROB=uBRj0O!rkt7wrZi%y<5stu4w$O<8PHLd3={!7W=4q(NKgGQ?Vv1>HoNzI`yH_ z0uue%$0!QSP=DRycQ9&atG`JNqGd!oYC8TE76JHJl}JjoAHu5%4m`;RJ=DW%z07=z zYF9gTm~*z+#CH_ZhMlmHYKAohgJ%1yw@rRzGlwM|XMAifC33tZBNQR9myH+;;hl?h zr8~n?IeykXr0ootT2tH@_wy4hdHfzb6_c^qWPpnUCpK|(Gf<`%pi+?re-yNmf{OyEvavzq^KRSRf zp*X9@YMEq~;hUo;*f8}kyvZHUi#Xk{^@gluM{Q0XF^P~^xC1tHbd+2g^j7M|)gygna3#$n(fxOUZ0+aZXQXM5!uk`^ zZ>Nz6bLcnW*r#;U)j$41bp)ggby8vJ&&HIllFTCnI$`zz{Pq~_Airuajg2!5Pz89N}H(C^2!q4 z!b+o7n8>p8@26Z<<6l-Z`~#0RwOdI!MyIg=CSsc z_^0UY$XpjDox{K4fFnFo@~6!k`Zv`pyP&F2;JeNaKB~Ua9~kyPQND?I zWpOMD^%Z+^BisqzT8%?Ut{Y{Pi>UF=(7~LGa9w*^a4!4L0~14&PHVFN_ai>DdA0f* z-M?=BqLpt5H>|&b_s(fU>kHuU;!bQ(lRhUnwbVKK6ZLJcX^CC!KpFpsugJVk*GmG^ zyqV1KI4BNHb*fN`SNs%WT*3`{SD9%JQMmmkqMU2goQqi)Z-}`| z+E_EcD#5++G>;+yz0%j+wf(MP5jF?SgLe_8Qa16KSMF;(qL!^{twEtt>eGdNy8)+% zO9)!2QuGG2@yPezt^D(}vwfXtv>&Brhf6R+zi#=Cd{G{is9u`*y)?jXdd%#YDA?O= zO9r%;eB>Pe=ZV;(!k&`<(U*~VhvxV?YuoL%eA#mLytuLyGIKKxERW3mPJi=`qq4n& z4X!uCh)x-q9({v7s(rnt=a#IZ3h9=9U=BkfKW;-=x&dBrGE6D&AN{)%$*m&E@7MyQ zH&#pIt#hy!2nfV?Em=I_S{ADxFdJAus@*oP~HbpMJ>;I6>r1tu9!I4<-8~?yUdA-58=R`8#SyTztAIJH|Aq7QT zoQyc>yQE-?0aHZHXx>uLy*l93#s3KnqbMq2p1CyvWdbHJOoS;KJ)AN&&N9NyimjVl zAfG@6ST}(#??3Uy9Y4P)R|A)2eU4QEU zL^C+xz8_|vJ?WODq5PxE4(kma zQVlIQB}x79m52iFSxVrCiN;g@~6BW&+DpMSOOrs6JodAWU_ zYo1c+|BpFf|DSqh=>=AW-PQRbC#iS%i>+{)Nq~%rJtj4^^D`kqH+;w3EI*zp7MD(% zxwC@oVp>@dAY`wX3#gc@N2`?S+tMy^ILJV;RWcfS&8)hl2RJ$uqahnPNybSsFijux zVnfqMeLX(&M6Q>}Q_5QCKD75_0v-Mod4rh%sbPvUJ?4(-R2Cn#NOT);VDbe#$jldF ze{h0PMhb2;9mQqA1SY)&QF#3)(1#5cm_p#ym_k70IvDRlY(jZ|n$crVf3t=PVI6z^ zVQ#B^MJLN?^^07M(Q!`Nrt;J1xg&Aym+QpbQeBj1skR!KxGj(;n_tOSon4GCf{MK9Cd&VJm6}8c^iRC6}9HKYhDS;j|maqt<-N z7{D3S@@m$}9T-w3uxs{481hgOJg`EEbg7LRT*Axv z;J|>@lafHItlpif%>A46@vV2cx|hhY-W19Mm@4`Anz!KubN$s##jT_VldfZ6;#%#) z2B7HX{@$y56nFK-Nuxha61WS#>P~?Z@CmZdCf$-~*GbRl{MX5JTRItX>;GgDe+xw( zyDiC$dgc2xxWfp29zC_^96y!ebA2vCl>WD#%sO7XtH{qRg@t{97NLCj+qY!2rA3$V z_vy;VrLxrdo$~_;h#yqII@3B{S+e5XDA2fZ43HIM8K(4+tmT%@M4^tCyy`y`$_k$9 z`glf)H{d6U+#DQhvho#;cqI(8fBh%9O`}C8Fyb*%b^taiiguB&O72X-$eUpTGP}<| zwl)}5qCGFq#5>kdgvg8bdgApql#@pGDG?n%5bJQ#k_p@~&s17RoNf(Fd1B|qvkt4u zlzzpziiN*@6cWyUhW{<$DIjN00_avu1kD3#qd>WgSZa6+e+cmvru4wVzkU63sDtrl zt5MZx36M^60#~-}-dBh8gM(76S$6H)3W{jbqS+W7uYMz4+xN2-Hk(&#T`(aCx|Mk* z2%~VY44nZix8}{(mt2FRpNx4|1!gCXlCniTnBp1dEeHARGh0!r^SC80e`tKF*k7*L zsQ*H%XFI+Wh0YrTgo-rPF$4a!(?@Z5D@&j+3O@@;X!>WdSnx(-rn-og@-o|2tN6=2 zsr!Pmd3u5idC6I`jJ`^Q39FI#F0E@O2i8?**^>2Q>mdTw(uFArrzVc&qRT>MU2kpV z*yfgu$>HyXO~FQf?w`q;>M`W=zr#M8)?B0X+~1f0{xN!PHs-cy#OIOl`Fl9E42ZvWB5Og4O=-o0TpV%8SjFc6~I=QBlm|* zODKZaJowHE9XT`uXN6oBP$=q5b;ute^(J+)|7#r%l-|ZJw^pA^o3yG3&ZtmcU|==7 zFlWe`_D-I>f8UnJoE;!xbv4ocYdS@|r|_jsR;LfURb)1KRTt1_aX8DD4EG&o4eV2= zi8ap^YIMBhM5ofS>|E!86bfZ22D$#AGv9=-G*g-x>kZpWA~&CH*)f!9DdYM074SC; zxO7hEvhU>oy{G9AyTnmS>#y&anNh=vQe1fiDTOfJ)c z`zHr5e1xBon#)>_8^d4h+s+8q8by4j^O)0N#dF6-FAN)c=G%hXDbw<4W!%bnHk0`T zaFzd~q+)5aTir1a3cwk&(FfmLeP)o3?ceT_xURf{{PqTR2tVU>4SJO(hb%Jq@H>qC z-nTYqN7I5+4=U5=iJ1K`mDD^M@_XgwFwl>%Z>K7!tLaxglxKrxB~XLEhcoF!?e*zI zJ?vgSd)-x}#i83xJ7RkfLI4VxLk3oOem*QeX22|7Y(8|jyG~9OR^)EDMBir>kH?cj z;-^(C(SR4DPfu3a-R^Ktvy}CHzVDX8#bu%+`N2w7wj9{*&xv8$a>5(iI9Yw9fP*rj zwwTRsdtq>FK*Fe1RQR%-trW>O_d91c0tdR23>wxA%TjVoV@`A{%5n=_k5F9 zf)?-dsL^zHHs}f$38hz8$hYtZU?-Y5&NHagpgKkNzPU=ClDQn0-(E}Rw9}lo9`F=q z#n2oP`Tj_EGaV7n@7P z&`X|9Of|)(BWM<=TCFzuf1VLf%KhA_ltG+Zxnn5XWSLeDe)HD%R8MWo8{G;wo9;S{ zZzCaBMn4|;^grWQ95n6fVz|e;y!zW5aK9*7D%O=_v_C(4|EzInmW6I@B&}|9=r_}P zZBFV%(dD}`0Ei)01y#6Z+>xR89L`+QUmZfJ{Z^s4eIQp6a+*B75Ej zi*jY`*KA2i_cxtCDUq#G(UI0ky*oB+L)(UBY^MY*fy^c$e)$Gv!g ze$O73lt(8_DpgG2qIA@(cs7$2`W zhz~!c?@e3w8$X{*E<+r&Nto>0ikEQa{8fuS>PNvJ2aLrbp@PR0(i72YK;Cj#enQMe zGlGsKenQ7qvDRT>kD;;fX}MMj{{%PcfGVw9>(X20#49fwt;PpOie**E03;sBj$X;K z3Spc>J%W@X&K!(X8BLn5qTL(>ZSTz=^_Y{;>U6y;o2SJ(C~nG-zG?YIX`2mg9;r@aefH zkKz=Nz|#irKRJ&WbPk6llP04An%AqR75W%cWnVI!3z(wYjZ3kwtmMOUnBDDg7#19F z;I7-ISFs8?zKT9B_7k=aUAmi%jrFDwuA*8sDl&=%vsJZ5vn%UQ+6ZH(9)DbQ74~9= z_?%yU6*=Q5=lQeLv;-)ykAKVSU(K~r7Qo-HN+sIa3xv{s`HdfWT<9QVuBu@Q+`&8? zzUWy#)>U#X5)=d#C>YfTJH5dmu+*ArCJY#sc;`Q?phr74qiM!1_0s_hicahC`>S=w z-oL@X*E1NrP~^~ciFd&$Q0Kc<78z1QTVjEevu*6YY_)jG<`z$LY}N!KtR>IraS?5? zj>+kBd&u-9zdvD{&UgsaQ7|vDD>@bK-Kt#iHSpnuQ$mKh|}fU$%BIW-)iK_dDJISlhd9 zGzR(aUw{Bg2gsY+<$2Btpgp-a&cF)j&5%$~Gv-i+0^P37DjCQcjN7hyR9o#T8GAB> z^{wWc#AHWu@WaLGvFs~pY72PwZ^83h|E!auNz5`HN~jwds#G71cI%Q)-D;3qhYn@D zy{a7kh(}EuvEgA2fyF#F?R+#3yK+QDgF`;g6-R=89xA^ zzL;Njbv56r}P-x#7WX7GDyz8E})zDg2sZ zLSFSDwGLJ&39tzD>4?Rp0)WwB&N*-x$575gN0A-?7g~(`m1(WD4>aG~XC{YF2s@al zb%6M~53o|F7tuojwY|badtI|fn*(0c#49O|S@g(!>X?Gw!Yr$)E^T_O=B*&t-=SAd zP}3ns_*Q*};ss@(%=ZMgFxZv8rDV?b@=&b)y+Mhf^o|Syfp=7Q*})mh+qX;EEe7vI z!=?Q#jfEB2)*(3U$1vb5(A+*|^e%R|U6i^Q8Vu6b&RXbS<_R*<=pnZ`#!)okn`@zk zAnRJ3?L7d3^jHD83!sqqvEjc#gI~)Sr;nq=6>lX0P8bfd`~yr;ut@Lxp$8Hq+|KOT z^rnYD2e5eL?(+n3mn-7!uYuLABi}}Ak33EA@Ldg;paQO!ZJ8v7me|-&kpX;;0My4btL^x<9YE6R1XN?dT3)r$ENpO(0p?c z^e)1WR3|_eg%SqL7bgFg#hsH46S?AvvwuNV6f_HNe4aV}foFa| zlOu?iCsSy+JQn$L3M)}NCz6-xt&ta9jjCJnO*8rH+zfeb)$R2S7I?FXi1lnbaPp&M z+H22pd>#ciz^&xt4)OOGJ?GV3>TBqj5LUnd!*XmQ3#Cb021_DXaX?`7f71rq4_vEU zO+mhuj}F?Jke@6*loAs9&&|*xxqGBO^z9z9-lQcj@NrHaRH;u_Uddszkj`z|63yZQ z@*SB8+?1S2(S*`PRLR>Y*Fpv!ixN3L7*l4<=!^C`zYPDz-sg|5h}JNACH($tIR+}sd@wXH!@ z^YXI%dp?{-4HhbCv-l^AMzephzqvVk65-(cb_i9@i$AmnhwYV3n{LRu)=(@foe}UU ziu^b$%U8yM*QqRIdDU|KowPl+eB!cST-o-RBqU^x;!Ey~KCn|!@alGHQ&X@~o10&d zpBNez<*L(6hNmTDzc!MOkjzlx`A4TtU@mplV=ADtV*BT+%OBenZC8hP{*Nj2~q!xCL}$s%_7PU3Aj* zo@P)wj`W8*Is&>2lImNgP8SPw2uR4X{j95&tsRF#{p9D=M5xsukW*;1tBx}aMFBux zFUqQy-+j_qWq~r*%fb9<2 z&Mi8cqkSrfQ9bGJ*O8bNed#wgTdPKI-wK%!PF~;EGEmgtelx$!?dtjUVg3^g62LVY zN6er^>y!Kbe0hzwjQUq8@^^Jp<a&x+MDsLYLE5Cy0SD?<$XsD0DfuqwDbhTc<5j8);3-$vK-YCPw=}7X{6v%1O5xK5{N-Z7ff9IbtXgBkPQ@GL%8>j!V8TfRP;;SrRaSk~oZEnquD5%oK4}?Q(!2Aqz z0?0lUvU0_+(KUx(u!LF!7pl!fb0n$tC;k1O*FS8irY(7Wt8~hb2m_3SDmo&Wrc$To^i0;?+En|AYn)B;2M7Rx$z@Aqfrs@WG!dfor1KLJ__MshH&irv=nxH zDE7WGsXLcUXt-m%2@!8TxJd?JD*AsKOMV_%g^fh}t#l083VSpj9pZYz=vMUrNPSj|rTi|v*z@RXu%oqN_^t)@73E+c!@+9O^w z29mZ(y5Ym97I-{_mPK=Z0rUkp=Q3GnyKVpGa>oyq;z0E{(Y>L$)v7DsWyGlm|9Z<| z<~w;2fi<#rZdt^QWPh$&)S+S~QIdh_j&XUCcik8NmZ&&FI(jKXve_m# zi8>F|0^52&8vM3Jlm~{HxZBtFhctM+H<)ssdh!X+M*VNkkq1!CWiNlI3^NIXnGl5m zb`0ucr8$YA@l}uK(#QuN;hYr|XzJK}Q?8z!h3>sWWRP+XnK!~6eSz!RX%9Qp0 zuZ34#BAKtG`4@Wo4IQ=@K+|jUie8@$&GgM*lykzT!+#EY%Zadws`=pI(d;{VegHXq zI~t$;@B>_Nd~_r{KjQW}?)BQF#fLhQ-y6P*shsmZg6RZP*+5Z(B;bl`>FS_b-O0cs z9=i5+sgdmfa3u&AZ!fnodfIJ5uKxO{b~%f9sry?sd&+pGCBn(RxrS2fe#}9YNVJA6 zy}%5gR7f1j`HXuM$kmVupYklp{9`_gsS^d}OpHpdu<=fYR&(_)^L6kihb+g1rqbpE z8j^Wnrm@)UWQa{=U}Enw1;QspSN`5Gu}bqon*=A(Uw@P^C79&okU#VdKKuILd@4!P zeDs1W?#pD-le3^45k&BU#tZ%r!gt8tXif`Zs%JOR_D>g zMn1)u@yePq&XQ8SiVvdiQ0pbZQ5jn=*Ue^#tOrFDb|s(3>8H?UX=P|4#UbEH=KGh! zWImN--xZYq=L*D+HU#_1`@s<9+XKuqze(p(#m6Ci)7~E6dN?o0#CB*3f)J1YuhYKk zTeZnhcoPK}b>{TRSHN-P0>%g1 z_bt<;Hy?b9H+6$RsZP=ul=$e!>G|3k0s0$Z*y;ao8eIGJ>eWWT z(Ex!E_8rK-`ZlD#^YyJGnK$XP2KEZM{@t2c3rrgXlnB?e`m^{qeg?R&UO+yV%1@7A zjpany;0vI@twN{+cjb2u_6gts>W1ue>BiqV8DPDn3moHwFCA2ZBg}jF8V>{nAS0Wm zJEvo8Ts?B$j~f~c7%J3s#>k|t7exJFGsK$9a1>1fhX9;6HG=#u6*g&6x3-D^s-Y%% z@jMKAM@PGPX=d9lg{_hyO_aw!mb9C1%Vfx85k|bsT}@Cv|GBVa>!cWaiSa(33o*4n zoFb1sEaUIKW{kU@(&Ga6MDy{)SI6+{+BLqhB|Mi$B^D8ob!VAyIKW_=f`I?+Q0VCOZh3;X6 z$hvE5!v%mPx$6i|uPKe0>@yzhe1E*511J+L&bq{CbBqXHJQA6441WW*71Mg#C*?Yp z`-@k4!$S{{nhH-G4n!a&EALYpC`Nbr6$sxv6xjIrnxa-pya(l9L#C1fMlmIR1-&1R08J0ny~h?}P$^{ja^aTLMa1tJfe~%uW~|Tw+bfly zhrgMmr>quKc1oQJ(%=b@b!_xlr1vpuQB+xD9pLT2wt?OULE2eyf7Tjy8?b)G+q?zQafIx{73AM&gM+xfug0TwE=@;EADy4&MV}RYVg&y34Yr$`StxLN9fTdr0Fp5%(qPku?KL7|T2(j`ogQc|jsj zcW*p1e$5-E9}}-qpZG*qdehthyL^k8?&tKEKB~aV9dWX5j*mg|_9ogco(w$aa9JBO=6O&WI+2 zr*6(U5L*RLLATPbl%8JJ#W!HWtQEuh1N=D@T@BS`k6MHrIsvZdbu`a+zte6K^;=$9 zR9t=2$@AE9UKlDON~l{2T==`Qi}bjneW^0^4}zR7BcC9*v_n^bsa4P~box^hVI))_ z{NT_^;mi?#W%OrOLd~-3|A(q`aI3U`qkT=BtjV@*yP0aTZ5xx_gbCARYqD#yn{3;* zHTgWd_jj)AoPVHe@7;s%z3#O>3zZh~wkLTeLb~+GQn8b9%rc{px7AMTo?a#I?T~Ik zWJIgiJL)B|yqIWFCKl7VpO8od4G440PHT)ZjvbWshyDXm=|YhqB2+pJs#H2N0Kh&W z((u@)j!B$W=ct#j zN+UfA4EJn*5}y1`;Q6r)%^bEhhR0cuM(v7Xfo7fDE?3eeC=%<@(|x1rC462Z{8M@n zfP?|lZyp6+E^a96O5=ZO+%+mA5~4o%$R%DJ{{vE3nLZgF$RZL=?XoVr%Ok)$WpR)f za;izo{)G)eM}QiBC-HRZTPPCXBdHPS;NC}9uYZ{Y&s@jWG+MwoZ+K1{;j_Rw?cGAA z4U?<(l>a?K?AWAUJ?zgrtLfrC>C1QJhV3`p zL&;om0X|5N`P8;#*c^*=5#qzY9;BSl(<;UtvKi0zBFy!hc&^vCrG$^yX|=Y`?Iez> zDr`A{$Wi2&MDNu-?vrqEq9cWAhrDyWG`=%8MvGXhuk_Co;>?|Q-pN)k=H|M4)dAC= zyVb3h;W$!==UBF2YlM@;Kdr;H3!h7cP8{?M;ErhL&p#f1awz*FwQx7;$fW`$#ZEC9 zuLRM$41=cK*+QM1L)@q3Zr%m*4BLzD0w(XivW*KW4OD72lw&6r?Hs-&Gg}N85`;1T zvCqHhfKb|mqb+%Reb9ymMGJ)W?^{zbr~E1z>J1=}wr#zVIL#MCwwM#o4;u>`vMo(j z_1F17Z#O@dLWDa5!HB8)hg3TfP=l(jSo8QjyfJs;IEad+GrnASyYvA3;1+Uq-uihy zC!fvlz2&XRxx|kMVhh(ELRA|OCz2m2Pjs|VfV`X8LoY&3VuHFm0{1Y8{$f=D~o1C<+(kT;=*nz{kt~10mA&@;645Vq$Z4tp@G5A* z%BWTL^KNI7;lV!;KH>k)RkchXwt%Bj|J7%6E}QuVmlm~24XI=-xo~^wIvI-@sF4Wl z5i$0eSp@`n)2^su9cVz^mBVEHvZLZjNefSDRL)bbtl7AzD2)nG%%bnQj3-gn9HVwt z>UjIJzVm6lgYRH2$O+98Agv&WWCye|R32VZyZPe(0sgVaNJ2{h9}2EH`0g?6?EWRu zv1-BWnLyBdh_UhFJV4&kG3)2_d0_(gWl>EdPa^HLWe*pA_EA7YsHnzYVBLRx!qOe= zh1&-!b4wigCD&cP_Wi`5+G3k zN)T$D*~L$5ia!m%kX}(EmWUjqixLoNd?giRk0VkKd>3E_(y&x3fViWAe9{ox`&kEXSz*FuTbb|%`)!ZORKkDWt3n$ zzzcTG@|_nI5D*(`hlu-dLNj;%otPqsETeoeQSS43)}q_FkjG^(eI&?7Rf4*9%Q>pm%Qciqh2RVw zI7+wG4Nox8p{f~Ind(1tfndo-a9L>iaJY8DK97B_lim99@ZD z>>ZR6a3Tykw?%Puh1A{}Ge+(=8E zslR6<8k|!DReEEl`}4~hDng^CIg7;}y+u(G#)|B{hjx_67F)90qI)oLX-0T>qG}^< zNm)@BJOKpE!$Zs=nv&(Ny0B@eH7n6q0C@3rlRnT2j;;CX`pY}^VuPUW;(8MO?)o-$ z$ZbVskZ2M4ZDy% zsO(N}mkL(K*}>k>SVW&SN~5t>y6>M~ySFy8TMwLAU~)~)gCcxGP%jO+MdmY4-mkJJ zf;8(&BHS8la$Imo4>~gjD86qqPnJ$BmWr#^$Zw?19x!aN zj@Fc>8o_R~Q7()fERDL2#s7Iox!RQ3KA_YPKG{ArI1tG?+x!YJ1`N?Y1X;_bg$V(f z>n(KUHo>pasuaf=q_zpH%#L1fiEC!(_41V)l>>7l3#)tj9cD;w=ve^KS%&MhDr=_= zbo)F}gyTHU?%jkvcQ(5rJco>4Jf;2n6Mf8&=~kSQV$U`D6fbCQ+nfiL16a~;)Z0bu zyY#u|7X{Yu%Ka*Eu5qTpbRVt7&tt|T;2~^=KFA{B0!^skAYz^Ht@ueM?ja{!D+TCQ z=#PQ=Oc{W8&w$l9hpmsr^X72Qqo;$<{0l%#%W*M2=VlAespkKjJM;k9hI{$q3z~c> zwRKAm0D@FsJM1UWsVYNPo}F_N1^U#u(3lg<*a*01^nU#t4gI=B7xs+VQo-oMrBO01{eq5O%l~V&mLg;)c6FIF1-CPI`?##S-jE7vdwFK z&S-`&TQ(#KT03;}2WAdR(0!Br6#$Pa0bz%Dql&cn-)7|6Bf;8(C;BlgC8|9C= zb9H2qX)~}5#6{#`hg3xAx?z1t6M&yrCoJ||Crtm$z*{{@!dKmv{1RQgRYenA4sQ5c zX_M(e3;9(m5sq%|{Etebfp&WW+_G@{PrAGQ#{Ks6?)9tAaTEC42@WGp@|4G4NJkXy z@>*g78YYPwkk*m3bq-B{W&IH{yb=w9e7-ml3=$`FWQ;~3a#_J+_t9p=}n1#bUNKka?GU#*VISWQ@NuY0jT z23vjh@%=jrFIVsx{=;@y@KZ-lX$PSA$b8U0*0jt>-o?O`#5+|x)nA^^6C zx!YkN6LHLa-M-}gcp1+sG>IW>x8trU2e^N}8EHIZbGpdR@`Y$boR(@-WOm9NqY&=b zm=7>Nl!`99$wm3nQpG%zSl!26oE9~x9EGV7&Y~^YC~CR$+32a;6=#(f4MoHmjQ)Z$ zg(7xWe0_ls?1u?Y2YmaX51^>+$gx^)5cBX8!;79uBL%LM|LDxb5CJ`Dr#1xP$~FA? zC1547XuPX$<(=i@>~t~W6@Z_-GGzLc^UcE4jop*idv5wk~&Po|q^pL!gH0ZD7ORy42%3#56FV{64Dga)Z1BmsR2)H?NehFhc;d-+|@AFRnk)GF4Ir-nB*%#WS4t+Tlxf0UxvoGPUIX&fwrWxFnR zY(r)LnwaPa(qvs~uTKI5xs&PNQ43n!;ypaN$zmzMegO6G*@6ETmp!_Kf^*1*0#VIs z-GQy->znW}HeM-9Sq3o`dr?;2!5vsF%hgs0c~Yq2EWtSc2+h(&rk<@8 zujkhgzaUUfk}4{fIJirdL5hAYrcDWCKx32RHU4W}$0M-yXG+*Day;Z@?5W{Vp7+PX zt5V*`hXFVXx<*^BC}*DWTa~d8Cq3nDy; zYx%PcOgL`>Hfnm-)aDu9_ty1VGKJp~y$V-y=4V=j4CWg~S}0@AJRM;^DhoNgA$U2? zZ{>?Zoos;&gC@DAa^5Svj3Srk1Z2~yYj&vUs{*3Tj4|PGlCB{4V;!kJ_!q9rwpv5|u3(a{f{j`W zmy7D(9>2tTMr-uP4^tIp;jW4UWX~?nSO%)UL8`0#e*GgNd*wvZFn971Qh*JfGt@WO zeBiQ6lcj%KEAicCD$>yt7|Dba8Ci*SaBn&z*Oqa&^AFi;e{NA7op$BxweK*p@9(~6 zy3fxd34RjooP+K6Cw#+yIn zK#q{X!4q(1hNF3Y3={>9z@k2}Nuc|8Mv7j6 z2nXTz)W)m7$R2F1En2jFpUW9N*I2nVf>gJ$o5w15TA5*8zhwRSB=P)Eqp*eANg$E$ z%?e`6_tgS(i<2u@1yjdq-Ai_-XsKT3iVu_ZXgAFhP(9nns2cc94 zL5rz`v0^3EU_it8{{#tma<44Em&dW{a9cD3Y`KL(XxbkvQLc-bWD?Jz>WZadRsuOa zXz2klb+n!-uWpyPa<=mpP$bxLs0Cm2N`PInf!1gGu*gA!_BsN|L(HNK4OZRXV|D5g z{e`Y;KjeBpo0qNRVrADK>$fnv`9x&$#?KPcSA>^Jv;J<2u)RE8BqY1qJM5a7@6{la zeaW`%Sat%OOMivU{S|EjP`~pKU>m%Xj!Ov^H9v_k02fR802F8=3dQx-X>{k1B}k8p zr;j0y0d1~AjV~hn{coh4;-(x;3NECUl0XDMpW_&ES^TE>fl5xS=qDT}5$l8+J^C|^ zAUvlxbq)D5+w7D+aXv>$qSSDUY|}KN({|QcGcBt8#zJamMQhhTbHr0D0u(zQ@tYs1 zs5-pa74zzL$Uey-Ri;{@6sRcOU3S7DL7;P4np7R#A|E_*GEAlI=__PGGdGqTh9TUr z>g3kIm8jRyLKtdGvj(X5T?ss=VD9Q~oz~@bZr9ko zw#t@65@xX9bLMijS4MkzY#DejK{o4dw9 z`3{Y}FN3>}nH$e#+f+AwlI0ANA-{3|TYMA^s^o;iazwK;n>4U!)AF@QIQ{-X2sm-z zNuBpsO-rsxs=0|s<$OQ>oa`L9F6-rIRz!`9nn!$d%%L-m-142f#1x|+5MQE##bABO z3?+%I!htmA@V9hKFF5@#UWJPMzu3~#oQ#{2fr(#-zs=Z-E#X;VXMOSQvXWGH74XP* zg8v0nY~L~mj{w&`|neXjRtTy0;6ThrxL0jNj$S7@r_1YS*0EQ}zr}hd;Q~Ysm zq<0t>m7OyMCZyx>IqjjRqt^!dK8|@5VwL|>9z28Y3{NABzGhZ8U&mbNTa5kZ zi=#oisVi{=Ma;SwMDzwdfuzn>pwHscGPZMKkMV2W51O%qlIpPkblF44n$8V}AAt&0 zNPBW&s(U5#MhU~whMA_}m*eY7V#4{V;nh|TzSPF<0gioc-gL}o)i}(g%40$~`>>H) zNI$gx0iXB#l9QatWTr^^bS8!*=)5Hkhr|m2%x=nYga@LC)3piU5y^n)h2Qu>ng{^7 z172PfY$?2NdKQkoDErSvT3-%&lJptGab}$UhLPxBauEl<25r`lte(mSfpu+^ByO=B zS%E$^QPs{nSg=cCMyFRP%~?9XPd!MbY9`}y`{|tVhxaO-Os!Q=J5R3tL%V$@AKQqv zTD#FWTM#N03ERa8IjYr9hzHVE9P1+IBiE$x)!+p&5UFJ)OzU9a1l(yZRp-u9)0x>l z%T$I?U7IN}Vp(Es;m8Qh5L>7G>>y=5f^&qG2Pq7$NtiGDK z=FAU`4hT%aO- zt7p7-6%Cc;lz5COKW}k>(&IF!CMnu$Sq$i2fW|%ZJzjotn_skQ``7H@)_x`0+jJ5|qp4^V#4eebeQcG5K&x)Uwv7Z~ie2%QYDTLFNdZP<`E zzeIITnszX%?P(5(@Al(Y1%QWZ2|jC~V8$y#0S(uPWzW?!&hj+=>!l&@t>n6q;QWIPu7>4V)b|KCcZ_m%rESif>3(pYSW!nns(FXbt?i zWtnXnZj94dI+_Q}DuVb~%4VE+<3^v`xTDz&+ zJtx|l_j#SsxMG7l8yUg=4he=XpCq7X{T-gjo6iStMO1yI$_i{`#x-MO?lcw^fR?$B z0{Q~AlY}e#`t9S_}Xk4ns1ll%wII zhO+M>{If6yILf!PNW>{@(z4vBZ*0xsDyup-?%l;xf+LI>j4v1g&ny-KxFYHwFT``j z2O4D!{pGnXqC2zblz+7Wmhg|ckM@g6%XC-!E)Q#}$^bh+Q`yU~y-v(GwgFhY$n5NE z6ASrK@65xnyu9HMCsgn)xcOw^J}3g${k_Ym8+(o*!5&#bJkKd%TW32W-_qj!yzRP! z{x*4QP=4BVQT%6=uPlFX4kq|gVvi%8X6LI9P#q;g3tdTMiifINdH zv00sP6`7rwC{A0H*BHN zWxzV+)>K&m8wN!K(j|8LVi5o=@?ms_r`cK@lk zCFAsr4k)b9Nw#M_r)+apli5-Ra&fCFC(POJuMji{t*XM{pz1;gzI7Jp6OKyz3Dzb3 zWEVR&O>k={@Uw!tg8Aj;*s;S~e3Xs(D;0*uTgIu`l1CV)(VM5;2mxq>uy|gI8gT#p z|3`;-g*JqE^BwN+nvd|<(>1%c^82cuM4Xa4aDax;;_xwK~_ltQQFehRNXt&TfAlj_UJcx}Wqa z$^c82fxAji>yIy8@{Ks^jMLlmUcMAlW)~hbSF!(J?;4n$GQ9WK`kpa8Z`|%rpu`zHQG~fYjQl!y=W$;fY z^U$XE&ShV-`cTw&)}IA=c!=)-mDEq52t@EP4<|wBl#Y+b zJHlG^m=!`~=Or()nw_3KSEu-jjWt^?9z{|LYJ0*k2-JW zt+S0Lft-%bnag`&6|4g{knT< zOxFn%p}cX|YJXLJxJ&YbqE;?jgQtE9%Gy5(IQ^H{F+Zm3)~mPl^_y46P|`yN1Ch+f z%fB>tg`c&n@u*nNz_tJ{r=hqjQVWawXd^`eJTS#fYlj}uM<#N{1K3m1<3XiP`@R>F zwe4?Bnk%dvw77V4{!@^EB2hLfOr)+9OaAgrU+^Qvr*;}E4p#=+ePGJ8H1Cxpi3aK9 zT;;-9Cm?kn4S4%yGvUD91Y83BuZW8qclNhgF2^Oq4acr`vj-(~g&rqfYq_o6Gf-mH zoft*n0*|u9r>XD> zm7!?apa?B%s}37`qB;Jg@uo5e;Nmu)mti`=`AWPY$8akv9xm}_1|*HoEX1t0Uzc+v zePYi>O1jlmCwusBay~VfB!jpB92kBt&A7mBnQr%!e$G*f4R{umh_jDU7Qy7Vuma`I z`zJ74hvRdL{mYGOJhB$}v@M^{5ec<(-8ERan0^Y!-wS|SVqM>pO{gV+U>#*`Vi(WU z8Ocn-NQ{|V^s-%L9A_V>k_m&nrB5%JAOD;C!+A+#Mgg?^p81RTMaHA9t9(b9g~a;w zNTPYIK*nCPo?sXATY|6k+To8LU~{-QYtCK;2=tD6#fh+?yxCF=GXOHW=3(g~)l#!r z2s~}%qgN`>K_K!_}>~Xg13>o?8H-dDg`AN&5l{!Tc_ejU% zltk}Z5;jK~SdbSH|D?WpLBReAuZeuQkk+BM;(4!G59!~K!NufBZU{65So-(7pnW&Y zYjKO5T}^UTbKV3hOb3Z_6$^ctYRpHwas-a6t>1(B}PGt0<@YBBA`A zi5!T!yR9zLkyPk_3UM?|4P{3;EY%j!{CeR2=LE0+9IAyypG-oBm{si7euNaj|i{kDAj5dLM#d1w}R_{ zj>sA6hfM;!R9H5F*}>T%#Kb|5$za+u>_Av6Td1az){d-QFJ0cJs}xn&hYZLYIJA4g_M@K>{*4^7;^^Tj2b8iR zERC5x=%9qXz@~HT1H|O|d#+2ERl`nbf_dL@JG-Tw8yt~rZ@_qIuxNkEw|rf$XYBq) zcvqM#=UCJq^wCN;9zMdMTgIW%eWEui7X{S9Hl@NIzKd8c>mLI|pFGCZk%vcG7C(vE zO`XPxO{w?;lp!3XK(&yN=czHRat_E~F}i{Tzwz>3EsG(>msUs;fLSWhWz8`cvD;9_ zqmDun2J}pA;8jni{x?M35~zDOJV{!=or7Wcv|;T79jr`|0lLXOzDYMNm=~5lz6CKA zMz?xXkF36#fVue+@g!gDjetb zoN%leN;OiSmbWHzoXDbK5&A#zT0`Co)1Y4Y5cqM|9H0O-ilgW}wMJT=Z`g7Q?r*Y) zMnI2aSfxf8=h|({EnufvNuP?}0v^v?S=BO;+`s=E>0G`K>lfeKCB)~6;4T7wonv1j z#!k5D*tP$Z@J#+Q7xY`cDG2B3Kd;ftDXRGBtQ$;A`)0?tvG(pWy~Km@{n-E!3vv_6 zJdQ_T%H!9_ISrV=fy&|l>j{?zINn8Tg1ldLHuce82m!?B)NAJGIjem}#onRQ>6$v$ zFCacoUdyq_2SK(~!|_};E~9)*BM0hHLF z?c14zcYY3HBi^vFNhZo4# zdCMDIAR)QdZ??40x+dos^j8Q&LtkQ0CxzZ{7%eQu30eak%{F&RYu z;<|s+A`4IU3qEW6g$QY|h*7)aixZOUV&?&gkKI$xH zt)H1NMKs7wpb!3eZkG_SdBic#7`C2GJ*DRIgJRd0Eh|#!O2@J}b>+z!WV86nRD3nrvzTo-{bHr)to3 z^ZBJBjQnpYuW$KO&=(DBi_!$bXxqxa$pD4GyjOYVw2b?=_DzHG0N4X>>fqVuw6yFF zR2QXJ0!0WBc2tez(^g-gT=}JSk6%oOg9sRpQbyZ6wD=o6-k6b$u;nJ6sJwasmvm52 zxI|X8NfjqSTTIKd`G{F7nI}w#$)XlC5#KdJ31^jX@Ukp2>^*yzYN0__gSRs*r?CH5 z^tZom+>Lja7@IV5wT(=Xv27uZTcEH40kboMfCM1Uzu&R53)O z{!wt&^0kd|Eiz{BEnTvAy^naXu4zCQG4^ACoRMrT;^LCJPor=LD#jG;{&?LHL|)nK zz}P`=HyA2*y7EgO-E&NvD#(@I7N*7hc5ul1_Ih4a>`U;A`>i=@U$Nd-jRs!K)fHFy{kxvMb+#Skap2uOV6cX7Z^>e)vA3UhJA|OGnKy;`2!d14Y zVP2qvQoA;w_LLbY(;F_1*zX7%SZwV`2gNg2 zs509U!->gD=Td7=pU0CT9^hQAgV6K!(*XzhQ%=+pHISTc)4ZYt#d#i3>JNJ&V4N>m zfXaovV~!Sk;*oj(sl}Dw4WIJ=c!lc0^r)lpwlo~Pz;oZ~lyGn-!n^y25kn-(XmM@% z1G0ASt?$07eYnIS(C{db_->|UArn*t=TU^@h(@3^Enj_(-*>k7TMb#NX>#2s8Q13s z>}0cgH0nUk)W41yk;T#Zl|CFz5W#$MKH^>CBGcxy6y~JBuFCaS&A8)bs`SMgje?9K zO6LZC(P@6n3S9r-dv}zB4vMDAp(K^;=(C@E*}5HsRbr`koHeSpj1gwNsTq9VJSUsOXH!VZEwMKH2*p4=5-Nv6=*oT70@k56mY6r zhzb)bGUD0=irpJP*hkl81M>T>7Ltiw(oFp?Fr)T(w`HB>c{jQ0%=?A-lG@y+YMoJ zWSijz;WGRuf>$#+5l!e@U|cGUKUnoVX_>-30?irO!pn{RS{llOd7LcF@8RK42375G z>{8qVX(U~;QRCQI?TP+)&52v5%Ns_0k$u`ML)3!(Y1F_V}i`xTyqea)go#ytUYjS(l zTk*tf##)EtS*qK^dAcr{h9W!vo8~pe)$_wuZ^I9+0E{l(&zz}*t zb^Re_EYm>V+F&1YwF1}usw$FzBKxoQiO$W@QAD?eG^v=^GIma$&q@LS7xTrY#En}> zV5<1YuN($MS!jlJib|_pIs@G6_AVM~`WNX|zi9s32%h=dgKWTUiiNK(jqyu7X^2N! zbL_%%(Thkh=FclqwJtu!F1H@BH?-wHV2SX8v7^z&{ton{kR`)RcLS_Kf7zLb2!7Xs zYpo3ZAU0`*E1z6?h$`CwBwD~$e{`3rtM}>>Vl^|fDcUB&q`}aZl2ty;uRnk4B0 z_J)%2cp2XV{iZYV-H#F0j5_-^eov2eChbvt2V_i_RicVhSlj#?pEuT9#!=g0N3?i; zyr#qs2mG9u<(E(C32@;ls;V*}A?oDJA|bmd}IgTVv8t0c#a0gSzt@8X(Zna6%x z&8VjH304RIg|`rk}NL;67rj82agx%&yNIO z&Z19cS15nXGL+~j--SPURRn}+O%i(MQ`C;pWx@I53s(o9Hqh&6L~V*aez*2w5NnX`OE`DnncE38gSQ42e3 z3RY{U^CU(?kpaulufke%KOy$WyD;8sRCigiUVg5Pp#&N1_Dp)la3g7>M(33eycxTl z`)AAQYmZk&o742B57;H-Ih>vuCo%~XFF|_j9sW4ae+)8iitL3h|1@%YL@YB97!(9%pfx7%q^liE{ z@w1rCFGs^&3txPyTgMl)<2}{W!dVK>9BSMgvjhdC3H;}Dhe!cBC8OyOgJ+=Uy1snl zn(Ua}@aby0H^R2*nuHcTqM}Yqh-nhm-3AkJoK-u}3z$0y?(7I*LuGAl6}49-)CdB5(#}w-?ft?yrXL&Z;q(^g_Ah+W;9Q#@E`%;`3M=d;8tzk5;d{%KXZGVO=1saH0yJb2cb!AYE z9F*Xd@63WWI4h{|YJ9BNrK_b3=h&Nw3$gVatxp~gt$KKaia$iXJSv5xuFJ7{CcX~W-wxk>VEAV62sFq<#~Kr4AsCVzKT{uqp@Iq*C2vt={!Eg_flPCil-0~=R36*gE{>6Cw3y!=**2_$1Y9Qn29 z39+&}39GpXM+@Vfq3WkUy@y|27d7Y{V+^o$>Xi5;bm;&Qi$rJ;4@B|35)-T;5f=f< z@1}MDk1h1T*m2vpyZwh1*{~0Btv^p-&Tg@L#KUs6+OvHB;0R4E60BdBD%3^ zA4po3EMjUjqx>FIOoZb(@%U6vdM04;;t)cb_oouP4$S9oI%a-j>vW+GFj9qm$4-_F zX2hTcpP?oEwN~G5AkaVwj;)BDo|Ad846h)cJn6BoInjfCywz~ZH_l6bidY$yP#L0x zb0~fm%6XFkg=6jd%ROtH>9s5VlD5NVL;3;aL|A!LC*D%VP8aamuFFhlQv(_71aMO~ zLD5|cWZ|!c2It=f*8Y?$uI@j5j||THaP$xVr%#+Z>pyeNP{W}Sz`%lB;AKR`+p?+M z9G9~op)cfH1!Ifx)g+ku96J$RPc8IE_}ypvWTkasZLE-wmik}1uu>#Wa2KtshDVN7QA_4rI_y8s!K`3*0k!@<5>?Th?qg=IV_a;HoQ+oMfH#F-v!i zUwB%P{x{IrSeJN5 z+TpWMbw8cfU3tCsl#ZFUzv}0;Z##9We4Q&P1WO83=X`5JiRb7ElGSDD`<(W9soAwR zyvX|YI5#BN9gT)KCt&UuyjE$E`g#hrR>G1J5l}P$zUj_D_n&U%&s<|L8Ual4%ri(ZsJdad!hUnX@ozOd^QXm-Nx_mSQv8TG9LkSV z`K`$74A}?)gC@YQzr-MHAg=g1+e)e_tnOQF=DwcE^}Bh{48(Bh z!pH%l4s*#Re!>1Hffk;4hijuqg=Z0{e*nY@=5Do`EyHJDo7b=%=-zhQc!4T8s|1f= z{!9$ze~$8lY60oP{{qGBf4Y2?u7WsCn-Jb4l%)}Dt-1%~m-ya5W`QRy-nO%=)if;~ z&;VKOPX9T>dxUX5BSOR8rs4VN-_gc)CdRq7@BG3JT5Jz+1Y7aFTE)xhRHEx9o-5dM zRSR2=A@+dmwb@CCrmPOs99M`KhN_sIgb$IlKbH|-NWbZqHv)D&reqocB8%Ff8y`E8 zzSDpm8+(VcLz|wPh?qtGwOP%nT|1~#AL}P2!a#xh{`HNbd_iFpL|Ry!>hQfv_*4JZ zCH*d7?%r4e6LJkmH&#aQJf%{`mxu6CM!=vdKV}B_M?V!0rb@USt0sHkoW-SNrjZ~6 zK()O^z0sTGYUEw;PDQ_}|EXkYySk=f>bsr7tW3SY?)y+M6vg+l!9uGgPr7QePsr$m zR(`4@Unoo5O6M$p3{n4VZD-FLzWYlTKz9w;<+^=7x42z7?)rkS^p2+y0pV$MHw6Yu zL2X=X@bnjY%-Czj(Cx;J_gK~%UUh@*g}r?^mpFWLC0qv)O30~m6~nfEBNcT=Xi-)p z=G_Nsxk97gKGWE|2QDZDBBy?rVc!_MCvC#)O-&TsV97#ACsp=KYuoB*Tp>aNfhwh z?_*s$vN;DBu+lA!I783Rq5RHn2(8q(u`(2I!YD~k8 z%OO>A-$ytAv}$YP`ng}KB5iJL z+kzBBd4cC=Q#xL8p)#^|IwY{!x+2of5&G|7_SlV?(Bxh>&S}?|`ptl9cVbRD zrm3hvv8hiSXaAS>;%R3Fex-N=fXF3CIGC2F13#@n-noX$2B{%W3?ez zfDJJzO+)sx)AQ%@u9;&R({*k&3!(+6sIDTOlDKk4K2nrH;vO4cM5-)H4qt@WxZKXy zO!`38)1X#q%%2zWC+W&Wm-^KT6kpRbjx6{`8>T z?9}gGK#5&4I|_E5WR&yW&CB5d?%aucQnT;=*&1z^pq{f1!m{W@8C6~}8^ZG0d4g9N z33D?uS{&=x3g|~&fko2?K@?_~ZB{3(2O|J#xp8fc>=v>a7~B2cS#lc6N%Uynz6i}M zTD4d(Ze8uf(6qXA>D+)z;LgB^LPIxHnd;}~Azkk*EQaR7U=l#PKgv_2csf!d@k%S9 zs(~B7yr+eM-`<#mX7#NCWL8k0Pl?U}3UfRHo zz&WjHWSI(@*1yb^Ser|bYGfF|&kbG{(im-N5(tqYT2Cd+gZjOeW?;_`)uXL60PH*b zq8v^@Sc^xlxiAFqTJPNcl{K)I2O{j~`ZJ{4{EL5zHia;mrjaJ*%@=5rjR4pH16pH1 zJI&XMUe6`LPX#sVy+>`tZBpD5i>bB`ecmfE4;so~$4Z)A0s8zD?USWa_f1-7oj(~^ zySb-6sflC$Qg@V#_zP!exQhl{ETg)lo8(H&z>CX-%*U`-hKiL-&UnPK*#U2i&p2Hb zFl+5?4~3y1xu*B6RxxwZ_Y#VbF&xtjke5ka+lFC_3~9NxE>)Z*^JtmtQ27njP@Nxb zEgU6}^` zH1C#S9ev~K@r@F%*QLDWm)&$fUA7ID-`m$`Ny>Q))lq@mHmBgh65J@{&D>f~XxdcJ zt?%!0_D~sC5~t9J;=V+gMFTH7a(DiSjL_-Vk<>zNR8auh$g(y$Y~$99V_<8Yc;>0g zzT1VTCxCakL6UnkW>nI+i#C6B_+JHw&dZE1ejjkyv@80=9RL2P0`K0Y{d3yQ_OEXK znGerk0TpL0>1NODmzK(UyWEYSd2jdMnA}2`5Xu6KTcoy)zwg#bFIui|fg$h6d274F zJkRyj*%hUhdTh{Q1mWB8kNXeMEE!5xU_qyvmj}#2ueopR0$`S-k|--+D3;KDJU^>9I&C5p;VXAm zJYF*|ZGjum@KZO$X4bv3hWo=u7kc3k3?d+jRDTF~w+PFiSZop?z+59Ga<&_z{3B!D z$yguxI`Q-Cr7r+9i{K0%n3=&={}Y6B`;s}T9#W6}^n(0FeXRYw-p4v*t^_9)Zx`-I z<;#L>qtrIJ9U_?FFC3&J4A||f(}!Q6bwZd3cZgdNKb*M}6m)H)rl6x2Q}l>de%mWZ*%My3UuIF9E=Q%j~t;$E1Trd61_N%u1Uw zIu5qmA@ECJO#>(ygMs~k`IY4voJXBE#2>;0*2>Gs1qM=x!R}ny*gO&_N~Q5*eFSs0 zn3%y*2hj3}Q)fUp=6<){elZa74^$2hehZ5_vEenph?!@ub#URx4Xo{4sXy}%MK9q2 zkRX<~^Z_+uh2Bx_c!yp{c$k!kyReAQ7uo`tme_+yQOJiv7m?b_s+ybAg2ke#dYGjY zT*rbohvH~11VD2nB8$VILkilC!t6jh7V>vUnV@wRYk2nZ!x0Yw1w*0qWQ zSno4*Up}gQSYY4WgaOD9q0BU8)ZQqgK9bHl?Au{^s`t?n8*tI7c#-g02R=$8_L4H$ z_ZOXuv)4X~Ol}COqU$J2iyB?X&O5HtZF%Vf5-1!lIgqvqERw%-0uo3$E{!!9mzVciQY+zCOBu5O7w%W;V`B38WLeZX zwgGYO$h)Wn{7d7e0fZdpIUd;MX^3VGbE5Z8t|}BrK|T3{041-iZdCm~qB3p%3bnsJ zA47tfyFap@5@v;lLK(uA(Aq$en{>=Ffs#8=l9Lvv%OVh?C!v7Sb|7Z(@hR}_!;^Q2 zjpM!ocVHZ_+gfGEj1FV-oE#P2=q;{yuWxjSaF)9WS}e<@N&R=F9Yr1C*^D^L72`2# zA#;|UJGf5g$0_rdZr&6J8luHG+?Zv{vt7`JIx_WJeNik;qJY2-x(G^)A>Sndlf^P1pxhBi>O|y*;L9p6KNA2 zsGmm{_*SAzs!*RPuu(BffxW``5HHG&{ZeY?m zMHJcU*HA5Y22lT1ikjZA38_6Fm2~!F`HrZa(;rI-PjrL#PNC5EPNAfq1w=DA1V4#M zj3H++CX2VxF}arGKyKQA|pC2VdIFx8<~t zHXKz1c)MJgI4AUQi#H$38B7L9r%%(WZZ8PMVwZmI7Z;gf^-d{6w9D0vmi*N3& z;Nyf7Tt+b>TJ&sB`1j_kd!{N_&;CM!>(}Z>tmk%(HS?2l*|yTr9+%w;**jmFso9_% z)a3{+R^3)ryc?(U*H_Q_TQjG-1pCuI%`Us86t`cPG7u3dx-{Fn5$X`*bVU8K z0<9*Svs60k$ICLkST!MF%Pcy?dYj4~e^A`~IX<3oW;&dQ=H{~g;0d!NhEg0u9Xsiz zPS9DPO*4eYz;e9{?-pQHjEMgF$q1X`>tCw!M<>KFjqU9gyw1;Qkya9CbvWI`S1@g< zn-RYmr>dBnFalA=4yxqA08Q_p`cZOGuzzvZ=MnEYmh;6)C&Nr-Rqlv`zL6soTT!~= zeNfAPT$f>WYsbfpC)(XDCI_>b-R->Mwo`(F<=k}o8<8LQi`Nxa@)RdzyYIRroJ5X{ zAnpX4Hp2Dq+>TD$aQQaIz)L8f&)ep7xo+mdj`zD>(L(NDjovn{=p!7xBVPnEn`=U| z@@s#yVdC0shOM zdmS$BHfBE?kNx}jEuze*{Py~*066Q_=$JT$`vxqubgxtms8?Hd z>h0bjssub~R2lzcrb4_hKUHmj4@|0h#qe2HeSV~G^$s&JQ*d;ctnvW_#Z!*rYF$IIc7*g6 z!o6Txdmj5rHu^z1-SQDnMRs(aywaco++`znq zksj<#hZD2j_HL%Yi5zx)ZbP#?e2l13GT~+_`s#d}HD9_M z_`5r&ty5T}lLc4ci~H5t_}Eq^xQzNEzz6=lKF}7L;RQY+(zSUm+3C;ghCceWwscs* z2Xtt&Nd#PrX5Xz>3?-5&ipJeyg@VskP(+# z?5-aPo;+tq!XkMvuZ_1cl&{luqwmGjKd#Re)eTEn!}Zs<7uSu_CGl}67%4DWRv3Er z;p10l-#Gs@8YPo=$Gez%!!DKu_*-&zW{N{_!-w4x7_)Ia$+eH3j~TTqx2{jq?my(@ zkpLHixj%IFQZ;KD2elP0xY+*v0r7uzaXd<^{r0gCSYiReDb7rF4J(OMi!t4SZsT#UH?))8HtIj#Bw6@c!sBI|;OxQ6YZp-Q)_1SY~e?K9!<={tmE_Y)_C@Ws_jn z5f=Qm>?Ov#Y2N_O&@zwUC%uwvk@63>#m($Zv zb_N%v@=s>(Fg9!~LoOdwB!5P|7GbT>ex+Yx(wuN9_zf=&wh5aDa|+<^WD~KNY-eU% zke;gqKs22GBM{5^nXB-SplWijBgC%cFO;5{A(j|9q-VNYs3<=2PD4^~KiXEqdH2+k_rRA2a zB{emv<+bFR!=#Zt@#?ANUNX z6?sk+f)BZgwWkUOug}1`>oDS#TFSxUs8GEv56J*VNVf*k$J}q~w?1*s#h3PtooVkr zmVC^O)?^^6DgC_aj`N#s{w>9s;1{F&P@C<@`>vzy=FZ93wQ>K$+)Q$seB?Dhagy$S zB6ln^eUQ>VC=B1n{hgJ+-xyyRnJnFnWk$xonGevbFX^do*s||b(Zvx_CVXu;R)Kx8 za*u5)uNJn{>))-yM?X6P*X0sgXSly>P_`|1Co`9BRMfu}B%kh((KqGbViuKYSMZB^ znQQm1W2({N=F^0uu~HHJ)y9InhhyVtuU5}-M8LzYa|F36lbq>b^cd5e(?V6(pQlm< zk5T=ue?_YF_Ym@{;*z4$XzrF@IVNV$RzK!n=^Xlll;UF0LDo*iaOCG+andqq0yeWY zUc<{8_8c8i*C}eni-bz>uZgo~+DAp9dNnzD(QG%XxS1i0S=BR(l0$Qj=rZt|%Sgp*br}vv4qB$q&q?>qmVZ5h7TMb>3Xw#n z+BHGDW6Ig-zlVESCBP7{Fz9%flE)JKv-$6A*vnK7MuX?v>PCV8hZfJbBwCt{E6A&y zbdEf@x#E{@`eSB?5C|pz7?$f%e+9IRB7Xn$51p2NoxAxf`nAj_KL%+Uqr435Q?&L& zgVL^9R;0ezwwC2Pzx0;HW!L4NUT=jBxi-RD(0d1RruT6BA?(}LWpAJt)Y(WRt%q(2 z!ki%|Zfe&zOnaS9Ya&T-EZo~8XGqbq4e~wOnIn9%`L~F+HXhS?$=W%rHnQx$fnR|# zFq(iQ>9Nym^a~0sC^e5`8k}TD*flS>nqgOUD*l=JgE|{;Tc+3=ud)gQf$mT!Loc4& z=oYeYyYS%}5PG@kWrU5L=f)^#v6wlr%p6{boBt%n{9XU%52*;FgKJ=M=}NTsy)X8P z^7)@nBJ))~XM1b)Tc>CREa0i80mq;RI0iLn^`48V;|gCsYFLoj(|5%pa8Ye_8&hp{ z>||c+QdM3wE?MQj3@ROHy14aE9JbV8+V=;=Ec7I}2uw|dXHJ;FvDL_^<~XHR=rb_s zai#7E8Q8IO)6hzso2^TaCx)>@$FW&njBaBpHgHp+PGocV(PHXytark0Odu|DeCz#s1}!S6vTh+t>wH?=@Y1#1xS(?yO%pH@_JYwr?5pI`LWs_(qghp6hnl6KXW2&c+BgJ6W0lLh%yMxYPh@M zVI)z#lJRd=BE=ooNFqb&MT#i5U=h3g1O$c9O_DPTqF28XzQt*&zQiR)#_0gf>9CRV1vzV~l!=q0#s1gNmnn+1;VySF z^fMh;ab+&1?rc(ZNJ`#XEBLE}s`7sRpeA#p08sl`xK2(<8PffL$-#?;V@-8c)3}}| zFe<#=w}zoUlcw?IK>_;(8vJJ%^g2UE;IA#WIAB6{ejZw;NdmJZd|MH>?OQM$qe+bm zmjswN_nOPtyvkH7?`cDH`7>p7%2M!9ZmRH_)*W&j^&j@aRKeV-8dFqE{|$86j<&%0 z7Yja>;{A8_3-Wlq13+H8WJQKA_a8|+shVMfZqxgl%AHSNIqooPRc`PF`M~gXou&IN z+qJQMYsXZquqiApBs73{$0P)QBnl_D4SpLE^I-$viW? zXFG%blBxl?=}T;==r7PJ;PsBie%}`$`za!^#K}N(+BzIA2MUL%VH69664oW z9-?}jTbqtmiNzi)2z4m;LC~O|@S_%aZ?tlHE~bbCx!4a4h}g&}hu=i$f-Rv`APfN| zxT74{j4k6>UF7Gu6rU@{PlpD=UDl83yE%wVhL>wi`Xczo&qLuYZK2BO-J4n6^Do=p zJ69!HCd;8mjbInAcmInwFYQE2aQV27r0fKt%pB`A>#x9#p}BPY`F+4?A2=~Ky*$NT zZn3D}AyGAEXVY@5H@o`lj*&)9O||xQ$Ptr6U&eH7B?jw4@HQoxU#c5w7I=cF}*; ze|U<^O>NwHFVDKGua%E&>moz_Kk3k^Z0nRP8XaYVj;Mz`4Exo;kT-tHtY-{9MLjN*}1s{k2>?L@$vOjsLzlo-AqNTzpcZB|%0(y7( z>HG1SsuXx@oNs%dX>4{#^)a7cQa{+Xr<_8I8Bdo~aRr)UBQisNj_i)({oSa$9dV}G zNXP0j93~xg%NFP!a7z8zn_Pa2r1UdiJE*15B}{LyZxlRIQo3V{8iX{Ei;@2ji>A2O z)QX8Pbn{{fr|Gd$k-})~PoSVL>Bcz*4t4(5Y&Tiu zgEU+y0{exr^FO>I>_sYZi0ie`{zDzcs~$?=XWK{|c(9BH?oeFy@^!hUB`aV?M`$d- zf@}Yuv+w(N;Ot{TS183eHQ=Xigb8ljxVw5>^Jvs%?sQzwX6{h3>3pa|BCsDu!0zl# zP(sh8i*bL(B5wXgdHl5=3ml`UC?e`7T3IhurcP#Fw(6b#$gVKD_UQ2@{U3x*WF0{0COcYg zv_e-2d1hlnkZMKz{y>V>m6Bs+BFk|a*bMCYBJV*?jS}>7d2eJ45}$#fS_b-z)9X03 z3~s1blQ)E=CIo3_)+ks`&(4vaamTQo0hq*oNAh>}!&{Z{d1{O)ikRsSR%tw7%ZgCm z0VtrzLp>uziCP_lF%5g1sF)fwi?Y*azl&|p@v}_cCZ+6!__tUZ8IR9S4{m=nRkYALUJ#lx2K zjoZkRHu$JEnk7X2dF2fW5`xEzsNS)|%JF2%Mz z^f7q{l)sYZx9i2UvMB5@!F91l`t-*jZufG)JHi*9Y9~`@p4&ydZJ`26DI|HHsX1lUVEo9U;=aPK zGMvyq(|y*Be@14X%NR=(?wGBo1$AajhgP43(Y`V8#pF(CobQ~MXLPpx-GeLr?iza@~-*_`Sf)nYy8GU`86b zA$*IdsUYAP^&V5Bva9wfnc~=K%pRRo5$`C~HX1fBXl^e+Qc79Q&J))vhZ6wV*sGdV zAE!U-;z)74?|yyuVZlZHN*DV0-(s2%_=9%cw58`e`?%+*pFFRj=(5u44pV$-+*cKv z=6__?nI(Lua;sP|Ief0wN3UVw7Vf33jBaxjx&IU$EAYDaV(^xHo-^phuuV_WdK^IA z%;772S=9Hg&;8SG>@^(!Nimb6CHIW(g?4G~@sQy#Wx=;r9NkqkRABY_GN^r;)2(aXOBt&YXrIr%>QFqtYGyy?VxQMP z0$$ z4VcmUEzg>@iaZ;d9F}n~N>ACw$}MV{pLs|Hg9+g(RC!QelEEJM|2u?~q37Ayj2^a< zY0EH9xUyRZoTz^@uDsv)?h3DSMjp6Z*}C-`8Ih@-@U`k4P$(WS;`;3$9LxrqDW}>` z1yX2Ubj)8*z^T}2{O$D|7hFAT@XEw>JI#4$$@RfV5bzzZqC=zsQ*MtTZ=3E<(Ip6U zZ^(qgAbl0m&3)yG+hwNjZOY(>8pFlpM2d^DHe~6g*_gLfP^CyDW0V7`iBzrQT=3kb!|4R@JH78AUN&nhL?Y_)Cw> zrO|8|!~i=yxv=LIs3Gnb*fgTsc5)c?qX-iP`p)Ygi1;BnZ-}gULaHUgw6okoe3y&+ zU{y4VwNoS*897;$Uvym6+Lz_GJG=(=cssLtZNSN8N`WS=bhboa&UYBI%y*E;3X&+r zc${8eICip_hyt!FYgxCU%5V9u0Hn0iUt%pHM&5t;gcg@tR~NFQ`l$;}OGOkA(q4GO zzHP5j#AZO~lHmN=h2&UZPLScOxB40HH3+AFp4C(HS}mFFcEKxwYAAAEA~f1Rsac)t zoJH&yfBwU?t8aUX%i&V7aKknk>ZWtSIm)ZJXcuV`W{X+F2{e?yadkKy3%8G)Cpq~M zDPiXD6+_0DyAm6gK91Ti8ER*??#mYsMbXTMk!;nAYb2oj;>5z07IEuuG&AVIw~#~k zMX5!s>(>8;JtS??N-`YJ{t-)W0Bm88{Ve_%JF@I@R1_LJPLW_ifvx#xF4W5Zux%y| z8bQ)kCxdPj)-XJW;|`kDUK5$2MFVqt@Sxnxxu>&Dl^J7>`pP6W$-qTXs-zIMtkA*n zOMXx+ZA7W1tBf7zIq!x!&^UkRtfx-_S1+w~`8lcTQ#h2CF&+?uweC^Se0QwQbv#s(U1{&*wc_x9RfZjb(V8HVx8T&ZnP zY9`EVvj&fc`*Wg8dBwf7;k+tUBsCgr%zos~$mBoslYBC=&hOS_NO8xu^E_!~=YPwP>>&H0G4(%M~G*Y5fN{ngo0adztvRo9!Y5{)tCdzeOz#Z7H zbqoAwxi7@0e^wHR{;`MKaH(E zRv+s{a^Tsfg*vSMF&t|lf6j)Q09bxg4|v@?i=zOrC|WZSJk!|}Z1y)<^cC>!$(&`x z45(2>>NYT8HNc#lq5Uk=8FxC3{q=&7dxrxnkIzj`=opm%Mo@XYPpRGpvEq;GJYhx*(#AD`kwP!rO%XbcYc z4Niq_)7Cn>K9l_f_ys*%hV?nub8>)RkS^BmVwS$qCjmKr-t^;mqwgx0H5Z28^O)8; z{^^A)#g6IZJ=O=2)C66WQEkFupg}V*#A9ddSj<)d>BpOY1-r4H(WQpH*b3XC^Jd+H zDN8FBzL^~>f-W34JoJqpP#L4efJHKVmLNo=Fcm*Mu@Xbd@AQjW?Z#A$&TUBXTv91* zFKUhuXdz@ogH#Fp${c6Qge9_%hhdEeH0J9sM-5O*IIODaz?{JEp&>bnmr3z6Q;%Z!J;&I_^}{ zl?8NdFmsIuL?@Dh9gqE=8wrI_%9$h#lb39705~vvHDW=1DZTg=S+5MkBqnyaa+#P? zSQ;6z6_TVN2-O{Y^@a;hkOs4?;vMDmr7#);(dt&#k69VQ&+12I(sUAZvz?#hr*yyZ zTQ$A4bawiC>qfsu$$?_*9N&Teu)Gx~=#GU!fDoE-xxFwhS&vxhNel-yuX-MLb$B@q zf37a0BaI(Td5OnHhZh1DQ7j*P!1-@kvd&AFbtFVoIxjQFb9v~a3`z7B5Xvwq9`$Q+ z^Y9lTO>)pk@cRL|t}5YwrrP4wOL;oFl}pmd>Jw741ALOVjRC2(%&}LU9h2vQ9ZpZ( zO6~(1Cyekv+9fO%4%NpeF`ODAqw`9cC}C{J6J7u~6!tvNOFyIrj#gd>RQICLtfm;A z>t$N(=`Zg}Y3J%`AAWZvVc6v1s74eCVxFtt)K%h&1rL|=|EOi1_m&p(l2~s#ZG%w% z9{qTTS@Jw>AqzMC*P1OgAb`@y5066Kt62rOuiv>>#}TsZ6NAHjrXu`n=E-?=kfC7J z!hrY@@bf@SD+YZc`0ds7C29hdq?tp-vIDF#J4FPpHD%uXE)+mSDGFq}^uWM&B~x zd;je}vznfTQGb3hjw@gSEMtbP{C=y)5A*aL*PWlJFe#yp7nuBip4uq7DYNn@<2_bi zu90{DqSk_%!x&hksm?g~_=iA9ub~0{py}vK`gkxIDmn@cDqM@EYL>NFH}0o}tt=+d z?q2#r2RcJGj3@z6OvD<(0+PmRW9rTS5KCqc;xbX-xkMoRQPuxC`*H?*qvGHb137uE z^=I`jvvwFHP3LQ(Jw=A+Rc)_M4gam0f^Q6Ie7l$y7bqZVFK_A-*TsQ3{IulV9@0t0 zXdP?wwNy(3)-qq$lCRKO(K|7UPGQ+9SzyXVaE6+40}f*Ng8SCsArhzlBNXx}d*{VA zanT#Cdek7LE0TZtyirNnfyAme7+RxS9PTv@H%y;}f>cUoMXxmK>f+Vqa{TEv0!X&b zPphdL)hEGX5?|RVK>RRuZ8nhK^*#*KYq{Rs&20YhC@;pJ_u#23BPT3>&%~h}cis6*&G855pDwoGMu27KUb1*RhqNTDB;8xb$ zW7u0I-GFo)-#~;+vBny&L6d!oPX=cB2sKBW_oAQ+WR0mjH|xj%di0J^Eu!q&y7`8= z8aMJuy22LzZIHAF*8PFcD8RbUsVBgo>HFPsXr6t}qPU60tkEbY9Jl5;K%gq>IG*?r zG*2th^j+z7Ugf@7=nLD>8zDjZ3RimCyiK@b+#KuPa`PFlOaQk|#D!7!Q!+qkVVVw2 z7vM`lv=&pbVu4MJvb*)~*~#+QVx6f8v`c*YB{_!Yw*e5@(VaY>>vjE7)FjiSG;ZK7 zScnb(JFa;8C5P_0iZE_LEv6dAsL zYTXw$SNbp-zZ&p=6Z6iKXf)*3t|fVQP7K=)v!{Y1kkIP6Xi(ViMR%$G;u*9-#(h|A z@mC8jobCC!JVQw={QC>ND28=Vb6GWN)rWTZMI` z1b$?4DfB=WpA?$1GtnWHtHR0MyXBm{q_w*PEjpMAfPwIvc4^UHi}?awQsa zQlTaS_1YA#7#IVZr2hm(SV%jdURQz=$Qmv@YMVL!!3~s-aM$C77h1*m3SHry42s?GIuKbt!@aPK;0{N7&j#>!>hedr=ejC~Y) zc+$t7w7VMd?Q-E`o>s+?l&{3dN%EF$@CnLO>Yeuq0zWl`b%v9Ph(epFEDYT7ojiB( zr_J4f_`-E9*2Y2viifvrTNJ8|OA=MK4zqvYekx9qsp#JPqf6&6K8u&`yfvDbD~^fN zurmYbx^pp+F+WUC9=d1Q$_x$H+xBhI5m-@9a_r2~O3h`hM9j_<%0SCK`5V)pjG#Z4 zH9q}mpOal#Z+n`q1#l8SrynWkJhV7lxpQ$X%pOf)$@=eC-Zrn?qS7>$U3tXevWG<# zQfA!w=Hm%TFLNop17b;7!^_Yb&|aU9kEY=WDp#Tke#F-htb z{d_#u@Vrq5KR&^|Zq8Bp`+)4~O^H_BPY2RRx;Bq9U+>eUDMk`epYaKQp!ZGnG+*0$Mrv? zq-C=aHyc{_jA4>0zO$$X9B0!Rrw_?uBb$F(tqq9ds6{^|S$xeH)+ze{(ImYe1p$wh zRYLqeuo>8GY3vDt(sro%?xl()>N8%2KY9*y=v`=KVK;50AEgE3!M20(;5Xz2JA%^5 z7!#y9;rXhKCrfYJMjcP6j;?=`R-8aAyU_B|56A6yzIZs5ZWmjrogvP$mz<{}%~#kh7K^d4x4r+YY_`3u!}xig&} ztzc~aIGSSK%sk}^g!ONHe`@TJF4&1U6T>Z4KA${zWIodx4rutjFt6N^G#7i4X@J6H z|F1TSv+?n34t*7-C=QY<&q|Bp;^}mj4l0caVkr9^``usAK3O1Cm>_L0u=>)eE+C}) z&$9Ktdc3-WxqRHXexI&EyXnHc*X@YFQ_A0aO+oIqw83rrv<_J?R+0;t244)xP;`hy zJ@SsPLX;U!a5FzJs8l{bHvHuSM&e7DX^V61V?iN(oHC7LW0Bc*1DoKrPS*>Z#kHeX zo|@kqooxIVRdV!#xctZUzN?9Sj8E9A<{W+rt_d#KwsLRvdifU=wWX<$y{+xb(}xNg z;j0m5<_Q+h2MNFXb`_0MnNPQ2@1P6|#(5+~)gDWM233zP2Mk zn|<|n+>pn- zVUmXUfSC2HCke-Lyvct%tYqA?>L&Gmv5mir-w6&KmX|7zgv@iQ4;9Rp^2JPhT%x;9 zHa-?W(~HmjyO8P}Itu(pMlnIZZO%65ZMvmYz#R5^)ABp|T{D$T@dtRl8`yrH3O+f~ zaL2SS*bO0)SZ}nHRmd9dD5%{kLJSL^47}ZL0zA>r0urm(PnnFkXrj8gkxZOly(G*I z2f)>lAgWUxFm)QUisNQY?}Z_m&eKTZ-1wM;g@PK_pDh_p-$R0HK4kho7$QE0I>=F1 zPAdWnvQFb31uGXx_XVw-k{u$OHkWDCb_fr=%}7DBSNoYnZoJlSbV^)?wyms2OB^hy zmGg|8G&?LtogQ|H39o5B|M4@9U5+;3;qoKiuTRtMA;5sr-5i1zFW_7LECgYnTSllh=4`a>D7v2-+AQPf{bCw1_f z&@%rWr>z3muaxWhJ%a5A#FC)j@7TU;zy#XIcs;c9r`Y_EBr7bg26!rD?;n}BOA$`{ zQ4hEhm63s-9YRnx`$H7-@q^@4*kZ2GO?Jn}+op2uU5VD=&znLP4@~vFnMHDTn^Kjm zIhY$$%kN|{yEsufpif%4!*Q%>?EPC4#ZkplZD>HL51W3cOqNRG^{nXkn!GkXruRm7Pg0a zBh^@+%0+~Dk5zi1oWT#@CI`10{)KVq@R#5zM|!L_v;V+Z@s2x zHSk`vpOVaD8UzIMDS62*T;RRzF-ZF7t|ktc#;eHN)u5fi?BQ=e^*Qbmf!lL|uYq%r z!p|JhkIxCdJGYhud{ccReqcd2n7HiK=exf;1{+qPF~;Ny0fa;PhVRI`!~Y=d%Ihw> zS01NBge(E|aLeOk*>AqC>2bgsv~N95g60Bt9f)^iiA9~6RfHK)AXZBfxsg?A)Y z{U24%e)@YajUWn5+@mnh>*up`=}p%s*&&Y0YV44=t5$#hy0F^Kxenr=tPvHa)k2TEFw#d@cZFtEie0s@uh!-OJrL?Gn{^-afmMODnc6_VK9QG4D{Y1 zya#$rg^S)hnx3>WH@{h}msP15%m82E5c-?xpOGmU7@0UUT1ou8&&GMhNB@%D z#0y7ky50iFjzv7zyfSj#;2ROle4JnPS6jExE~bw9cGY_UJ4yB&!~}V&FkLJzYO9Lr z_PYtnvzc#A^%+O(ONBDbmjQ60Zi|}S$>@!s{Pe?NbJ823(l+X{bda3h2di*+PguL+ z``-LcPdF^2oUb%7`M$@SGxKE!SYNTqTdF-r4#bh;RrY!}{m;-9-{|v)y*B7~recOl zQ;SU1Q9t2B`<=ZC+sv%rNp~4KJbj3-UK?a!K8c&E%-S{Bxedjgw^^zF)E*c!=U1}Q z5el2VR?E0{;EDI*M=77BNgLu%P#F60hBjx2WrL5SCVwBg01y__iTD63K^hwRlM}g+ zHYZDZB( zNKP$dAdbnc2P3p(2i3>_@G%t`+H66Yw7*UpB)w1tycUk?R*O~?LF^ClwBMr1#P1R3 z-s9?K^b02MWrK_dE4c|oRR>@&lDX$S(nWC@oxq8_=AsV04~u(c)k5tkcGjHu zyD7BHF~S{HMOU0M$9EAjh0MLEQ?qh42xnt(Rm%92@H707Z~#$qZa|f;ws{1GLOmx2 zE(7LPR@#dyb?D(GZxzmarmsW+V>+)p6yT)Xl=fUj9t6r_B_9!8Bo{JJvDu^#G}>^& zQ84R7K{s;i1pK_@ie^JI3BB^m+;9MlM4yK&P(M@vLgA4=Y@N-qMgyC6RsE05dPGP<7Y1qzb*qu zU8?@@Ews|UK|sR@24Bfq0027H!=FQe|0b^Rp%9h6YMwV@e>eL0z-ZzXGR|-5Qq=6Xz?&j|+G5{~F&T zU%vcW6 zPEX^tp`!9Sy|LXaY{9N{RT%MfL7fDx;u$~Ko)q@q2^x$Lg?K(g`*iR3nb_CH`V2v6 z0i?zj-YKU1`e_K7-`mK^*>`2OBI`Yrp)Y5M7~`tl@rd24>!_+EV79kZ#?uNkKOEX- znft7`+G9_A?tf3I_bfejdhW8yNJ|pD2;n zW`Ed)#$C43k#kx~erLUYCIMPB);N+JV%d3PPh(F1p=CenV)xH<$C!54d&ON399!^N z+BZ2Yg(2PWq$_a0?@TXtEU1m{a+Y2Y4q2!#crh5_9mB%T?#qCGTlH!2L_2|ztw5#2 z(&1>LVRduF0t|nXfxih>cJt?T*U-lLED29-AUCrSkoa@X>YpizWDD|rnePwugK$&D zwz6LJv{KL(OYCx0Mp|fK7N+q+Ru9D)7#>=<3M^^a?fo8v zHmw(k34!_N9W5XGs71wKVB}b>;^T^q>wyx9yn$n}XDoLYcf8 z?-`Cn3p@>3daWkaQ+5U4zCIynU4atmpxm9%fI*y--T4l)v3KUYMs~*6A1_!rd9MNJ z)5647zwlc-d)n&Tw0FI&qxxTJnxs;ya!-Q4?3HUbH!?sVzR8uq(|px@(ke5`rjw~_ zzdP;s5Kj1=*P`QOH)Jg|T@PZ2OMbzNRv0DkQXKA{5^+pU48G<`+r%-%ftQd!J=-!Q^*JfU#^raL;emUsphJ${c(<`w*^w@J`e^_(X{=8(#V& z1brQ1nC(KUXC4tE9Sh-JNgl3^aT6b1W>Fp}SaJo@Pr+4;C{QQsb|pmAQ5n)3=D$Ct z37*ZCgc|F(6(J#G;p?N8c}KOHfUm%Z+h$8s;Cs0bxw=?E{c$TfC9`seYIWj(UMoUX z_JYV!_w|h+2uaXO9qCj16+r(e}az>*!6erJ4C ze(i0uGoj8H+KTDz(L>H}xAZX@Q81^rEuoJGE9U#koHYl~OHK{1Lo}UV+i9Hp8YNGc znj^jd?!my_v*IL+e|K@~lV)Ab3zbMn$AWu%rC8m<_5NzuFTk;P)8!|MskSkn-ziY5 z+>o>O?2UK7f&+Q_rRB|5`YTt*+7*aK=h&&Oq8W|1l=rzDQAX`4?UL4NOD`Y57f85# zbz35TsrGilh7<+L(L3ny=P!6KM_NLQ;26!|ES!_`usJtRzBCY?B4nis)r`ra+$crH9dZ;O=+>OasP44S%lEsekIKvX4{U$J&4YpKIVXvNr#TMrkN=T+r7S zerZN=nZm-DiZ1z)?-5p!PSC-jWk$+WURQTq(D>mci!3`m7C38tVc_$VwGI93qLxF- z8wRfYFRRB4*8-Yu*WPwG*qa2%i{dNtIF5QG-+2(}sf_o9cq(PN*_O6Eh0)@$B_P=M z*J;sre{ydaxyjSW;`$20KDzH+LF1z4+gjM=Rj86E7I>u$3F=H*kAZ7cQd`=)4${M*X&;r z0<>=D*Dt-!s^AxukRR5ey5e`C|LKY^D*krgRn{2Thu*WC5BAxA^tc_t*Vr68JH(TY=l=iu^dypnh+vSOTvSbw^}I_lFL%t$#_YM@<1Y3UEKr z%g-Y&rXn98c+9Msk*V^SzL0Rwm!{>cEn!hPbRuF7fFMU224s+X;Ad&L@?+vG9YU91 z_1o#>W_b>5*!A?Neoc!fU1Glu9x5J_<4s$;ioDLlkxqdjYGdCuXWwtjHrq!XY+4RM zVQ@6pDIaJOdAB%6aKJOCub;gF%gtaW@v8U_?usxw0xq_qJ)Qy*SA7%WL&njDzLhET z{Yri>PEa@KbN->kqbJMr5oLme8VaE$nH1;7s2vAiJ|Fgsga-JJ{}HDG?5`7y7nt;j zP1eP+nygXYW=RcIVp+P6I}SErVfd?eZWPSP%WGiM!vAJYuhwKge1SclIt}fH9lf-B zF=)=L3T6vuhWb5gj92s1&*hy4t&hG+9|z`4j@!6{2kaqXpvGl4tOQvTbk!%&Z`1HX zCa&D&GxV@q)@wW;=LQO{&ZYc>CGVr-Hp9r;-e~`SQ@fJ09m?jbE9dA;S93f!5`QcU zm-b0do8Y4!blvCHulpF@Xl!L&4JkssIP&l{$|OaYRAlvV)&pd}ti@G;4@%N~z&Vw> zz)gIxfi175Qnjrt%|fa&wejqSF(w_d*(DPfdL7cjnqYZT><2HvuUXO|O;KpZk>3QJ z*&&YamJXpq#l%YnXMo+Afc4v8ogl1LbFj{7amFdz~7Fwfa>f0|1`1be{ z2Da9%EM#wF95bBneE!b+Sw5gV(gWeE+DUahBir^1{Z{HzGoGXWsDaV3>I$^-One}7 z2b0=z)TpyxW2fkcDQ*JSOV@VP9GFju=yAtG@|{oi!TnW!NLB-~Z$q04_R_t;A6&Nw z`^pTkY0V-lPlgur>Gbf%{*5xOK0pK;*4|bZ!WqxVn?T*K^aWOE)IQL@*TqVl*8p)3 zDJNzZ{+%0=8HM4b4-EWU8c4y7XzUitXkt^3tGtDclg7R{zu33FL7F?-H4 zmnq&x$!SB(=orZ@m&uyKA_7go8%uRRHv7lUkiYS(y97)> z3%69Qq!WSWTWT<-_81P1Q|Y^|#cRJSkfE(I;N;8z43*G&vE?KIgXrsK14rDZTQ=s; zWj14NRRbQk+2RFAOZ1xH?{8XA^STCFm%R9$#Vd9(2VtLRg_s3$V=!{1*KOe+@Aav2 zA%e>kUft4^K?St$(6*UH^7@4_X8SvJ?b@Lg8z|^gb>MI&2or=@ynmZx{OL7jX!Ym| z_O7xHt#OzgVuql9#p6w}K3GRmOUFU7(IgOz*;ZQ|pz3W6@?x!YDo)MyjqHNkrj02^ zj(GgH5cwHhLWrGab<<=ftVay{&Gy$$f9I>vxOJWKS$T2ijxKAQdmYNTXg5V=b~GUh zkW!-lds9Xm?5k^#+m%e@-r?qCMx+YeSzgAqcmO3YH|Ia<_rVKXjq+||jq=r1ueb|% z@{%81IDGdec9e@@-*;LPSc$wOjNTY^;9)mYFq`mos-(|adVzp$NXL}CN>91TOmG2! zzlaSL@dj>P`5fFWsM~4m<^zi%BWa)co9mJcw)vLohQdp)t2ebueU&Bn5R1=*njx4d zp><_W?wv{CyDIYa41XB>4B4mrKaC$pvO4|WbOnQLH!mPh2(H=qpT z-d_KzFn=9~z;L>HrpPaCzz1C|<6>=;gKv*9sVHu9mEeB;o?MQfLgQgZPBVtruu$!8 zZFcgcxIzAEp3<)*gvE;w&3&nfizFLA>CTF1r?&a98&8Cw^IzEI4pp{`7zgssNcb}} zV%XbiGeazJ`HJ!s6C4{)*m%BqnLIy>vKj2i=5ousb~HA9zr9DT;+e;y0b$X3H>FS% z#z)!@3PoKx^n&^RvlKNK;Cf)YH}l4jfFBBBk8p)AU|48o(A_4)ADmRRH)%L*-qt!Y znE+I~DFA%Jn;i&&g>}!b{L6~1C-~b>HEhvt5sSLtP!FZMqjy<=pYr{|YA$i|-8&^S zW~{H~&|yyA3~fh+4YolDQO8b+c~P#@aFs13{VyC{5t)uKVo3K~?p5!f4fF%R13t9E zPe-+Y3#hkt9sB+v)990oR#oi2?aZrs;iAl|^Z@?`DVk6+&>(o@eWm$S;P z$#D_KEItuDFNZMO#y+DLVGom8Q~Tj^&HRqz-{-+r#e_q|mC$DYBg~W~QLoitFeF#C9tto&cx%6P{zlaV?6SDzeK2CS4$s1 z8CH-;YXA!fIOL_{m12F=W(HZawfm~MP_~6FyjmDdBL8i~unfT}HX`1o3KuK1Cw_U4g1c{P!VvLZW51sBS|3g-j(8nE0xX7m?gIcOs zoFKX5XJoRK0ld4!-IpZ1q%R=a?d&wHV1#;3U_(bG`4j8h47xSIprcA?uPKX`j{`gz zm8ap`Ufd-nm6HxVU)3QsAJOZJuYrrb1mqp6bYgMtveAr=RKQ-PITGp=ttyZxlovBX z-1{Q@rGD9$TH%VeD)BAoLa#=8J$03 zr%*zRj-oh&!}O_Tjav z%-PT@_eMGbjvQ_{Zzydl9A;Ce&v`PaG14nTvGkK7ReQngtM$|_7g*`virxSM9>|ZH zME6bi;+I;NN5>1$FvmL2wO>!$g#NqUBilG1bkcJOR=}yw$nKRfHP<(2{%!L2_+62% zbH$kHmw7+DWPHbw2UWIz~`_-lavm9Ys9_u70g=M6Teh%qe$*GO-%Oo2_P$%`h>e8u$P1Ob1$)%M^`ODkSHdi<0F@*Gs1Se zy&AXTTH}O|hL9|+ZuH&{7&enG2;eNnKj^ifz-HePh6k68HDNT2V-ZMHx zPIeF34S=E|z(9?_%C|Lcm_1*ZTg2vyUAM5>W_4^r1A76-(OwH7(%CC;|&*=iVGOX z6j_BW-tP7AM5|Tk``uo68KDuLjQqM&28SR9E7w9!WCS zlxfoaonOUSEr))JKiFzcQzk&}#b2wNK#Mra4e{vw^pH>XL5XIhd=|?ZHO|`spr94b zLfgo*%>*iwSzpzsf1I$5j@O|f4ENZUIr_D;oj-rDJNN&X`sTkp-}nDz-Pz`9E!(wh z+pcBX_QIC6Y}?ja=CWAA1w{^|)L*Fjj2`%e? zdkP8r^RPtmZi1s&C*w>!D^T@<3Ne9jN8`LuyBZ%2kh}=I_>+X`cR{z#t;QPWqADN9 z_uE)3NQR01Q|n#KcOWz-q{xTs`Er1x`ceIeK1I!W1ycJtx;QSWv@>x+1Kz^~vn~M) z`8uI>q`!^1Bj6{~6chVG49vC^P zFrw8xN&oxt`&~+T+Pgd=9dQL zquQR`+G~yK?)!D=_h=;gpEr8t0;mDs0N$|g_mQ+s4u#2K`FcdNAqfzno}`yNXxC`| z=pc))fELX2FGsp5yPH*{IJyjQVuKZEUMT)1Ef}xKJcZ<&hm+FAT9&Dj|oywS!bRon;fM=lf>{|_ZB*>M_aVk9LY2lFu zxK1m6>i`D6aJ4wOEzkHMDM(c+Xn>%Hm69?HSZHnm19{XC;b**B4N3_EF3X2#E6Two z>#@6mC90g%J8R1CWRpOPu0_!AhCdz+G-3AVF=2TW!9BQ1w@SZlpho}KsaqYb(ap?^ zLwg+X7YF&9C5HlG|6@!I1TL_mVtqeW{#ZxeH5bAf14zm%Wfr>~K-Cs-T-S}+PBi`E z3R^5?o9z1@dGTw|^LMg{7qg}L?;)(sw`T6=Z$tGpl>^A|9}J&sx+t(^{@+X-_K;|W zxYr^2kUPiWDos=O4eSVTAs4+2e*zbr*(hGQ7Y=2VP zBoOX7%bE1$fLUg2^pAIocH^NwEy%00bu{VP*&>~4$RFqKUzo4dZ9WBD;VHh<1@P&l zP}xtm(l1+DS)mpI?uvi1;3e?jvLU59gIZ2h?3(NONHyvLfJ2(iO#J#k0ilJF zNkC6OS5d*QXZbKC(g=!MS(gW`UDls==c}#wL-A}= z_m7x5*DGphpQ=2s3QC#VxI1{{|FvD;cueKe6%I&g-W29LxB0$;1=fB>QxD{zZd#Z% z@SG+w2o8!yc6bDbJ~nBaN|!ykVRnv>BxYi^KfiR6Q)G~Zs33a9iL4=J2=hE4F5yCB zC~@yxResd+dTgIWG_0PJegnC5?3gM{j>;lF3}EX2}$?G=?{d$;$~?lg#; znWP(34s;pkLL&_RXXAjUZ8BJE_={9n1OYM91%w7GVUgk4ncZA3!eqx~vfjLT*%AbK<#EIyk~6`|<359mtd3uf_+Ua)WdL1br0xjDz-$Y}Lu@hl@?umG35xWIvknld4pFS9HyLbD_-dBic*Hlyg2Tm|7X zRD*7MdySD1+5=-oA$FWsNvSzAgwHUWfkcV?(NEm-xeT|cmv%6;J5M|ADUyhDpjz&b zH%z|PQy!|`6m1=S^?LPu;cM6g=#unr>8rQj5h>=@b^LlK{D(5zwN~DS&5mK5cSM#7 z3A~!hH@%V+wvfM#1ut8+bbYGe+eG+?4UwU>%eeWm|H#oP5|D@JA?dR@w?|4cRNs;z z{7fT7sewLHwF;$mnHDDkHFEzGAB#gBNAHlGLr>l0onW&+YoW^cy`QPlwHRw5$3VwT zt3K{nd7V4FghGf;cbe%Pmi28Fg5dPUp{WM5w(T$c6QZXEMXcp_^S$b4cMGIbZ(h{h zi_Dw|MeKh;`t4vT%D?_-Lh!NPZkLofpFV!E*KWH5deh!0mCZE00#~V9#~!&auaQIy$L}^EWSUXqz5=>cJY=YuF2hTSw*4a1 z($>DMz*Smh#mfbzBuYIl9pp-+Kd1Pdd>H!J@dSCN(gB*Cw4bMRyrv-F9A_Kxn;TW+ znyXasJ&#p0Rj?N3NmKfsx5*>uu9G*PZZxi9U72V-d$(nrRK9OK@19Ga=NpRZz&GBD z=c@Ka+6)9wJcxxgzjapoQx74bB$nV@ICepQ^%3UhBoYNC>gOYGT(oL%Ha-Pa^oq1X?*SqWX zkwZ>X0?x4(A3MzUUG&4BkFQKS=FNb6PUGf|RB_054hmaC-JWzcCpj<*of8-g==E6Ae}t&AzE%yIoVFN@b~M<3T#ov#Wa;S6aq<`^*0^`sguFm zo!1{M;_@QY>2q6JO;x5_YG2J`gb#eRrC+S`wsb&`HhVb+>gugeUJzE;MOoMiH6>rNkH8Qg(d_uH%&A6%ZP$HHpJ zpyWs4&VQ}8k+b#}lx<9N2S6#oqYK{Jk3O>`5Z&U>k5FcV=9er;qr9@HEG9#mn6m+&cx5NA zHHwI@uK*O4!T~Fw@8;Vz>RjhBMG7b(I#`bZYuc0Nhu^ZS zgY>+8-A-io-KK3#4MMx^ek$QaYZ@B(T^Yl~5Tp?4^MJao(UpD_sIHKsV860GJf zDzRJa@~5q*H~yU8B9Kp@Oc${CAj=E2PGJUxGkMp_>!H<3s>nU)AM0N|HovuhLMQ$EV! zke(&uqTT6jbLW8qDt92u#2n-SYlt38NK^@%ca0XkVZJf-Tsxe^{V=r0sebb&>{eej ze&I5Q8%gLX=qG=pv47ttd&-l0+g%*kAN}>r5Tg;yq;AmEUFwBeQE6Rq8PhFb)X4Hv zN6L*f^)jp4?&!yuP9W5<^%Dx0W^8?bho5g5s6+DT)P#T-;MP`jdN|d#+`O=lKn`jk zx4l_2FR;z!tgLHOQRZ)<*AM(9Z!72J?3#asJHmZ^$y~gOQ=F1`^r%+eVNyY_5r%-^ zy$3}Pn&--1p>EEQw-r-IRqgpm&*AbTfWS+83@%m7B6*04 z&jaD@XHX?%0%xhoqu$1Xn``bhPh&yi{^|L#Y;Ef@ecAA6q5kP9@!sNJbcaj>^1`+z zeRtRctb>sgvcUHF@&N#+del@omOMgF#$?Z+wMK{n|4;bUtq9J!aO`gtn4c1BmYgnA zF!0Sa!J8Xgu-(v%K|vKBJIKAa#RvHHiCU80rgV2-up^D8?9)+sGWY%%YNDpDyp4+tbV z4+U|)h3$(rTKu@vndoEG5WjAyyuPJ+4VDPi%b*@ip(-9oW|94$w^~k~S0o%`b5gmDC)J0dYALEWF9= zekxf%G$bJ(svH5_RNQmp_!kMUkg#dOn}drcGG(JaA0JyneE#mj^T|m_ywa|JFmhk^ znfzEqL)YjcL9lW0(o5(hbsw{{%Tjcf`*0dsE=nrkUY)97gg1G^MMTF%Z=QyIujzR2 zEHt}M{8BZ1{6hvEoxlq?>RG9m$Fx#VqFGg~ttb#u7`}4HWuq5Mn$N$7F=w*vKch1< zsj&T&)GA43o5)EtG72=tDaTYEjqRN{fW?peFj)VsHblWQxelRJ0ybM z17DkZh~A-42mBzZ@eQ13=l`xe3z?7sI@PI#*^n9-vl`w!#C#1|reC#DnE{=lVKrO1 z_~cT#isT7R6@{)#&-ciC=y|DaF&q)KjvR|%Fh{l0T|w<-79MC!k=uC0d2TK<7|`3t z8gkIdW4}L4DhTQ>#o-+12r&VEIDju+I|nGX|12GhiHSK3^D|=t4q@ARsreJrdl3A| zPrE6Ev-CQrOomZezddkmQHA?aX~7A;B1bIhUuX>;sB8$9v!N?@mpXu}!2?wZH3kZr zG9i10-crm&2srhKduXf?{q(4Munpn3i9n&V?;j$paWdKD!xhc0TkwYKX!pgSo_UR{ zuo8S}U$KQxNcAkv$Eznim7O-5%0wFCR>T-3kz(j7Rrzc*J*Ks4mIn(aPF>a3$f_BX;vr#lms)dYXsuO^ekH`BGst6O| zXN?Mvq1f?iGSrDtcA!b|6QJ@HtdpPfxCyz`z8y%Vzs$qMJi0c955 z=yUMUzzY~uQf5kKP@7T-0;%Rf&K1TvxT~^-L~r586oTUrtE8*?zT6>>vEx5onnaYa zo6voM7s9c=RZLG_QopS_kS)y`1~Jqg)FCm<1A;uZH0>mvL3HS;2hFEw!o*;m6;tGh zECoA`u@)J%b!|aW!kk*`piX}yC8Cp;AE#Ce;B+)N#Oq`pDi8xi8G$ZR4TK8$98BoN z?iW!U{-FuB%`W1JCWv97q%d2Y}dH|=j?OZnK_Ahfsqo+Ra_^gpN{!8=H#93QonBvHYtwvoKwHp z_uLN_kA)WJ8CsO&O+mxn{EP=WNIh@VE zFm`ujocK>B-St~7*?F)2!|@RGn~)n>?gROEAsGXbm+_nPM{+tfkDgCj5UgL0R5Yb2 zS;PXrWVCkv_(}rRh$5&Nzyt_-&!*;G$O%TpjAa@(vUrmZ%@&*QseMfrO&RzR2|nf==hRVC7bUOiC-z|@W2G8 zXg&rC6cD1l0VfXVrSbK+>WA09nDE{B?l*%X&7kNXqs0yMGEVfx9Vqe~{Q<%6f>1Dj zI3|UAmIoRY$a`MTV8&cFP4*>QE_u-E#RJXUkz1Nz+$?IoE1?ro%rVP*`bUpEq1mbF@BWr6n zSj@yZyv(qr--&wpL5;3Au;DLK10svcU(Jr$NnD#^$>(H8?}$lE3oPe<%4<9C-R3cd z_GoboS-q2bRsqv#pL>8{Rg*!rn%(M5TR+6k{VmbKs~4$UQ5gw<30~A46>gRmEA}r1 zia+s=9P#zEMQ0v(i{97MoDCBL=0X?cd@*;9$N80Xx7!KmZ}K__1fF62436b6|A%^< z(dKRZAKOc$3p-o?a75laJKm+l(hJF26&Nlgna zyQ~t5d7f$34ckWJt0)E7poU|Um);*r3=SJ#XJmYSvMT#3jV=#&TT(Cd!^+1s$5(Ak zHgM~G)hwWIJli=I9S-W@uJIRuNY?C@KZIX{Tgy2r`MW^~k0`|n^Z`P;8%*$$Z^w`bS))$=kbWd@p8?w-B0mdy2&uMQROu$EELH9(e*k-$Ut8x2)MLO3z&@6 zCrFZ)%Bv8lUD$(WOB`7L$0vJa;$`P9bhw!66~3hevp%sR07IAF&iizNEU$RRgUz#^Ji zd=f+X>FSE>6q{Q2DXf!T3Wzl<(@C}DQuB!=BPdAy#Z)bY#uq#2!08vus0~{<@V*j! zd0o?g^bLudYYf)N;KFvHM)}b>4d+RgiC+eyD>Z-``;^qHlqDS|lvy@u(_A&Y)gXQw zHOd79Z(?ZepUd*ev!RS}7N4(U0JxaH;AyW zFFmlY-7juY@DriC*H(zHcrHh;X|x;`Q&weqk650t?wM7;K3$ydZh7AF1MX0cV;jL0 zs-p+X&{xI=29qN(*ebfAyy$h)f8RQN z^1Dv0f|EbXaRD3HDBC8IJ*HNAl|WEIF4b<%;QLAfiYGLLv!~~jRJqwPOA^LRShIR^ z-kIs1qvf~SWqLdu4aWmOY`rxHCr4n)>*MjC5I~XcK|PV~&j)i}^H!ny_ZR2Vg#*6M zk=NAO0{J%f>sj5>Sf7$kCx7mrQ%jFySMPh(h;iv7J>*k7z29@UF$W*uNka_&TtN0m^0fcik3s&ZxnIH48}$X7m?x5 z8aY2!nOKQixYhWHluRk6f{itqjJ`v2(cE4lbU0C{kP=^yh29d>TTKVNpgTsKoA&5`N;SZz4|UsAL278 zBy*Lg$^4Z0@#PaRKVKKtTPXWL@D|1m58ayd>y-}1>U=(ezz$R%U#Z=bLMl)MP{j_};g#zKq~BREaBxLz@_KR`4UXCd z{ObfA?>P55;(tE!V?{JSG}Ye3cBCzZ=b;j{cfMy;zWtdc zV4y?IF^c6MF_+x|T3E7D zzNHG=8TdVN*_<*UnK=4~LHCBN0DLOaNU-rpoMir4G90u-p*X!DqehTO1>2sv^WP&F zsmL!X6!4#KjXM&qoJ6FS>h*_!-L;cKX}{qX9EB-^wGb?b=hEe+X(mrO-vT-N85fTz z{DNEM0A^YW5~E!nI69;vt-)Y@`Zm)ghW&bVU~^Sg3xeBZnuiGA3=*6gB-E}8D3ui; zkX;mw2Z%blg*pE{zS=I_oAfyFhJNPkS6YzVZh*-|51LKpz@l`fYjWbWsomWgS40fssL#MhdkQ-K5m)yS z35o#-W|<8$vVIEPG-!^)efy!f`N`UUXr}Fyo1r*UL8wQqV>$o${$JZED!UH@4E_En z>hFUr+hmSm=AVT&Ft6$sYmWoH6WJTGlA-z; z(oN4>PUn(?mR0wSQ~8%Sp=916b$bsD|nzdt_T4xWO*0#&98eiH({{>63NV_;@zI78G4 z>9Vy5>OaffVcV>0E`f(&)_btCmd_?OUIWMXkS}MhL)=A^hnsx7);-Y1KW;8&?+Ya| z(GQ;1^aRV}iF8duq4OTBf^Yi)h&fo`y=hZ~dWbuLBad72QDzVBcqX4Gx=R4FpJ|oNmKdhX`nXFbkG{0Dgbs50_oxXsC~m9;b_cqZd6Kbwk^pgLSvftGV|zext_pplSF~4v zUCbP<5`=tUrbf!t;p_J+;JFEY`}1&4c=AN_Y9kJ%@fsnVJ?@Lc@&3t36Zx`Y`}lxy zN&ND3%5Z1AS~~8}izoD5a`p@!VdRH@2hRwd#rXof_z@g#h@$uoYAH}?BFdopN0o&Q zy+EFmfN|^RW`3IbS)Iu{0T*(vFSuBv+VJ%mL8P ze6NN!EX8S4V*Y;1*;xIUDlmw!Z=LQh*AeJxs-?dbN58usAzLq^xi`qo@iL#LflDWy zx6v^!-*ph{^!eJ4wRMJkdTB2?m-ER5_hoYInD1u-=)0Ur$aLVa5Z* z)^;@Y_gqE9%1JT>(yzyKPtv?OG#8+p?}4(v*Hvr(cJ2;XX4fuM-ku}+lyP84R$iID z8R&iLwI>;+%O*3u*SDm~doAiEf)SenwV^6*b~8zMrWRlV2`N05WB8Dt5;`d5IfqbO zG-EbY7V3JCK`u+G3_2Z%q$G1v7-*&{07R8USjqS~BXveYwjj-XIp8@Gl{087$?C8P zq&X*)tcvvggMd%94Aj{tokDPqyfWLa!21tn>0w_SI+$rn;o^MxuBwaM45|Hu4PC)S z_m}|hEz6<d`>(*JVI##SMY2wJDYA7p60PZ5xrU!FBci5aIg=96iGpo8-p7oJH;vBz1wXP$zR78QVbrMoUv z1dS}l2F6BeT5IZS-^?S(HXauVrNv-5gTe5Mi4kvEr0(_iCk)`HG1* zE8HY~NMi`X5JLu>DaIFLS8mZrFcNSWijw+nBPb6cN3BR000&rfsD*%TJT=7+&wTX>~&!m zvkHhtJK|E@*w%4lfJAo69xnkLvkEu@N2*HB?AYXQ72D$Zo6aqdw@GOO3=Dphu@QC9 zT_ax~FMA`Y)7x&q(RvI{r)LVUFIifl9c4Ibu+ir_a(yBcuVrR(FlSO`p``JYkENnh zqUSCu)Qm((O&cB0uI<*95R$W`y>YBv>avB%$qy+11ChbDm0-?JVS%=PrQD*Ipd}9Q zzvO#4aIDiunZy^yj)!0ksG9RMF>u$KV`h*8=zXq@O0%;_YJF$Je&ovg+GzCN+o8$D zSChg`6LZ!9ljv9m|E%L-j^NHv9`@PW&Isdt^?e@k_ol%4OmN!e32Di_eN*wRKbby; zQW?uFxoNx|HmbfKwh98DD!ZyWm+u%CJ4K*>*i&`im4GQB#S=OObVM4jKwQHhngG-N z2>puo&cqn?J1jgIjvU8?T~TU{b}WKgrZ;rj$b`k%BS*a!9wk{Yx_ZVol@T5HtR$sr zf!rCMy0COJ@?DOe0IU&CxvrSiz+wqd0t9a}e zQy$LAjYTbI2<4<-saA9Bt^`QDJ$e#bLB1eEmx8w;(}+KKoYEbtO_JQjLPR)p%64 zBNfheIXr!3dy-?JJSQAxMViDb$J7_7U5O+eh8#fb5X8H0%;mHRS6yghUt!C9diPlp;3i&QN90`IKy97E0>^{Icf|}TMy#Lz zuy%d9y36MFniU7Okz<7A^bRAfJqG<#uYm=6X1L2E(Mz0T1XA1+LmP-9>dGH}`^n;1 zpB_Kx3b;NUcxqr0i9w&1JaV1t_>&jsGwmRl+6cIl&caXfRYsPCJ|wufp08weB)rtj zhU_&n+@XNx>A%^CTl$K*WePO^H$Shq>1g^Gtn-9=3kZv?pOQ`0c2#qY5AkLeqg^**hk*YI`^;2teW`xNyawSf>c>u@@i{4rGC&G_)Zyi z>EUU~BD30;UpQ%n{;QVxC^V#CSQAk?FT1>9Vxo~f85^&s&uN~n%t#n0X~(M3e?!sH zGgzmXC{Xfrk&7#>oABQX$(|{M*t~$Zz_}mzjuy^9-u}sQ1UBG_-tpfN(v~qsufgf| zj8fYLOKYwxYP;AR3$77gki8wJMssrN-H#l-Dhq#jKW{qsS-dkJZ!D!R>KjDq+b>B~ z9BI)4vR=rUVe+lQ4EE;%L`N_9){o<73$n4uZIoRYcbn8eX~%qbX9q+H)Coc#Zlpwh zDZC&wq3R=7#qt+}58<5Y*$dW^!c?g^#2s!3zPKW*zOH2$08;aBm^S9BzGC|qvDD@g zamWa5q#mm1@zxVd@l+?cN{D*ps+LDmENGKUK^!e+* z#AZ*a(jfQz$4dS&4pCgH>~ybwLNXiT3H5;3xki**cwy7DJ-A;a>OI6s-^D)wTUl`K zoc`9_A*7;_o;|9&p4UwI>FhrUpG33Ou;uQMqYM*SlvS%k4hp&>0JeLQi$o=^@dowt z`O1xoP*VVO>$OW<@IdH@*90guTZ{{RjNE&P8jZ-f8n|%QI zl~RXd{eTcYGekguV5B}HMV|B!iTxs|Yu?~IcIS*<8YI+ghn{)-Y+CE1LCfNT8pd5Q zvH#u?`0^|LCgdgZDthGV<VKqp1( zuN-L4^n{>0QA)jTd-?7;@H^2han-0>AI9(+KfeB) z+s8t6CTI8Lr_Chxh1d3pmkE9sjK4M-*RoLe2I#pdMaH50@&$?sN!#nqAYK!PG|}%f zyZy_h)6$aW&PYG-p^-}6j7ZJ!AXNd;0+d+i8tp;Z=E}b0=kYyW+vM~Ueu0yJu(9~@ zg*gCpH6A4{v9*50B`kUkh|I-Vc=jX|ylzBwt~b1H{8nC)wr4|PQ&8&qvwq`=G_Yq0 zms4+u{eR{{EEBdcPdNcroHl8J4BxIdT120iGG9A1XvjIZK)O-iUG1Cx6PU!VW52v`1!O&sB%Y8~l45TidZ0x;g;~mc(zdQn7*Z`gZKH^HFDFJTt#DljrQg!emGy z;0bT=C_s0aOd6$>@WSP^a2A=&-$M|?7G&S7$mS-$qe+tWAGHg{H7E((%bm1&3s=PZ zfD0dpp@OJV7`}LR04Go+j1n&BR+35;^5wXA)-Tfx@r_5bor2pQ_GgB`RYU7`7#hxz zXSbxHg-p)V-zTZ zavRQsZCP1>p!De7Rs`O-A0QY26I5YzWnN4}DUer|i`paoL2SZCBf1-G^|%{!Z@5K+ z`C-X*4;t?1FQk*DMtw6j4={Pe>e%RM;&jwHdnS@(4+uP}{y`{U00+ybFN`32y4Q(S z4Mh??0`jOV%QYZ}&cgAPvyzt~`H(<8e<6t`Sfc4+G+6t5wJCV)_*cuYr`?OymhV#? zJ&U>yXu+Us^G!TR?FS>gE#bmkL6s^#ob=E3kgu$i^s$r)w)S{$IFzQh1tGo`fWIKG zuUB#;p=AGmNT0kPWr%UHbT3>c0NBV0V5VSq9YmogIMR3aPud1<4qM0h?pUrH#T(s@ zNlwqTvlQrGk0qQ{m}_^vdi-MT^RE$?uUE+zC&|CZTo2F2vSs*_c9b_UV46iKkVoo% zmJ9=gROzP}bd7RcDlumQ&65Nh^RE?7=YMcAe=IfBuSJu6EO1Os(^=JG`@w+j%uMz`_gwXI;HksI z5F7yImIf$Az4>ujd*GWf_#iD!}2rR+2VARI$Y)Rqb z@BJ-@w4j_QPCgW-0ehi946XFwR^G=(d%ToGeensEW^7x)Z&G^7EI!Lezu=jIUwa6K z5+G;Q9A375WLkP=F$1-}ekcLUDd|A(#lOGi1TvheKjCusSnpWjytBWUIAK||ns~n@ zn#|Nvj6~iI4D&-ldf_4kj z$D)wddMFO|pI0K`2WMPv;_Rm6QIazew4V62r@Nwwdn(vVPxu18;=ETScd(Azyn}6b zn$Aw3qyD1w2K@0eLTNtzY)b>!zh<4FJ67%z;7WJ|DbR}J-xX15=+3*QZ?$(B2EZ+x zSnyHiDT0t1&D8Jhs;V7GDp|}99 z1=v@Sb7cVFPR8PxT*UVfrjHDVC{SSw#iqo;2 zH&YojL$Kvd^oXW~tsVdS>(b-tdDHCdTM~Bc$n@dwWAH&7XzlCK?8t5HI>xTCZ=}k~ zB1Wn;@pcNjb{@R zfQjgv`i0O3xP>E!urpvyVX2PwKN}L1_yj}ZL!F>nNOuwcdX{1SAGp$%6)H( zOYZ_$2gb(V&oKOgIBLghe&xy27Pikpb3HUJ?knY;!VWct6YE}bj!T{531^yp1FqN# z1Ms==^!0dT@sP=Ic@l$rAbr0(J@JUQp$*U71}r4phjzSA*i-mG;1pL31QFEw!+M31C7~wASh!K6!rnke4p(&efM#-g|P!&kdAm zF5FTvZ^&<|C5Yx=FBWX#)xYnCz+P+@aDm?(ueRz@zf;!0f%85Lv<3LiQ5u{5j%_YK z_9s5F^w4z6o&WtIL=PjYJO-Y&F=)6$8K-`f)G88RQQ7jPQ2rFE5N5=zpDzDTj=B^y zX;x+C`ymVpY7n-6c_S$Z^>oNwY%R@!W+Q$9NFs&4tdMY->Sk3&h9JC?JR`NE{V^8I zfh@SCUddDO9E6|-IZFiI2V7l4zMf~mT#Y+_9U-WU!i+PeAK}s}>JR_~M{ESq#OBPD9 z`)hO%_c(DncOEJRE#{2yt*;xQuwXnYm)tFDSIr`sP+X&uKo@2D^FSH$q(x;iK=@~n z5Mcc00qyDO?!Lta?LE3$>=@<6PJ(uWzBj=?m|7cCJAGbOhFHj1 zBV4{FJZw0)n`XI5q0eb_udzbZjLQaSKTmF&J zKaWfAy56-b4%<&h`9!=lkpj>Uykd+|vq-!QciiCzfGraCG3%?zd}3dI3F3cD?^FO) zN!%=_R7!Xv<&AWOK%lNgKJf;yDBLlgRminKPHb2}tmvwn+hVPeJnrUn@*5AOS%Dtf z{^-D*K(UbC-n%4%`RkEMqtVNCFQfk^*)p(+?ESU3 zd0PQ99+;B(SxnG%KhSs~hqTXxTIQhF`8TtXgaOHb(==`f0}Wkgf|D0Mj-y&AEwEi8 zO}f;9jfE+lrogoC+r+&Ar{wpcE`>RkOtSiA+y~p5)pZ!dvty*y*M!ecde)31EmDz1 z&U3W{>f+xM}n;*eL*}HUVh1K{^f}OLC86Es3{d;egM1-*F2`XWG6bG};&2P?%Q>Hdv z1Lo6oZXUEBe5FXET_x|NWb{gF*M%-s0k=g#Jc&_(*jpCX@y$T0TTTj5FK|GN@JN}a z{u^b{q7auX`-2+hKH;x0A>k(wpWEGLJF9R%o5ouJl`RDOX2S1g>&YXQwx^!gy1<=i zQn-?b{ryfP*0s}j`OZAlEP?1dc3GG+mwZy8KjKeqNXSwR%~L!`+h(^0E$|OG>_E^D zzs(7sh?DdYWTxwamGnY52=7mcn?r)%h}B)L4Tl0F1(FN>zTe5y3>uUO`xJJ&2|H&7 zF4CIcO(bsPn$g!I&C;dROG1(>;5CE3P%tij-3+gw6JbyQUdCqHE0C79yYMEnnLkgc zX&-xwO-y&%P3>5cn?;SqCcz9K0t59~Z%enebR2w&ZwUcj|KQ!BGLEAxjT^B{D1$Gz zm7}(3gmVQ^2p%*mHVFawEL=ZU<31cvEtb-4uLExx3?s_$ zad)^+vRuq~6s^47od+rWi{N$H{)z85j_jL9)O<#9d>@GErs9TSz?bnwi6G@r?zQHv zOJ5KE>%e1Diva$XFtTiX?E(~AI?S4$m-j&%%gL4mCO!hlnn9olf0^c^Fr@YL^IAXp z_0UyqF*kT>b7Et1$F=$YQTHxa*?$8xY@N1`2LK4WJ(`_w>-`86rwfIHp0!9qlv76fUANJV8K>)GG#zz9@#@ z{bBohPz;Gh+`6(g;8zE9@8S+18rm!hYqVm@7&rVF9qZYtC(O~SeW-X#V0^V7VHJz* z9PuHWeY#kH;~~@#i-ODe=gNt@+aC>xypbo!*tfVbqpH|g6<@=HFInxQgTjfs4Qvb= zbZP<2ph!F;8BK0VJ@K8tC>M1Hb%1{b|aiHpZUvyBM&T>chUxUu{g)81uLeuR;8 zui?J_0Na?5b-0g}88cZ)*pO@YuDWquXW_xxemB*q@_cnY$T$(-Rf$1hP3c3HDtH_P*13j9Oyb7+(RdW9>or1xol658#E8vxn0hZA6?fp zR3pOpaI95b`dbmFtUiXbCj`VRh`ydH2(Qh~=huEENc`Ncs9ok6)Qtua|0_CA(E!Po zQyw(yNXRy)mlkETqXdZ8pu(MbpjfomGi*?*^OwV-X^jlvPH%Q#lg47EJa}8B8NS!W zDev&hn;}Y$#D&(-{5h)`RY$%sYS@~=WKovr^eo|LQJN%g;h0U8jy!?;976lgX9a~E zr`(Qq`<4g2!w^6rJ>Moc?7^Rk5Fubr9G*GeU{>#VtguMm9AOgYT~oIU+Oyj@iI<2u)l$Jy$#P2H<3pfufN;HQuDU3R?}%P?od0Otwo8ttzF zB@n8U>16g|00F$q&i`kDrn-@8($Stdj0Zxrob+AN=o-y4<6kPB!0+-iWtG9g78HY+ z4QWru%6GAI0bBR}M@C4;6UYcysjRdy7@UZ|4gg}IyD9r%2=?D7v z)X28<%!kUe{#65+lFM)Bn#^ml(2sgEYZ|v0!mE_dQ^?z|wl4Eyc3%ie>Fzv^_C-%# z_9XvQhv<%n@>nVWWWvgr1F+``#A>Qn;^nw%7;@pw zLv(<@M6sgk(BYYSVjq{L^W`&jClANS)#ZjVqx*5**RHX~h`wo8n|0g=s(_H2F+j{lkAHoHz zK+%%Vl+D0y$*XYY!9CoYKO6h?cQ+9qD*e$Rda^g5(uep&P}aI$?=7{B@6jCicv6_N0n__1R4KSUVC>;Yzu}s)hbpztriW1I>;$`7E@c7wN%J^Xn*5bBt44Jz zCW%EAMX&xJPv_v4_y52Byjr&HT3p6jwry|O=CZx)mTjAB*{)^VzTekA-{1WY>^QD= zU9YFk^KtU)GR=ZbmK$m%+RD!`BfwtrHI2iaOi$x`={n+TkYOs0B{M zA;2%f?|VciX&}VZeOd#I1;J}HYTWP3``Vh#nq;6k2X*aJ=sH*bx`1pJW~e6OhYcPT zYvu1*m9;~Id-Fp?!JEysWq71LO0*psOS~1{)lIb6Hy3#3Ui>BdEjTb9f`d{~FBz*v z-&d&jZH5qZ^N+1|0sCBM!I&*A=pre{yiEV^7#ZN7D+u3USB+&+uz8Myn5E*nD(wNO zbF4rtW3hmne6ZC%Ut!O1u};V@$tk#$a_MazrdfRZQ9FUN zkL)u+8{J-AjX~8ff3dlVKOdj9k<44c{sW`MDScrFguor4a~S8%n3{O`+5w0ZJhorBUMx>sS0lSVe?h zkJpiSilDaQ?wAZ6u80ueygq#p=)vn98CND%Kn_#l^pcUSL9ECecC@aQic|V=n4&`E zcRIu8PTPTX$E2gjdWNi{0Rl0~4PaZtGpC%cJ~VMaS0#7x&;Netl^@~+Wbg{Ls`Je- zl;YuzDjJoDCoSnO;5@T$CwOs={rX{OO{3v5w zJ`~z=fze`7j(uJez(4;hg894D>-9>_=Yc<2Qu)C9f}e^=t>X!CBGo?(z_?fCZPc*F&1-tcCvS zdxVD#24GYs@4Q?t4AUzEH8t7Tco-AG0X6x|fTnnhx1_#h%dF$zTV$G`?>*gN48aKY2B!?KV7AZt*YFOCd~kS)HU(bKmR~7 z8-iS{5GipQ8k?v_X2gCTlEWp)`U-W#k#DS^D8dRP7aD7+N>hELGAYm;7*CEU^HuQl zNPVYf$hh_Iq_7PfcA3S16$dVl^9|S*;bPs$Di{gO3iIR92~0fo;b}>i54BV+tyYS_ zL>0fzr>xix(G?Z6y%duNj9-7S*&)30767q~aQAnVxm%csqq9+;rr2|jSQUQzTu6Fxj~NH$|@P_grcQmKJLsnA3ZrJ=J$WnQY|CGG2RG~fH4)yMhS z3XLu-H-UfG8~r^|W7Au*iGUt8%}2+%#6)1BhoEth2U=C2pt6w2RRY#WGFFU9mM?rY zUs{Q?l`F(!$Lu@vMK7me-pqMTBsdPB-}ooVGX-i0HwgV@6>_Sl3QWOL>>b^e^B{dM zSGcu*bm5GlgeStOlC#rCfmEDgmTGv5cccbNYMxr%!&lN}mF9s8PQ$^<<5!Rck$E2E zLB?k39PLVYwQdP;;yy+@U{Kujb61T9XL*1P=&;NR6e51E~DwuV-k^B_#Vg(fEH z(?nO#_;~}d5yfJjIpd^2vs*Yn`wg$bRznD=jR~)*txm>iRtFx03M(4WHNwYn+JLN3 z0WeuggY~BYuOW-6T-7G>;Rjxt1CLJl0B59}`3k`FhxgGx{z)-^RE^o-esAAN_?OqL z2cAr`mvSnb1)QH^{)5bqb((PX@5*g65By%~dmOBcW)^BdhSB)_EkIO*Uf03O1b;CBH1Z}| z3HR0(8m|D~0>pVx75Jus7-4j4VF+EJ9=9V;JaL1-t-Bf{ zU@p~g8tA7Jyi7&` zE+5!xY_;fbu(9T}F8neWTH%QGKeHYEwJc;18H$aP!*b3KgdnIBTzz}xh4K64vVO{@f3dMbHX|s^G1T&n_RIWu zPe)X2j?mH-e@`#ANB*^V<32CNr+sZVnB&``JvZjGRzECcu@Ad@^KP+>tip?B$+%8d z=BGLVMxghU)hU!P01qFYRc(2(EI&nARkK5L$@3{-_e0yLmjD7EP$*_Og#BbVS>SX` z`_krV1KOv!fOTx;H)N`;eA6f%O%#y|l_^%u$#q`YRT}?ID0CQ6Q27f6nm*qrlk&{7nT7N)mowCpwe=a$+D5Wbi!K z`VCc~@+V#N&iZ<>I@qtniHXhM??1IDjvMf~`5(dGxxe}toS$xf0a|5B zBs3I_aR;b8zGS-Ue}l zQAogoO^~5OH9uFJV}EbDIk<^%b*XXsLiu=CMP*Q(mni#a+>I)63Lg!~mB~X{Y{rNo z0q#w2T&X4jt06Lmj772wB_LRw4T(!kpQFiei>Ij$rbVGBV=M2X5g31F_0RPKxRV;s$rD|atb-fi*ra-BRRuPo)(yC=^HM)abNe&EE5ucFe4dM zt4^WfLqzCR0p*>9I2IZQ?#67eokPKf>>r{iPzm6-;+(b#C_s?v#z1 z9+@)g2RqVtpm@8iv#zu>PmunW_D$To)RnA8IW&31p_5$X7Pl`AhE_Q8g| zJ9uw>ChCd!c?KR$+gfeo=JpS3pMZ^Sz)S7WHTTIw^h-Ie{-;0Q;MX-i%5lNS%oi`! zkfY+*hK8%8k)<`nFF)R*lw`?u4ZfHbUgoYG=KA+q6 zTK4E?WZeB@A6<*BPkLwvuo%lEsAEt6`_B;GLOSSBX*;%usODAEN0qtN#1!CkPKeOu zJ(d*lQ;OE!h69~2yiCTWb7$gEN#w>Vd`IE;dydrVrxn4N?aspM#6l9|Dsfwdv&YjP z$74G$aE(pUBfl0Ioh##wN)9h9)l%)f=elFWspeJ_bWI0$x?>i=?rG^5Pli(!og&s~ z$&@$Ld%g-FAx(BtA_M}aqGo5JSGtWOzY7zR7?kQcbb>S*aaR*i7G4b-htNC9Zi#z6v>li}n`;R^~^qik~ zjr!&f&@tf%9m8O$xqnFm6B5X1{gcmc!Tf8!0S8bclB>)9F^a7R#A?{=^oW%bATgqy zg4We<_}rw1eTz^{pN%im`YA1XSd#YH)FXQe%mDwm5hhsxa%gbcu~e_*CrvaYWtiLd zpk_4%JB2Z}eE4u`v|bWjT1NB+C8qbqbzl9uS^v-bF2>g|ttyw5j=wLvjU@YAhrMt?hF6@eaLXjt; zdm@kxqq0r^l!%w9UKA|ejyD00p4*_Kr)A-Wap%&fnHFK++=0Q`3K>mitb^hiG2FDM0LIlBO&}wG+ z7OiLr_C~Z-T#t~ojIhN{k|1AfsXKlRJr4U!NpjN>rf5C%)@1VoY}d5o4s7zi2(}E| zAaHpfu@>;`MtR!AOjh^)Vyh=Z1uAgitgE{#$^0rlVPcO*`Yey&? zXaFWyTLlF3&Pd7Vn8qBkSn!J}$ZRtPxD*fprd=%`)LTp|q-QT=AkV$H-SCTc#rG<;Bp_6>M{gy9%Wf7p;Ow1_pOlGZYtZn5QywaENrCi4Lyeeil_)zigTNN<3TY`Jkd)2-(7_vS8=g8y zOI7msrWC`rv?X0b_YeTUGCfnsP~7|G6oKh#ain~`dW=}eGV=h-vrO|VHjna?y`d!| ztIWKGYz1aH=LDSzoSPL_C2u6E#(#HQKT+i49wTeH?DBC+k|QjJ=$}e%Ym`b>-Ou+m zG`_N!GFGCm)Ei%8P<`oHDTP+ss4Y)?k#`Hv*_b(MjD#1l*NylnYmn}8A4oQ5vF?C0 zE*$jp12+x`(26PU*#xzQVa{DYB_px%hC{kyj0PzHnEkF=*!*1!c+il`bo_D!4S5BM z5TU0~kI7z3gN%^bnf%k}C$~`yRdM~4GfIs;lB+(^yuOh5_oxv*Ze*9?pG8c|-_U_x zgCirz!DKhC!Q?aA*SBoa=i5f0UI@2$QQtpiF3&7b{ifIL#0I;^+IdB9^hUnsk-DI= z9=9CY78fK;HOi-j%!OgLSxX1;;WpGAIb)!XK=(H>#A5q_j&GF7fb!=a_Wbuq@)B}H ziWW)`Kz`{oPQyhp)x5x|;1QdY*(M15Dundwc&?|vTxBd>H?nE;yl(qe7&RD>X^2}* zka_?lP*!30EO72fP8?1dV!w64lvfH&65Sz>bk69G7~T)bg!@`aSDSXYKF+ zw~N=7+xOwZhWVCEHe?;ev$-Q16hV+%l^@;%6C0a715K|@gANUx^#j#sTZO5@v_cma zE(UZ~vAO3m+PvPBa?LEqA0oFvo@@WYpkQD@Lf$4LjEi1VE5pTXPQK`F;%cyFg|QSx z6-NQ>mmoa%J|t2xJF!BRn|#f^lE6wzXE}4f;_(vF_<>crOK6Hd?twAldqvUdVh@H4uDj2IC9?Q zxzUAKtUk{=jbQ#Yyuy0Lk<|@Fq2}OF19`yT8^+&eEz_tU9kQ1Q7S?Ddm{|j|XX?>N z3UPp*Q;{x@{vGunIp$31!23AX+Qa+>Ptuily;GUFd1$M~SyxtFOXs9v@Kr3Hr z!5;#A-mO0W1&}n$=>S&+#WE#U)xC!YU;gHOa`)RKac*Vs9+o5ly|Su>|)=w(8fp0nGD$s^fNB`6&hGNP9AX2 zL?9^Wc@B#p1Y8FM6@Qbz`VeW*rP%xw2o=V$Vt43I>dtEdxre-PaOVJzVgP;!i| z7A@ZlhH|%=QX9om9D(!%@ffl#{CtP{#h^C zJuaq{JdHjS^g*A=b^hO2sVs6TiHL{@NA!RSJb zy+_Scr%Yy>E>S0?xB*TG^Ww7N8-_FQA7H9pVyO`M;u>00<|95SW$en{Xv%10q^8fG zv^0Y|kf=i0#T0+8X`CoR0dPX}Im9TSG1>vr3$73^pcxlEWdNP*?55B>2h2!K zyBnHoV?4uM$*V~wV+aa384}D%uLM$6m#au&JQZ*J>_||M>f`xkh9+?oIlJTmJo9p$ z?CCXaR1c&sKoe=gKh*}hU{H~F3f5)`U{FD}tuoNH;U?8ou`@oCx3odVq#>nu$U1dS zGF|1e;qz`db#flU@VBgoUzq`dW;mC|tFG7D4(Z^^rCaK`_8r}^O56Fq3Lwnz2d}%w z`W%_NSDqy=_N-Yt?^^Z9r_i#KZRvAA`{Pamp#69h%%sm<9$Fx=8<;RpzYP3$OiLj` zlA&;pYsauaLZUM(pnXNSjrCRfyqu>_7v2sAqaE;vIN*5861B?$;=&~y*T}TR#&tMP zyfS6(JXD2Ab0GF%Js0uGShnZPT9DnoV~k^5w=-9*Xcv`ZMui72KDCdX$ z^{_b}<gmIjnUfUSwSI#0lOtUTTTExg0?OJ0et<#u=iEGXrk?KU7)$k)bI6O2ZfE(zGDHL*6=Ts} zFBm9{N|66>w*!c_o8o(?0Ah~!2Cvnk(;}C~>;C`-`-o7u-iz5!e{!ni`P${T>iYw# zVaw{fOM@-TAN28WcK4jV_HUtq;9T})SeO0i%2}6r#n?Iq&I=6!jrSW1vuDfd+BqQE z{Lu)ZU&NEc=hmPQ-m#k(g;dLBTy*_k(d~U@rn|gkbHi>z6o~HZpS*zCGqK#U@@soC z*?hgbB!h!7R3F^lLzo_rYctwyXn=Bo2m}9+#L=a#$eH8olk*3mtFOcY7>D_mH&udgE#Q{blD}K|FZdVcdu>1%#`5l;wzyw z_;xdVClEDOblwImlqv-(_N!b?hE!(njS|D7d$t_gr7W_?hJa$PY|4?HfIWQFlP8Uk zTlE27j=4ns#vjy@Tvmf0vJyo)rKUbcqppKRdZ2Y}m|dLTJ2l9i(%#k|$hUS9y?D#+ zV+7MqZRly19-PZB-V(kfURS($VVy4ae&+mky4hwxWhtNSuv$27YSZCC*H{3W$V3-EjC z`_U<=%;8&IXvJ^PEy((&VoDg2RLG9hF2jj$?fgN;0Z?t--2B1w=hywNH$ddQ*~9D7 zd~MWp85Zm-I_$$A>}#8aWiFW5p5oe5L{PVg7G6lCXe=b6bxjN0hu+92)ftd~K(REQ z(bJRv1Bv1!iuw+vJ>F8+6A(%1Vi z#QircVfZ>oBr-|LVX)B`P;>5gc#cDa)ZI0d7~phD&_2G9zLU;DZO0j9lhJOaRlgPr zD7bzIJwACG_6}W{?BDN>C;9Z2PtJO$u&+Mc{^G`AD1 zm*kqj0Up##7AG8NhyE z>SVq=YGfXiny_QOh{-Ua8PSfQ3^jZFz>Yzv?;gu4gGA{V? zpF&OJqwrgHz1@6Od4ed9ZDkrbprq|t6`1;We?EeT2w3ehsHXc%*m{U@|9U?$7k5kG6l{!8hU-Q9iN(vuvD>W z&c>)E_()Osgm1z_$8!GuhwU|6NJ85)h$-6&>hzTU5V{T(PG>o*{Vn?!Eu2a$^F@Gn zR1O0LuqOx&{G-EQf|9$v?=)46Jp#J2=oR70#0EZV3gh%aRl<51LIIWD)rh$~2JGgk}1Q6%;pQK-e%DN&my_KY!6a8Uu+ zLu@o_F?xYt^i*a&5g;+a5qumtIvd`{TR*^OaEF-AvWT~d`~3Enp4+_7r@jEwu#4!Eelf~ zbdTQgDXO%t2`$WcXf(i>3gV~5zw!rzu`K#?08P$YAwr~NC}4zwwYQ&5Gt{EZ@9~y9SQ2HWN%H&tYRv#pS^ewlKFa^B;YO9z3;VJl}&-0?_ zpg^L(S>u6@c2;DvLMn)|>|Tq;Oa9)A37v7j>`3rH`0&*T#B;(ssoRXnZJt0Z^2s?w zMiZg1TH68*X@S+H6co&%#g~p+9_oCc0n-PqD&O~aS`_73KQ_Lm9s+wdaqm%WY!z+< zThl2dwgFnVfu-rA<7~wzK+1CQq4Y5Kw|en6*Pivl7TCVyB3gHZ_?i?;{|*w%0tX^y z)i2b?qC8A<*8v6btzQ5_OkZanHfWHb!2vKLA^~%OPWmh_Rp4&mAB>_NodEy+wpG?6~P~7u^?DkxHPhIv7pY4R#qq= zo+h@LZe~Sww4!A*5f;D;PhI?(d3O@z1iHC3YgLcKp&EcMIIxsvD5xMYIF;)F72Qqn z*`Fg#U-^U=hgGtyiuTj##G4DiO4oP>8~PQF3Sh`Tr-BPi{Gc1ekEDYEl01Lg-e7fS zwt{z=EXNxF%UJc=j3Qs!xa?rc!F^wa9-nE#r(Pd7>s(7rWQM+M?lQ3Yfxr^h=Vt6mF~U5Nya_GHeL^gv$!K@n!fn@w|VFD9*?Njv|}& zz4X}@X`tUt_I~o>C0?2uhp=sq^A7BGJsx*=Cw5r4573Pkz{cUpAp#oS-T96L{#y$5 zUn3szy(m{+KP-@V`*Ei%c!U3TRx+c_T_V_5zIwg=x5M9bu|Ao0fiIIQ zqsiA$W#P9Hs<=)9%dVK8QP{DT3e)r{6u>Ydd9+fAN@sW4<9Y#>Lg~IH?sw% zx2)i5g{>qy*kzZ(Qy$kgU=LBH%s1#3k)Aeo%KEy{||qZF%I;1L9+J%t`O zFDXluhYeHw6WGkU;S918vFY+fhH05|YA+lc3EUZQRZ3`}Q#2`$fYBa1*Z4h0XU`lZ zvG~hzkVT8!RMHhX?m;X5auiF;TZ@>x-+fD~`EtUJd@Y+oUZU1(P?q{a+RPKxN#K^( z1X_l?V70=qXt~ndz__#;KX7=o>WN>ReoOem5TDqovTdDrP07Sj(yAjIwe3Wz4NQZZ z&9}!>EFE#y5TIKf(a&u5fjDXbI-PLCv@gNy~?|iGXsVwuN&gcB490caiy9NL@q{QN`+*(Zqe0uy@j z_Rn%6O0fHBKW4{1GaRC4u(BieU9e%L%IX6@RlBYgytCQ;shpcaFZ>5yCWDoGwoW8G z4;&7NFAs_ph202Jt$_nMPOB57NUs5b5WF;+jI8istaF{-S_a0-Q8fU3Z}I_&VCCd1 z)e+1aej9}+b^=Opf-J%+E!D?g3aS~iy3&8e__u=9<@$*1YuD%SipUab_dJy21)54; zV7(RqhVe86!%x=2BAgvZ_Z=y7y`&xa=E9V3EweJS7Gqw8y~TD3D>n@NfF$TRIyF7<%JjmyjLrTA%gq6(irG;n_N^CQmj#Q`l;6m}id`VBgY9zb>|3v#Bm@T8 zXQSz#s5k=?2koaG1jHF3claRRvy<>IdK~fweFa-P1wVZ+vuUqi=x)+}4$eIELh{toU494nre$rXO5Wz2 z!^54{XalI1Hk%qIe~z$koAe*vXA75Ot>GLStc!6D*!c`(1Q->?orEHdS2^;Ofje@i z_)irC;pF{90+WAhYzMvN&xDG&^rv^!9z)zKJM!b-Hll{(L*WgHgVDtj3ycQsI|@{y zaL0cnsxp_bbFRXEv`~;mk!TZvHBo3gR}iFcxTbF)oUJ@f!8y5!&-+9SW2rDq9PmB# zIGOQ5^)vZ|GIY<%eYlw(50Af6+D8AOxA@hXifaUzApT?MI$q%a$b87D(wmYA@a};C z86taJuT@NghKB4T~E878Qya!4k&6>k|?@_7qaBXHd? z^vZz{SI6*yn}Kn`h6Ej)k8OG_NV+vPyTiqiG|lsNpMPV_nL}TY;&OVBnn(nINX_G2 zi>?_Z^ipshI6($ij9$T-z4IsUKZQrr+ zd23#|A>59dTB{WC$l|^I`6*}=nk&b9fC4c(7z<=UfLFXGYZ01= zf(xbM-6;3YhoP!8i7#&BX^Ht2nX)S$hhPJMdc#Ha7!4qzAUzlR82RgBp7g;~$7DM? zJelJiI#OpXQvV*wQL7gnD4!jtr_0Qs-Jvqi8b8>E?K3EgeyN(kl)Q(zhN=R>sJ}7C zu=E@o=vm9fFvlzdxr*yxBJ+6=hsTT~zq+W99jyh70l@t3qpRgfh?6^8{M>ExIgk4H zsgnqjbpt@xKJm!EHkCC$NFlnn*Gn*Kh*}V}?^tCc{>T)3@TqygEj)nsZuTH@+%{$$ z#Lx+mTIURKA^&4Tj@3AkJPbgprtaKp?NSP-V1cQM0Q7XRk{#a-Nq244nqpCn|JRo)DHYE~^NT%y=-GHq?q zH>0um8K3?Y$PK9l=1xbtAbqe1f0Jd>&55L zg1+EEoD#NZrHSbux-z2;>9ZFj@08DurUNRjw|wlFp96;1rgy*G^?rm%BJ{xtefih2 zknThvkm$4F9I}yQ$&qe!eK5>Ss-1C4cU=g~*;B67DynFWIUvb(3ef}GjL!N7p58e# z!)D8IGRZwRVRBtaL5X$~Te!yDkYxX%M-#Y-w-5<_OyGrBkTJIx1#QWyF@CtMJg6L-o zifkCK=uxa4%7^DbX>FO`ScVndM&-;+i(u%$tQU{PqD>DZaj<=X&gI>VUpB2RzK4o9 ze)MU;(dqQCn;&6&jT z!|2eRQ^wsAF+yPibcG2UcsUA9%$J+geqrh(P;Vr7InC*NFReP?9>2{%Fpv>y{RBYr z2JKApE?G${%ejN)IUA)RqF2RYQT%MpeOoZDW=0~Z&H!TkYXp|bY!#e84RCANCbimV z1fmoSnJ#`}Bvp)XT218u;;qSMj3k#`d=j&Qu#R!H)VepltJcMfQZlAq;Bq-nUc3ZW zAaeALcd?uN_k=m(bF>OMYSO&b!8D|El#30r#M0sinx(fPA$oqOfLmvgV+`O$!=%A# zR|I~te*E)zN+Guvjvjzs+H##`(US<`L=sl9&Gx&4rU~-Ww_gKZfKI#Y)Iv3Y6RTNX zeY$M5AUkipZ4GYXeB;gsnIxU$tKp~pcRj^N{;7h@2qR+z_&#mUjCg}^_G;i5U145s zNU9q+7d1kjtF{KvS#+8Ev4nX zvI>txfEAA3_PuidatG{@{fBcJb9LrM3`D!xQIN8_GC5ifl7$HH5}&wt(lyQl?${DI z%n_jE2z-pB*2wTEaBN_X9 zhU(H^y5>qh##n)G*vc-GqZ;}c(9{Y$i*F2E(duUFQj0bY6WvSACXGxqI;3dfJ`pS3 zid?;d{koen0M@HP_W5*E1VN({$v|P{QDqeXX7Gl!bQTzH zn_%I~?M5bMy6g$@s1{o?5>>tVt zHOcaofP=o8{bN4s?|ODJ=HW-m=a@py!a|AuZC{1cXxgP5?3WMUd9v#mHik2JFA$bR zd{|nXhi7lu;Qai~3BAxhk&=9Zux3eYQUBFHkMfU~yuorHDUXi1frlTE;{>p@Q(7 zbgZ_vt|Mf?B{)m%0ZPXa_RbQ7M7FJlAsRh%MR=)3u7rY`ex4HaC#Y2TK@EH;|_H$+)|7z-VR)9my$Kr}@e8d134 zFvBHA=bwb|aS1{j4+&6}X?Cn)YAio0N=N|wItB}YPXtk4^-5w$qeH;m5!bwc=tuJh z&Mdnqa74msE;VC*LAs;HhivPtxoaa?sUK@3KzO)d_Q5S^*K{)g!%li>z)s398jyfK z^7QOlTPQTC=6zDg{m#{nqXp#!2Lxo~C6sTV=Xufs?&r+2Cr6hnlw=c)zB;!f#m_k> z^;jr@S_>xKz1u+)WA%52E>}ptP*1+ zY5$?<^B!STeBKOXe0Z-{S-#@4>sFEbB*`yzG?O(#EdS9QPp;1a6VEIvg0SYXz^(ecy-)on7HcpSI=UUXe>s3?o;)kCGY4fMqKU5WX$^KA{;D?F<1j?_+QgKz!ik}3RrsdteZ3myOicN|pxY(@s z|FIp-FH`Fq%3tIfsV%@)9y$iX3xA6JR~bue7!0r)Y0?1gMqAJLnw3ysGR}j{E|^Vxlc|m^*F% zXRL>OL}+)%?n;CFqVxWc_+tX_U+{f;-e?8yZFASkhgRJ*(vw6k?uGdrxvvz_TddDc z=+&1KfYb>rsGy0s8{-j9{s5o$Rym&Z3Eu%W2EH7RiU$~uWRJC(nnqp(%xkLtR9}`u zf!5=?&FZC8cZsuco#5gq0{c5`GZ%M)t6@yzy}(X0$h$L`^U89NRptJ5wR_j~d%%NN zj0F|G6?=k!lyAJ)B;<)=NMc;UTf4;E|D*qlk(Ag~DOCp5X(8Bz@ww1KdhBH|Ma$ z+m?=2LFlwANnj68GcVa;*53-yPvQU?rn19;c|q@96x+31v(GuG4`Yo`~K^mGr z{Sf>uUNT(tu*B49Kya6k-NYAnOBc=zJA!Y3yN8){{-=o-?LTjiCxeSufw5#dzWx&# z2~PQ|?{YJqz%ONuhtf1Xlsj!YAGA_)E#|nt@<}0Fy77_yB0s zs;T^?C1eZ&)yCFlSpe$&yuz7CMzF(YkH;VJ)p7%KEG>tUX2sk=nDG>LB_*o271wS>s^mPNj~4CdIe`0CyIK7i)fZkM zCATx^ywZSBzduB#W-ovJhV1RwE6eC4Nc7|&#kcZ;hnp)p4hJ2a|zp@(AAZR zSC21(3K`x4kEb)arAemXsMN8S=jG7pfG@W#H<#_0)Am$ao-Fl8M$`a^d z#v2J?YM;NO1+f(+HrgKkp{RIE!9v)sjn*|yKy53N`$3KzoS-ht6t0qMZSt35Yd<5y z0?&v3HH==eTJ<^f>mR9x^5+FX27$$v5C|rK`W0=tCJd;?D>umy$UZ~Y-v8UhT(Ylz zZVvVo*6rIQo4=&=`pudQf_KnDZVqG?&*wV`6e(x;PTsc+?5-{}kR?@Cb*1~t?$gVz zjriO*9lJYl3cMqwcW#VnV{&M(b(ffiYjk4T7ZE9LbQ^bBC$u`Cdcqrkg@4NF2!!~Cw=GkJw%-aY^cB}deA!(*gH2E$N++eT?5Md27(e2 zofX#Y+EGr9c0Im1B;hK9Q5$R^A9 z2AlT`xws!Wzs$_kpJQswW#<+ABXFtKAG>tZ5iJ(^24})#s0y>%*jwg;aa6V3z|F7M za9B{f9pO?n7o;oRhIl@m9luo~THA8R$e`PmJScZU*71XIgK7HIfAzgx9zC3=E+lY- zx2ePAL(`(EsI11^1+55+U`5|5@Y0HEEM0`@(cf~Urq8tQ7l{B;*c3w>-`?G=KPC#s zXZ>kn^7_SvC#NjWmeecnY%xZk>-HL&t*-a~%CK_&(k^eFk>05IoEMd)>(lRH?i*$3 zphmZMz9RkvuUs(N<<0Af*UX%S@*D(AUf?`n|t%HE++EL!tzW* z8VRBBWB2}PnrJ*f3@@Jc_Qw!sup<2gNQscq$=^|eL#$+9%}|rQ`y&?sN(UI4)Y0r+ z9fQwPd)RfrG;S#T2Eg!s>NSq|cz*h^xJcKwNC}9kteb`H)bVY^hMa)T;x~01-AbOf z(@OB}cc@*q9lR*YfzZ}tj>K9eYJvT-58pdvW{3}8*d-U{@iE*K!TRij8lp&k{cB1Q zAUt3qqt^{0qxspF+s+$)E38r1ePDL0lg!2%meLP<;FxNWQ8$7hRYm|oo-4$D0`x)% zoi0EPkJQ*0IbW{E!$|UZ^?rpo$}YRON}8rto?z(yzaIPMDvSRNlA7v4VcAz2mTQzW z&lUnTz`IDuGgJb=(k{R!28C3RvnF}lvc!Y(H0yq8F>gu`M)k4+w>R!Lz>y`M6Ut&L z?wpi?{&Da`1#KX-*oL8>#6AR2JaQ0d5U1g11kub)uKEeWPM*RsEx6{QX8>Y2S>-y3H zOGmFau1mMqZN}-HuGf}}V^zKAX0R8?h!-}@adifV)#$`QYc{;{h;cq1zgB}+ z5nkfhL1bK{Zv|-a?o#u8vUh@a7t80qkHhH^|GiG`IQ>7wetl)vg8Mk22FqizPrs;Q z6x8k%6~MW$ac#VQ1_I9r9`q0EuFu;aDgnO?s-JS7?pV}PZqH=#%*G1S2H4B()?2^> z`p4OJ<5B_0p`2jTfCIf;e9zn7+IAia(6 z23*Vs?_r-_{DfdcbQ>1%u$P~Hg)9t%(LI8GUepfo@2#ao?W&vRmN0-$a=RIHEx zS|9^b7PEID7|Zu7i}N<<;A=q#NOr+ZR>Tr^y82Mq_c*>vb_A|dvR;4{Zt?Phh0JKM zeeY%mM5@4I-nyTn7>=?oc_WhDNPY+f8KsDXN`KgSzV&0lXngwUW;WZ3E<%;@JP|64 zns066ojJId+zi!YkjcWu;l5R-2Q&56!#rz*r(KK#9&Uxz)4x1X>yf)fexgx6_IGQh zcE2C32heZNPQzk`>y-fgnnEr%e!t%~dJN>m`@;UmH(7Dl*8F$LI{9ST+~WuH$)%xVV~n zng>)-iVxP&!t#>}Hyo<+CNPL$g1B(F<&pVJW^PKf{s_ivMR}v`AI|`U;1^0J`b{h4 z(Wb5zN%wXN-W$lr&cqMA`rVD^c2ya+yGT~+2zaqX4n|82UP{NzeT`CWM22NFkjPrsrg;6A)#MHlAjMk z_Zha;Ty7zn@-%18>6GMKgAEbK>KetEGWN^jtwD9C-%anLP4GPw6UcS#hFrIy@ZkZ- zaT4+3HQr!Z=cR3&*S5HM7Z15Jh=-e3ChZ7N8Xu2amlYDglqzo8ctJd}UMyJ#>*%UF z4Ebx*rXt)C;aoTd-fj(XBa&ai#nIz#+hqs&gWB3%$ykxC$92}rt%)(sNFM#*7Vb)W zn-{PM+9_0F5_aIHN}GTL+x0o?6iH6WlTPK|fuG}~$Hz`x!vbOj>3$eXvju7LTB`0! zm66HY#Gj(%^|l0p^iioA&=+Gg{Xo!|$_OW!8Vy{{)wa7H4xs55)cfZc!mTCm^rN02 z{~2HG0XXoTUPik!WiRgu`-_71;nh zJstKEN~3G9Gu6{t-ga(+z9%UJi&`z$A56eQxHEW$iuVP?0*gb;wx+gDHV#vBV@t`d zK%A=E9|9taYW)!HaoL!}?7Kt+sdKY~7lI77!d|U;!bt$?xl1_CbFrq&m&I+ije8-S z@^hpP<`1}=Z2uCPNac7-L+Le+qwSYT!rV%G*DAw5U(HG91=s-qsLt&DGLxm?a@^ww zEey{asNMM!tNoZZ?+OB^|4U0QwW~yWu(_&m?>L(iz<)UE-(kq*6eJ^8y+hJo{U@G1X`@+}yFGdzK(?94F^0l_Y>`M5n;0MPB(ToYNtcCd7mYKg$r6<-I-uKaY~K6H z0H+&5hZO5D`yet!Ihzk}@Q!+w2rs0>7ER!0GlGGzl^8pEi=PxrTi*GXZv$*Cv=T=e z>_0|#k7|S5PGqUi|D_MUoH1|UNU*|G^0?_Y)#ZXS!#S68L%S#msMu@-HbJ8Kk} z_MYOnswB72RS=a{6DVFf~l@9YSIu0lHd^B zA-KB}+#$HTySqzp3j}v}cMlH1-66QU`<$D%zWJu+2T%p~a?ajsb@$V&3v|<|Uv9W> z?H09-DBME&FA!uRC5aJyE}<|l!pD7cM>sJ03l**{4%4n}7*n1$XO&etp!8QWk+9J9 z&1G*VoaA07Q-xKLe*(wlQSZT@w>Z|`;}Htdn=sj&)--Q+XJnld5}@k4sRS7TvR@c- zkjh}^EPVhz%vE$!#!wFLk}NX=B1HmVZb6T7p9E~ZP>&=X7P`x@={x6IanO<1BD0}& zXaUP>{oYB!P;3Nrp|zCP=x+V0L)R^Ct^GOFF4JXvbD)z&0b#*0BMe(QX#J3q%Ryi77UyBTJDy5-tdSLmwa_LkCpO zQj+hn9OUueqHdEvshexlyCPt4D{!NP&;cL=<*Zbr_>@`5o74KAZuZ5K1B@2+fFrFp z_p@&5W=YAEiGqz2hWjXcnlYDcZ~yl5Pw2qg{`{l>Ym!xRk1pUc)9dYDHs}q^7+ZW6 zhui~R5GLcVQSaTw<%1YE&f5Flarh&y2Wi(Fl&(Jezp3}Bk7$D)$BCmA_ANAD+!)1v zBujVL9Z^}*^~C1HQV^=Ck%HnX$E^Dz#xE9iKg>`RS4H2 z)VS-rH;ARGEfNNS3t+f{9#QR8lC!26l_0uaU3RQE|NB`-fQ-~7jYfMgu z)h?-S`q=TiylE-e;v_h=h;{ZCxm-z|bi8fU7xXDPLb%3H+$I}v-6J66m4$Gp1nCk1 zP24If?^TmN_h~dZ3jgkPhzjX2S0pGzjobw!DWOQuScSn*Fsg64MQQd&7`Mh|h-r(l zF&y8Rwa=^dU=SIpPx4H}J|n*J4mR@g+!&&#l?jECPz?8j{3*qVD`iiH^Hw%2o73Q9 zf9!z{X0m(0_b$iWQ1{qm>msm?)ItO|Uu}2Ovyx!|mD6gT>i-@Kq}jvGmrK89LT))h z>3m{EIR8Gwcq&8PUGTa|sp)lWCM1M~U)1P9h4w?t z+eeL7`qfr|QNWfdxZx%{+9Jh0jwBTf?uo{cR%#qa_ru0*L5~{O} zlK;HnPR2_@Xu{<#$)v|8Z-o1Q=)O$edjaZ=z-eBR8A&rVwnRaJv=m;Tw>xA8%a}Ag znQ)wccBSM8M(T#zOxR{gpLUKz?;7j!6nt2~oh-X|sg@*S3%rp{z9XgxJ3xQl2`D+o zJb<6vZoIFJfvT9~BmY5nT%}CSa`@Dt*Hw$WjB@8?8#EspF;RFZ3VY+_3SfCBEeV=` zh!C0|HJj;HO9LiTwG(W&9%pb?5^w!0<-B&4ANT?%`j}SM2gud!zrsUd6qN6yPYj263NtusOVc zYEqTzKQ$>?HRVJL{jhFesc6#+7NByqJOLf+eRKCOE}gd~4nELrngaZv*x5^f3Zs$s z21F%@n}3cjAHa73JoX`DGHXUvZP3vhA=jiXW zvZa@&1drMpR!#?%=_2~tKG}~^8E!yhHg+K@eN~84*OwHO$-G18ZavHQ2j;dHF+WuICYW$oa@qe%+)8_ zt7Av8N+J`{^#p$=EgI%+c`x{uAX3I9+S>rf;#15S$ zL3qbQ1NiuL5b0SciDiBdyTk<-0)EIwdM9{BpEMMj!11d}WVyH-?NtDC!x}lPg zY-By#UCXJkWO?i{Sae|Kq{K&SZsu0)fL+gXtwz?u{IF(OL}(1a0i-8hZ%SvD7+Nyn#E+Sk7}zZLWBG|&t^OO)ghUd507}}P%l|`3WB#X_2izdQsm{8A_fs(bxR|<~}7?W=tZ?h#F}a;1F{12pTH2boO8TzR>%( z0@jAhb$-|)^Beo>oQq9w{=Nr8x{Z=cQHuTdi52X&Y8SXMG#{BAy~!-Qz9`Xx1^|W~ zy^aq1T8v?NY{U~80L*@VCvIOG{xcHdhH3?-E(14KEJaDUSy~ueQUbYE+@g^3_7P%F zJ=Ptr><6xiN84cNtZT3J4>ZJhYD(7As9NnSco#sn``#1zOx)bl4^7)5{6iEy^JEhOCel9`0 zTCxs?MV=(o6IP#+vvy+1LUzE_#8DJ?v`vO<0Dae1i5(a+&7a^%s)#~0OHvw6cyW?) zj{A|}iVm32+SPyyjey7m7^O!bc)#lQ2CdR4l>U5tqK(sX;r)NjA0PSwHApJF9D!?| zB_ynsN*j=Zj2;r8r4sjDtE;~7yckOn;B&B@$d!tEVBi$KTLr+5Y&3%tD)|=Ewj}Zn zJnjxC=EC8KRbtd5;Peug3utC^RBYFm@4aCWgWe;pQwg*72Wj>C4VHVBT)yHPT=uK` zh-EvSEn^}&z!vPQ2`hL|RrsODpYf@_d=Y5^jD*d(nO`=X>3WPL1oWY)HmzD0Ev0Fy zBd2>l-FAANvKf1_LhLU3)t!ZQ(0`wM{_&PU1Ftv(!?%ELJ@M-LE4=OB@wuDNuASOd zGqzmmO=){xG=DZEK3@MS@oVL4zk>Jhccp8#vdyO=5!XIZM3GL%2)J~iE3@5eB#M#n20SlLfF4ZGa(Hq}lr&?#Z zq$~+?A@vv4nX!-g<@3Wy{PBbN)4XH3D>i-%0o@w3o`(kpLHol0+CkkAa9GBE2eOVW zrd&sZuT4zb-%AyaA>}KkQ+u?TC*T%e?+mjY6!o7eCZ=!H;ccuGCIG}T@KlGIpe72y z2XRE*X7zx4rBU<_tT2PNx%$2Po1vf%eE~&Bi^d=HY$PB0#)V?h`(YPxqLY$B8+dot$KEOV3E>jD z8Xg~8CQw}vQ^@;WxhF#e>HRjFwMIm<;LDjx3_!V~OwG!Yc3&Vfq_(i^2NYd9|L+EMb!kVgs&S!I%KYySp!6q1ihd0~ z^>0sx%acxrh>#quQ(CZdi0XGmv(VKr>Pq)1!vn(GRp9#{=IAU9|`U78m?y>fy{Wd$J@Drzk~mVe*0p>$*3v z?1plze(1ampl6c00KX_=#EyK_{b)}QFjV?y>b{?y`r)Ty-s*Ed z^yBF9rdja^A5G5o&pJ@ZYok3qBe*vfM*|f8OpKCH=M_&S8m2OXe{@RbGPTAujy1V$ zDR9Ozf4l@)o2Y#+To6bva2jUf^ah#e>$cP}A1;3aUwFqv>K+cEVF42Wnd3Zhl%v%e z_Yr1*oBzbAvkyNt0!r@&UwZ`}Y5P*ZscKwA6Rm>bIkyGcy^G_cS{u_zJ9Luv-?Jfb zYcIe9S286_FH=)4-vHhX&3%NKRtQP<;-!lzH0rPyVs;pfnL3a~K+t(^o5TDH1%!0+ zILw7DHHpC98xBlPxQplb=TNlXH?AE&L)1uK<`iy^MFKhrn>t8G*#%v*v%x~*48SW7Vk#%ycDLJm`0bJz^-3oi~OB&pba_^SCIohATX(cL#sVR z*8mT(!adWPmGF<6IW#`D;m2S64aRPF00A&I%PT@Bdjk)!CFZW)2nW{ZzP0c|nX}H) z1Q2kmu51lTL8yhQqqme9okpzMWi=Wiem*3gv{F6X#_<H~tuwbyXj`q)3+Kj=rX3`vMPT^wDyQ~_u<**AMKtab|aCqN{{(^t!U^iLIXzV)GPHF7*u z>%p}Gcsf?yw6wp0;X6g(bRqWaFX%I`@1=V$++TYo(5%FAA6s~T(LAu<0=9@0lKIUW zI=@%%n^&GQ+T;|@s7Kl>(cm$21>Wax3w82^0x9h7=^JRVjX*f3%(#t$hWN=p^B$nI zu_4)H#4%Na7PitK$!(3W8b*Wqy*-vlK}^|2TD8)Aj9|>MiMi-m-l8DR~AW6b}sN zDP(c=k~qAnHpoiAW2kYbU~Lq1_2282B1Su{{)TRfa^}{XfXVY8tz2XLQuAl|*$;0g z>IZ}bIp>hHHTv&8V z3i?ng8lzeji-Y~0Fy-tdXFTIC9zXf3u*=8={1F2yJg&$~%E*DDAtv4KGLQ+4LD#Z9*IZQY;c>vG5N9_iNsHVN<^xPspa2RCcuC)&ChdZj zf#xl2Ty0qU+hT^^2|RYj+_npb>v`2|WiF}F z+qzLFhF6-Wc;H;rY$;!Ge5jWJj0JvcSxeiGcqeYT&e#y~huWt1BAu)A+r;yW2y*r; zx4)b`h_054HoJ+-g(&6c1*5+?b)S@|f%wsPN>^e|%?@yMY2%?sAM(ptN}5E*`3CL? z5s6L!TC~!$eybVO)i;vu>S(xuE*rS==)!jD%b?H_RTd0{*ct@_{-n`pTIxVAKx`Ov zzGe{g$i)CnHu)HkP_&MLIkET+XLt}DI;a=Y9@b8fcQl_EY%=5LT9u37wMkVvh2$VT zpRXdETW&pXe_-DIZw(yRVfAJ%<)hXmIdqOnqN`-%YU>jIZRwEo$_oQvm@+a1_~zb&7^V;V*uVMj ze@QVU2C^*T{RrJPlz$Vw1Cx{LBi;~$uVA41}gJxh(aH3GKN+=9$RdTGM z-Xy<>)Re;Bh%0aQmK9Ti!IAste^M2~9|jnEvdG7hj*th;^*bvhzkMuvqmZ%>3V^c& z2^>EGq8hq1VYm9!MHAxpv2bV;)kDl!4trm{+brox$>v69M`8VtO5+dzK-)5K-{;>~ zI1irr`&_z7X`O9%eP$E2Ug&EEu18`=?d?dLFiriAyMVeao^2s?g!7jZC=W9{{Idgw zc)4M$Cm-4uPlb+JCR1o1MT|gh&|@6)H7Ejg%{4_nC~vzAd+d0JUtKCb3?fp$dca}1 z-PI?!&nVG1HQ2?`7mWE??a|uk6}Hsz=ni?#r*CC25X<6uh%a_6b#O2%E9~UnX)dl> z1p_Aje3Bb+DQkEBe7;uE@^GVdbJlS#MRs=b2edNc{CpfBE&AXVhhstnN|OT_#uHfs z;2a2$W5Qq5KylrQs7mHjNRx_fp4NK%ka)$pLX)mLZF|#^%&i-5wU+Mi0UF>c&zn6h z3#0l3kD3`!=RJCWG3TiRzuRN48AaZbnA)cOVqe_6$u*gFVVSTg^N9Mm@iLQr-%Nwa zud~Vc4y|5*bE| z384thZ5&SBC61)wR&n=eE1hPn3cD}@6ampw5pLM8V}Dp6oq!vukf$c;4ZJ@#o|Gu+ z&J)n9u{34r)5k)o(Z9V#pV&W=AV<~gU9z@`B=@P8 zyu(Kj0AY-@2cJoZ&=aGK>2KqgCPKSj30&N9zG)LKO#&5z&=T#13F%Ox=E*(zF)Yaa~o85 zVNrirb$QiY`iLmd2ebz&+zT?!fk|{8edP^dBIr|Xx(M_U1 zZeZKYN#FGv1r?Ua=ZeTsc>@eV4GGG%+@fD0Xuz)J`wLiIWl01t&s1fe(?6tDv4 zrhU1dk7W5oCN3@gCnDRRASE_I^l8gVLKoNc^>t2Evt}2?VscT>GXGI=Hj0HmPm|oJ zB%T89h<2QtOyN1~7fKuIc!HT|!9ad_=h!b^ZXIT)PTIpR&3hG+AV`Kqi~R$w@v7yp zSMj+dTi$IGR*wIg1d=A!1d5H z9)8{x$D5~S-)>8m5kjG=ZnEO~bKwcYV^cIYU~(0X?%T(fom8n}8!1f7Xu)~w-ZVY`{Lm(;tu z8+Dh-h=}CIP+!ZEv{TdNAEPJV!;PzFCiOAR)sdfPI+Z|Tf$Dz0$*__={`z)>UJqj- z=l*iGCD)BsRd;3#dtOVIwK)rwXhxocvpMVhP4%8d^ys<8v4Pg7Jz3>hq=}BLCH7fh zC6g6+OQRX;8ut&jy!`zR3jI3;g-wy7kXM?+7SvQV?l)*oDyA~5=j}1fIKsjedA);w zjN-r$lA|MW%pBQlnEAB_^8=Ms7J2$1^4sXq$VBwk6`!x#*ZZh1DDFCNy_9Vc$$|#B zx!-bPPaQ|)?ju^5T^w%ft>M50RZI7+1#EeN#?>6v9Qb}|X=Q@&9ZKg!^Q(%M)>=N1 zVv+NLOT|go4LN!kC7$k6R5n>*Z5jTYZqi>yucb4r-zFu$ysEaEoVh$n)sI&TgST}- zIk!Y*G<9oF2YK0lFe9!*s#UE41vf9PGcv?IHLGNfE*sxm9*-V+d<huz=!q zsy9rq%?k^2S-i-Kr`~|&fiyP+7mo~Nn> zcs049Dt!ycx>^GOS8b@F?%VTG6iy1IxI96nQN!w#<-VcM2KZ)4_zM$5h3&iM<{O93 z#hsbr+{>JA=cOklGgezZEG%7#S!}<4=EW>$b!dOGm|6h=SI;8g>~vYs&LGm(X)i`% z@_7nb0k8K6KIYAoU*{SN&^n-!>R=APYx?^=TU3Z_DTn-b(l2uEu0Ze83mws#tt0)P zJT5;qt}mx?4<6kV;3>|58={)%H{17!mF@PxT@iEaJqCtMkEvNzMsr0)tUgb%8df-9 z>B$iOGhD)x2l~J05$0qqO#-Zjxoy|1$KVIFdMo1K57I!P77xsmL}*oMipid0+VJl& z^EE*iyS~s1?!JiTzbTZ^qKj5$xs$ z%|lc-aIHfgfzChIu->BW^{Zf)v{83oxUx)hlPwzVQe+$ep})R*f0&3%HOuKWQ&0B~ zh*jLC;on(CO3hL-YeLG|<-;=Q*_RReU<%6=aoGdHksdaZa z=Z2QK0p}u-D&Flb&dVjBNzbsAk^wwu7AkHwR(=CMP93N@TxwN}>k8;uzSV*yp=&#O zvQA)dhCQp^&ug$nLPP!0&G6%RtWF_BWx|9|{#%BgQUd~t>d}F9r-ZI~+jOp(?B6rd z9K=A@Zzlz^YcPc2>mVW)81c345f})`dDe|D-kj+%_ObnpX(cA0g4?^VDScN9oxX>T z$^=x(yAcnDf0X1cA0ntxn$)m(4_7FIik372qi zk>r4;Lm;-Njw}V_Y9n^zq&bwxxV`3-6fUV~cd1_|cN^6@Idrev-6?28fkb6R#m>a{ zrUU@y;q9Frky)18*8>%W`^Z^T5K*XYQ}DXu4nDi6rNxRjFA%@-ETXWwKU`ZQ_(buW zK`oHonn27)RQ0wkAPF=dU6_3D!hu)m(!{=u?p~4jdh(iR{pKMaVMJ*_RH4`WDy>py z?@BQq{0-qyV-;8*d>r=nSXP*{z5Wj$qfx$48RIoX1=(R1o-j*Gpc-U1|})lb0%z_YG7xEyl2S-=kyUC!(f2OG4G->!aF>1 zfc}u+5f%_i5!jAL)J38yJ#)i1-=~qAh9eDM0j+bnPoGqe=?x~|K3>~PQTG_mwEY0#8XorQ5v(ew z-8!oO_d>(`Ia`8!%7v$Oxh6@3bZ z62aTl6TutZas3SWZt54=aTd^t;d*^qD_*R^kInH|T9;Avc$L;l9}?I2Htf+&wEr`A8f>Hm{jZOmM=$c>J#0W9&-00>L`WK_cOe*YhVj|PmP*K4!|N$w~A zt+ug_u3z4~5gl;f$jKhh(!H(5%Ul-5a+Tm>hydC3e4)GKCMM&q|U zkMY$z_r)00Jhkc(k}~68zX{YFi&1^Fj(L?86rmN5@v|Rr11cfw75LTJ44W0O5!WPys zhS0$^;J?tY6mRYB*IzdyrN99o_Ybz4q_N+NOFp}K&x9kcxTWp)>P5ZP8@B<+innie zC`EWeC%@4*_TdTh(_i>HSp6G_B?h0)NSX9!6;KVLP%j++Z$vsn=503DR}!;S>BZ! z?_5vlp3&$@%W-x`&x(kY%&%L&H%v{IO`ZUD@uKr_i$1TsezIe|9w@AMDZwx)jB+%` zu*)Q0HfB!S^(o!gRphPR!s@&B7O+Z$_VU#4HT&@7^6Af2sgf*z;4w7+ev!&|kHLgr zPgeoO&N23!fc+L?QkE0>5{SJ%n%j~BfAwVMe}4SaA5coPn|eyLuXc~G6U|yacz0)J zf;;z|?>Pt`nn*8!ydu5-Mx4!4^c#(aD=v+XkbslGTt_l{cObG9t%El!KHS=Tx;OCO z>^g^zajsbA5ve49VVe(k@O)c>r0x^H?>Ea8hVlQBBo&&$nbxD?{9i~NDlz2 z@#U_2K{ax{tw~XIpIF^k0~aPf-SP>j(Ng9N9emFYfCL<#&TncqPwRtYk>H{? zH8xWR5FzDJe*3aNgTV(7xr;vn?YKY$;NJ5JiEU>&b_n>*$1aG83)E+Br>=OM(H<}g znUr|Oh2Gkik!{ox10lg3^f~m;2`R{X^zF)j90?tpk`Uz3U+N!U5XCnsNZA7T_NEGG zdy*Z%$D929Mizu)gbfogXTYjvaZ7NHgn=IZa58@H3W_@@eOhL?SP}k&e)Z@$Ul<=! ziKNykL_cKv>QR3k;$SFs)1-0u$=`PkfTxuP`gXnQBfRq{knB-x>Y4?-{=fBegJ#}P z{!*d)GOvJ_jrpY*ob)uq2PmL3%v9xkU5+nV66E<8^pl}zAYBZX#{km0x$lw-cTuaW zej>#I=s6oY9CO$K+@*;_B!4_&euhuRXww1_DY}=*gj{C(V_U*;$3}IIuKbOI5YIC& zncCaJmhdM4P@*9+Xt_t`(E&PQ+()e|3tl5adfaW%I}NK{B_Dm*ACE+iR|6%+_l@6( zbAPb8oE~Dk46z+Ruh%eV&@Uyb{61sy9RkouGC#3b*LF0oDb4}YuO1IkANS`DSSEk> zi)Zq2`uMWp#V9YVhX{4HmLjVioZO)`3~S9megNtY_5 zfT+|lKLFHU`mcoETq>GXI2R@u72!F+g?I!0ryzG2I5;Q&{%n0678o3vI2@R}z%19q zcXa^xZ*c3qq{6C=`vAO|$pF>Z0(iP}-%;B^6hHkg7@Yd2-+}u4zj@cTIss@rm-UQG zMiu)oJMBMe+}Ju=*iQ>*&9KW zA7Q(ucT|fl@HL-=$Yw1E9+dGQGFGBt2o1M))Tr+l{0Z_~g$mP61%?saS zXuQg%P0Yy2p9i5&F$eJcKL^_b1|_=!t|xJIf%Wy6`G)zvhbH<;>lK7~#3SU2d z!O5tW^dJodn2`YGm>Oh%gzAI(MeD{efX?uUNAg?0?iSb%S+x&X>()7^3F_b(W*I$Z z9=Y8Ic~3ZPxVG{!LcKKS`UZ-0YL|ii?Uu997eY0|%p^+s0^ge18cae;VU_V$m98gS zpBJy(Aj~@u6X=F@zBKypT&G2U^R{%s6pL>)l_T@#;&7V#dtoxd7e9_`;C_nzh=M2r zfPZ!07@W69CJxX@I!nnuhEsjWJ;U~Rfh#?fZGH|xE@2jL3A1@?(JmNYyUS@YKnX8j z)XQ+6{G8?J*bm2espP@=0lDWw(p);|`+1{Y@|WHq;40vehV>~6jG_@Uk`i=6FlkB!{f)QI&XpT z80vhfO{xN|9T@p7LP5MJvA!4$plQw8vw`5U=`;|l_d2fLHZ|hnpDl;kJ4JXsFJnPl+CKc7=l zmp*rjcbbmDyX=SneRASwxVQm3CQea=0<7B{DlGwm5L}2pvSprQFdpWU<>Q~Pc~7EMLhF~JJBpvy zs{P_WDeZ9w#mfT;A6A6_*5+hEJ?D#C4@Wo!`dDO)#DA5_uFb*eVrO;vwcu#3vBQ5p zW0deRgdgWYJq__q5lGI~=8t%o<$Pb8r4!CsXcaEh0(vnSaD(TniR{yH{*g)5(+Ew_ z=3RJm0#r1f(u&%%2VUvi-M+Hci)3>fM9&zru2PZ{SJvv0v3<*a!R52RdQet;iz=Zk zB9~qITkt)v&4pE&S+|5T$Hk^7gBJS=Y3B#f5KZp;tJUF(*+X6y4aL|#r#mS=Yle92 z#jPtj=f)v_UJ|IHRC#Olk=zq$%=dj;W3Q{>dy3TYhre?rdQ~<<^1kslHuO6a+!}mu zVX-5vIWxZf^*Jw;V@UnALb_Pc=7d)~C&Ccu+@zrE!LOa@Jh}akrG;jC3SKX8xtxzr zzrTB1x-#-;;z!j-Hv)g&h4Tfshh^XJr^Qnbwe3RCyTGjrt-6kHQ|I{H*AUOAlE642 zj+sY@mDwYmSI(j=^*iL5%f37Gce2b_?Jdy!CE^mkpQL88ab?g@g~rliOied~z8gaH z8iPfUgiTQ1E>BQ9uDMYRYT3K94oOq>-24Vg*3RO5F0(GJqfNou`feI(n_0pzA5pG1 z@bI(qN@9vfB&xX*ATO$Ki-OfCNuvZy_OoOoZ3D?+gVe$+1-}DHu-st2$YJ%8q^{k5 z!&)aD*6VSy;BAl!S&^vm#NZ=JZ-Hf?`{n7ZRO^{senfm;RYbLRtgn1lQo#EJ)Jbyq z9+NP{w(uR12q+YuH%ziUXJNT`@i}ag6BHPOZ{;V7({f~WMU1ag5CVuSK(ot{@!M&d zb}s>L$bU)O2M^(Iprq}&E+}bh5I3OaTUR-Dcxlklrs?cech=C_cAR$0A2%qB(-JH( zK1S@`*r|l7J)}|V!T-3kvE)C#;3QRsbGt$Lq`PK~NZCmPG1nxMS{Zsa$$_q(_w@RB zit)zZP!hP78OVH6bEeIa>QNeL&kxhl?3@HLXtrl(YHEoDLSbzK4Zm8H!k|x8$q+|c zP$E!MrjrA3pf0YP91;mhIx6A>Lqb_T6pf+nn>vlG*C|R!AHjbpqr$>2CS~8>QJTI9 zK#>b2T^=0H9w3zjP+&tqfs$_8hQg^xjCgRFz;U#GaVDdZQ_f6K~l&H%Wlqnw;# zkKd)PaC;sVc)vQ!)=VhgI*^(g%Jg`EE}G2B&SPvEYD4nYyFXX(PXZoT-1CoFyOrlr zY8G{0F3$fOg1ApGWVCf>{J+8kdgHF)KTiR=xo2f5#Al}LZ=3t|?DhX@6)-i1b!$va zUSX4DDF9VJI}6A#n9!q&veA5=<>J9tJa4PyIhpaUxe?|S_Vg1|)nF=$`_SD#$?CFBpl zYG!y$V<>kREI74S9D@WI=={t2Du@XL=)B3$%rhq+Tf5FJHOV9mn z#r=ASKAb|_px54*BpIB)8&qwDb#V>nm&J~Gah$WZ-nal~PJ3}o*XNmH!$!|F3mu=% zUrS(4Bp6y4J2CV4p3i-={nlnU$VIO=gKCUW<^v{Xgitn!JO)PS`0B2RuBY%-rtTuS zE#&x4UpHyAS}IpRv<1gqtq*j;W2woH-ZJ`7tW2ngMGaq`Y}r>E4m-65Y#5vKm>s*0 z$ifVjk9X~pTg1N0UBmr$6YNum#rCj4YETfd{XD?7lAA_)X9ySA08x#hVo&iABD?)o%~v8u3WMHdNXlU(y0LM@e>e-_28e2cI>{EgCds>6SGe*L*#=kWryWl<@thm)ycy3H3AEk0s9F*c@#m3!bMF8WOD1Ji5&aU<2A@B1G@6(*Eu(In0Qi*P!h)!iNn zb8ym1rAfJA3!Q0{Wy&I)5OBD`gbF>NFq2*dFv9|cnZ&)L1Fmpy17k2JbPTKIS!jMd zjIgS%G6iU9H$mXKno=ESUb*sH{?Ae+T?;NH0dVN8iin5d!UkJS1q)QbhV`UWJu+DC zi&3L04W!#akTpF}@ObBw^XG+@9zTPXwP$!5pQv@{7U*0jS%o8FdhM%Jt#Ub(;7{`? zgI1B>wo>8QZ1*%dESH{^JZ*O;S>k&Q5{v|XqMt=DBsU4Td%kA_FS5>WV4fO8J;0XUffbkKGs62* zjeyZlWP1Ojd|;5hl~PeloE)|r6{fk$C4CTb~s&(DiBR~IJU$R#J&R~Nlfv+>Nu z@9{qt5Axo#HXPW*avXeSWK+(_j`0*JbVkxC^`r#Qi^q5&L0#1-iSNv%@h&ax1w z%?dK~XA$Xd=>LS$spwmIm$!u75vQ4SmB}awg5YgQTL!`4+<&D#Mxl$g#TAq#GF%m@ zaRd-ZpAn{Bo8<+DyW)0vUZuj|G?nAU7tWi0?Lb>S>xfNPN9VgYh{Hk{dPj1E2NbjZ zB%~44C;X($Q0)yjPQ{wFq*+7wH-}O2`n0aDIDalWN!PZ-{k3`2w|Ol&Ip7;$|HCvGw*n`P=Tfg5#ASqOMvQaQRdeiUdF4BopN$L7U`PM*u?l%=9 z$(`nV4vE-p+`Bj3XxxwbIQvhzM{TpDsOvnm(*d0n{i_^5V^?$CB)wQW;SP;Ata140 zFmgn3^uHE}9V0BMU}>s>iRiJjNXN^<(*iQsQ2u;aR0#X_#7-(!+(w z*AKQ5h{I3jKWWl*1GPk_$DxjCdUYOPY3or#I>T!}w?LUAuBOv9&%|hny}}L#(#4Br zkcGAFE*LPD@noID%#Jt|BdS=Vt-(MusO@vxk#An%HDh%gP;^f*aCz)Ny(48%qRk}K zNz@ppTu`%l@YXM6giVQdrDF>l))93Lp>)jB8EiTs= zlzm7g7j@16i{fux@?&QzNyzi!&+SgHe9yo6dkW7p{-!m4Xps18Pa;Yg_DZQje(`Xl zIeSH{L&wzH_xb6oyP51mxDd#AeaYpoL4NM{E5Sv5hs*bmT1p8mGG-4W@Yd&;0^>Ym z`4w>b?aKz%sS9&JDmK|oee(k35zK^fYrPHZ`Jg^f?9wChPXoq!0s4}p+}?vUd-xH1 zUa5xHD!HaKNcauU7FKq4CwZ44?#lp{=mVbLqcenNCvz8@vCpfR!sK9W6yx4!^^|4| zd5GLTFP(!1vbz8vkQ1IzQnQ^P@sSD8s<&%9MYs64mp_%L#S@RHimNxS*r$l~HXt@e zPP}N87RCIeV!^~(6@TD7rIHF+7(TCMR_btCDy(rChceU%-v z6=1lj;5;(VHvG(*O0fNYK?aH(+(lPBD&8AaO^_!xy^2gMiWG5VAyBu{Vq$v%HxOdg zOCY<~Qbfb4JNZiE-l|eY)mkG{@>mfD5d%|pE{IC#TH__TV2YMtns#FE3(Mf|1pN~W zlzioA-(0q9Oq@iJu`e$hyzX(UV!E58yE7fShfwClXJP=J>-phof56@KeL|n@EM{1M zTlHji`=k8GBCr}*mOt@oX?}uc&B>Yxfu^E8T0AD@d52BEkGid@$d!f zA+3dzyf}LxzhXVe5GpY&$L0EhK>Hk74s!|q!Ey@5fu|DEM(6U^dM zcTiGOg`!=W+4osG@pV<)!R}eLp7urgpQfozIlHV>?**fw>awl-0GTRJqtT0>apfcK zkrzT+XFMI;x7ObVjYdZvifEPwjrkq#AYVU+-LrL+Ax7O7Dc}gHYt4}6;5I|AH#Shg znKY#eUobix^r}-YbX-|Xj?w2hG^5q;+@(<1;tn*U<=;1*8*}UF*EA+B)^7{7AjDSu;o|j(-|@QvkMqrD!PUjf(!~pBiw5d_Xts#mR}L^KBX~JFA&Z6{5#Z4K zfHY4Qbo$Q4%beYQu{Xc=2V{pwK4|j(2t>&+UZwMbnHt4$rUR~eom2&*sX9ptwpkxe zq@mRiR4N*puB%gD|DSSkmbtWn+- zs-dRduDueBV!r_&a`J=P?&~%DUjqIjyqC|$zzFihP&eJBKQ_K)M=a{!4r8%f&!_sg z*x^n6hmiy(G_WdEdqcvNvN%78IV9~7&OlvOZ;_kHKKX57F5H1Kj62;bNC4P&WOYo- zM%8`kg=%B177}%73Gw~Axu~7mZNzgIKp`DCOzejbz1>>=1wYTxKXj%movob`ryLXF zr)_&l>@7J^mJTu)Nlnd-{sEfoVSI&vc5|gOkKE|aQsvXNDbtl57#UvQqhJdrFR$N4 zhBCo&zzuhcVZcctcucl9X-GY8-VKD8|;^G4wqX;?X zBxc_190nQ^0t`J=Y74Ei`=--UPvppDg@r@V`Q@`R;CVU{4-Zf$jcg)ceEb0Ga*a0q z7k<%2*_&XH=5bmrfat`dhUjFn&MoR9bhXnU>Y|IDGVeaP$FU$$qeCh+Wz?&Z$YoZv zm_u%LFO28{;K%3rj>pT@?ts<>v+F70U+%7ZvPk#ysmk5xH`~r#YEy^{LbT80=#}~d z8QGWJA{=Mg|bA!yi2a zSO*@NTi!F7cJ6+@bx$kncT*ti;r80~ym3s*N#}lpU4>&3e&i%C$`1Zbo2(bcFB?zz zCx7)oL0=tzQ;ZL8oKBc7D6*o=r;Y~dK~NQ*>wwq=-ihUI$a8uXp1A(Beb&uhILW$jpMh8K zcb0DAZN>Wm?XM#znmXk=8B=U;&4F{4$h?jRVud;!U&Y~HLz~W}jNxAatWIPHmx$o-Gm0pcucW7B&0gYMlrboWkuP*fZo|81(MJwtz$WZ%j5&&O*$=$dmRs+7$mYQ= zPj65*za56+lYHY2&`E7jfhBjrjRd^E1?8TPDj@D%ito~_f8Otq&1QpI^ir%4=f+N* zv*Eop>6klDb598<%QoNt1cR_x^d%KK!=rE6X~e}_@am1PG0+<6_wwu9R6Dee1qVDT;y*Zc!R z_{w_rh=^K%W0!~}{1|<-5eo1z+(;=Fe5!~uPL532yLWWR%CyeXa6osXyY`*g45~Ad z%z*0mJ66`Eo8GW_`c-0fRkE22=uR}aPY{H!_fUovs>yJE2^M%p zUk60Vp3c;@B4-nSWp7u~f9iqMmld{kLUU$K3E!Cc-8BlM+h-?^N}fOyH3SwGhXjns zvxg#VZAK^+xhZy$%Dl6_g!N2m7HB z?^+FM?q{lF(3gZ7m&`U-k9qb%{CI0HylHT*Lj>>5mbSH}ag6F~Zr1MP#aIno*YMej z&RzzaiT~5oH%8ahcJ0Qt(Ku~v+qP{xY0Sp9lg75un2n9bYHS-lE6;m=eE+k@$lCi} z_nh;Z7sRKr@>8)TsBM=wqm0cwKR1iwkf8zO@Ir?oM#}1|x}dne&YVX(Fn|SZ0c&s& zlT8B3g2^8~Dzka`@m{YL1k@LF`o-UpKv?Lv*3>2Oc(YoFj_;gH@Wy~Sv()5F{x)PK z@OlwIK^-yTAP{tG|BD6vTQ)k2{rIR_)K-S+>>U0HJoO{RVESuLedpgFH)}xKSH(A% zCIgy27s`#iQm-}%&SgMg_sBQ6_9Hwk^XC&586OHl{AnxFbw4TXAU;~iPum^}@)wOIy7HCyXLYP__6?4}V(l*yIs)3ysIm z&oADGd=9)D82&*GtY$hwyzOfvd^S4X|I3Fg;BA8|0lK%e-%%x?zrF?I-w2c`6HBrm zg<0~4{Fk`1-(Rx6CiR+FU+>7=>JXaZFgrVEF1@xDigbS>=SUgDbkRuPCfipPEC)Y0rlaYA&#j5_-ZV z=o6lm0oIZvw5)k06hTV!X?1xfnjXp!C4f&3H4>0&m40}8IFW-oKHv7VhkpkS^KXK1 znrMt~>)Ozu>8@%i-U8&-=LOLU@fI-t*c%>0cz*b{Kq|tY{Q1MwJI<{-G6R;*hm$3e zz{++=s|0x}*Q!Cg=fS<+82iR)d%#gQwGnlY=AH#6;slR5bo|-l9=#2n-eG!TcLE?4 z%_!WhK7_n7ISit?MJ7~*&gI*99q;4#vBZ_i=tZZ*L3hP1WEJ}6FSaIHx+E;kxxu6+B| zZS4;lQ3vhG$<^zR2$I8neelmucUEASw6s@&Q|xmsuFC*fSJIwsraCIVKGI3AAF6n}O%tO?BWZMB_uP;l`* zJ^t7%9i@Iw;3G$TR!HFada*zz{h=ZdzWT=_Ich@jj7-gSA4e9qYEBFY!LXDSkYU`h zl%0&^O;1mOdOXO8Ecl6)QsvBnZ(DtFR7}XTF*tIs+RlXreKON-H57n1GB)SRM-7My zGM|gZ1IMhvu<*xYCBiR&!xiM^gSBuo5CN;SFB&&Xx91^{l^^Y)ED<~gv{zHH9))Co z`+*NeIS_y%){5x0krzndZ=?JuH;J*tENV zzstP?*^3S*ugORsCHnTSep(JnYNfwYh~8kx*%VUEm40qV3;y7?UWkvZh|=D-L^eFD zJpssnLrP`efrzsu5BuD%k4TaibKd|ehD+(sIlw1Q@rP?R>Q!?=MDtYh?vlIYOnje)6ZJv#58@4y$`xGR#iDw`BAonh}QM z3z2Fn4v2K%%qX)~TtlA}(Sm3Gc?z09BI98~Z379#`+Ev18uEVPL}L+D5Zo;`FQ`AA zUv;=K8(#)87;am6UUW9?@c+t9-vY|qt1)`vZ_I_n-bDX>sroCZLN7etzH_5`tI+ws z2#E!5EXw0r!t;94Bsl285)6j+$s_*Gtz~YGi5$_-rOpL&BK7;WSMGOx!OD0ZamFm^ z^aW2I8cnvR{Y3b!;ge68zk{ltaiZ7HMQb=y-m3lSoQ8n)1q-^b_BlJC;PDkr7kz)Q zXp+kRB19pV!J`8~LFSq^B&{rwu;k1YW4TTSHgF8}&0QOJThNt&sC2gXNV|MLMNl(y zxAK^y7ouiiN+)&LDAzfb>LIM}rGUjPEFjx@u2PQgYAeZ_uo05ufD4PF*QyECwCY3s zTcu}%>B+CDQ~_H&+9XE62jMQE!ycAl6YPrQ^=*8!>pw9GwuAa&ewWA6w|kH4iy#Xy zMCCL}H*oh2y^7hzS8l35QKoHYw-43Jg&Khk!yDa~X;( z@{g{76ENB=PG3h+xe+NaR8VYa+|T#Y3{F3{-LvEvI(0)a0AZelK$xchPxmV?DP%NCxu67zwZ|pqXs(pDRi8qS{;9xn5%V*aVnpVp(t5WMUMHNYx>8JrTIL?qk)kFvzs5D-h6z#Q z3zXU!LVNxvM$feW@i#JQ#e-_0KSpvsYS-X+wR<62{{b-ZLTqJsh{>IG;)KRP^M)zk z-s2y60A`C3MHq?gkk;2WQIogMiX zq#WjK*r*LpNbKjv@F+RTmKUpw2C==0SaWA|m_1C8>s38=Mdd+7gmJXmy8nh5G8d6flR2*Bmo|YYrp7(BjwxpB5lXh0&h~F^U zR?0*83WK1oa=wr-n&r{0ubk~>Ugju6fa9|sZ{SO$GQP={%5xeoxZU1iQ%M=2K8YM< zMLh@VlKK@|8M?Wb_14^_D*imS1(JdFS_kU2E?7{t^3Cuz+!(Zy^ckv|m&B_d7ezsG zn54{wRKs~1xUqWWJ}~CCsFI}hCXP}fuc{_NcVqV%o@?OMI>f^Gj?f02nf(vIU66Nx zdntNYEkcJc+ZBo&RRg_`WnQHdJ|>Ft>B5q|q)w#Q=}C*c@x^!#uzMvG#WwhjA2NpQ zM~mFOM4f6AN!yk}Hi#EM%=%T*lLi@lfxmMKSl#$9?CN!`kNr${9rC6498m#6u+Qu4 z`d~(I3cD}1Mr%;I{-@=^1Css;Nn~=2XS>WCYj;pwUg#vLu&~*JnI$t9P4hLg7X5t8 zt!RLG)SeN?4S-C*#mL`2y!ayM73;_LyDh$A*w7%5dPg>xp(b zB7MhZm_^hL<})?;u>!A|0@_;5>0|E*8VA+!;}MOYsHn`RF8D!Q>85t{z`MoT8GI>p z1Ynv@3MDZL6o{ezZ>z5ZlD4oL}Q(u$*j1imF>KO#EV=Wos;J3M@;+ zdtUM!`;|;^_c4NgrLe!7k9U_lIOSG~`Q_gbGzi&+eE>6DpX?c=W4FsKkap?lFAGVl-O>|4L7G z{<2VlI;79-;WW#*{I9`G~{D1yKhfpD~%X-X*IlJl(VmsZ$5nQ(t@^IhD0ljLYL)< zgftY_-Z@KgHSQkJ8_R+f8OP%X9H%t_-n+87^lmDcxI@l5(Mjx&f)COoWU`>aPwims0)Ig*6Y|#IFnsqTsx)n z9l{50IKNE#)qc1X1n_%1qQgArW4S;W`MUPcr;cn3K@y-6BwU8526QyR(kwxOh?##e zy)^!0~O7t85v$KV!Y%zfG#^rFLtyzCijZUA*{( zaJ2Q)Xs53=4w3xBQjytLHYxrU@!CyvCXkxSaSiB_=unksC!)dW^!`gqUO1SgL-`7% zaca9OOGkj80dR%k_tH#~*ib7~vrR-xk7ipqauFH{RP<&%iHq?mJE;aB1!4CF9al(l z7XNc5Aio-3U20d6%4l#_zSwz7mW&HRJ$0zL@;a%B&*LE7mE1)m&BRi_cJ9= z0ruG#aH<`l(Cfh_EdWDu)$c7C@}I8AyawX*hIXhWgkb;j=6V~fv2}J$T}1h`(Vcga zFv4s8=?*K&srX6PtTVD^;;mx{c-JXaZCCnhdEYK|vUHt}7XkgEc85Qm9MOoD)vG=K zzxUNor;LS%cfeqC^rl*Yj||+}7M3p>NH!WrWAC>p4)szhqpq>az3@Q8(|*pByk|*w z)HYAu9RWy{3V;7wOe_w4#;pjsCT-U14Bk3^>2=hViWBFQyEFfUCg(L1q-7)x(?H(5Lm_ zzxJ+_tyudWsf?`DwpG{1)0UB3WrF37ZtLyF!d5lVb$AMB{thUQ>2&hBFV`U|7z(I= zh`a0TLS))TXz#!cK3(`FdCWbATO2gRn2FRLUIV#08d_+i%nV2;V1iLc7tk?O$Mz7Y1bK~Z=c~r zu-d`;fEOWLCP4PrxUJy=RQK-fc(` z!YrN4-$o4gNTjY43>7tTw1`G?d&Paav0A4WEed279Z@2Npp&*lWIj|A+ZRh!LCQwG zebo|nE<7-t9L9kP?tTqq@X^3d++A27C$`*8?t^5AR^~?QV`31q^z>On} zLmB-eUMJ}mO@i-9H4gDCX)~9hXzl0lxtn=907wZKD^>G4Xh^AB`q*P{$=>Ywy;~xk z!H7A68A`e0SUO%1g|Q>pWX@5JK+5;`5Em@{tx=v%t-U&s#%#0yHX`ye}iag#RoF^B8{DsAsmbd zN~dxxx6oeg({#C0nFQ78wE3=!(v+-aa>sQJ=U`SLi_=D>FrC7T_*5NlbbVYdXZMgMvE}Xg0z9qDxeRug$Je z@i%?;Q$F0pgS0)Wx%36Y^Y5be?1Wti;-tMP<B zf6d}D1ZxwP)$Y9hIHkN-mtAWqPsWA@*4#{5c6xL`ko+=*$7d=+kT2?NA%GO|C!Krc zl|4Yowwz)~*JLHl1I`#kzc0u3?{WQ$_B1x9hv?Ty)qg zDhM%jEjp~y$Kq!gcK=^~RW#W1fBBZMD9LF?O_WK+>5N(JqEWCStwGj+QWimMS!2IF zE*SPdy#Vb{-9s}Y6^-51QZ&`Lj&Y6|MMO9oN6`S4$$&DAuSRjoGFuty-vgHbL}>L1 z^Jkd5LE~;KeJr;7qQB}Dhp`SXRB{)$rt_LidIEq8rJC#qh^`e1MQmc3By-yRdq`g;FhhT z+{&wM>J}I;%&r~Ju2ux7rypAB*d;G%U*gq5Jo+uKaSK|dZNW%t6aNcCdhO21hKxk^ zyE|oGD;hTwZ{F{|iB_{w;^=n0#&}h!lBPjGeP2H>ccEQTG(xo=8fZ_bO1~Zf(YNamJ_epVk1KQqRvGYKw|F)9gTj&U| z;qj-Yk5b1SN>lO;81#v;Xl5C{zw_o|Bc z?eZI^>)ZlU@NWZ2L@U-2t#hmb#VmbHw``Yf5ldP<^c|Oxx9N?t-Ztf2eEGHUkzVLYSpN{oaq(wMvRn8*OX1NjXZ4j z1>eAFvYpd14y#uQRtUEo*1DnIl6YqNC%cs6zb%gS&L>L9Wf(tdYygxA#MyOsq zhrd`W)8~7~Zk@T0at^&dX#r#$s3DK7U&=Rrz9~y?yW)T4f-Q0nF zQ9KwIPL)bf)8Y?cE?r=a^-;_2=cFSMSDZIzl6F9gj8b-`BLTd6v|mz(hUhPeZXCAG z##A;?Iv6#7NO&K^&gu#=(dgrd3jMs2C2DnhNfJDZShA!T(Js%PK)u&(RZ-+pjW6)+}mN=Sbjsv1rusu=YU{tG4a>dmDSe2=H{t;coP zW$sEpHvTisQgYTALq2}l{B$*yk&DLeVe!AgFYROyfMTmN2)m3%E5%=G8cd|z=|p1^ z_F&pA3E?w6+;)h87(e07PSD}kH=~qw4s|KCb|Ata5=^U%+{riPc8-HMW&iN42{3{^ zX+_U~Ir##rJF7Lxmb_kSu~y1P4vmea2QG;MxFoVA3JB|wJ>&XX7G3Tdy~GeS3bXG| zM-385$LyOIu+NUQeuo>cEsl}|RBX787j9ppGvIr}Ccs8E2mZrDY_WwbX9%0v%ZGou zDTp?GOe?=yqGJ6^o+g@O$F|ke)NL112)20beFAgyLyp#|-%t-KL((ICO&FtKEfh6* zknsh599?r?{{WK*#?Lqp>5AE@Wyhb11+c*&$OJ)D$iHD!L_**j)D8M?4?EuW2h1M2 zTz!k8e1SHUkLV}7ducw7cRqCp0d5iet@G*-p@gFH1_hwz_z2$BONA|zU;bjPypo&8 zvuFd(1`{V>7ggGRI7XfTuCzA7>}^@m`LaMrWxMF>vB*q_Gl zY-%zj90D4P4tDQj=|R1j;HJM|hM%cg?*E}9uxw_Aj#{;H+|6}Q3I-|mk}7^(dixK} zN7||1S8jaO3RqHaBw7x6q}qU;zP60LgzAN`=DKq!rTWI0*6!S&-+O@Q@VBNO>59^p z`je;1i~L{YCVJ-Q&>DB8~@$<<*+y-dTFZg&vY+!~13C@=u~6r=lo1yy#(k z2`CGl0D4wv2=Cd1;HC!`Oi$39!Q@I0(Jt>h(c*oEOT$MFeN63i?AXC1k*=?&-#S&z z6h-0D^-1UNwYHCB`k0!jExVR$>vo=6e0$4Nzqjkou>K!e?#^zcIh@p6KjYv(WXda* z+_uCS<|IEL;@nu>-s{h$8XLq2%XFX$a7@8`Jk?wH>FHY-3cx(e6t<*@X#wZ>)~AXy zTX!dZiL(ag)b1L5&LZ54YP0Di`edx2quoDq;0i6-VDKth|K=KEDs_xHN8qJc);q>> z$Y%Sz-lf%*FLC_7G3D>ewjD||HsJ{2#G7B`j=(I>5ofI)oCsivaA(mpr1oW^Xivqf z8i|Uu+=0y@%xF)F5EMA{9Kp=78kS&cR@xERG;b_UX6P2;b@RBR4Q!Z(*t(#o6kk4d z|Gejq6Ii~_q54;cF*VOQp zIiira0(t2cgbe5u&w2B3?a^;c(%DdYFp|z%Z{;Dlo)%G?NrX^$Y!ydO*=n;Z@c%-Y z3@P$MCXISqtvdhi*A=4>ADjB(FG-i4mieGS?zV=!A9$!NMg0<{-k=vG*bd_MhDaBw z3|g9+Q_NuqB=RamUfITZ`hF=yKKb^I7#|OUqJs{4Vdj~Xbxy2_1m#(k7`Zu1S+#%* z_4f@E24(3l#HNao3@)S>6zC?A+d4|~d)b`umU>+CLCQd8I>H&r;(-TTVhZ)>b)doD zh9#RW4;rQ0A64EaY~xa`t=aY;`4&@;AI)5gv{qOyi<%WAb}5CNng5!NmYMR>1Tz_K zYmbxOj3?DEGp3IJldnp{U@@fHiK5y#1kMAiL4Z}g=1MO|dS^w-#=F8k=25LudFTAa zvuk6;4b0MC9m)y$G}|w~zvGAMmDf&M8`8QntvkE6mQdIdk&c6edm$bqiVLHjzw_&= zBf>e8qggtA6Tz!XI3g1Pt|=JrbV6IwAC6hPZ_+M#;TU`Q`tUgZN`?m^aS?PWMRIM) z+`XYixK+O&dUNf!M-~R}H?seEyp6UlQ?F;k<`;K*s_U90ndeS}fFIWkr=VIzqw4>N zo$5sYe8iodg;?rfjgxtESermQJTVU;=$i3Bh*h~)wtsy3L((0zpTAozJ8W%PbB+y5 z^fHmOHdo&h-sWVK9=*nRb|O8I(-uW%tFl0LcPJZRk13Y$fMY&2B&XHU%)^7yBSv_d;WQqfk2(3`WEt8f4E$2J6&U5 zu_WE2byABJUcpn;3{Ci19Mq~!{vm8hJ2VO>Ekip+PegTR~Fe2h>ts00*Sz3dk zl#kIJ3PT6&Yk85Zy3W#g#NB%>WkRcwLBRMu<#?9$fQj8Nti1F}1T!9F=B2uxr(uu>LFvTj^@Dr)S;6?kdI6- zm)=0u5yZ^Xz?UiPl~pJToY!MeAH(Di?_zm6!JfCOzxJIFnr&MgDX;M-8im_MHZ&hT{;Vd&idVv z>r{)SYGGZ3!1*=lN-{x2KK!-P76KVT$Q#96T+hyg=`bBy#IaF3%tchfTaO2;AQpKH z)L?UYSA850;Kp=3<4<4iYjL#;W+1?RVeVZ_^1T;+o?HGESx##v1M#e`b9#MZsQ2C! zE>OI%RQb9s+Zc@Yb_mM$5mY)I%=Hnp1L5J;mW=k*0z76Lu0?@` zoeq?0M8pn8XETZxR{JRS$q17cQQ8PId_r01)vhyhX>5i-jNVFCjJ6}FA>7QHHTI2B zB9u6pM4)AYha$AYQ%z^Mv#j<5QQ}QI?emlCz$arnwS31CO`6$R-fK^JikQr#-Oy!O z-F4tNHUoe+F6`Am)~#t2S)7Ik?SoZ-Wqhg-J*5pgwhpq@d^a>H> z1O-ml*NI1)`qEQ`No$A~{;CB3;lC_f~){-c>pXATGU~>gQv{Q~yk>0QD>4oj! z=45UrhPx1B1p|p7lEy01QjV76!Yh$lS(>)6mNuTs#_Zr79S1U*v2~fsFxYpisX3{A z(O}1|V{v*y(o}>0RK)a9YV);D2mbCF3A>AeZwA}ause@sq!s%T(WF}-Qe?v}hre`< z4%uF*_i|?X1!sDmcGn8pRn1Q@Wk;S@jHfuT5x9m z`U?ySGBcxO=HuHT`fU*X!g-|UGHX! zJK5A;3SL*p)_WsC+500rFpr_v1{78|nJSl7Lvri;PA|IPt5o0=qUcTFXO7#02-8n^ zTuOIKvC(`#3kj#-hnGDdFgY2jvgzUwm_Y-GM!_sz2Rwba~Xw{8yvSHSV$tUvy2+b#ES~{e5J$9nC&cTeU?g#c#4Fvznaq~Ezv&@OF5xPjR z2$~UHTF!dUiFl{&uPk{8iY-JK7(hpMOUwI;J?T`gC=aSMsf`+6uC-Eq^HaNFQyiWc z0f~k;`DMcJMZ^k;PXHls^;va<7=1Veo4kzZ&`3MpUjh0?@!wpU!4ECeGa*Yl%&x7% z`7|HCp+AHZ_EPup;`qifkgQAK4@6f^hBLh>kbaNb4@= z+q)|=EON~cSH_*(Kd%ZHITq1ycDXv{UBPf9ocn*-#Y0fAe?Ec}t6_!WapRUK@L|)E zyFvn;%suY=DV!@40-|&V9assuJ=KbIDt$GDu04N*#z6}QvKLSgS8>eAqS-@%Vu3dp z9YNAGLA~DAV~wm^eqO6xb5VU&2BfvwXmwz>CCcgI!X*5TvROq@fyMobWpCo zjkCj#{(wC&oMS%w-VIejg-dWj>gfAz3_rcg*mWi({arlyl2Aygng&QnV%F2aFGfX; zb-~2>+HA~FguuqD5N0!3U$O>V`aP8Z-USEOAj>_tvFh@52-N)jkt>;YQ5HU(pO93} zju%A+T2Qa@7>VY;hW7Y^+V#204XOB|L)kLs%iWaH34f_#Q+Ul%qAci{z$#I9hL+Lo z&*jF02!Yk83khOxBubi`agNvrO`^@GGG(|o9qAnliGr|Ijqc0ar5cd^?J@>-^*;W8%e{rbfedk{qA71ucl_#X_dB z?BCkrdzAXeX--xuo171Tt;0QxxXOo-k<*B zu>2>2v6QM&|6eNYd8ouLJ%`AM7{wjmti$V4(?-QIuw0;L@eMhfLUG)ct`R2S{AF-& z>vW%9#eO{hZ~~R4s(a+(g(o;(Mr%9QPF_C8nj-HG^p6o#TEt*PCaWiiho$KIGI&}uev00;ClN`#cHTu14ctZ2PTt3%< zc7{P^`1i(`_BVBZ{Qh!zeI!U|Es_|iuO}7H?Kqg+I5*#GC@k~!Sb-`ulj1y2X|Kd$ zAe=R=*uOmV2F4_?tV*oiKQVxh(fpP^Ft{laUgFI=W_5-ig2XEH2xEjx5V$Prbc+J^ z3#RJ6q#h!YwaKGFx~X9A+2J`y6)7>sxit96THL(Nz-5)ry~7SUz#mRtm((!vWTx57 z%V6Gqs1tSN^B_(4T#gZf9PrWZBvFqT^tK zQo6&itQH*%L2Lmt%sc{5Bu)-JX0}u=_8(HArOUSF2#s6L%7jN`kTlkz?&9h}LMtJz z&FjzJdOuIxPH!1V(IaiZANn42v+kWXT&dO15~u882h@40(FW}UZMCaVOE5Nb@8#+u z|MQ|?I2eqF>#c!6!K2IKWvIl~(qmozvUb~R3zqh@8` zha;KQkEhd8-P(uO?B!rb7xP-(Q*Qe=8FN?bVQFHCWb)I8_l0gkPnKaOC^34(pkbg_ zhMF8+g*c{v1qG}%T8)VV!BH`R7A@ScFRB%9t^$RcMwGE&kfgFEgBg;uMkI4wxkS}J z#5)H9DIU)vAT*6~&BBqloJfi=+Q0Xo{0{yJNJx3ASZHWUNj4>M3=_3#dsqXX_Kw^% z)m8@{Js%6o<{m6xC>`zv8fxAiR-`4Z*?646kC?Q2Ha!PaKjs?N^Vb=Y7$%h#W!DmJ z6{x(k1Q7{CYY0Q695UBkh7HstbvZ$>ND8KiV%il+b02IkBr932#1#m1_mxz(U~qm> zBEQ*{LaJWb@hzjf%g ztFc|T1Ph0EWYB5PenyZifq$*k4HsWQ6zC4(>SlLkEK?!wzOE@f3vLbfWLwi@ShbP_ z7cqrKk1agg#)Zl;1b+=UP41$9c_=>)AgX*`@E{wh%`d+x?`ukBHfLdD^-TjVgO6F^ zxK5MLF&eQwR$T3CDb2vR{yIlAOvgluHvYp#EyvoERK~mE)@1uA|8N`F-6(PHScW*S zAB~5DmhCAweTi>#pGz(>d=Q^If}WV44>`ubJUlD3cRnAeWcOGT)4dHA-jNCK=Rxs3 zG4UsZBh$g?@4o6hvu47GD9!}h>R7WM{e=&63{B4 z9~R^y_QM;Rslb?FGm6)>#{QV6qmDO|Sjnz5Oh;>Gk$wL2ch7jR^>0%*M(1XJ19`Pc z?Z^8+wc&A*sZ-{CetrzmH7;l}$<0Dk`}g@0OmgMivawVkp}h^$Mrd3g-f@|K`5t|v zXGDt=ozD@TiTHbANV6R8dha zX~U0cQ(9V^U1(wtLFUpUwcOs#n8qJ0@!pL>U33{bW#wFkdCT$t;zol2keD=X3@qL7 z51TXfq_3kEE;L-@k=A(U$2^2q^fD~fArPL!pS1!FLa;ED^w+yIX7K@9$qU$7ysp{b(3bI!vcWqiatD!CmwC=irA46RB>9c?6nlN)?EMWc{J@ z8BnX_)C4Nhc|m2=`AJ4Zx~M~^RFOhX;Cgx^03h`0 zwCij(hec>luYmtWd1X$MDCU^fVjOvEL+7%4p!3;2n_+i?o3gZ#HLB9NZ1-1D8*NGx z*5BQ1df;jbpI)T&*>h8WEOUD7!5@0Bm8vUUcxC$u{iExpLOv*tM=P!k?2_uvk9t_3 z@2Psb3vqMyo}FXRyY=+&-pyhSHa@63>|WmB-2E{Q&RW3lI`!+2pXq!3y_*Y1 zMc~V3?F_!wcIRHq^BdO#&XbA8&Mme$;?rBc&^O{cJ*|wp7qbLe)gNG_@nNg+?dy-4 ziN6@pq;%E9$YqV&VvALy+w0o+23KxmFBNhY;#+5&K&@o=?f$7HJXFDEzyys;-v0p) zQojMYgTPf%JKkjMD)#aEX*vj%RokO_D8mC|JBMTQp*?zA5(4h|+2Rl)A+R|bF6+I^ zfVpOh1xBwK+*7VI3^7+DYRqd?ZPlRIGvqgNC zw1dV_g4|=EH`eLgM&Y*xe*4C^wQ~(j7qaZC+{ELiP^4+s6(VU*rMBJ5fVB?Z6tLF$ zL5Xel-#qOff#zSzb_vfT=1in+dxp8ZXg93WSdblMi4lf!SbfMqYJPlwV1;l4>LpCJ zq&fX9t3Sb7seXf#fhh2X<^EwN7kIi*qJ@>N;E}j;mU0af+VJHzK>fW@4OoL^;@@8nqm!yD;6L`>yO6rhEE~#6HdM^2>zop>6Xw zYu;hcrl9)MxO|#wuRY-&zW{085pr6C8Y}$jP)W1bx(YPk060+y001UY^kk?dS2W^8 zTejFIWrJXU9Nwic!9CQW;Q{Ru_O>XYffW+PGuf?D&S~JoqjwYKMBBb$s>ZXZq)GKQ zl#$!WE*HZ>*BbjtbnDX0Cv&J#sx5*MZ|;AfwORfNXxxz^(&;Z`V8y}QhdSx^#ClB{ zb;03vhcR4RtI!B)l<%P{%)+hG-1+=8p3_h>n8eX*KWOF$yBk8nSqu0A$}PVE@${P* zodK?>&AG#Ueqb(D0sKa>7PTEE7EI_xx2+#JNsHR?7{ij|Xe4jC<334=mRugfvXKir zY_D8{k%GRMu6h5@12ZGF$|hgX+!h*%H<(d7R&!-QfAY9H8{-(yMQ8x<1AS+k5f1Jw z1nzQlRBP3)Xzog{mC%D)wJ^T-iODRY%=?3=(s>Mv3l*mu)U#d!K0HI@-Ow8c0*3tO9)T9BZ}Z-) zQeGy*l_r%9V+NS%I&AnH#TF6OMqQcO_A9cYQTAxB8$DAI@wrK?qQ%@V*-{^L;Q|#S zX}w4Oy@i=6$=Xmw@gFd~{5ix??=GS#T%Sg@f|^c+(H+bB^3ry7*PB6YHKOl>Q22+b zZy!4sTlqPvLQcbnuhK%v^~)N?q}hf~#clcSi(ux32w4>MT4@AId$*Qaf8hfq3i+Gj zp7QU(RGK*RXFT7b($i-R8$5yCK*Ns3Ed=MT6(vbL6GF8TRRHgD;W_L>Pw+v>mdJ#f zX!21YTvJOkqIS2gM^bV6YV#z#6;bG>P_BNt#3d|nZmyFuk>8yraDlNHr*Po^eQ0st zZ!-YTg#V_vZnyt#GNz z2+>y9xICN=yDz68jo{L+G4+VCq|voyiUwY9`kvS-+SgN?GC~g(!uTP2>@qi&dNG{U z@O2@a^(cVL)kHd<&ls&dl2Y;e-+CITFSaH@td2$yk|tyEXY}bFb1kHg9$^tcnSi?k zk4cmfviMjRUEqiY<8eAlZM%d?yyD23%}-3da*IjGL?HR2iW>RNvXOWmWBR!Qzv}p` z+VNs16b6s;j@VS{4vYN@PwYZIv<|y9>9{d4X%v3<<&$<3`St^arelS_`JSUY9GGqO zy9NUU;GS`NG`W+RsY#T_#h%)5+uQAs(|QME%FoP~3{p3M_V9cfQbBktZD;gFsvF^a zny=1`je?N!4n>3fwI3s`;hRk``@|t06p~dm;!JhXd&N|dDRu*m=VLt^UtOubf3rz4 z=ubt>sbp2nN%qYyRd=tuAdtkNC%8>_&dC6hjhPgtyly*nBW3%^Pn+t7u9TnQ1f!AxJT_PT|I)xovnxtC)Ays>B56po zZNt6jB!Fi_GPAV4O>&X?_*aLyoShgc%6^RU?^0uCnYJ5Rx79OgFkS4#q4ck>GQ$Hr z@}F2iE;QSEyOG8+^7xZ^!qysncDv0$$E8Y6E^EkzBKE0oCRJay>KgPik!70Q4n(zJ zhr#^*y))B(r9dpwR0qIF=3Zl(;)J4KgZ4iRwf1)(+tUEwhMXM)ZCUuTB!So^9C}ms z32}tNZIaRmO)9UUQp!O-k z_Bx3c;?f}MSPbSf+8ycJyR{l@&LXA*Su-4}wL%h?VIDQ$0cNr*l?YbOtGJobZV`hz z)P0+OLb?Bo#5PDd(48B7VS3Nn>+JS=x=5Z?HJ!wa*@EkQjeK;;PU12^YzGWdhvKIQ zMHt-zFy>Z3%aD(+h|y8R_V?snkf036puy)$yPy685KEsB#Kf6Wp^7CbM9s_Z218fL zB@$W4*v2MqFgm*B@Kk0;F9Jt>gS%P3mWJYkt{ozer)X+XP%c;B5DB`Z z2DSgMC-)YO{$EpG;eP2z0G&95vq7~1yG)3f&+{M75q6O$PHnfWMQumAk3ZzT(SEZi z?y>r3#bI}UyhVSGF2z+H!1%4O!#&-UWM8av*qEo4Ux?-M4*9{zMc$a=v8P0qhE~lI zM}f!rl}}r)q>w_D_j%8J#597{SB%X@0swWTLy}rM@3&w4)G}3E9~}X4gm+Rbx@Ma> zQot!HZua{V62MrV6S)E_;q#%ouh(mudUJS=_j;EPb^;-h=Yxkk9wJWjLdd+L_!u~EOWa<7tG_OUjq9F`bz=NiGaxggV|wg!L%m}*f8-|EC`;lmW?YAZxK=v^f4u&rv}!9jc(TtWWoWfd!&`nb-mEy}hSmLQ1Y zpvETbDPd?J`xyyQ%Oy95G(mV`W3)RFr^(&$U$|;ofIv3oVN0NLrH|y zNT`hju(EERe_vEP$R-0OCCizmvdS}ebq!C3i=U9eKhr!?qYp<_I>%cO(7yOemmYO+ zgBp|n62*48nSHlNbQlxv#vzQ`i+f9$96KDiw1|_P@f8>qpz!cq^GQ=w1TWLxV{XqC6dGG`-&_{xq*t z59^Kxd}4&ARyh<3u-)s*x#F!4AGe( zehvy&iIYs(n{SW*K4iN)1$uD*MPDCGJAAybtUx}4$3|-MCG~v8{~kJ<`_Fsp8v9NI zjBIAh_HHZ0MRJB=x0G{@{7FG7YZ~k6HSR-FbaL9^uSIa`3|-&{4OsH6`?J@x8{aF% zx0M6Nv48I=`Xrml7o<_$T~+9yRlNC2ZL3BEq|Z7j`(HjZwWoKcSK&$Dgldo8;#iN7 z1XPRlM55@_%kC4S2z@(u2h5}#^4IoS?Nm;yB&P<1C2|vM4N&eDb*}22Pn$OW-Jumu zKc;>?H|Ox>rA^)2`FNJI`r%!D@b#jybFQoXd*;C!0{v~f^cmw{{ zMjJwuU3i!pC#bQ=XV9*)fyA(<9Ln#fJth6b-y`rbX*IF&^aqXO#0z)61nwq6d%#$J zKP3V)Zt58Hojc`Y!9cREPg3;&%}@PVgR&!4f5CD$7J|lfw;=tj2DL7sl$VwDD3mYD1ul;3&|>sLkfqOsP1t> zA5r>i%o!TKbb5)^%JYQrX>6V^^uQnN-Rz=MaKQ7qG>12qj;gf8zCMr5pYlKdK(M(E znr&vLA>7U=EAi#yb8~@fx8!ovbr^*=*Mtt-rDdx^M1UJ}(%|b&(j!>UCgk&&M~s?; zYTFBfF4$~uWIJe;(Yz*Rtyxz?zM^FjT@o0Fz8oFbKqgGT}|y!<7LiOzgHX zgU#gi&Ml*`WugaE7>k`S)mFRInZAx_ApZ|-QWQOZ*BnXTU&FRMihScuV8peXAA*dkf2W;w`tSX zPA68=PGS$Uf<@YzTbISLn(=?{S#DwxvXPWp#?uFl(AnE}?uXUxmlH{n*(%1eCCP5& z$fulei~N*RzQ7OoNnG9WV#F7)aDLVsB3`T!Q44TjcWVCe(ZFb}cxb%Z`3I6uZ)d)Q7BOn*YjCC1@J z#7H(Jqbc4HUCBweKu{OYKvT`(-~jPtGEid3Fqno`C(Z9HJz)(|L>|Gu%Y`a``f??Q zD8N^;btT)xy^>F_G9EHQ0tql&WHg*)sRYQMijLPnb$Ij!ng-8_LrDxmgP$Jq6U<2% zQD=$fKA(>30BC5jpm+hPQ=n3e+&44|zK@&_TwqB#%l)Z{kTca4WZw5EI1?wLSi~8o z!5q_!whNq+*uYbgI|It>Lqt?3ilQqUc9q>%0-Gc3q~yHEF?8%egjhs$)eR`acTB{o z?~QXuah5>U8@&1)(T+Y|b^gy~TQnuasX?H{QkbdV@i3Z=%|cV z-uBnWBfK?{CM*gtwdaJgrOoq<2)d#OkaOyj=wb_AkI;nKIekBi-yiX=7Qc!41sH#u zA~yY??3DU`-;`BCeo4Aot6{6E78nW@`W%_v0=R3L_$Im^N z3OlOln10}*l^uEZXN+%p1=c28Uq}SFB!nu9Hypujae#>b{H40U5s6iYu+7O-BO_!vS(n>?1&7>LG{! zQP8n|I%0aSgYAD}7e(Jp>3|mU`Tp;=Pn2zPn0+W`V;Z@s!xFVK+9O(e9c=$CT@-!O z(yP`vO0XSM(%fX-R%I=b@7bOoq2ok*5qBCA)<^J%?!i92OT3)T*cK&hbq)uX;{T^L zi=k(h4=TJaNwTGF6yyl{Ry#~t*Bp+cRyU{t-F!1j|rrgkh6!4 zLU0>yKjJp`91!t%HT zxV_ZxW2^_{K2DN8LeJjM`dE}6=95oU_7^72_<7_WSx0Hly~Ca1?N5Tq@q!Efo$?)? z+$DPeyYnHsW9CDCTK8F^yp|g`65jAbvloDypPOB8aEslTpEYAA3IhK2y?J0eAPbuP zE%X7?1ir+Rxy?hn@;&k1PH;*iRs1B!x9J$ZMZyB1YgLpMXcMO-GYeovv zHBFh0r{;Wax)aBk?{Q`4K>_AV=aL(BmYgKs?8&*<;aGMtE-b7gXWb@1xgaRg+$wBL`AX)Bp=f9pxKDoitkJ!11zLCzB zkX-QViK%Mp&>W4`i78zo4^dK#`uf*m3L#W%)+Aez8u22(gSV-oM^rJ=Rqdc_LM}>{ z^9WJbGMs@i#M)QR71jJA!%r7MYN4Sm7MzL^qY)amIChi)PlPz-;@?n+{TcVjq*e%l zfuAF~AYoP4)R~R>m}(+^7ib;ZuH@{-T!wK$iOW4ZXXLJ^yH>^bXZRjX;b93615P2? zcyol&Tr)hy(2%2y&~&WKClg&6qA7Mqld%Je&3Vpnyv?Io=YhOFgsR(hc|muU-EZUg zs`=^xH6z%-j9AuzCsCX%xr%$B6uJX;pV7sIG>G zRaZL{hsC(Ex+;{}UN{xW*J7003?*^&bEL literal 2132 zcmV-a2&?xWiwFoSe(_xb17u-zVJ>QOZ*BnXTU&FZMizeeuVC4iq{=X$3liih<=NRx z5_?jyGMgIPMK#b!z2=st@mO*Bzwc>oq7m{SYsNONt+Gqf>DzbiN2t%;ktE4%onYCL zWG{B*V@|k1LB=U}@Buy&kB_Daag7*Ou8tkSM_kUys@KAaf;~;=GYm{ z@bPBIjf0r-!~Ushj_-`+#+Zjwmy(1P2<63!q!RqCfgh>lUCK}Uhp>vI$O*9b4kMOP z0b~OvOpH*Nv-!3Z;})ZpE((rna+Y|AVb4a44~{h5R5Vl3jfG}f+Q^#BRBb-{RBU&D z#Q*P)j_&#^H$+LQFdX0zGrG3KkB?BcxL!~UVvG_eV>tZ{(^HfPqgN3+ zBXhYgVuph1%*IACBOyLP2{%x$+loweuFXH~?R}Mrby`gi<82=M7~^&0$R|q+d;mhn z-nLq-7H!nYNZ_4iAy7?Co9U)GnoedD%{29<*8^AYVj3c5vA_9Qe=JVKSdu&W`wGfb zH^=^brYYXs&=p-0u4q1*PUh~^H>cxA3%_KepU@3!s;fXdTmxXH zF&bN=k)@AR!#u>&Hxc@P;QS@ty2Ew`+4Luro?{%H#f;=z^1Qk;gY^ppP4SF0)f|rw z5Kk@xC4mfsX=L@%{NBd413KjYincV@H zcmoQv0UBJ?sv*B3M`);Frz0e*IKnUA4?MKCW8eOa@%5m<+GOV!5&St@5*PQYvQ{YYZ9j<7^F(_QcNP&gMDT|`gME6J zcs&neJCv}~Ib1l3|DM(^hF(}csPTFv&5yQGSRfdZQ`F!SOkL0xS`N&s2UXT}qJBl* z{cxeTnMR@^CXhiw&fjbmg1c}BF}JywfOrs3VLMU3B7YW@vD2Ub%231zTOaVq@Ttu# zz0O|#Ba0d>L$`yhE&#Wm1w)MWfIPryIz;IC_p>1urHA?C6P5j?Ni%*Qc|g`t+4JCV z=Xi&cU<$n8f`4WF2~XjY1AyK865Vs=Lw;NLMWVctTOA4S_@&vivMpxwfLol#f_xae zaTxM%-`f|qA8s#dU)q&tk7_fjZXt`?^}F6YvGlPzo*#1Mz7W4P0)fC+|Jbtek zDM;5eWj>voj$?W=*Kodie^!2UA-PF!$w^{oPr=0=*RoqpQw0m>=mvWqod05%onnU6 z0$R~A^z-?LGqvDZ*r8i-N9|^sMnhS}@14*#mW7eXA19a3>BJMOo0Dy7eb+}EsD3gL zslqLTt_3Ym0eZ)?L2&|<4svH}TC4M|>3}Q3(pEE3r!Ly9Ty53xeIZJ%$Z{3HKl?EV zHX-Atu)7Tb@&bSQ$-i+`Z!hIMfCVU8X8H3spj;PY_dxeazl54fUivXf0{kEB{6g59>3F7&4e7gIep;OVdMpLx8cYAi?sfdVbh3ivg5S(c zRa3|2WU9_g=^Xipl5*A8Z;L5~P_x;PY)xv#i=qc_TSZ?`#Y9)NgW7~Vl&+i@QO`2m zkuk>FSI!mn{vyLq7eN}Kp(_>~ixHz08g@8#oC8mVIOXBrP=td8_sFzS2!Vm0BDy3| zUDq_3P57F6Bi;+NiEWp1-Z7VBTvFn3&n_6bE$gmz`T7}NCv$kSf;S^hA^Cc9f{~*c zzG7&|RVHXYRh-#OSH@_Ly~%9qf?^Ava~$uBXx4inuMeT>_B>wDo#g#(9ACX(Goa=K z8<-KxI`AZl(-n7d3ijF7X@Wp}TV2@=Th==DlNXEN^_zA^Lm3$h%>d!>=%pFPr*?7q zJBEBqw-3t)7jb*5nKhbOQwW5!@h5p#M228oS%1%n{BUX2bS9{-#)nl`dlZMQ>Z(*` zci~hflLsoMIx=lZ=S$%Z1U@sSUnTR@s>$896!-h+4;nnSQT55f{?yVTnVFN89R3GK KmDJdwK>z@%VJ_4F diff --git a/x-pack/test/functional/es_archives/reporting/nanos/data.json.gz b/x-pack/test/functional/es_archives/reporting/nanos/data.json.gz index d0531c76077366d510adfa1723623ccac2d1ae36..2811c495aae2d2f7e9dd330661fd9f5f76850ef4 100644 GIT binary patch literal 863 zcmV-l1EBmLiwFo|YCT>617u-zVJ>QOZ*Bm^R$Xt}Fcf{~S44Rx$PUmnd8^b`+oV!y zpgs%`GRaNInh)kUY*od7pFffimv#*m+oT|pWBdBtbA9jibI&kL_Ou1lGt40O&AtG3 zBq;^*%s=>N9Eedr&%!wJE(d6UtR zwR~UOF)4&VA@iZ&Hs%$&Y=&zQDw+*mZUe#~SP>>hZG>G5ITmtfHulC2e+Jlgzp3r2 z%^F)Pp(uy;y?w9u++AuZtF@6G;;^+IQJ&ZlQ21-W1)7WNlX1ql?4##tmWC}texmb`g2ami6X zFEhq5#NP{_##_009A^{)Vg*VUE#KU?hqtM1<)m1rprSJiX5S2O)V;TiN$@ zhC-CCB-Pyi!n5#m3OdiMOxHjqb_$&ue8H!NI}?)UOJ~#ub?NGXQ?)x2S;eqZkkyR; z5o48aZITV5QEaDSnFU&W_-pr z^JiJr=E9UCFBaYOG+HJaKThbA)jDy8#Y*MGl7JJf<+ z)j;Ffus=vr-3&Hyv`P4nT_wpOD|ag12jE8u^hweq!SYeYh_sFX#7Badoq&+#x$ zm}qId8ab?G@JZroriE-lB4oQhQOZ*Bm^R#9)GI1qmCui&`XfNT;<;jPkcb$8OH z(k0r5OQOhufp8^|Gp2V{mH&QY8xp*2x1`G5N<@Kg?D03>cxO zB!Nd(G!l8n5B$s%X|4AxhA4rQHHA>)q^V5cA8B?xm+|_u3_PYdDO$*&I^fP{vT>phb(Wj^=K9&*Pdy4g3)#d%+tRolJ36 zR9r6hGa;LFGq!uS1nQXQd!ZTH^KD*R_&i}eRvW#gR{P1AmDg-jKyn96G~6KBqlp7c zwo_r=wL-oKw9AH$=mP(#Zn2OA zo7f}7VO}_KD232rINgDi5+E!Nu0uF`&vYWRG`}l#;E-_c(Z~<*aj6$xSZXD!vu8p8 zFQY->ejp*nDrR2N9E#+w;yWh3u)Xy6ytJhbOFP21Ji&hrtV>o__0m2Z`URloOP%cn z4wt)JO<2o`qoqq-QoCwW8+iv2R|^Q8X;PiZn~?x3z& zHc-w7c>25I|3`5vqO1O)Byv%x!&hnb@`Ct&OY-e$iLHtMf!3tE08DoSZW}Kmc(LPc z<4-Pp+i0C5n2@ngChD5;FL=$o)9I)P{%G(|H_mc-fkE@%A*p2DI6gW_+^k!JS~P)|Q$H;$3-K zaAmYjM(^4$g>5e6a-;{ns)51t$o?cr+Zk;0Y+K+@+!n>DDj#*ePrzRd@F(3tbgxTW zoe>2qvql{vh&*W90r501guK$Cg*-2m$iG86?T(&v@`et3dFcgSS6mj`;vMa!nmwIY zuN^G&&$Ic=`gA-0Y)x;c_p`p_kH_6l-|q7D<`{Y!c%D0^Hy1t)=!+WH$K{*#t)$ZQ ze1}kc=G2QQiN@p Date: Wed, 26 Feb 2020 13:20:24 +0300 Subject: [PATCH 64/73] Fix TS for vis_type_table (#58347) * Remove eslint overrides for vis_type_table * Fix TS for vis_type_table Co-authored-by: Elastic Machine --- .eslintrc.js | 6 ------ .../vis_type_table/public/components/table_vis_options.tsx | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 9b00135df5bac7..087d6276cd33ff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -82,12 +82,6 @@ module.exports = { 'react-hooks/exhaustive-deps': 'off', }, }, - { - files: ['src/legacy/core_plugins/vis_type_table/**/*.{js,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: [ 'src/legacy/core_plugins/vis_default_editor/public/components/controls/**/*.{ts,tsx}', diff --git a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx index 5729618b6ae072..8cc0ca24568673 100644 --- a/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/legacy/core_plugins/vis_type_table/public/components/table_vis_options.tsx @@ -47,14 +47,14 @@ function TableOptions({ .filter(col => get(col.aggConfig.type.getFormat(col.aggConfig), 'type.id') === 'number') .map(({ name }) => ({ value: name, text: name })), ], - [aggs, stateParams.percentageCol, stateParams.dimensions] + [aggs] ); const isPerPageValid = stateParams.perPage === '' || stateParams.perPage > 0; useEffect(() => { setValidity(isPerPageValid); - }, [isPerPageValid]); + }, [isPerPageValid, setValidity]); useEffect(() => { if ( @@ -64,7 +64,7 @@ function TableOptions({ ) { setValue('percentageCol', percentageColumns[0].value); } - }, [percentageColumns, stateParams.percentageCol]); + }, [percentageColumns, stateParams.percentageCol, setValidity, setValue]); return ( From dfcd4d1e93d4bc49193ea1a9902fcf916105028e Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 26 Feb 2020 11:34:11 +0100 Subject: [PATCH 65/73] Functional tests: Fix saved object management button click retry (#58218) --- test/functional/services/saved_query_management_component.ts | 5 ++++- .../apps/discover/feature_controls/discover_security.ts | 3 +-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/functional/services/saved_query_management_component.ts b/test/functional/services/saved_query_management_component.ts index 9f0a8ded649b2c..b94558c209e6aa 100644 --- a/test/functional/services/saved_query_management_component.ts +++ b/test/functional/services/saved_query_management_component.ts @@ -24,6 +24,7 @@ export function SavedQueryManagementComponentProvider({ getService }: FtrProvide const testSubjects = getService('testSubjects'); const queryBar = getService('queryBar'); const retry = getService('retry'); + const config = getService('config'); class SavedQueryManagementComponent { public async getCurrentlyLoadedQueryID() { @@ -177,7 +178,9 @@ export function SavedQueryManagementComponentProvider({ getService }: FtrProvide await retry.try(async () => { await testSubjects.click('saved-query-management-save-button'); - await testSubjects.existOrFail('saveQueryForm'); + await testSubjects.existOrFail('saveQueryForm', { + timeout: config.get('timeouts.waitForExists'), + }); }); } diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts index 87ae5231d10312..1dd069bb907d10 100644 --- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts +++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts @@ -28,8 +28,7 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { await PageObjects.timePicker.setDefaultAbsoluteRange(); } - // FLAKY: https://github.com/elastic/kibana/issues/45348 - describe.skip('security', () => { + describe('security', () => { before(async () => { await esArchiver.load('discover/feature_controls/security'); await esArchiver.loadIfNeeded('logstash_functional'); From 08e27d08e9ca5662d1b9b3601d8ff627daa8fcc1 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 26 Feb 2020 11:34:53 +0100 Subject: [PATCH 66/73] refresh once to make sure everything is fetched (#58225) --- test/functional/apps/dashboard/dashboard_filtering.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/functional/apps/dashboard/dashboard_filtering.js b/test/functional/apps/dashboard/dashboard_filtering.js index 1cb9f1490d4427..ec8a48ca74911c 100644 --- a/test/functional/apps/dashboard/dashboard_filtering.js +++ b/test/functional/apps/dashboard/dashboard_filtering.js @@ -63,6 +63,10 @@ export default function({ getService, getPageObjects }) { await filterBar.addFilter('bytes', 'is', '12345678'); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.dashboard.waitForRenderComplete(); + // first round of requests sometimes times out, refresh all visualizations to fetch again + await queryBar.clickQuerySubmitButton(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.dashboard.waitForRenderComplete(); }); it('filters on pie charts', async () => { From 3b1921163c10acd03ba116b9d4fbceb427c01633 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 26 Feb 2020 12:05:47 +0100 Subject: [PATCH 67/73] satisfy proptype check (#58538) --- .../kibana/public/discover/np_ready/angular/discover.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js index bf5049cd976a30..1ac54ad5dabeef 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/discover.js @@ -556,8 +556,9 @@ function discoverController( $scope.opts = { // number of records to fetch, then paginate through sampleSize: config.get('discover:sampleSize'), - timefield: - indexPatternsUtils.isDefault($scope.indexPattern) && $scope.indexPattern.timeFieldName, + timefield: indexPatternsUtils.isDefault($scope.indexPattern) + ? $scope.indexPattern.timeFieldName + : undefined, savedSearch: savedSearch, indexPatternList: $route.current.locals.savedObjects.ip.list, }; From 342e50183d74774e36c275b429cd9afc54d45508 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Wed, 26 Feb 2020 16:04:58 +0300 Subject: [PATCH 68/73] =?UTF-8?q?Converted=20brush=20event=20to=20TS.=20Mi?= =?UTF-8?q?grated=20tests=20to=20"jest"=20way=20and=20optimiz=E2=80=A6=20(?= =?UTF-8?q?#58206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Converted brush event to TS. Migrated tests to "jest" way and optimiz * Removed unused definition in interface. Revert changes related to import deserializeAggConfig. Co-authored-by: Alexey Antonov Co-authored-by: Elastic Machine --- .../public/actions/filters/brush_event.js | 71 ------ .../actions/filters/brush_event.test.js | 199 ----------------- .../actions/filters/brush_event.test.ts | 208 ++++++++++++++++++ .../public/actions/filters/brush_event.ts | 80 +++++++ .../public/actions/select_range_action.ts | 21 +- 5 files changed, 296 insertions(+), 283 deletions(-) delete mode 100644 src/legacy/core_plugins/data/public/actions/filters/brush_event.js delete mode 100644 src/legacy/core_plugins/data/public/actions/filters/brush_event.test.js create mode 100644 src/legacy/core_plugins/data/public/actions/filters/brush_event.test.ts create mode 100644 src/legacy/core_plugins/data/public/actions/filters/brush_event.ts diff --git a/src/legacy/core_plugins/data/public/actions/filters/brush_event.js b/src/legacy/core_plugins/data/public/actions/filters/brush_event.js deleted file mode 100644 index 67711bd4599a2d..00000000000000 --- a/src/legacy/core_plugins/data/public/actions/filters/brush_event.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import moment from 'moment'; -import { esFilters } from '../../../../../../plugins/data/public'; -import { deserializeAggConfig } from '../../search/expressions/utils'; - -export async function onBrushEvent(event, getIndexPatterns) { - const isNumber = event.data.ordered; - const isDate = isNumber && event.data.ordered.date; - - const xRaw = _.get(event.data, 'series[0].values[0].xRaw'); - if (!xRaw) return []; - const column = xRaw.table.columns[xRaw.column]; - if (!column) return []; - if (!column.meta) return []; - const indexPattern = await getIndexPatterns().get(column.meta.indexPatternId); - const aggConfig = deserializeAggConfig({ - ...column.meta, - indexPattern, - }); - const field = aggConfig.params.field; - if (!field) return []; - - if (event.range.length <= 1) return []; - - const min = event.range[0]; - const max = event.range[event.range.length - 1]; - if (min === max) return []; - - let range; - - if (isDate) { - range = { - gte: moment(min).toISOString(), - lt: moment(max).toISOString(), - format: 'strict_date_optional_time', - }; - } else { - range = { - gte: min, - lt: max, - }; - } - - const newFilter = esFilters.buildRangeFilter( - field, - range, - indexPattern, - event.data.xAxisFormatter - ); - - return [newFilter]; -} diff --git a/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.js b/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.js deleted file mode 100644 index 743f6caee4edd0..00000000000000 --- a/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.js +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import moment from 'moment'; -import expect from '@kbn/expect'; - -jest.mock('../../search/aggs', () => ({ - AggConfigs: function AggConfigs() { - return { - createAggConfig: ({ params }) => ({ - params, - getIndexPattern: () => ({ - timeFieldName: 'time', - }), - }), - }; - }, -})); - -import { onBrushEvent } from './brush_event'; - -describe('brushEvent', () => { - const DAY_IN_MS = 24 * 60 * 60 * 1000; - const JAN_01_2014 = 1388559600000; - - const aggConfigs = [ - { - params: {}, - getIndexPattern: () => ({ - timeFieldName: 'time', - }), - }, - ]; - - const baseEvent = { - data: { - fieldFormatter: _.constant({}), - series: [ - { - values: [ - { - xRaw: { - column: 0, - table: { - columns: [ - { - id: '1', - meta: { - type: 'histogram', - indexPatternId: 'indexPatternId', - aggConfigParams: aggConfigs[0].params, - }, - }, - ], - }, - }, - }, - ], - }, - ], - }, - }; - - beforeEach(() => { - baseEvent.data.indexPattern = { - id: 'logstash-*', - timeFieldName: 'time', - }; - }); - - test('should be a function', () => { - expect(onBrushEvent).to.be.a(Function); - }); - - test('ignores event when data.xAxisField not provided', async () => { - const event = _.cloneDeep(baseEvent); - const filters = await onBrushEvent(event, () => ({ - get: () => baseEvent.data.indexPattern, - })); - expect(filters.length).to.equal(0); - }); - - describe('handles an event when the x-axis field is a date field', () => { - describe('date field is index pattern timefield', () => { - let dateEvent; - const dateField = { - name: 'time', - type: 'date', - }; - - beforeEach(() => { - aggConfigs[0].params.field = dateField; - dateEvent = _.cloneDeep(baseEvent); - dateEvent.data.ordered = { date: true }; - }); - - test('by ignoring the event when range spans zero time', async () => { - const event = _.cloneDeep(dateEvent); - event.range = [JAN_01_2014, JAN_01_2014]; - const filters = await onBrushEvent(event, () => ({ - get: () => dateEvent.data.indexPattern, - })); - expect(filters.length).to.equal(0); - }); - - test('by updating the timefilter', async () => { - const event = _.cloneDeep(dateEvent); - event.range = [JAN_01_2014, JAN_01_2014 + DAY_IN_MS]; - const filters = await onBrushEvent(event, () => ({ - get: async () => dateEvent.data.indexPattern, - })); - expect(filters[0].range.time.gte).to.be(new Date(JAN_01_2014).toISOString()); - // Set to a baseline timezone for comparison. - expect(filters[0].range.time.lt).to.be(new Date(JAN_01_2014 + DAY_IN_MS).toISOString()); - }); - }); - - describe('date field is not index pattern timefield', () => { - let dateEvent; - const dateField = { - name: 'anotherTimeField', - type: 'date', - }; - - beforeEach(() => { - aggConfigs[0].params.field = dateField; - dateEvent = _.cloneDeep(baseEvent); - dateEvent.data.ordered = { date: true }; - }); - - test('creates a new range filter', async () => { - const event = _.cloneDeep(dateEvent); - const rangeBegin = JAN_01_2014; - const rangeEnd = rangeBegin + DAY_IN_MS; - event.range = [rangeBegin, rangeEnd]; - const filters = await onBrushEvent(event, () => ({ - get: () => dateEvent.data.indexPattern, - })); - expect(filters.length).to.equal(1); - expect(filters[0].range.anotherTimeField.gte).to.equal(moment(rangeBegin).toISOString()); - expect(filters[0].range.anotherTimeField.lt).to.equal(moment(rangeEnd).toISOString()); - expect(filters[0].range.anotherTimeField).to.have.property('format'); - expect(filters[0].range.anotherTimeField.format).to.equal('strict_date_optional_time'); - }); - }); - }); - - describe('handles an event when the x-axis field is a number', () => { - let numberEvent; - const numberField = { - name: 'numberField', - type: 'number', - }; - - beforeEach(() => { - aggConfigs[0].params.field = numberField; - numberEvent = _.cloneDeep(baseEvent); - numberEvent.data.ordered = { date: false }; - }); - - test('by ignoring the event when range does not span at least 2 values', async () => { - const event = _.cloneDeep(numberEvent); - event.range = [1]; - const filters = await onBrushEvent(event, () => ({ - get: () => numberEvent.data.indexPattern, - })); - expect(filters.length).to.equal(0); - }); - - test('by creating a new filter', async () => { - const event = _.cloneDeep(numberEvent); - event.range = [1, 2, 3, 4]; - const filters = await onBrushEvent(event, () => ({ - get: () => numberEvent.data.indexPattern, - })); - expect(filters.length).to.equal(1); - expect(filters[0].range.numberField.gte).to.equal(1); - expect(filters[0].range.numberField.lt).to.equal(4); - expect(filters[0].range.numberField).not.to.have.property('format'); - }); - }); -}); diff --git a/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.ts b/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.ts new file mode 100644 index 00000000000000..0e18c7c707fa3f --- /dev/null +++ b/src/legacy/core_plugins/data/public/actions/filters/brush_event.test.ts @@ -0,0 +1,208 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import moment from 'moment'; + +jest.mock('../../search/aggs', () => ({ + AggConfigs: function AggConfigs() { + return { + createAggConfig: ({ params }: Record) => ({ + params, + getIndexPattern: () => ({ + timeFieldName: 'time', + }), + }), + }; + }, +})); + +jest.mock('../../../../../../plugins/data/public/services', () => ({ + getIndexPatterns: () => { + return { + get: async () => { + return { + id: 'logstash-*', + timeFieldName: 'time', + }; + }, + }; + }, +})); + +import { onBrushEvent, BrushEvent } from './brush_event'; + +describe('brushEvent', () => { + const DAY_IN_MS = 24 * 60 * 60 * 1000; + const JAN_01_2014 = 1388559600000; + let baseEvent: BrushEvent; + + const aggConfigs = [ + { + params: { + field: {}, + }, + getIndexPattern: () => ({ + timeFieldName: 'time', + }), + }, + ]; + + beforeEach(() => { + baseEvent = { + data: { + ordered: { + date: false, + }, + series: [ + { + values: [ + { + xRaw: { + column: 0, + table: { + columns: [ + { + id: '1', + meta: { + type: 'histogram', + indexPatternId: 'indexPatternId', + aggConfigParams: aggConfigs[0].params, + }, + }, + ], + }, + }, + }, + ], + }, + ], + }, + range: [], + }; + }); + + test('should be a function', () => { + expect(typeof onBrushEvent).toBe('function'); + }); + + test('ignores event when data.xAxisField not provided', async () => { + const filter = await onBrushEvent(baseEvent); + expect(filter).toBeUndefined(); + }); + + describe('handles an event when the x-axis field is a date field', () => { + describe('date field is index pattern timefield', () => { + beforeEach(() => { + aggConfigs[0].params.field = { + name: 'time', + type: 'date', + }; + baseEvent.data.ordered = { date: true }; + }); + + afterAll(() => { + baseEvent.range = []; + baseEvent.data.ordered = { date: false }; + }); + + test('by ignoring the event when range spans zero time', async () => { + baseEvent.range = [JAN_01_2014, JAN_01_2014]; + const filter = await onBrushEvent(baseEvent); + expect(filter).toBeUndefined(); + }); + + test('by updating the timefilter', async () => { + baseEvent.range = [JAN_01_2014, JAN_01_2014 + DAY_IN_MS]; + const filter = await onBrushEvent(baseEvent); + expect(filter).toBeDefined(); + + if (filter) { + expect(filter.range.time.gte).toBe(new Date(JAN_01_2014).toISOString()); + // Set to a baseline timezone for comparison. + expect(filter.range.time.lt).toBe(new Date(JAN_01_2014 + DAY_IN_MS).toISOString()); + } + }); + }); + + describe('date field is not index pattern timefield', () => { + beforeEach(() => { + aggConfigs[0].params.field = { + name: 'anotherTimeField', + type: 'date', + }; + baseEvent.data.ordered = { date: true }; + }); + + afterAll(() => { + baseEvent.range = []; + baseEvent.data.ordered = { date: false }; + }); + + test('creates a new range filter', async () => { + const rangeBegin = JAN_01_2014; + const rangeEnd = rangeBegin + DAY_IN_MS; + baseEvent.range = [rangeBegin, rangeEnd]; + const filter = await onBrushEvent(baseEvent); + + expect(filter).toBeDefined(); + + if (filter) { + expect(filter.range.anotherTimeField.gte).toBe(moment(rangeBegin).toISOString()); + expect(filter.range.anotherTimeField.lt).toBe(moment(rangeEnd).toISOString()); + expect(filter.range.anotherTimeField).toHaveProperty( + 'format', + 'strict_date_optional_time' + ); + } + }); + }); + }); + + describe('handles an event when the x-axis field is a number', () => { + beforeAll(() => { + aggConfigs[0].params.field = { + name: 'numberField', + type: 'number', + }; + }); + + afterAll(() => { + baseEvent.range = []; + }); + + test('by ignoring the event when range does not span at least 2 values', async () => { + baseEvent.range = [1]; + const filter = await onBrushEvent(baseEvent); + expect(filter).toBeUndefined(); + }); + + test('by creating a new filter', async () => { + baseEvent.range = [1, 2, 3, 4]; + const filter = await onBrushEvent(baseEvent); + + expect(filter).toBeDefined(); + + if (filter) { + expect(filter.range.numberField.gte).toBe(1); + expect(filter.range.numberField.lt).toBe(4); + expect(filter.range.numberField).not.toHaveProperty('format'); + } + }); + }); +}); diff --git a/src/legacy/core_plugins/data/public/actions/filters/brush_event.ts b/src/legacy/core_plugins/data/public/actions/filters/brush_event.ts new file mode 100644 index 00000000000000..00990d21ccf378 --- /dev/null +++ b/src/legacy/core_plugins/data/public/actions/filters/brush_event.ts @@ -0,0 +1,80 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { get, last } from 'lodash'; +import moment from 'moment'; +import { esFilters, IFieldType, RangeFilterParams } from '../../../../../../plugins/data/public'; +import { deserializeAggConfig } from '../../search/expressions/utils'; +// should be removed after moving into new platform plugins data folder +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { getIndexPatterns } from '../../../../../../plugins/data/public/services'; + +export interface BrushEvent { + data: { + ordered: { + date: boolean; + }; + series: Array>; + }; + range: number[]; +} + +export async function onBrushEvent(event: BrushEvent) { + const isDate = get(event.data, 'ordered.date'); + const xRaw: Record = get(event.data, 'series[0].values[0].xRaw'); + + if (!xRaw) { + return; + } + + const column: Record = xRaw.table.columns[xRaw.column]; + + if (!column || !column.meta) { + return; + } + + const indexPattern = await getIndexPatterns().get(column.meta.indexPatternId); + const aggConfig = deserializeAggConfig({ + ...column.meta, + indexPattern, + }); + const field: IFieldType = aggConfig.params.field; + + if (!field || event.range.length <= 1) { + return; + } + + const min = event.range[0]; + const max = last(event.range); + + if (min === max) { + return; + } + + const range: RangeFilterParams = { + gte: isDate ? moment(min).toISOString() : min, + lt: isDate ? moment(max).toISOString() : max, + }; + + if (isDate) { + range.format = 'strict_date_optional_time'; + } + + return esFilters.buildRangeFilter(field, range, indexPattern); +} diff --git a/src/legacy/core_plugins/data/public/actions/select_range_action.ts b/src/legacy/core_plugins/data/public/actions/select_range_action.ts index 8d0b74be505352..7f1c5d78ab8006 100644 --- a/src/legacy/core_plugins/data/public/actions/select_range_action.ts +++ b/src/legacy/core_plugins/data/public/actions/select_range_action.ts @@ -23,16 +23,8 @@ import { createAction, IncompatibleActionError, } from '../../../../../plugins/ui_actions/public'; -// @ts-ignore import { onBrushEvent } from './filters/brush_event'; -import { - Filter, - FilterManager, - TimefilterContract, - esFilters, -} from '../../../../../plugins/data/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { getIndexPatterns } from '../../../../../plugins/data/public/services'; +import { FilterManager, TimefilterContract, esFilters } from '../../../../../plugins/data/public'; export const SELECT_RANGE_ACTION = 'SELECT_RANGE_ACTION'; @@ -43,8 +35,7 @@ interface ActionContext { async function isCompatible(context: ActionContext) { try { - const filters: Filter[] = (await onBrushEvent(context.data, getIndexPatterns)) || []; - return filters.length > 0; + return Boolean(await onBrushEvent(context.data)); } catch { return false; } @@ -68,9 +59,13 @@ export function selectRangeAction( throw new IncompatibleActionError(); } - const filters: Filter[] = (await onBrushEvent(data, getIndexPatterns)) || []; + const filter = await onBrushEvent(data); + + if (!filter) { + return; + } - const selectedFilters: Filter[] = esFilters.mapAndFlattenFilters(filters); + const selectedFilters = esFilters.mapAndFlattenFilters([filter]); if (timeFieldName) { const { timeRangeFilter, restOfFilters } = esFilters.extractTimeFilter( From 2ea4bdfe0dc61e303fa555a12788a3868e7510db Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Wed, 26 Feb 2020 07:14:08 -0600 Subject: [PATCH 69/73] Server-side license check for APM service map (#58547) * Factor our the license checking logic and messaging to common * Add licensing plugin as a dependency of the APM plugin * Throw a forbidden error on the server if trying to access the service map routes --- .../app/ServiceMap/PlatinumLicensePrompt.tsx | 18 ++++++------------ .../public/components/app/ServiceMap/index.tsx | 13 +++++++------ x-pack/plugins/apm/common/service_map.ts | 18 ++++++++++++++++++ x-pack/plugins/apm/kibana.json | 2 +- x-pack/plugins/apm/server/plugin.ts | 2 ++ .../plugins/apm/server/routes/service_map.ts | 17 ++++++++++++++--- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx index c5771995daa24e..9213349a1492bf 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/PlatinumLicensePrompt.tsx @@ -4,15 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; import { - EuiEmptyPrompt, EuiButton, - EuiPanel, + EuiEmptyPrompt, EuiFlexGroup, - EuiFlexItem + EuiFlexItem, + EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { invalidLicenseMessage } from '../../../../../../../plugins/apm/common/service_map'; import { useKibanaUrl } from '../../../hooks/useKibanaUrl'; export function PlatinumLicensePrompt() { @@ -43,14 +44,7 @@ export function PlatinumLicensePrompt() { )} ]} - body={ -

- {i18n.translate('xpack.apm.serviceMap.licensePromptBody', { - defaultMessage: - "In order to access Service Maps, you must be subscribed to an Elastic Platinum license. With it, you'll have the ability to visualize your entire application stack along with your APM data." - })} -

- } + body={

{invalidLicenseMessage}

} title={

{i18n.translate('xpack.apm.serviceMap.licensePromptTitle', { diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx index 5fea4be9ca0da5..b14ecaa803f6d4 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx @@ -17,12 +17,14 @@ import React, { useState } from 'react'; import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public'; +import { isValidPlatinumLicense } from '../../../../../../../plugins/apm/common/service_map'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ServiceMapAPIResponse } from '../../../../../../../plugins/apm/server/lib/service_map/get_service_map'; import { useApmPluginContext } from '../../../hooks/useApmPluginContext'; import { useCallApmApi } from '../../../hooks/useCallApmApi'; import { useDeepObjectIdentity } from '../../../hooks/useDeepObjectIdentity'; import { useLicense } from '../../../hooks/useLicense'; +import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator'; import { useLocation } from '../../../hooks/useLocation'; import { useUrlParams } from '../../../hooks/useUrlParams'; import { Controls } from './Controls'; @@ -31,7 +33,6 @@ import { getCytoscapeElements } from './get_cytoscape_elements'; import { PlatinumLicensePrompt } from './PlatinumLicensePrompt'; import { Popover } from './Popover'; import { useRefHeight } from './useRefHeight'; -import { useLoadingIndicator } from '../../../hooks/useLoadingIndicator'; interface ServiceMapProps { serviceName?: string; @@ -195,13 +196,13 @@ export function ServiceMap({ serviceName }: ServiceMapProps) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [elements]); - const isValidPlatinumLicense = - license?.isActive && - (license?.type === 'platinum' || license?.type === 'trial'); - const [wrapperRef, height] = useRefHeight(); - return isValidPlatinumLicense ? ( + if (!license) { + return null; + } + + return isValidPlatinumLicense(license) ? (
{ plugins: { apm_oss: APMOSSPlugin extends Plugin ? TSetup : never; home: HomeServerPluginSetup; + licensing: LicensingPluginSetup; cloud?: CloudSetup; usageCollection?: UsageCollectionSetup; } diff --git a/x-pack/plugins/apm/server/routes/service_map.ts b/x-pack/plugins/apm/server/routes/service_map.ts index 584598805f8b3d..bead0445d6ccce 100644 --- a/x-pack/plugins/apm/server/routes/service_map.ts +++ b/x-pack/plugins/apm/server/routes/service_map.ts @@ -4,13 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import * as t from 'io-ts'; import Boom from 'boom'; +import * as t from 'io-ts'; +import { + invalidLicenseMessage, + isValidPlatinumLicense +} from '../../common/service_map'; import { setupRequest } from '../lib/helpers/setup_request'; -import { createRoute } from './create_route'; -import { uiFiltersRt, rangeRt } from './default_api_types'; import { getServiceMap } from '../lib/service_map/get_service_map'; import { getServiceMapServiceNodeInfo } from '../lib/service_map/get_service_map_service_node_info'; +import { createRoute } from './create_route'; +import { rangeRt, uiFiltersRt } from './default_api_types'; export const serviceMapRoute = createRoute(() => ({ path: '/api/apm/service-map', @@ -26,6 +30,10 @@ export const serviceMapRoute = createRoute(() => ({ if (!context.config['xpack.apm.serviceMapEnabled']) { throw Boom.notFound(); } + if (!isValidPlatinumLicense(context.licensing.license)) { + throw Boom.forbidden(invalidLicenseMessage); + } + const setup = await setupRequest(context, request); const { query: { serviceName, environment, after } @@ -51,6 +59,9 @@ export const serviceMapServiceNodeRoute = createRoute(() => ({ if (!context.config['xpack.apm.serviceMapEnabled']) { throw Boom.notFound(); } + if (!isValidPlatinumLicense(context.licensing.license)) { + throw Boom.forbidden(invalidLicenseMessage); + } const setup = await setupRequest(context, request); const { From 3212754e62a73f75dd055d5c9e8eb1e43a5dec29 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 26 Feb 2020 07:50:11 -0700 Subject: [PATCH 70/73] [Maps] add Top term aggregation (#57875) * [Maps] add Top term aggregation * update pew-pew source to handle terms agg * make helper function for pulling values from bucket * update terms source * better join labels * categoricla meta * remove unused constant * remove unused changes * remove unused constant METRIC_SCHEMA_CONFIG * update jest expect * fix auto complete suggestions for top term * get category autocomplete working with style props from joins * pluck categorical style meta with real field name * mock MetricsEditor to fix jest test * review feedback * es_agg_utils.js to es_agg_utils.ts * typing updates * use composit agg to avoid search.buckets limit * i18n update and functional test fix * stop paging through results when request is aborted * remove unused file * do not use composite agg when no terms sub-aggregations * clean up * pass indexPattern to getValueAggsDsl * review feedback * more review feedback * ts-ignore for untyped imports in tests * more review feedback * add bucket.hasOwnProperty check Co-authored-by: Elastic Machine --- .../legacy/plugins/maps/common/constants.ts | 4 +- .../maps/public/actions/map_actions.js | 22 +- .../maps/public/components/metric_editor.js | 13 +- .../maps/public/components/metric_select.js | 20 +- .../maps/public/components/metrics_editor.js | 4 +- .../resources/metrics_expression.js | 8 +- .../resources/metrics_expression.test.js | 6 + .../connected_components/map/mb/view.js | 15 +- .../maps/public/elasticsearch_geo_utils.js | 18 ++ .../maps/public/layers/fields/es_agg_field.js | 33 ++- .../public/layers/fields/es_agg_field.test.js | 14 +- .../public/layers/sources/es_agg_source.js | 38 ++-- .../es_geo_grid_source/convert_to_geojson.js | 89 ++++---- .../convert_to_geojson.test.ts | 159 ++++++++++++++ .../es_geo_grid_source/es_geo_grid_source.js | 201 ++++++++++++++---- .../es_geo_grid_source/geo_tile_utils.js | 3 +- .../es_geo_grid_source/geo_tile_utils.test.js | 2 + .../es_pew_pew_source/convert_to_lines.js | 19 +- .../convert_to_lines.test.ts | 68 ++++++ .../es_pew_pew_source/es_pew_pew_source.js | 8 +- .../es_search_source/es_search_source.js | 26 +-- .../maps/public/layers/sources/es_source.js | 11 +- .../public/layers/sources/es_term_source.js | 91 +++----- .../layers/sources/es_term_source.test.js | 91 +------- .../properties/dynamic_size_property.js | 12 +- .../properties/dynamic_style_property.js | 27 ++- .../layers/styles/vector/vector_style.js | 10 +- .../tooltips/es_aggmetric_tooltip_property.js | 6 +- .../public/layers/util/es_agg_utils.test.ts | 37 ++++ .../maps/public/layers/util/es_agg_utils.ts | 51 +++++ .../public/layers/util/is_metric_countable.js | 4 +- .../maps/public/layers/vector_layer.js | 15 +- .../maps/public/selectors/map_selectors.js | 15 ++ .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 35 files changed, 726 insertions(+), 416 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts create mode 100644 x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts create mode 100644 x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts diff --git a/x-pack/legacy/plugins/maps/common/constants.ts b/x-pack/legacy/plugins/maps/common/constants.ts index ab9a696fa3a177..542abfb004d0d6 100644 --- a/x-pack/legacy/plugins/maps/common/constants.ts +++ b/x-pack/legacy/plugins/maps/common/constants.ts @@ -117,16 +117,16 @@ export const DRAW_TYPE = { POLYGON: 'POLYGON', }; -export const METRIC_TYPE = { +export const AGG_TYPE = { AVG: 'avg', COUNT: 'count', MAX: 'max', MIN: 'min', SUM: 'sum', + TERMS: 'terms', UNIQUE_COUNT: 'cardinality', }; -export const COUNT_AGG_TYPE = METRIC_TYPE.COUNT; export const COUNT_PROP_LABEL = i18n.translate('xpack.maps.aggs.defaultCountLabel', { defaultMessage: 'count', }); diff --git a/x-pack/legacy/plugins/maps/public/actions/map_actions.js b/x-pack/legacy/plugins/maps/public/actions/map_actions.js index 2c6c60db9a0124..cfca044ea759a1 100644 --- a/x-pack/legacy/plugins/maps/public/actions/map_actions.js +++ b/x-pack/legacy/plugins/maps/public/actions/map_actions.js @@ -18,6 +18,7 @@ import { getTransientLayerId, getOpenTooltips, getQuery, + getDataRequestDescriptor, } from '../selectors/map_selectors'; import { FLYOUT_STATE } from '../reducers/ui'; import { @@ -76,7 +77,7 @@ export const HIDE_LAYER_CONTROL = 'HIDE_LAYER_CONTROL'; export const HIDE_VIEW_CONTROL = 'HIDE_VIEW_CONTROL'; export const SET_WAITING_FOR_READY_HIDDEN_LAYERS = 'SET_WAITING_FOR_READY_HIDDEN_LAYERS'; -function getLayerLoadingCallbacks(dispatch, layerId) { +function getLayerLoadingCallbacks(dispatch, getState, layerId) { return { startLoading: (dataId, requestToken, meta) => dispatch(startDataLoad(layerId, dataId, requestToken, meta)), @@ -87,6 +88,13 @@ function getLayerLoadingCallbacks(dispatch, layerId) { updateSourceData: newData => { dispatch(updateSourceDataRequest(layerId, newData)); }, + isRequestStillActive: (dataId, requestToken) => { + const dataRequest = getDataRequestDescriptor(getState(), layerId, dataId); + if (!dataRequest) { + return false; + } + return dataRequest.dataRequestToken === requestToken; + }, registerCancelCallback: (requestToken, callback) => dispatch(registerCancelCallback(requestToken, callback)), }; @@ -98,11 +106,11 @@ function getLayerById(layerId, state) { }); } -async function syncDataForAllLayers(getState, dispatch, dataFilters) { +async function syncDataForAllLayers(dispatch, getState, dataFilters) { const state = getState(); const layerList = getLayerList(state); const syncs = layerList.map(layer => { - const loadingFunctions = getLayerLoadingCallbacks(dispatch, layer.getId()); + const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layer.getId()); return layer.syncData({ ...loadingFunctions, dataFilters }); }); await Promise.all(syncs); @@ -412,7 +420,7 @@ export function mapExtentChanged(newMapConstants) { }, }); const newDataFilters = { ...dataFilters, ...newMapConstants }; - await syncDataForAllLayers(getState, dispatch, newDataFilters); + await syncDataForAllLayers(dispatch, getState, newDataFilters); }; } @@ -653,7 +661,7 @@ export function syncDataForLayer(layerId) { const targetLayer = getLayerById(layerId, getState()); if (targetLayer) { const dataFilters = getDataFilters(getState()); - const loadingFunctions = getLayerLoadingCallbacks(dispatch, layerId); + const loadingFunctions = getLayerLoadingCallbacks(dispatch, getState, layerId); await targetLayer.syncData({ ...loadingFunctions, dataFilters, @@ -773,7 +781,7 @@ export function setQuery({ query, timeFilters, filters = [], refresh = false }) }); const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(getState, dispatch, dataFilters); + await syncDataForAllLayers(dispatch, getState, dataFilters); }; } @@ -792,7 +800,7 @@ export function triggerRefreshTimer() { }); const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(getState, dispatch, dataFilters); + await syncDataForAllLayers(dispatch, getState, dataFilters); }; } diff --git a/x-pack/legacy/plugins/maps/public/components/metric_editor.js b/x-pack/legacy/plugins/maps/public/components/metric_editor.js index e60c2ac0dd7ab5..530f402592b2ba 100644 --- a/x-pack/legacy/plugins/maps/public/components/metric_editor.js +++ b/x-pack/legacy/plugins/maps/public/components/metric_editor.js @@ -12,17 +12,16 @@ import { EuiFieldText, EuiFormRow } from '@elastic/eui'; import { MetricSelect, METRIC_AGGREGATION_VALUES } from './metric_select'; import { SingleFieldSelect } from './single_field_select'; -import { METRIC_TYPE } from '../../common/constants'; +import { AGG_TYPE } from '../../common/constants'; +import { getTermsFields } from '../index_pattern_util'; function filterFieldsForAgg(fields, aggType) { if (!fields) { return []; } - if (aggType === METRIC_TYPE.UNIQUE_COUNT) { - return fields.filter(field => { - return field.aggregatable; - }); + if (aggType === AGG_TYPE.UNIQUE_COUNT || aggType === AGG_TYPE.TERMS) { + return getTermsFields(fields); } return fields.filter(field => { @@ -38,7 +37,7 @@ export function MetricEditor({ fields, metricsFilter, metric, onChange, removeBu }; // unset field when new agg type does not support currently selected field. - if (metric.field && metricAggregationType !== METRIC_TYPE.COUNT) { + if (metric.field && metricAggregationType !== AGG_TYPE.COUNT) { const fieldsForNewAggType = filterFieldsForAgg(fields, metricAggregationType); const found = fieldsForNewAggType.find(field => { return field.name === metric.field; @@ -64,7 +63,7 @@ export function MetricEditor({ fields, metricsFilter, metric, onChange, removeBu }; let fieldSelect; - if (metric.type && metric.type !== METRIC_TYPE.COUNT) { + if (metric.type && metric.type !== AGG_TYPE.COUNT) { fieldSelect = ( { - if (type === METRIC_TYPE.COUNT) { + if (type === AGG_TYPE.COUNT) { return true; } @@ -70,7 +70,7 @@ export class MetricsExpression extends Component { }) .map(({ type, field }) => { // do not use metric label so field and aggregation are not obscured. - if (type === METRIC_TYPE.COUNT) { + if (type === AGG_TYPE.COUNT) { return 'count'; } @@ -130,5 +130,5 @@ MetricsExpression.propTypes = { }; MetricsExpression.defaultProps = { - metrics: [{ type: METRIC_TYPE.COUNT }], + metrics: [{ type: AGG_TYPE.COUNT }], }; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js index e0e1556ecde068..e4e3776c8e92ca 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/join_editor/resources/metrics_expression.test.js @@ -4,6 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ +jest.mock('../../../../components/metrics_editor', () => ({ + MetricsEditor: () => { + return
mockMetricsEditor
; + }, +})); + import React from 'react'; import { shallow } from 'enzyme'; import { MetricsExpression } from './metrics_expression'; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index 1e44c7225a564c..fdc8ad2176d085 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -23,6 +23,7 @@ import sprites1 from '@elastic/maki/dist/sprite@1.png'; import sprites2 from '@elastic/maki/dist/sprite@2.png'; import { DrawControl } from './draw_control'; import { TooltipControl } from './tooltip_control'; +import { clampToLatBounds, clampToLonBounds } from '../../../elasticsearch_geo_utils'; mapboxgl.workerUrl = mbWorkerUrl; mapboxgl.setRTLTextPlugin(mbRtlPlugin); @@ -234,12 +235,12 @@ export class MBMapContainer extends React.Component { //clamping ot -89/89 latitudes since Mapboxgl does not seem to handle bounds that contain the poles (logs errors to the console when using -90/90) const lnLatBounds = new mapboxgl.LngLatBounds( new mapboxgl.LngLat( - clamp(goto.bounds.min_lon, -180, 180), - clamp(goto.bounds.min_lat, -89, 89) + clampToLonBounds(goto.bounds.min_lon), + clampToLatBounds(goto.bounds.min_lat) ), new mapboxgl.LngLat( - clamp(goto.bounds.max_lon, -180, 180), - clamp(goto.bounds.max_lat, -89, 89) + clampToLonBounds(goto.bounds.max_lon), + clampToLatBounds(goto.bounds.max_lat) ) ); //maxZoom ensure we're not zooming in too far on single points or small shapes @@ -306,9 +307,3 @@ export class MBMapContainer extends React.Component { ); } } - -function clamp(val, min, max) { - if (val > max) val = max; - else if (val < min) val = min; - return val; -} diff --git a/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js b/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js index ec0ae4161b3f2c..9b33d3036785c9 100644 --- a/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js +++ b/x-pack/legacy/plugins/maps/public/elasticsearch_geo_utils.js @@ -433,3 +433,21 @@ export function convertMapExtentToPolygon({ maxLat, maxLon, minLat, minLon }) { return formatEnvelopeAsPolygon({ maxLat, maxLon, minLat, minLon }); } + +export function clampToLatBounds(lat) { + return clamp(lat, -89, 89); +} + +export function clampToLonBounds(lon) { + return clamp(lon, -180, 180); +} + +export function clamp(val, min, max) { + if (val > max) { + return max; + } else if (val < min) { + return min; + } else { + return val; + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js index 65109cb99809fc..28c199b64d3ef4 100644 --- a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js +++ b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js @@ -5,9 +5,10 @@ */ import { AbstractField } from './field'; -import { COUNT_AGG_TYPE } from '../../../common/constants'; +import { AGG_TYPE } from '../../../common/constants'; import { isMetricCountable } from '../util/is_metric_countable'; import { ESAggMetricTooltipProperty } from '../tooltips/es_aggmetric_tooltip_property'; +import { getField, addFieldToDSL } from '../util/es_agg_utils'; export class ESAggMetricField extends AbstractField { static type = 'ES_AGG'; @@ -34,12 +35,11 @@ export class ESAggMetricField extends AbstractField { } isValid() { - return this.getAggType() === COUNT_AGG_TYPE ? true : !!this._esDocField; + return this.getAggType() === AGG_TYPE.COUNT ? true : !!this._esDocField; } async getDataType() { - // aggregations only provide numerical data - return 'number'; + return this.getAggType() === AGG_TYPE.TERMS ? 'string' : 'number'; } getESDocFieldName() { @@ -47,9 +47,9 @@ export class ESAggMetricField extends AbstractField { } getRequestDescription() { - return this.getAggType() !== COUNT_AGG_TYPE + return this.getAggType() !== AGG_TYPE.COUNT ? `${this.getAggType()} ${this.getESDocFieldName()}` - : COUNT_AGG_TYPE; + : AGG_TYPE.COUNT; } async createTooltipProperty(value) { @@ -63,18 +63,13 @@ export class ESAggMetricField extends AbstractField { ); } - makeMetricAggConfig() { - const metricAggConfig = { - id: this.getName(), - enabled: true, - type: this.getAggType(), - schema: 'metric', - params: {}, + getValueAggDsl(indexPattern) { + const field = getField(indexPattern, this.getESDocFieldName()); + const aggType = this.getAggType(); + const aggBody = aggType === AGG_TYPE.TERMS ? { size: 1, shard_size: 1 } : {}; + return { + [aggType]: addFieldToDSL(aggBody, field), }; - if (this.getAggType() !== COUNT_AGG_TYPE) { - metricAggConfig.params = { field: this.getESDocFieldName() }; - } - return metricAggConfig; } supportsFieldMeta() { @@ -85,4 +80,8 @@ export class ESAggMetricField extends AbstractField { async getOrdinalFieldMetaRequest(config) { return this._esDocField.getOrdinalFieldMetaRequest(config); } + + async getCategoricalFieldMetaRequest() { + return this._esDocField.getCategoricalFieldMetaRequest(); + } } diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.js b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.js index 2f18987513d925..aeeffd63607eeb 100644 --- a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.js +++ b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.test.js @@ -5,24 +5,24 @@ */ import { ESAggMetricField } from './es_agg_field'; -import { METRIC_TYPE } from '../../../common/constants'; +import { AGG_TYPE } from '../../../common/constants'; describe('supportsFieldMeta', () => { test('Non-counting aggregations should support field meta', () => { - const avgMetric = new ESAggMetricField({ aggType: METRIC_TYPE.AVG }); + const avgMetric = new ESAggMetricField({ aggType: AGG_TYPE.AVG }); expect(avgMetric.supportsFieldMeta()).toBe(true); - const maxMetric = new ESAggMetricField({ aggType: METRIC_TYPE.MAX }); + const maxMetric = new ESAggMetricField({ aggType: AGG_TYPE.MAX }); expect(maxMetric.supportsFieldMeta()).toBe(true); - const minMetric = new ESAggMetricField({ aggType: METRIC_TYPE.MIN }); + const minMetric = new ESAggMetricField({ aggType: AGG_TYPE.MIN }); expect(minMetric.supportsFieldMeta()).toBe(true); }); test('Counting aggregations should not support field meta', () => { - const countMetric = new ESAggMetricField({ aggType: METRIC_TYPE.COUNT }); + const countMetric = new ESAggMetricField({ aggType: AGG_TYPE.COUNT }); expect(countMetric.supportsFieldMeta()).toBe(false); - const sumMetric = new ESAggMetricField({ aggType: METRIC_TYPE.SUM }); + const sumMetric = new ESAggMetricField({ aggType: AGG_TYPE.SUM }); expect(sumMetric.supportsFieldMeta()).toBe(false); - const uniqueCountMetric = new ESAggMetricField({ aggType: METRIC_TYPE.UNIQUE_COUNT }); + const uniqueCountMetric = new ESAggMetricField({ aggType: AGG_TYPE.UNIQUE_COUNT }); expect(uniqueCountMetric.supportsFieldMeta()).toBe(false); }); }); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js index 967a3c41aec269..bee35216f59dab 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js @@ -8,8 +8,7 @@ import { AbstractESSource } from './es_source'; import { ESAggMetricField } from '../fields/es_agg_field'; import { ESDocField } from '../fields/es_doc_field'; import { - METRIC_TYPE, - COUNT_AGG_TYPE, + AGG_TYPE, COUNT_PROP_LABEL, COUNT_PROP_NAME, FIELD_ORIGIN, @@ -18,23 +17,6 @@ import { export const AGG_DELIMITER = '_of_'; export class AbstractESAggSource extends AbstractESSource { - static METRIC_SCHEMA_CONFIG = { - group: 'metrics', - name: 'metric', - title: 'Value', - min: 1, - max: Infinity, - aggFilter: [ - METRIC_TYPE.AVG, - METRIC_TYPE.COUNT, - METRIC_TYPE.MAX, - METRIC_TYPE.MIN, - METRIC_TYPE.SUM, - METRIC_TYPE.UNIQUE_COUNT, - ], - defaults: [{ schema: 'metric', type: METRIC_TYPE.COUNT }], - }; - constructor(descriptor, inspectorAdapters) { super(descriptor, inspectorAdapters); this._metricFields = this._descriptor.metrics @@ -81,7 +63,7 @@ export class AbstractESAggSource extends AbstractESSource { if (metrics.length === 0) { metrics.push( new ESAggMetricField({ - aggType: COUNT_AGG_TYPE, + aggType: AGG_TYPE.COUNT, source: this, origin: this.getOriginForField(), }) @@ -91,15 +73,23 @@ export class AbstractESAggSource extends AbstractESSource { } formatMetricKey(aggType, fieldName) { - return aggType !== COUNT_AGG_TYPE ? `${aggType}${AGG_DELIMITER}${fieldName}` : COUNT_PROP_NAME; + return aggType !== AGG_TYPE.COUNT ? `${aggType}${AGG_DELIMITER}${fieldName}` : COUNT_PROP_NAME; } formatMetricLabel(aggType, fieldName) { - return aggType !== COUNT_AGG_TYPE ? `${aggType} of ${fieldName}` : COUNT_PROP_LABEL; + return aggType !== AGG_TYPE.COUNT ? `${aggType} of ${fieldName}` : COUNT_PROP_LABEL; } - createMetricAggConfigs() { - return this.getMetricFields().map(esAggMetric => esAggMetric.makeMetricAggConfig()); + getValueAggsDsl(indexPattern) { + const valueAggsDsl = {}; + this.getMetricFields() + .filter(esAggMetric => { + return esAggMetric.getAggType() !== AGG_TYPE.COUNT; + }) + .forEach(esAggMetric => { + valueAggsDsl[esAggMetric.getName()] = esAggMetric.getValueAggDsl(indexPattern); + }); + return valueAggsDsl; } async getNumberFields() { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js index 4e15d1c927c364..bb9bf1b508f941 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.js @@ -4,68 +4,63 @@ * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; import { RENDER_AS } from './render_as'; import { getTileBoundingBox } from './geo_tile_utils'; -import { EMPTY_FEATURE_COLLECTION } from '../../../../common/constants'; +import { extractPropertiesFromBucket } from '../../util/es_agg_utils'; +import { clamp } from '../../../elasticsearch_geo_utils'; -export function convertToGeoJson({ table, renderAs }) { - if (!table || !table.rows) { - return EMPTY_FEATURE_COLLECTION; - } +const GRID_BUCKET_KEYS_TO_IGNORE = ['key', 'gridCentroid']; - const geoGridColumn = table.columns.find( - column => column.aggConfig.type.dslName === 'geotile_grid' +export function convertCompositeRespToGeoJson(esResponse, renderAs) { + return convertToGeoJson( + esResponse, + renderAs, + esResponse => { + return _.get(esResponse, 'aggregations.compositeSplit.buckets', []); + }, + gridBucket => { + return gridBucket.key.gridSplit; + } ); - if (!geoGridColumn) { - return EMPTY_FEATURE_COLLECTION; - } +} - const metricColumns = table.columns.filter(column => { - return ( - column.aggConfig.type.type === 'metrics' && column.aggConfig.type.dslName !== 'geo_centroid' - ); - }); - const geocentroidColumn = table.columns.find( - column => column.aggConfig.type.dslName === 'geo_centroid' +export function convertRegularRespToGeoJson(esResponse, renderAs) { + return convertToGeoJson( + esResponse, + renderAs, + esResponse => { + return _.get(esResponse, 'aggregations.gridSplit.buckets', []); + }, + gridBucket => { + return gridBucket.key; + } ); - if (!geocentroidColumn) { - return EMPTY_FEATURE_COLLECTION; - } +} +function convertToGeoJson(esResponse, renderAs, pluckGridBuckets, pluckGridKey) { const features = []; - table.rows.forEach(row => { - const gridKey = row[geoGridColumn.id]; - if (!gridKey) { - return; - } - - const properties = {}; - metricColumns.forEach(metricColumn => { - properties[metricColumn.aggConfig.id] = row[metricColumn.id]; - }); + const gridBuckets = pluckGridBuckets(esResponse); + for (let i = 0; i < gridBuckets.length; i++) { + const gridBucket = gridBuckets[i]; + const gridKey = pluckGridKey(gridBucket); features.push({ type: 'Feature', geometry: rowToGeometry({ - row, gridKey, - geocentroidColumn, + gridCentroid: gridBucket.gridCentroid, renderAs, }), id: gridKey, - properties, + properties: extractPropertiesFromBucket(gridBucket, GRID_BUCKET_KEYS_TO_IGNORE), }); - }); + } - return { - featureCollection: { - type: 'FeatureCollection', - features: features, - }, - }; + return features; } -function rowToGeometry({ row, gridKey, geocentroidColumn, renderAs }) { +function rowToGeometry({ gridKey, gridCentroid, renderAs }) { const { top, bottom, right, left } = getTileBoundingBox(gridKey); if (renderAs === RENDER_AS.GRID) { @@ -83,10 +78,10 @@ function rowToGeometry({ row, gridKey, geocentroidColumn, renderAs }) { }; } - // see https://github.com/elastic/elasticsearch/issues/24694 for why clampGrid is used + // see https://github.com/elastic/elasticsearch/issues/24694 for why clamp is used const pointCoordinates = [ - clampGrid(row[geocentroidColumn.id].lon, left, right), - clampGrid(row[geocentroidColumn.id].lat, bottom, top), + clamp(gridCentroid.location.lon, left, right), + clamp(gridCentroid.location.lat, bottom, top), ]; return { @@ -94,9 +89,3 @@ function rowToGeometry({ row, gridKey, geocentroidColumn, renderAs }) { coordinates: pointCoordinates, }; } - -function clampGrid(val, min, max) { - if (val > max) val = max; - else if (val < min) val = min; - return val; -} diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts new file mode 100644 index 00000000000000..ba79464a01a9bf --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/convert_to_geojson.test.ts @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +jest.mock('../../../kibana_services', () => {}); + +// @ts-ignore +import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson'; +// @ts-ignore +import { RENDER_AS } from './render_as'; + +describe('convertCompositeRespToGeoJson', () => { + const esResponse = { + aggregations: { + compositeSplit: { + after_key: { + gridSplit: '10/327/460', + }, + buckets: [ + { + key: { gridSplit: '4/4/6' }, + doc_count: 65, + avg_of_bytes: { value: 5359.2307692307695 }, + 'terms_of_machine.os.keyword': { + buckets: [ + { + key: 'win xp', + doc_count: 16, + }, + ], + }, + gridCentroid: { + location: { lat: 36.62813963153614, lon: -81.94552666092149 }, + count: 65, + }, + }, + ], + }, + }, + }; + + it('Should convert elasticsearch aggregation response into feature collection of points', () => { + const features = convertCompositeRespToGeoJson(esResponse, RENDER_AS.POINT); + expect(features.length).toBe(1); + expect(features[0]).toEqual({ + geometry: { + coordinates: [-81.94552666092149, 36.62813963153614], + type: 'Point', + }, + id: '4/4/6', + properties: { + avg_of_bytes: 5359.2307692307695, + doc_count: 65, + 'terms_of_machine.os.keyword': 'win xp', + }, + type: 'Feature', + }); + }); + + it('Should convert elasticsearch aggregation response into feature collection of Polygons', () => { + const features = convertCompositeRespToGeoJson(esResponse, RENDER_AS.GRID); + expect(features.length).toBe(1); + expect(features[0]).toEqual({ + geometry: { + coordinates: [ + [ + [-67.5, 40.9799], + [-90, 40.9799], + [-90, 21.94305], + [-67.5, 21.94305], + [-67.5, 40.9799], + ], + ], + type: 'Polygon', + }, + id: '4/4/6', + properties: { + avg_of_bytes: 5359.2307692307695, + doc_count: 65, + 'terms_of_machine.os.keyword': 'win xp', + }, + type: 'Feature', + }); + }); +}); + +describe('convertRegularRespToGeoJson', () => { + const esResponse = { + aggregations: { + gridSplit: { + buckets: [ + { + key: '4/4/6', + doc_count: 65, + avg_of_bytes: { value: 5359.2307692307695 }, + 'terms_of_machine.os.keyword': { + buckets: [ + { + key: 'win xp', + doc_count: 16, + }, + ], + }, + gridCentroid: { + location: { lat: 36.62813963153614, lon: -81.94552666092149 }, + count: 65, + }, + }, + ], + }, + }, + }; + + it('Should convert elasticsearch aggregation response into feature collection of points', () => { + const features = convertRegularRespToGeoJson(esResponse, RENDER_AS.POINT); + expect(features.length).toBe(1); + expect(features[0]).toEqual({ + geometry: { + coordinates: [-81.94552666092149, 36.62813963153614], + type: 'Point', + }, + id: '4/4/6', + properties: { + avg_of_bytes: 5359.2307692307695, + doc_count: 65, + 'terms_of_machine.os.keyword': 'win xp', + }, + type: 'Feature', + }); + }); + + it('Should convert elasticsearch aggregation response into feature collection of Polygons', () => { + const features = convertRegularRespToGeoJson(esResponse, RENDER_AS.GRID); + expect(features.length).toBe(1); + expect(features[0]).toEqual({ + geometry: { + coordinates: [ + [ + [-67.5, 40.9799], + [-90, 40.9799], + [-90, 21.94305], + [-67.5, 21.94305], + [-67.5, 40.9799], + ], + ], + type: 'Polygon', + }, + id: '4/4/6', + properties: { + avg_of_bytes: 5359.2307692307695, + doc_count: 65, + 'terms_of_machine.os.keyword': 'win xp', + }, + type: 'Feature', + }); + }); +}); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js index 0912e5a9f1283d..a0ddf584bcebc1 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -10,9 +10,7 @@ import uuid from 'uuid/v4'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; import { HeatmapLayer } from '../../heatmap_layer'; import { VectorLayer } from '../../vector_layer'; -import { AggConfigs, Schemas } from 'ui/agg_types'; -import { tabifyAggResponse } from '../../../../../../../../src/legacy/core_plugins/data/public'; -import { convertToGeoJson } from './convert_to_geojson'; +import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson'; import { VectorStyle } from '../../styles/vector/vector_style'; import { getDefaultDynamicProperties, @@ -24,6 +22,8 @@ import { CreateSourceEditor } from './create_source_editor'; import { UpdateSourceEditor } from './update_source_editor'; import { GRID_RESOLUTION } from '../../grid_resolution'; import { + AGG_TYPE, + DEFAULT_MAX_BUCKETS_LIMIT, SOURCE_DATA_ID_ORIGIN, ES_GEO_GRID, COUNT_PROP_NAME, @@ -34,21 +34,10 @@ import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { AbstractESAggSource } from '../es_agg_source'; import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property'; import { StaticStyleProperty } from '../../styles/vector/properties/static_style_property'; +import { DataRequestAbortError } from '../../util/data_request'; const MAX_GEOTILE_LEVEL = 29; -const aggSchemas = new Schemas([ - AbstractESAggSource.METRIC_SCHEMA_CONFIG, - { - group: 'buckets', - name: 'segment', - title: 'Geo Grid', - aggFilter: 'geotile_grid', - min: 1, - max: 1, - }, -]); - export class ESGeoGridSource extends AbstractESAggSource { static type = ES_GEO_GRID; static title = i18n.translate('xpack.maps.source.esGridTitle', { @@ -175,15 +164,120 @@ export class ESGeoGridSource extends AbstractESAggSource { ); } - async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { - const indexPattern = await this.getIndexPattern(); - const searchSource = await this._makeSearchSource(searchFilters, 0); - const aggConfigs = new AggConfigs( - indexPattern, - this._makeAggConfigs(searchFilters.geogridPrecision), - aggSchemas.all - ); - searchSource.setField('aggs', aggConfigs.toDsl()); + async _compositeAggRequest({ + searchSource, + indexPattern, + precision, + layerName, + registerCancelCallback, + bucketsPerGrid, + isRequestStillActive, + }) { + const gridsPerRequest = Math.floor(DEFAULT_MAX_BUCKETS_LIMIT / bucketsPerGrid); + const aggs = { + compositeSplit: { + composite: { + size: gridsPerRequest, + sources: [ + { + gridSplit: { + geotile_grid: { + field: this._descriptor.geoField, + precision, + }, + }, + }, + ], + }, + aggs: { + gridCentroid: { + geo_centroid: { + field: this._descriptor.geoField, + }, + }, + ...this.getValueAggsDsl(indexPattern), + }, + }, + }; + + const features = []; + let requestCount = 0; + let afterKey = null; + while (true) { + if (!isRequestStillActive()) { + // Stop paging through results if request is obsolete + throw new DataRequestAbortError(); + } + + requestCount++; + + // circuit breaker to ensure reasonable number of requests + if (requestCount > 5) { + throw new Error( + i18n.translate('xpack.maps.source.esGrid.compositePaginationErrorMessage', { + defaultMessage: `{layerName} is causing too many requests. Reduce "Grid resolution" and/or reduce the number of top term "Metrics".`, + values: { layerName }, + }) + ); + } + + if (afterKey) { + aggs.compositeSplit.composite.after = afterKey; + } + searchSource.setField('aggs', aggs); + const requestId = afterKey ? `${this.getId()} afterKey ${afterKey.geoSplit}` : this.getId(); + const esResponse = await this._runEsQuery({ + requestId, + requestName: `${layerName} (${requestCount})`, + searchSource, + registerCancelCallback, + requestDescription: i18n.translate( + 'xpack.maps.source.esGrid.compositeInspectorDescription', + { + defaultMessage: 'Elasticsearch geo grid aggregation request: {requestId}', + values: { requestId }, + } + ), + }); + + features.push(...convertCompositeRespToGeoJson(esResponse, this._descriptor.requestType)); + + afterKey = esResponse.aggregations.compositeSplit.after_key; + if (esResponse.aggregations.compositeSplit.buckets.length < gridsPerRequest) { + // Finished because request did not get full resultset back + break; + } + } + + return features; + } + + // Do not use composite aggregation when there are no terms sub-aggregations + // see https://github.com/elastic/kibana/pull/57875#issuecomment-590515482 for explanation on using separate code paths + async _nonCompositeAggRequest({ + searchSource, + indexPattern, + precision, + layerName, + registerCancelCallback, + }) { + searchSource.setField('aggs', { + gridSplit: { + geotile_grid: { + field: this._descriptor.geoField, + precision, + }, + aggs: { + gridCentroid: { + geo_centroid: { + field: this._descriptor.geoField, + }, + }, + ...this.getValueAggsDsl(indexPattern), + }, + }, + }); + const esResponse = await this._runEsQuery({ requestId: this.getId(), requestName: layerName, @@ -194,14 +288,45 @@ export class ESGeoGridSource extends AbstractESAggSource { }), }); - const tabifiedResp = tabifyAggResponse(aggConfigs, esResponse); - const { featureCollection } = convertToGeoJson({ - table: tabifiedResp, - renderAs: this._descriptor.requestType, + return convertRegularRespToGeoJson(esResponse, this._descriptor.requestType); + } + + async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback, isRequestStillActive) { + const indexPattern = await this.getIndexPattern(); + const searchSource = await this._makeSearchSource(searchFilters, 0); + + let bucketsPerGrid = 1; + this.getMetricFields().forEach(metricField => { + if (metricField.getAggType() === AGG_TYPE.TERMS) { + // each terms aggregation increases the overall number of buckets per grid + bucketsPerGrid++; + } }); + const features = + bucketsPerGrid === 1 + ? await this._nonCompositeAggRequest({ + searchSource, + indexPattern, + precision: searchFilters.geogridPrecision, + layerName, + registerCancelCallback, + }) + : await this._compositeAggRequest({ + searchSource, + indexPattern, + precision: searchFilters.geogridPrecision, + layerName, + registerCancelCallback, + bucketsPerGrid, + isRequestStillActive, + }); + return { - data: featureCollection, + data: { + type: 'FeatureCollection', + features: features, + }, meta: { areResultsTrimmed: false, }, @@ -212,24 +337,6 @@ export class ESGeoGridSource extends AbstractESAggSource { return true; } - _makeAggConfigs(precision) { - const metricAggConfigs = this.createMetricAggConfigs(); - return [ - ...metricAggConfigs, - { - id: 'grid', - enabled: true, - type: 'geotile_grid', - schema: 'segment', - params: { - field: this._descriptor.geoField, - useGeocentroid: true, - precision: precision, - }, - }, - ]; - } - _createHeatmapLayerDescriptor(options) { return HeatmapLayer.createDescriptor({ sourceDescriptor: this._descriptor, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js index da0bc1685f2237..251e33b9579cbc 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.js @@ -6,6 +6,7 @@ import _ from 'lodash'; import { DECIMAL_DEGREES_PRECISION } from '../../../../common/constants'; +import { clampToLatBounds } from '../../../elasticsearch_geo_utils'; const ZOOM_TILE_KEY_INDEX = 0; const X_TILE_KEY_INDEX = 1; @@ -87,7 +88,7 @@ function sec(value) { } function latitudeToTile(lat, tileCount) { - const radians = (lat * Math.PI) / 180; + const radians = (clampToLatBounds(lat) * Math.PI) / 180; const y = ((1 - Math.log(Math.tan(radians) + sec(radians)) / Math.PI) / 2) * tileCount; return Math.floor(y); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js index ae2623e1687663..88a6ce048a1788 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/geo_tile_utils.test.js @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +jest.mock('../../../kibana_services', () => {}); + import { parseTileKey, getTileBoundingBox, expandToTileBoundaries } from './geo_tile_utils'; it('Should parse tile key', () => { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js index 2057949c30c882..96a7f50cdf523a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.js @@ -5,9 +5,11 @@ */ import _ from 'lodash'; +import { extractPropertiesFromBucket } from '../../util/es_agg_utils'; const LAT_INDEX = 0; const LON_INDEX = 1; +const PEW_PEW_BUCKET_KEYS_TO_IGNORE = ['key', 'sourceCentroid']; function parsePointFromKey(key) { const split = key.split(','); @@ -25,25 +27,16 @@ export function convertToLines(esResponse) { const dest = parsePointFromKey(destBucket.key); const sourceBuckets = _.get(destBucket, 'sourceGrid.buckets', []); for (let j = 0; j < sourceBuckets.length; j++) { - const { key, sourceCentroid, ...rest } = sourceBuckets[j]; - - // flatten metrics - Object.keys(rest).forEach(key => { - if (_.has(rest[key], 'value')) { - rest[key] = rest[key].value; - } - }); - + const sourceBucket = sourceBuckets[j]; + const sourceCentroid = sourceBucket.sourceCentroid; lineFeatures.push({ type: 'Feature', geometry: { type: 'LineString', coordinates: [[sourceCentroid.location.lon, sourceCentroid.location.lat], dest], }, - id: `${dest.join()},${key}`, - properties: { - ...rest, - }, + id: `${dest.join()},${sourceBucket.key}`, + properties: extractPropertiesFromBucket(sourceBucket, PEW_PEW_BUCKET_KEYS_TO_IGNORE), }); } } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts new file mode 100644 index 00000000000000..5fbd5a3ad20c0e --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/convert_to_lines.test.ts @@ -0,0 +1,68 @@ +/* + * 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. + */ + +// @ts-ignore +import { convertToLines } from './convert_to_lines'; + +const esResponse = { + aggregations: { + destSplit: { + buckets: [ + { + key: '43.68389896117151, 10.39269994944334', + doc_count: 2, + sourceGrid: { + buckets: [ + { + key: '4/9/3', + doc_count: 1, + terms_of_Carrier: { + buckets: [ + { + key: 'ES-Air', + doc_count: 1, + }, + ], + }, + sourceCentroid: { + location: { + lat: 68.15180202014744, + lon: 33.46390150487423, + }, + count: 1, + }, + avg_of_FlightDelayMin: { + value: 3, + }, + }, + ], + }, + }, + ], + }, + }, +}; + +it('Should convert elasticsearch aggregation response into feature collection of lines', () => { + const geoJson = convertToLines(esResponse); + expect(geoJson.featureCollection.features.length).toBe(1); + expect(geoJson.featureCollection.features[0]).toEqual({ + geometry: { + coordinates: [ + [33.46390150487423, 68.15180202014744], + [10.39269994944334, 43.68389896117151], + ], + type: 'LineString', + }, + id: '10.39269994944334,43.68389896117151,4/9/3', + properties: { + avg_of_FlightDelayMin: 3, + doc_count: 1, + terms_of_Carrier: 'ES-Air', + }, + type: 'Feature', + }); +}); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js index 176ab62baf98cd..53536b11aaca66 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_pew_pew_source/es_pew_pew_source.js @@ -20,7 +20,6 @@ import { i18n } from '@kbn/i18n'; import { SOURCE_DATA_ID_ORIGIN, ES_PEW_PEW, COUNT_PROP_NAME } from '../../../../common/constants'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { convertToLines } from './convert_to_lines'; -import { AggConfigs, Schemas } from 'ui/agg_types'; import { AbstractESAggSource } from '../es_agg_source'; import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property'; import { COLOR_GRADIENTS } from '../../styles/color_utils'; @@ -28,8 +27,6 @@ import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; const MAX_GEOTILE_LEVEL = 29; -const aggSchemas = new Schemas([AbstractESAggSource.METRIC_SCHEMA_CONFIG]); - export class ESPewPewSource extends AbstractESAggSource { static type = ES_PEW_PEW; static title = i18n.translate('xpack.maps.source.pewPewTitle', { @@ -170,9 +167,6 @@ export class ESPewPewSource extends AbstractESAggSource { async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { const indexPattern = await this.getIndexPattern(); - const metricAggConfigs = this.createMetricAggConfigs(); - const aggConfigs = new AggConfigs(indexPattern, metricAggConfigs, aggSchemas.all); - const searchSource = await this._makeSearchSource(searchFilters, 0); searchSource.setField('aggs', { destSplit: { @@ -199,7 +193,7 @@ export class ESPewPewSource extends AbstractESAggSource { field: this._descriptor.sourceGeoField, }, }, - ...aggConfigs.toDsl(), + ...this.getValueAggsDsl(indexPattern), }, }, }, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 288dd117da1379..35332824361393 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -28,31 +28,7 @@ import { loadIndexSettings } from './load_index_settings'; import { DEFAULT_FILTER_BY_MAP_BOUNDS } from './constants'; import { ESDocField } from '../../fields/es_doc_field'; - -function getField(indexPattern, fieldName) { - const field = indexPattern.fields.getByName(fieldName); - if (!field) { - throw new Error( - i18n.translate('xpack.maps.source.esSearch.fieldNotFoundMsg', { - defaultMessage: `Unable to find '{fieldName}' in index-pattern '{indexPatternTitle}'.`, - values: { fieldName, indexPatternTitle: indexPattern.title }, - }) - ); - } - return field; -} - -function addFieldToDSL(dsl, field) { - return !field.scripted - ? { ...dsl, field: field.name } - : { - ...dsl, - script: { - source: field.script, - lang: field.lang, - }, - }; -} +import { getField, addFieldToDSL } from '../../util/es_agg_utils'; function getDocValueAndSourceFields(indexPattern, fieldNames) { const docValueFields = []; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js index d78d3038f870d9..782f2845ceeffc 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js @@ -18,7 +18,7 @@ import { AggConfigs } from 'ui/agg_types'; import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import { copyPersistentState } from '../../reducers/util'; -import { ES_GEO_FIELD_TYPE, METRIC_TYPE } from '../../../common/constants'; +import { ES_GEO_FIELD_TYPE, AGG_TYPE } from '../../../common/constants'; import { DataRequestAbortError } from '../util/data_request'; import { expandToTileBoundaries } from './es_geo_grid_source/geo_tile_utils'; @@ -270,7 +270,7 @@ export class AbstractESSource extends AbstractVectorSource { // Do not use field formatters for counting metrics if ( metricField && - (metricField.type === METRIC_TYPE.COUNT || metricField.type === METRIC_TYPE.UNIQUE_COUNT) + (metricField.type === AGG_TYPE.COUNT || metricField.type === AGG_TYPE.UNIQUE_COUNT) ) { return null; } @@ -347,13 +347,16 @@ export class AbstractESSource extends AbstractVectorSource { } getValueSuggestions = async (fieldName, query) => { - if (!fieldName) { + // fieldName could be an aggregation so it needs to be unpacked to expose raw field. + const metricField = this.getMetricFields().find(field => field.getName() === fieldName); + const realFieldName = metricField ? metricField.getESDocFieldName() : fieldName; + if (!realFieldName) { return []; } try { const indexPattern = await this.getIndexPattern(); - const field = indexPattern.fields.getByName(fieldName); + const field = indexPattern.fields.getByName(realFieldName); return await autocompleteService.getValueSuggestions({ indexPattern, field, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js index 7d7a2e159d1283..9cc2919404a940 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.js @@ -6,46 +6,25 @@ import _ from 'lodash'; -import { AggConfigs, Schemas } from 'ui/agg_types'; import { i18n } from '@kbn/i18n'; -import { - COUNT_PROP_LABEL, - DEFAULT_MAX_BUCKETS_LIMIT, - FIELD_ORIGIN, - METRIC_TYPE, -} from '../../../common/constants'; +import { DEFAULT_MAX_BUCKETS_LIMIT, FIELD_ORIGIN, AGG_TYPE } from '../../../common/constants'; import { ESDocField } from '../fields/es_doc_field'; import { AbstractESAggSource, AGG_DELIMITER } from './es_agg_source'; +import { getField, addFieldToDSL, extractPropertiesFromBucket } from '../util/es_agg_utils'; const TERMS_AGG_NAME = 'join'; const FIELD_NAME_PREFIX = '__kbnjoin__'; const GROUP_BY_DELIMITER = '_groupby_'; +const TERMS_BUCKET_KEYS_TO_IGNORE = ['key', 'doc_count']; -const aggSchemas = new Schemas([ - AbstractESAggSource.METRIC_SCHEMA_CONFIG, - { - group: 'buckets', - name: 'segment', - title: 'Terms', - aggFilter: 'terms', - min: 1, - max: 1, - }, -]); - -export function extractPropertiesMap(rawEsData, propertyNames, countPropertyName) { +export function extractPropertiesMap(rawEsData, countPropertyName) { const propertiesMap = new Map(); _.get(rawEsData, ['aggregations', TERMS_AGG_NAME, 'buckets'], []).forEach(termBucket => { - const properties = {}; + const properties = extractPropertiesFromBucket(termBucket, TERMS_BUCKET_KEYS_TO_IGNORE); if (countPropertyName) { properties[countPropertyName] = termBucket.doc_count; } - propertyNames.forEach(propertyName => { - if (_.has(termBucket, [propertyName, 'value'])) { - properties[propertyName] = _.get(termBucket, [propertyName, 'value']); - } - }); propertiesMap.set(termBucket.key.toString(), properties); }); return propertiesMap; @@ -90,15 +69,27 @@ export class ESTermSource extends AbstractESAggSource { formatMetricKey(aggType, fieldName) { const metricKey = - aggType !== METRIC_TYPE.COUNT ? `${aggType}${AGG_DELIMITER}${fieldName}` : aggType; + aggType !== AGG_TYPE.COUNT ? `${aggType}${AGG_DELIMITER}${fieldName}` : aggType; return `${FIELD_NAME_PREFIX}${metricKey}${GROUP_BY_DELIMITER}${ this._descriptor.indexPatternTitle }.${this._termField.getName()}`; } formatMetricLabel(type, fieldName) { - const metricLabel = type !== METRIC_TYPE.COUNT ? `${type} ${fieldName}` : COUNT_PROP_LABEL; - return `${metricLabel} of ${this._descriptor.indexPatternTitle}:${this._termField.getName()}`; + switch (type) { + case AGG_TYPE.COUNT: + return i18n.translate('xpack.maps.source.esJoin.countLabel', { + defaultMessage: `Count of {indexPatternTitle}`, + values: { indexPatternTitle: this._descriptor.indexPatternTitle }, + }); + case AGG_TYPE.TERMS: + return i18n.translate('xpack.maps.source.esJoin.topTermLabel', { + defaultMessage: `Top {fieldName}`, + values: { fieldName }, + }); + default: + return `${type} ${fieldName}`; + } } async getPropertiesMap(searchFilters, leftSourceName, leftFieldName, registerCancelCallback) { @@ -108,9 +99,14 @@ export class ESTermSource extends AbstractESAggSource { const indexPattern = await this.getIndexPattern(); const searchSource = await this._makeSearchSource(searchFilters, 0); - const configStates = this._makeAggConfigs(); - const aggConfigs = new AggConfigs(indexPattern, configStates, aggSchemas.all); - searchSource.setField('aggs', aggConfigs.toDsl()); + const termsField = getField(indexPattern, this._termField.getName()); + const termsAgg = { size: DEFAULT_MAX_BUCKETS_LIMIT }; + searchSource.setField('aggs', { + [TERMS_AGG_NAME]: { + terms: addFieldToDSL(termsAgg, termsField), + aggs: { ...this.getValueAggsDsl(indexPattern) }, + }, + }); const rawEsData = await this._runEsQuery({ requestId: this.getId(), @@ -120,19 +116,9 @@ export class ESTermSource extends AbstractESAggSource { requestDescription: this._getRequestDescription(leftSourceName, leftFieldName), }); - const metricPropertyNames = configStates - .filter(configState => { - return configState.schema === 'metric' && configState.type !== METRIC_TYPE.COUNT; - }) - .map(configState => { - return configState.id; - }); - const countConfigState = configStates.find(configState => { - return configState.type === METRIC_TYPE.COUNT; - }); - const countPropertyName = _.get(countConfigState, 'id'); + const countPropertyName = this.formatMetricKey(AGG_TYPE.COUNT); return { - propertiesMap: extractPropertiesMap(rawEsData, metricPropertyNames, countPropertyName), + propertiesMap: extractPropertiesMap(rawEsData, countPropertyName), }; } @@ -164,23 +150,6 @@ export class ESTermSource extends AbstractESAggSource { }); } - _makeAggConfigs() { - const metricAggConfigs = this.createMetricAggConfigs(); - return [ - ...metricAggConfigs, - { - id: TERMS_AGG_NAME, - enabled: true, - type: 'terms', - schema: 'segment', - params: { - field: this._termField.getName(), - size: DEFAULT_MAX_BUCKETS_LIMIT, - }, - }, - ]; - } - async getDisplayName() { //no need to localize. this is never rendered. return `es_table ${this._descriptor.indexPatternId}`; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js index ffaaf2d705b5c7..39cc301d458cbe 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_term_source.test.js @@ -8,9 +8,6 @@ import { ESTermSource, extractPropertiesMap } from './es_term_source'; jest.mock('ui/new_platform'); jest.mock('../vector_layer', () => {}); -jest.mock('ui/agg_types', () => ({ - Schemas: function() {}, -})); jest.mock('ui/timefilter', () => {}); const indexPatternTitle = 'myIndex'; @@ -44,7 +41,7 @@ describe('getMetricFields', () => { expect(metrics[0].getAggType()).toEqual('count'); expect(metrics[0].getName()).toEqual('__kbnjoin__count_groupby_myIndex.myTermField'); - expect(await metrics[0].getLabel()).toEqual('count of myIndex:myTermField'); + expect(await metrics[0].getLabel()).toEqual('Count of myIndex'); }); it('should remove incomplete metric configurations', async () => { @@ -65,84 +62,13 @@ describe('getMetricFields', () => { expect(metrics[1].getAggType()).toEqual('count'); expect(metrics[1].getName()).toEqual('__kbnjoin__count_groupby_myIndex.myTermField'); - expect(await metrics[1].getLabel()).toEqual('count of myIndex:myTermField'); - }); -}); - -describe('_makeAggConfigs', () => { - describe('no metrics', () => { - let aggConfigs; - beforeAll(() => { - const source = new ESTermSource({ - indexPatternTitle: indexPatternTitle, - term: termFieldName, - }); - aggConfigs = source._makeAggConfigs(); - }); - - it('should make default "count" metric agg config', () => { - expect(aggConfigs.length).toBe(2); - expect(aggConfigs[0]).toEqual({ - id: '__kbnjoin__count_groupby_myIndex.myTermField', - enabled: true, - type: 'count', - schema: 'metric', - params: {}, - }); - }); - - it('should make "terms" buckets agg config', () => { - expect(aggConfigs.length).toBe(2); - expect(aggConfigs[1]).toEqual({ - id: 'join', - enabled: true, - type: 'terms', - schema: 'segment', - params: { - field: termFieldName, - size: 10000, - }, - }); - }); - }); - - describe('metrics', () => { - let aggConfigs; - beforeAll(() => { - const source = new ESTermSource({ - indexPatternTitle: indexPatternTitle, - term: 'myTermField', - metrics: metricExamples, - }); - aggConfigs = source._makeAggConfigs(); - }); - - it('should ignore invalid metrics configs', () => { - expect(aggConfigs.length).toBe(3); - }); - - it('should make agg config for each valid metric', () => { - expect(aggConfigs[0]).toEqual({ - id: '__kbnjoin__sum_of_myFieldGettingSummed_groupby_myIndex.myTermField', - enabled: true, - type: 'sum', - schema: 'metric', - params: { - field: sumFieldName, - }, - }); - expect(aggConfigs[1]).toEqual({ - id: '__kbnjoin__count_groupby_myIndex.myTermField', - enabled: true, - type: 'count', - schema: 'metric', - params: {}, - }); - }); + expect(await metrics[1].getLabel()).toEqual('Count of myIndex'); }); }); describe('extractPropertiesMap', () => { + const minPropName = + '__kbnjoin__min_of_avlAirTemp_groupby_kibana_sample_data_ky_avl.kytcCountyNmbr'; const responseWithNumberTypes = { aggregations: { join: { @@ -150,14 +76,14 @@ describe('extractPropertiesMap', () => { { key: 109, doc_count: 1130, - '__kbnjoin__min_of_avlAirTemp_groupby_kibana_sample_data_ky_avl.kytcCountyNmbr': { + [minPropName]: { value: 36, }, }, { key: 62, doc_count: 448, - '__kbnjoin__min_of_avlAirTemp_groupby_kibana_sample_data_ky_avl.kytcCountyNmbr': { + [minPropName]: { value: 0, }, }, @@ -166,11 +92,10 @@ describe('extractPropertiesMap', () => { }, }; const countPropName = '__kbnjoin__count_groupby_kibana_sample_data_ky_avl.kytcCountyNmbr'; - const minPropName = - '__kbnjoin__min_of_avlAirTemp_groupby_kibana_sample_data_ky_avl.kytcCountyNmbr'; + let propertiesMap; beforeAll(() => { - propertiesMap = extractPropertiesMap(responseWithNumberTypes, [minPropName], countPropName); + propertiesMap = extractPropertiesMap(responseWithNumberTypes, countPropName); }); it('should create key for each join term', () => { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js index e137e15730827c..dfc5c530cc90fa 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_size_property.js @@ -43,16 +43,8 @@ function getSymbolSizeIcons() { } export class DynamicSizeProperty extends DynamicStyleProperty { - constructor( - options, - styleName, - field, - getFieldMeta, - getFieldFormatter, - getValueSuggestions, - isSymbolizedAsIcon - ) { - super(options, styleName, field, getFieldMeta, getFieldFormatter, getValueSuggestions); + constructor(options, styleName, field, getFieldMeta, getFieldFormatter, isSymbolizedAsIcon) { + super(options, styleName, field, getFieldMeta, getFieldFormatter); this._isSymbolizedAsIcon = isSymbolizedAsIcon; } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index ef19e9b23b10de..af78c4c0e461e8 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -13,21 +13,22 @@ import React from 'react'; import { OrdinalLegend } from './components/ordinal_legend'; import { CategoricalLegend } from './components/categorical_legend'; import { OrdinalFieldMetaOptionsPopover } from '../components/ordinal_field_meta_options_popover'; +import { ESAggMetricField } from '../../../fields/es_agg_field'; export class DynamicStyleProperty extends AbstractStyleProperty { static type = STYLE_TYPE.DYNAMIC; - constructor(options, styleName, field, getFieldMeta, getFieldFormatter, source) { + constructor(options, styleName, field, getFieldMeta, getFieldFormatter) { super(options, styleName); this._field = field; this._getFieldMeta = getFieldMeta; this._getFieldFormatter = getFieldFormatter; - this._source = source; } getValueSuggestions = query => { const fieldName = this.getFieldName(); - return this._source && fieldName ? this._source.getValueSuggestions(fieldName, query) : []; + const fieldSource = this.getFieldSource(); + return fieldSource && fieldName ? fieldSource.getValueSuggestions(fieldName, query) : []; }; getFieldMeta() { @@ -38,6 +39,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty { return this._field; } + getFieldSource() { + return this._field ? this._field.getSource() : null; + } + getFieldName() { return this._field ? this._field.getName() : ''; } @@ -180,9 +185,10 @@ export class DynamicStyleProperty extends AbstractStyleProperty { } _pluckOrdinalStyleMetaFromFieldMetaData(fieldMetaData) { - const realFieldName = this._field.getESDocFieldName - ? this._field.getESDocFieldName() - : this._field.getName(); + const realFieldName = + this._field instanceof ESAggMetricField + ? this._field.getESDocFieldName() + : this._field.getName(); const stats = fieldMetaData[realFieldName]; if (!stats) { return null; @@ -203,12 +209,15 @@ export class DynamicStyleProperty extends AbstractStyleProperty { } _pluckCategoricalStyleMetaFromFieldMetaData(fieldMetaData) { - const name = this.getField().getName(); - if (!fieldMetaData[name] || !fieldMetaData[name].buckets) { + const realFieldName = + this._field instanceof ESAggMetricField + ? this._field.getESDocFieldName() + : this._field.getName(); + if (!fieldMetaData[realFieldName] || !fieldMetaData[realFieldName].buckets) { return null; } - const ordered = fieldMetaData[name].buckets.map(bucket => { + const ordered = fieldMetaData[realFieldName].buckets.map(bucket => { return { key: bucket.key, count: bucket.doc_count, diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js index 62651fdd702d60..053aa114d94aea 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js @@ -625,7 +625,6 @@ export class VectorStyle extends AbstractStyle { field, this._getFieldMeta, this._getFieldFormatter, - this._source, isSymbolizedAsIcon ); } else { @@ -645,8 +644,7 @@ export class VectorStyle extends AbstractStyle { styleName, field, this._getFieldMeta, - this._getFieldFormatter, - this._source + this._getFieldFormatter ); } else { throw new Error(`${descriptor} not implemented`); @@ -678,8 +676,7 @@ export class VectorStyle extends AbstractStyle { VECTOR_STYLES.LABEL_TEXT, field, this._getFieldMeta, - this._getFieldFormatter, - this._source + this._getFieldFormatter ); } else { throw new Error(`${descriptor} not implemented`); @@ -698,8 +695,7 @@ export class VectorStyle extends AbstractStyle { VECTOR_STYLES.ICON, field, this._getFieldMeta, - this._getFieldFormatter, - this._source + this._getFieldFormatter ); } else { throw new Error(`${descriptor} not implemented`); diff --git a/x-pack/legacy/plugins/maps/public/layers/tooltips/es_aggmetric_tooltip_property.js b/x-pack/legacy/plugins/maps/public/layers/tooltips/es_aggmetric_tooltip_property.js index 7cfb60910c1557..229c84fe234bd9 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tooltips/es_aggmetric_tooltip_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/tooltips/es_aggmetric_tooltip_property.js @@ -5,7 +5,7 @@ */ import { ESTooltipProperty } from './es_tooltip_property'; -import { METRIC_TYPE } from '../../../common/constants'; +import { AGG_TYPE } from '../../../common/constants'; export class ESAggMetricTooltipProperty extends ESTooltipProperty { constructor(propertyKey, propertyName, rawValue, indexPattern, metricField) { @@ -22,8 +22,8 @@ export class ESAggMetricTooltipProperty extends ESTooltipProperty { return '-'; } if ( - this._metricField.getAggType() === METRIC_TYPE.COUNT || - this._metricField.getAggType() === METRIC_TYPE.UNIQUE_COUNT + this._metricField.getAggType() === AGG_TYPE.COUNT || + this._metricField.getAggType() === AGG_TYPE.UNIQUE_COUNT ) { return this._rawValue; } diff --git a/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts b/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts new file mode 100644 index 00000000000000..201d6907981a2b --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.test.ts @@ -0,0 +1,37 @@ +/* + * 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 { extractPropertiesFromBucket } from './es_agg_utils'; + +describe('extractPropertiesFromBucket', () => { + test('Should ignore specified keys', () => { + const properties = extractPropertiesFromBucket({ key: '4/4/6' }, ['key']); + expect(properties).toEqual({}); + }); + + test('Should extract metric aggregation values', () => { + const properties = extractPropertiesFromBucket({ avg_of_bytes: { value: 5359 } }); + expect(properties).toEqual({ + avg_of_bytes: 5359, + }); + }); + + test('Should extract bucket aggregation values', () => { + const properties = extractPropertiesFromBucket({ + 'terms_of_machine.os.keyword': { + buckets: [ + { + key: 'win xp', + doc_count: 16, + }, + ], + }, + }); + expect(properties).toEqual({ + 'terms_of_machine.os.keyword': 'win xp', + }); + }); +}); diff --git a/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts b/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts new file mode 100644 index 00000000000000..7af176acfaf467 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/util/es_agg_utils.ts @@ -0,0 +1,51 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import _ from 'lodash'; +import { IndexPattern, IFieldType } from '../../../../../../../src/plugins/data/public'; + +export function getField(indexPattern: IndexPattern, fieldName: string) { + const field = indexPattern.fields.getByName(fieldName); + if (!field) { + throw new Error( + i18n.translate('xpack.maps.source.esSearch.fieldNotFoundMsg', { + defaultMessage: `Unable to find '{fieldName}' in index-pattern '{indexPatternTitle}'.`, + values: { fieldName, indexPatternTitle: indexPattern.title }, + }) + ); + } + return field; +} + +export function addFieldToDSL(dsl: object, field: IFieldType) { + return !field.scripted + ? { ...dsl, field: field.name } + : { + ...dsl, + script: { + source: field.script, + lang: field.lang, + }, + }; +} + +export function extractPropertiesFromBucket(bucket: any, ignoreKeys: string[] = []) { + const properties: Record = {}; + for (const key in bucket) { + if (ignoreKeys.includes(key) || !bucket.hasOwnProperty(key)) { + continue; + } + + if (_.has(bucket[key], 'value')) { + properties[key] = bucket[key].value; + } else if (_.has(bucket[key], 'buckets')) { + properties[key] = _.get(bucket[key], 'buckets[0].key'); + } else { + properties[key] = bucket[key]; + } + } + return properties; +} diff --git a/x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.js b/x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.js index 54d8794b1e3cf0..69ccb8890d10cc 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/is_metric_countable.js @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { METRIC_TYPE } from '../../../common/constants'; +import { AGG_TYPE } from '../../../common/constants'; export function isMetricCountable(aggType) { - return [METRIC_TYPE.COUNT, METRIC_TYPE.SUM, METRIC_TYPE.UNIQUE_COUNT].includes(aggType); + return [AGG_TYPE.COUNT, AGG_TYPE.SUM, AGG_TYPE.UNIQUE_COUNT].includes(aggType); } diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index 1698d52ea4406d..e1a30c8aef1d37 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -365,8 +365,10 @@ export class VectorLayer extends AbstractLayer { onLoadError, registerCancelCallback, dataFilters, + isRequestStillActive, }) { - const requestToken = Symbol(`layer-${this.getId()}-${SOURCE_DATA_ID_ORIGIN}`); + const dataRequestId = SOURCE_DATA_ID_ORIGIN; + const requestToken = Symbol(`layer-${this.getId()}-${dataRequestId}`); const searchFilters = this._getSearchFilters(dataFilters); const prevDataRequest = this.getSourceDataRequest(); const canSkipFetch = await canSkipSourceUpdate({ @@ -382,22 +384,25 @@ export class VectorLayer extends AbstractLayer { } try { - startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, searchFilters); + startLoading(dataRequestId, requestToken, searchFilters); const layerName = await this.getDisplayName(); const { data: sourceFeatureCollection, meta } = await this._source.getGeoJsonWithMeta( layerName, searchFilters, - registerCancelCallback.bind(null, requestToken) + registerCancelCallback.bind(null, requestToken), + () => { + return isRequestStillActive(dataRequestId, requestToken); + } ); const layerFeatureCollection = assignFeatureIds(sourceFeatureCollection); - stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, layerFeatureCollection, meta); + stopLoading(dataRequestId, requestToken, layerFeatureCollection, meta); return { refreshed: true, featureCollection: layerFeatureCollection, }; } catch (error) { if (!(error instanceof DataRequestAbortError)) { - onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); + onLoadError(dataRequestId, requestToken, error.message); } return { refreshed: false, diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js index d1048a759beca0..4074344916390c 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js +++ b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js @@ -125,6 +125,21 @@ export const getRefreshConfig = ({ map }) => { export const getRefreshTimerLastTriggeredAt = ({ map }) => map.mapState.refreshTimerLastTriggeredAt; +function getLayerDescriptor(state = {}, layerId) { + const layerListRaw = getLayerListRaw(state); + return layerListRaw.find(layer => layer.id === layerId); +} + +export function getDataRequestDescriptor(state = {}, layerId, dataId) { + const layerDescriptor = getLayerDescriptor(state, layerId); + if (!layerDescriptor || !layerDescriptor.__dataRequests) { + return; + } + return _.get(layerDescriptor, '__dataRequests', []).find(dataRequest => { + return dataRequest.dataId === dataId; + }); +} + export const getDataFilters = createSelector( getMapExtent, getMapBuffer, diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 4a627d48c3cf05..3c7d0ce47acb76 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -7263,7 +7263,6 @@ "xpack.maps.source.esGrid.finestDropdownOption": "最も細かい", "xpack.maps.source.esGrid.geospatialFieldLabel": "地理空間フィールド", "xpack.maps.source.esGrid.indexPatternLabel": "インデックスパターン", - "xpack.maps.source.esGrid.inspectorDescription": "Elasticsearch ジオグリッド集約リクエスト", "xpack.maps.source.esGrid.metricsLabel": "メトリック", "xpack.maps.source.esGrid.noIndexPatternErrorMessage": "インデックスパターン {id} が見つかりません", "xpack.maps.source.esGrid.resolutionParamErrorMessage": "グリッド解像度パラメーターが認識されません: {resolution}", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e0ef4a7a1ebdba..b262be626aa534 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -7263,7 +7263,6 @@ "xpack.maps.source.esGrid.finestDropdownOption": "最精致化", "xpack.maps.source.esGrid.geospatialFieldLabel": "地理空间字段", "xpack.maps.source.esGrid.indexPatternLabel": "索引模式", - "xpack.maps.source.esGrid.inspectorDescription": "Elasticsearch 地理网格聚合请求", "xpack.maps.source.esGrid.metricsLabel": "指标", "xpack.maps.source.esGrid.noIndexPatternErrorMessage": "找不到索引模式 {id}", "xpack.maps.source.esGrid.resolutionParamErrorMessage": "无法识别网格分辨率参数:{resolution}", From 47aa5b46df1dcafe0cf26043e00cb113da6bad79 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 26 Feb 2020 15:59:22 +0100 Subject: [PATCH 71/73] Saved query management: Discard pending listing requests (#58433) * discard pending listing requests * consolidate requests --- .../saved_query/saved_query_service.test.ts | 27 +++++++++++++++---- .../query/saved_query/saved_query_service.ts | 13 +++++---- .../data/public/query/saved_query/types.ts | 2 +- .../saved_query_management_component.tsx | 20 +++++++++++--- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/plugins/data/public/query/saved_query/saved_query_service.test.ts b/src/plugins/data/public/query/saved_query/saved_query_service.test.ts index a6b8de32a00bd4..c983cc4ea8fc58 100644 --- a/src/plugins/data/public/query/saved_query/saved_query_service.test.ts +++ b/src/plugins/data/public/query/saved_query/saved_query_service.test.ts @@ -169,15 +169,27 @@ describe('saved query service', () => { it('should find and return saved queries without search text or pagination parameters', async () => { mockSavedObjectsClient.find.mockReturnValue({ savedObjects: [{ id: 'foo', attributes: savedQueryAttributes }], + total: 5, }); const response = await findSavedQueries(); - expect(response).toEqual([{ id: 'foo', attributes: savedQueryAttributes }]); + expect(response.queries).toEqual([{ id: 'foo', attributes: savedQueryAttributes }]); + }); + + it('should return the total count along with the requested queries', async () => { + mockSavedObjectsClient.find.mockReturnValue({ + savedObjects: [{ id: 'foo', attributes: savedQueryAttributes }], + total: 5, + }); + + const response = await findSavedQueries(); + expect(response.total).toEqual(5); }); it('should find and return saved queries with search text matching the title field', async () => { mockSavedObjectsClient.find.mockReturnValue({ savedObjects: [{ id: 'foo', attributes: savedQueryAttributes }], + total: 5, }); const response = await findSavedQueries('foo'); expect(mockSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -188,7 +200,7 @@ describe('saved query service', () => { sortField: '_score', type: 'query', }); - expect(response).toEqual([{ id: 'foo', attributes: savedQueryAttributes }]); + expect(response.queries).toEqual([{ id: 'foo', attributes: savedQueryAttributes }]); }); it('should find and return parsed filters and timefilters items', async () => { const serializedSavedQueryAttributesWithFilters = { @@ -198,16 +210,20 @@ describe('saved query service', () => { }; mockSavedObjectsClient.find.mockReturnValue({ savedObjects: [{ id: 'foo', attributes: serializedSavedQueryAttributesWithFilters }], + total: 5, }); const response = await findSavedQueries('bar'); - expect(response).toEqual([{ id: 'foo', attributes: savedQueryAttributesWithFilters }]); + expect(response.queries).toEqual([ + { id: 'foo', attributes: savedQueryAttributesWithFilters }, + ]); }); it('should return an array of saved queries', async () => { mockSavedObjectsClient.find.mockReturnValue({ savedObjects: [{ id: 'foo', attributes: savedQueryAttributes }], + total: 5, }); const response = await findSavedQueries(); - expect(response).toEqual( + expect(response.queries).toEqual( expect.objectContaining([ { attributes: { @@ -226,6 +242,7 @@ describe('saved query service', () => { { id: 'foo', attributes: savedQueryAttributes }, { id: 'bar', attributes: savedQueryAttributesBar }, ], + total: 5, }); const response = await findSavedQueries(undefined, 2, 1); expect(mockSavedObjectsClient.find).toHaveBeenCalledWith({ @@ -236,7 +253,7 @@ describe('saved query service', () => { sortField: '_score', type: 'query', }); - expect(response).toEqual( + expect(response.queries).toEqual( expect.objectContaining([ { attributes: { diff --git a/src/plugins/data/public/query/saved_query/saved_query_service.ts b/src/plugins/data/public/query/saved_query/saved_query_service.ts index 80dec1c9373ea9..4d3a8f441ce5e3 100644 --- a/src/plugins/data/public/query/saved_query/saved_query_service.ts +++ b/src/plugins/data/public/query/saved_query/saved_query_service.ts @@ -95,7 +95,7 @@ export const createSavedQueryService = ( searchText: string = '', perPage: number = 50, activePage: number = 1 - ): Promise => { + ): Promise<{ total: number; queries: SavedQuery[] }> => { const response = await savedObjectsClient.find({ type: 'query', search: searchText, @@ -105,10 +105,13 @@ export const createSavedQueryService = ( page: activePage, }); - return response.savedObjects.map( - (savedObject: { id: string; attributes: SerializedSavedQueryAttributes }) => - parseSavedQueryObject(savedObject) - ); + return { + total: response.total, + queries: response.savedObjects.map( + (savedObject: { id: string; attributes: SerializedSavedQueryAttributes }) => + parseSavedQueryObject(savedObject) + ), + }; }; const getSavedQuery = async (id: string): Promise => { diff --git a/src/plugins/data/public/query/saved_query/types.ts b/src/plugins/data/public/query/saved_query/types.ts index d05eada7b29e62..6ac5e51d5c3125 100644 --- a/src/plugins/data/public/query/saved_query/types.ts +++ b/src/plugins/data/public/query/saved_query/types.ts @@ -46,7 +46,7 @@ export interface SavedQueryService { searchText?: string, perPage?: number, activePage?: number - ) => Promise; + ) => Promise<{ total: number; queries: SavedQuery[] }>; getSavedQuery: (id: string) => Promise; deleteSavedQuery: (id: string) => Promise<{}>; getSavedQueryCount: () => Promise; diff --git a/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx b/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx index 2a11531ee336df..9347ef59742611 100644 --- a/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx +++ b/src/plugins/data/public/ui/saved_query_management/saved_query_management_component.tsx @@ -33,7 +33,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { FunctionComponent, useEffect, useState, Fragment } from 'react'; +import React, { FunctionComponent, useEffect, useState, Fragment, useRef } from 'react'; import { sortBy } from 'lodash'; import { SavedQuery, SavedQueryService } from '../..'; import { SavedQueryListItem } from './saved_query_list_item'; @@ -62,14 +62,25 @@ export const SavedQueryManagementComponent: FunctionComponent = ({ const [savedQueries, setSavedQueries] = useState([] as SavedQuery[]); const [count, setTotalCount] = useState(0); const [activePage, setActivePage] = useState(0); + const cancelPendingListingRequest = useRef<() => void>(() => {}); useEffect(() => { const fetchCountAndSavedQueries = async () => { - const savedQueryCount = await savedQueryService.getSavedQueryCount(); - setTotalCount(savedQueryCount); + cancelPendingListingRequest.current(); + let requestGotCancelled = false; + cancelPendingListingRequest.current = () => { + requestGotCancelled = true; + }; + + const { + total: savedQueryCount, + queries: savedQueryItems, + } = await savedQueryService.findSavedQueries('', perPage, activePage + 1); + + if (requestGotCancelled) return; - const savedQueryItems = await savedQueryService.findSavedQueries('', perPage, activePage + 1); const sortedSavedQueryItems = sortBy(savedQueryItems, 'attributes.title'); + setTotalCount(savedQueryCount); setSavedQueries(sortedSavedQueryItems); }; if (isOpen) { @@ -103,6 +114,7 @@ export const SavedQueryManagementComponent: FunctionComponent = ({ ); const onDeleteSavedQuery = async (savedQuery: SavedQuery) => { + cancelPendingListingRequest.current(); setSavedQueries( savedQueries.filter(currentSavedQuery => currentSavedQuery.id !== savedQuery.id) ); From 8524303b6e5cac434353d57700a31e907ab93f5a Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Wed, 26 Feb 2020 16:22:35 +0100 Subject: [PATCH 72/73] Allow savedObjects types registration from NP (#57430) * expose `registerType` API * expose `getTypeRegistry` API * change SavedObjectMigrationFn signature to add context * fix exported types * update generated doc * update migration documentation * fix legacy service test * fix typings * update service setup description * add saved_objects server folder convention * fix unit test * documentation NITs * add typeRegistry to SavedObjectClientWrapperOptions --- ...-plugin-server.isavedobjecttyperegistry.md | 13 ++ .../core/server/kibana-plugin-server.md | 7 +- ...-server.savedobjectmigrationcontext.log.md | 13 ++ ...ugin-server.savedobjectmigrationcontext.md | 20 ++ ...na-plugin-server.savedobjectmigrationfn.md | 21 +- ...server.savedobjectsclientwrapperoptions.md | 1 + ...bjectsclientwrapperoptions.typeregistry.md | 11 ++ ...-plugin-server.savedobjectsservicesetup.md | 24 ++- ...r.savedobjectsservicesetup.registertype.md | 60 ++++++ ...avedobjectsservicestart.gettyperegistry.md | 13 ++ ...-plugin-server.savedobjectsservicestart.md | 1 + ...ver.savedobjecttyperegistry.getalltypes.md | 17 ++ ...server.savedobjecttyperegistry.getindex.md | 24 +++ ...-server.savedobjecttyperegistry.gettype.md | 24 +++ ...server.savedobjecttyperegistry.ishidden.md | 24 +++ ...dobjecttyperegistry.isnamespaceagnostic.md | 24 +++ ...a-plugin-server.savedobjecttyperegistry.md | 25 +++ ...er.savedobjecttyperegistry.registertype.md | 24 +++ src/core/CONVENTIONS.md | 43 +++++ src/core/MIGRATION.md | 3 + src/core/MIGRATION_EXAMPLES.md | 181 ++++++++++++++++++ src/core/server/index.ts | 2 + src/core/server/legacy/legacy_service.ts | 3 +- src/core/server/mocks.ts | 8 +- src/core/server/plugins/plugin_context.ts | 2 + .../__snapshots__/utils.test.ts.snap | 6 +- src/core/server/saved_objects/index.ts | 6 +- .../migrations/core/document_migrator.test.ts | 2 +- .../migrations/core/document_migrator.ts | 3 +- .../server/saved_objects/migrations/index.ts | 6 +- .../server/saved_objects/migrations/types.ts | 33 +++- .../saved_objects_service.mock.ts | 5 +- .../saved_objects_service.test.ts | 13 +- .../saved_objects/saved_objects_service.ts | 95 ++++++--- .../saved_objects_type_registry.mock.ts | 5 +- .../saved_objects_type_registry.ts | 13 +- .../lib/scoped_client_provider.test.js | 12 ++ .../service/lib/scoped_client_provider.ts | 15 +- src/core/server/saved_objects/types.ts | 21 +- src/core/server/saved_objects/utils.test.ts | 47 ++++- src/core/server/saved_objects/utils.ts | 20 +- src/core/server/server.api.md | 20 +- src/legacy/server/kbn_server.d.ts | 1 - .../saved_objects/saved_objects_mixin.js | 2 +- .../saved_objects/saved_objects_mixin.test.js | 7 +- 45 files changed, 841 insertions(+), 79 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-server.isavedobjecttyperegistry.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.log.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getalltypes.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getindex.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.gettype.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.ishidden.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.registertype.md diff --git a/docs/development/core/server/kibana-plugin-server.isavedobjecttyperegistry.md b/docs/development/core/server/kibana-plugin-server.isavedobjecttyperegistry.md new file mode 100644 index 00000000000000..bbcba50c810275 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.isavedobjecttyperegistry.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [ISavedObjectTypeRegistry](./kibana-plugin-server.isavedobjecttyperegistry.md) + +## ISavedObjectTypeRegistry type + +See [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) for documentation. + +Signature: + +```typescript +export declare type ISavedObjectTypeRegistry = Pick; +``` diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index 9ec443d6482e89..15a1fd05062568 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -27,6 +27,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | | | [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) | | | [SavedObjectsSerializer](./kibana-plugin-server.savedobjectsserializer.md) | A serializer that can be used to manually convert [raw](./kibana-plugin-server.savedobjectsrawdoc.md) or [sanitized](./kibana-plugin-server.savedobjectsanitizeddoc.md) documents to the other kind. | +| [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) | Registry holding information about all the registered [saved object types](./kibana-plugin-server.savedobjectstype.md). | | [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). | ## Enumerations @@ -108,6 +109,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [RouteValidatorOptions](./kibana-plugin-server.routevalidatoroptions.md) | Additional options for the RouteValidator class to modify its default behaviour. | | [SavedObject](./kibana-plugin-server.savedobject.md) | | | [SavedObjectAttributes](./kibana-plugin-server.savedobjectattributes.md) | The data for a Saved Object is stored as an object in the attributes property. | +| [SavedObjectMigrationContext](./kibana-plugin-server.savedobjectmigrationcontext.md) | Migration context provided when invoking a [migration handler](./kibana-plugin-server.savedobjectmigrationfn.md) | | [SavedObjectMigrationMap](./kibana-plugin-server.savedobjectmigrationmap.md) | A map of [migration functions](./kibana-plugin-server.savedobjectmigrationfn.md) to be used for a given type. The map's keys must be valid semver versions.For a given document, only migrations with a higher version number than that of the document will be applied. Migrations are executed in order, starting from the lowest version and ending with the highest one. | | [SavedObjectReference](./kibana-plugin-server.savedobjectreference.md) | A reference to another saved object. | | [SavedObjectsBaseOptions](./kibana-plugin-server.savedobjectsbaseoptions.md) | | @@ -143,7 +145,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsRawDoc](./kibana-plugin-server.savedobjectsrawdoc.md) | A raw document as represented directly in the saved object index. | | [SavedObjectsRepositoryFactory](./kibana-plugin-server.savedobjectsrepositoryfactory.md) | Factory provided when invoking a [client factory provider](./kibana-plugin-server.savedobjectsclientfactoryprovider.md) See [SavedObjectsServiceSetup.setClientFactoryProvider](./kibana-plugin-server.savedobjectsservicesetup.setclientfactoryprovider.md) | | [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) | Options to control the "resolve import" operation. | -| [SavedObjectsServiceSetup](./kibana-plugin-server.savedobjectsservicesetup.md) | Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for creating and registering Saved Object client wrappers. | +| [SavedObjectsServiceSetup](./kibana-plugin-server.savedobjectsservicesetup.md) | Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for registering Saved Object types, creating and registering Saved Object client wrappers and factories. | | [SavedObjectsServiceStart](./kibana-plugin-server.savedobjectsservicestart.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceStart API provides a scoped Saved Objects client for interacting with Saved Objects. | | [SavedObjectsType](./kibana-plugin-server.savedobjectstype.md) | | | [SavedObjectsTypeMappingDefinition](./kibana-plugin-server.savedobjectstypemappingdefinition.md) | Describe a saved object type mapping. | @@ -195,6 +197,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ICustomClusterClient](./kibana-plugin-server.icustomclusterclient.md) | Represents an Elasticsearch cluster API client created by a plugin. It allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)).See [ClusterClient](./kibana-plugin-server.clusterclient.md). | | [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Returns authentication status for a request. | | [ISavedObjectsRepository](./kibana-plugin-server.isavedobjectsrepository.md) | See [SavedObjectsRepository](./kibana-plugin-server.savedobjectsrepository.md) | +| [ISavedObjectTypeRegistry](./kibana-plugin-server.isavedobjecttyperegistry.md) | See [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) for documentation. | | [IScopedClusterClient](./kibana-plugin-server.iscopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). | | [KibanaRequestRouteOptions](./kibana-plugin-server.kibanarequestrouteoptions.md) | Route options: If 'GET' or 'OPTIONS' method, body options won't be returned. | | [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. | @@ -226,7 +229,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [RouteValidatorFullConfig](./kibana-plugin-server.routevalidatorfullconfig.md) | Route validations config and options merged into one object | | [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | Type definition for a Saved Object attribute value | | [SavedObjectAttributeSingle](./kibana-plugin-server.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | -| [SavedObjectMigrationFn](./kibana-plugin-server.savedobjectmigrationfn.md) | A migration function defined for a [saved objects type](./kibana-plugin-server.savedobjectstype.md) used to migrate it's | +| [SavedObjectMigrationFn](./kibana-plugin-server.savedobjectmigrationfn.md) | A migration function for a [saved object type](./kibana-plugin-server.savedobjectstype.md) used to migrate it to a given version | | [SavedObjectSanitizedDoc](./kibana-plugin-server.savedobjectsanitizeddoc.md) | | | [SavedObjectsClientContract](./kibana-plugin-server.savedobjectsclientcontract.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing plugin state.\#\# SavedObjectsClient errorsSince the SavedObjectsClient has its hands in everything we are a little paranoid about the way we present errors back to to application code. Ideally, all errors will be either:1. Caused by bad implementation (ie. undefined is not a function) and as such unpredictable 2. An error that has been classified and decorated appropriately by the decorators in [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md)Type 1 errors are inevitable, but since all expected/handle-able errors should be Type 2 the isXYZError() helpers exposed at SavedObjectsErrorHelpers should be used to understand and manage error responses from the SavedObjectsClient.Type 2 errors are decorated versions of the source error, so if the elasticsearch client threw an error it will be decorated based on its type. That means that rather than looking for error.body.error.type or doing substring checks on error.body.error.reason, just use the helpers to understand the meaning of the error:\`\`\`js if (SavedObjectsErrorHelpers.isNotFoundError(error)) { // handle 404 }if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) { // 401 handling should be automatic, but in case you wanted to know }// always rethrow the error unless you handle it throw error; \`\`\`\#\#\# 404s from missing indexFrom the perspective of application code and APIs the SavedObjectsClient is a black box that persists objects. One of the internal details that users have no control over is that we use an elasticsearch index for persistance and that index might be missing.At the time of writing we are in the process of transitioning away from the operating assumption that the SavedObjects index is always available. Part of this transition is handling errors resulting from an index missing. These used to trigger a 500 error in most cases, and in others cause 404s with different error messages.From my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The object the request/call was targeting could not be found. This is why \#14141 takes special care to ensure that 404 errors are generic and don't distinguish between index missing or document missing.\#\#\# 503s from missing indexUnlike all other methods, create requests are supposed to succeed even when the Kibana index does not exist because it will be automatically created by elasticsearch. When that is not the case it is because Elasticsearch's action.auto_create_index setting prevents it from being created automatically so we throw a special 503 with the intention of informing the user that their Elasticsearch settings need to be updated.See [SavedObjectsClient](./kibana-plugin-server.savedobjectsclient.md) See [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | | [SavedObjectsClientFactory](./kibana-plugin-server.savedobjectsclientfactory.md) | Describes the factory used to create instances of the Saved Objects Client. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.log.md b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.log.md new file mode 100644 index 00000000000000..4e4eaa3ca91e67 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.log.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectMigrationContext](./kibana-plugin-server.savedobjectmigrationcontext.md) > [log](./kibana-plugin-server.savedobjectmigrationcontext.log.md) + +## SavedObjectMigrationContext.log property + +logger instance to be used by the migration handler + +Signature: + +```typescript +log: SavedObjectsMigrationLogger; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.md b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.md new file mode 100644 index 00000000000000..77698b37cd3c90 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationcontext.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectMigrationContext](./kibana-plugin-server.savedobjectmigrationcontext.md) + +## SavedObjectMigrationContext interface + +Migration context provided when invoking a [migration handler](./kibana-plugin-server.savedobjectmigrationfn.md) + +Signature: + +```typescript +export interface SavedObjectMigrationContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [log](./kibana-plugin-server.savedobjectmigrationcontext.log.md) | SavedObjectsMigrationLogger | logger instance to be used by the migration handler | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectmigrationfn.md b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationfn.md index 629d748083737e..838fa55a7f0894 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectmigrationfn.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectmigrationfn.md @@ -4,10 +4,27 @@ ## SavedObjectMigrationFn type -A migration function defined for a [saved objects type](./kibana-plugin-server.savedobjectstype.md) used to migrate it's +A migration function for a [saved object type](./kibana-plugin-server.savedobjectstype.md) used to migrate it to a given version Signature: ```typescript -export declare type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc; +export declare type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc; ``` + +## Example + + +```typescript +const migrateProperty: SavedObjectMigrationFn = (doc, { log }) => { + if(doc.attributes.someProp === null) { + log.warn('Skipping migration'); + } else { + doc.attributes.someProp = migrateProperty(doc.attributes.someProp); + } + + return doc; +} + +``` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md index dfff863898a2b3..67746126e79b4c 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md @@ -18,4 +18,5 @@ export interface SavedObjectsClientWrapperOptions | --- | --- | --- | | [client](./kibana-plugin-server.savedobjectsclientwrapperoptions.client.md) | SavedObjectsClientContract | | | [request](./kibana-plugin-server.savedobjectsclientwrapperoptions.request.md) | KibanaRequest | | +| [typeRegistry](./kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md) | ISavedObjectTypeRegistry | | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md new file mode 100644 index 00000000000000..afd68986993841 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) > [typeRegistry](./kibana-plugin-server.savedobjectsclientwrapperoptions.typeregistry.md) + +## SavedObjectsClientWrapperOptions.typeRegistry property + +Signature: + +```typescript +typeRegistry: ISavedObjectTypeRegistry; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md index 9981bfee0cb7d6..b6f2e7320c48ad 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.md @@ -4,7 +4,7 @@ ## SavedObjectsServiceSetup interface -Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for creating and registering Saved Object client wrappers. +Saved Objects is Kibana's data persistence mechanism allowing plugins to use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods for registering Saved Object types, creating and registering Saved Object client wrappers and factories. Signature: @@ -14,11 +14,9 @@ export interface SavedObjectsServiceSetup ## Remarks -Note: The Saved Object setup API's should only be used for creating and registering client wrappers. Constructing a Saved Objects client or repository for use within your own plugin won't have any of the registered wrappers applied and is considered an anti-pattern. Use the Saved Objects client from the [SavedObjectsServiceStart\#getScopedClient](./kibana-plugin-server.savedobjectsservicestart.md) method or the [route handler context](./kibana-plugin-server.requesthandlercontext.md) instead. +When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`. -When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`. To create a factory or wrapper, plugins will have to construct a Saved Objects client. First create a repository by calling `scopedRepository` or `internalRepository` and then use this repository as the argument to the [SavedObjectsClient](./kibana-plugin-server.savedobjectsclient.md) constructor. - -## Example +## Example 1 ```ts @@ -34,10 +32,26 @@ export class Plugin() { ``` +## Example 2 + + +```ts +import { SavedObjectsClient, CoreSetup } from 'src/core/server'; +import { mySoType } from './saved_objects' + +export class Plugin() { + setup: (core: CoreSetup) => { + core.savedObjects.registerType(mySoType); + } +} + +``` + ## Properties | Property | Type | Description | | --- | --- | --- | | [addClientWrapper](./kibana-plugin-server.savedobjectsservicesetup.addclientwrapper.md) | (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void | Add a [client wrapper factory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) with the given priority. | +| [registerType](./kibana-plugin-server.savedobjectsservicesetup.registertype.md) | (type: SavedObjectsType) => void | Register a [savedObjects type](./kibana-plugin-server.savedobjectstype.md) definition.See the [mappings format](./kibana-plugin-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-server.savedobjectmigrationmap.md) for more details about these. | | [setClientFactoryProvider](./kibana-plugin-server.savedobjectsservicesetup.setclientfactoryprovider.md) | (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void | Set the default [factory provider](./kibana-plugin-server.savedobjectsclientfactoryprovider.md) for creating Saved Objects clients. Only one provider can be set, subsequent calls to this method will fail. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md new file mode 100644 index 00000000000000..89102d292d6341 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md @@ -0,0 +1,60 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsServiceSetup](./kibana-plugin-server.savedobjectsservicesetup.md) > [registerType](./kibana-plugin-server.savedobjectsservicesetup.registertype.md) + +## SavedObjectsServiceSetup.registerType property + +Register a [savedObjects type](./kibana-plugin-server.savedobjectstype.md) definition. + +See the [mappings format](./kibana-plugin-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-server.savedobjectmigrationmap.md) for more details about these. + +Signature: + +```typescript +registerType: (type: SavedObjectsType) => void; +``` + +## Remarks + +The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts. This API is the single entry point to register saved object types in the new platform. + +## Example + + +```ts +// src/plugins/my_plugin/server/saved_objects/my_type.ts +import { SavedObjectsType } from 'src/core/server'; +import * as migrations from './migrations'; + +export const myType: SavedObjectsType = { + name: 'MyType', + hidden: false, + namespaceAgnostic: true, + mappings: { + properties: { + textField: { + type: 'text', + }, + boolField: { + type: 'boolean', + }, + }, + }, + migrations: { + '2.0.0': migrations.migrateToV2, + '2.1.0': migrations.migrateToV2_1 + }, +}; + +// src/plugins/my_plugin/server/plugin.ts +import { SavedObjectsClient, CoreSetup } from 'src/core/server'; +import { myType } from './saved_objects'; + +export class Plugin() { + setup: (core: CoreSetup) => { + core.savedObjects.registerType(myType); + } +} + +``` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md new file mode 100644 index 00000000000000..82e67bb307588f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsServiceStart](./kibana-plugin-server.savedobjectsservicestart.md) > [getTypeRegistry](./kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md) + +## SavedObjectsServiceStart.getTypeRegistry property + +Returns the [registry](./kibana-plugin-server.isavedobjecttyperegistry.md) containing all registered [saved object types](./kibana-plugin-server.savedobjectstype.md) + +Signature: + +```typescript +getTypeRegistry: () => ISavedObjectTypeRegistry; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.md index ad34d76bb33f45..293255bb33c2a2 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservicestart.md @@ -20,4 +20,5 @@ export interface SavedObjectsServiceStart | [createScopedRepository](./kibana-plugin-server.savedobjectsservicestart.createscopedrepository.md) | (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository | Creates a [Saved Objects repository](./kibana-plugin-server.isavedobjectsrepository.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. | | [createSerializer](./kibana-plugin-server.savedobjectsservicestart.createserializer.md) | () => SavedObjectsSerializer | Creates a [serializer](./kibana-plugin-server.savedobjectsserializer.md) that is aware of all registered types. | | [getScopedClient](./kibana-plugin-server.savedobjectsservicestart.getscopedclient.md) | (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract | Creates a [Saved Objects client](./kibana-plugin-server.savedobjectsclientcontract.md) that uses the credentials from the passed in request to authenticate with Elasticsearch. If other plugins have registered Saved Objects client wrappers, these will be applied to extend the functionality of the client.A client that is already scoped to the incoming request is also exposed from the route handler context see [RequestHandlerContext](./kibana-plugin-server.requesthandlercontext.md). | +| [getTypeRegistry](./kibana-plugin-server.savedobjectsservicestart.gettyperegistry.md) | () => ISavedObjectTypeRegistry | Returns the [registry](./kibana-plugin-server.isavedobjecttyperegistry.md) containing all registered [saved object types](./kibana-plugin-server.savedobjectstype.md) | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getalltypes.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getalltypes.md new file mode 100644 index 00000000000000..d71b392c408403 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getalltypes.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [getAllTypes](./kibana-plugin-server.savedobjecttyperegistry.getalltypes.md) + +## SavedObjectTypeRegistry.getAllTypes() method + +Return all [types](./kibana-plugin-server.savedobjectstype.md) currently registered. + +Signature: + +```typescript +getAllTypes(): SavedObjectsType[]; +``` +Returns: + +`SavedObjectsType[]` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getindex.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getindex.md new file mode 100644 index 00000000000000..3479600456c47b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.getindex.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [getIndex](./kibana-plugin-server.savedobjecttyperegistry.getindex.md) + +## SavedObjectTypeRegistry.getIndex() method + +Returns the `indexPattern` property for given type, or `undefined` if the type is not registered. + +Signature: + +```typescript +getIndex(type: string): string | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`string | undefined` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.gettype.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.gettype.md new file mode 100644 index 00000000000000..b32301a2537319 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.gettype.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [getType](./kibana-plugin-server.savedobjecttyperegistry.gettype.md) + +## SavedObjectTypeRegistry.getType() method + +Return the [type](./kibana-plugin-server.savedobjectstype.md) definition for given type name. + +Signature: + +```typescript +getType(type: string): SavedObjectsType | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`SavedObjectsType | undefined` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.ishidden.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.ishidden.md new file mode 100644 index 00000000000000..956ba2cbc1dbde --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.ishidden.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [isHidden](./kibana-plugin-server.savedobjecttyperegistry.ishidden.md) + +## SavedObjectTypeRegistry.isHidden() method + +Returns the `hidden` property for given type, or `false` if the type is not registered. + +Signature: + +```typescript +isHidden(type: string): boolean; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`boolean` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md new file mode 100644 index 00000000000000..e6e578d8936480 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [isNamespaceAgnostic](./kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md) + +## SavedObjectTypeRegistry.isNamespaceAgnostic() method + +Returns the `namespaceAgnostic` property for given type, or `false` if the type is not registered. + +Signature: + +```typescript +isNamespaceAgnostic(type: string): boolean; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`boolean` + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.md new file mode 100644 index 00000000000000..3daad35808624b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) + +## SavedObjectTypeRegistry class + +Registry holding information about all the registered [saved object types](./kibana-plugin-server.savedobjectstype.md). + +Signature: + +```typescript +export declare class SavedObjectTypeRegistry +``` + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [getAllTypes()](./kibana-plugin-server.savedobjecttyperegistry.getalltypes.md) | | Return all [types](./kibana-plugin-server.savedobjectstype.md) currently registered. | +| [getIndex(type)](./kibana-plugin-server.savedobjecttyperegistry.getindex.md) | | Returns the indexPattern property for given type, or undefined if the type is not registered. | +| [getType(type)](./kibana-plugin-server.savedobjecttyperegistry.gettype.md) | | Return the [type](./kibana-plugin-server.savedobjectstype.md) definition for given type name. | +| [isHidden(type)](./kibana-plugin-server.savedobjecttyperegistry.ishidden.md) | | Returns the hidden property for given type, or false if the type is not registered. | +| [isNamespaceAgnostic(type)](./kibana-plugin-server.savedobjecttyperegistry.isnamespaceagnostic.md) | | Returns the namespaceAgnostic property for given type, or false if the type is not registered. | +| [registerType(type)](./kibana-plugin-server.savedobjecttyperegistry.registertype.md) | | Register a [type](./kibana-plugin-server.savedobjectstype.md) inside the registry. A type can only be registered once. subsequent calls with the same type name will throw an error. | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.registertype.md b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.registertype.md new file mode 100644 index 00000000000000..4e6d62ccd28d06 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjecttyperegistry.registertype.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectTypeRegistry](./kibana-plugin-server.savedobjecttyperegistry.md) > [registerType](./kibana-plugin-server.savedobjecttyperegistry.registertype.md) + +## SavedObjectTypeRegistry.registerType() method + +Register a [type](./kibana-plugin-server.savedobjectstype.md) inside the registry. A type can only be registered once. subsequent calls with the same type name will throw an error. + +Signature: + +```typescript +registerType(type: SavedObjectsType): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | SavedObjectsType | | + +Returns: + +`void` + diff --git a/src/core/CONVENTIONS.md b/src/core/CONVENTIONS.md index dd83ab2daca827..2769079757bc38 100644 --- a/src/core/CONVENTIONS.md +++ b/src/core/CONVENTIONS.md @@ -7,6 +7,7 @@ - [Applications](#applications) - [Services](#services) - [Usage Collection](#usage-collection) + - [Saved Objects Types](#saved-objects-types) ## Plugin Structure @@ -31,6 +32,9 @@ my_plugin/ │ └── index.ts ├── collectors │ └── register.ts + ├── saved_objects + │ ├── index.ts + │ └── my_type.ts    ├── services    │   ├── my_service    │   │ └── index.ts @@ -259,6 +263,45 @@ export function registerMyPluginUsageCollector(usageCollection?: UsageCollection } ``` +### Saved Objects Types + +Saved object type definitions should be defined in their own `server/saved_objects` directory. + +The folder should contain a file per type, named after the snake_case name of the type, and an `index.ts` file exporting all the types. + +```typescript +// src/plugins/my-plugin/server/saved_objects/my_type.ts +import { SavedObjectsType } from 'src/core/server'; + +export const myType: SavedObjectsType = { + name: 'my-type', + hidden: false, + namespaceAgnostic: true, + mappings: { + properties: { + someField: { + type: 'text', + }, + anotherField: { + type: 'text', + }, + }, + }, + migrations: { + '1.0.0': migrateFirstTypeToV1, + '2.0.0': migrateFirstTypeToV2, + }, +}; +``` + +```typescript +// src/plugins/my-plugin/server/saved_objects/index.ts + +export { myType } from './my_type'; +``` + +Migration example from the legacy format is available in `src/core/MIGRATION_EXAMPLES.md#saved-objects-types` + ### Naming conventions Export start and setup contracts as `MyPluginStart` and `MyPluginSetup`. diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index d33fd9bcce7a01..6ee432635a947f 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -1207,6 +1207,9 @@ In server code, `core` can be accessed from either `server.newPlatform` or `kbnS | `request.getSavedObjectsClient` | [`context.core.savedObjects.client`](/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md) | | | `request.getUiSettingsService` | [`context.uiSettings.client`](/docs/development/core/server/kibana-plugin-server.iuisettingsclient.md) | | | `kibana.Plugin.deprecations` | [Handle plugin configuration deprecations](#handle-plugin-config-deprecations) and [`PluginConfigDescriptor.deprecations`](docs/development/core/server/kibana-plugin-server.pluginconfigdescriptor.md) | Deprecations from New Platform are not applied to legacy configuration | +| `kibana.Plugin.savedObjectSchemas` | [`core.savedObjects.registerType`](docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md) | [Examples](./MIGRATION_EXAMPLES.md#saved-objects-types) | +| `kibana.Plugin.mappings` | [`core.savedObjects.registerType`](docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md) | [Examples](./MIGRATION_EXAMPLES.md#saved-objects-types) | +| `kibana.Plugin.migrations` | [`core.savedObjects.registerType`](docs/development/core/server/kibana-plugin-server.savedobjectsservicesetup.registertype.md) | [Examples](./MIGRATION_EXAMPLES.md#saved-objects-types) | _See also: [Server's CoreSetup API Docs](/docs/development/core/server/kibana-plugin-server.coresetup.md)_ diff --git a/src/core/MIGRATION_EXAMPLES.md b/src/core/MIGRATION_EXAMPLES.md index 5517dfa7f9a23c..def83ba177fc9f 100644 --- a/src/core/MIGRATION_EXAMPLES.md +++ b/src/core/MIGRATION_EXAMPLES.md @@ -19,6 +19,7 @@ APIs to their New Platform equivalents. - [Updating an application navlink](#updating-application-navlink) - [Chromeless Applications](#chromeless-applications) - [Render HTML Content](#render-html-content) + - [Saved Objects types](#saved-objects-types) ## Configuration @@ -737,3 +738,183 @@ router.get( } ); ``` + +## Saved Objects types + +In the legacy platform, saved object types were registered using static definitions in the `uiExports` part of +the plugin manifest. + +In the new platform, all these registration are to be performed programmatically during your plugin's `setup` phase, +using the core `savedObjects`'s `registerType` setup API. + +The most notable difference is that in the new platform, the type registration is performed in a single call to +`registerType`, passing a new `SavedObjectsType` structure that is a superset of the legacy `schema`, `migrations` +and `mappings`. + +### Concrete example + +Let say we have the following in a legacy plugin: + +```js +// src/legacy/core_plugins/my_plugin/index.js +import mappings from './mappings.json'; +import { migrations } from './migrations'; + +new kibana.Plugin({ + init(server){ + // [...] + }, + uiExports: { + mappings, + migrations, + savedObjectSchemas: { + 'first-type': { + isNamespaceAgnostic: true, + }, + 'second-type': { + isHidden: true, + }, + }, + }, +}) +``` + +```json +// src/legacy/core_plugins/my_plugin/mappings.json +{ + "first-type": { + "properties": { + "someField": { + "type": "text" + }, + "anotherField": { + "type": "text" + } + } + }, + "second-type": { + "properties": { + "textField": { + "type": "text" + }, + "boolField": { + "type": "boolean" + } + } + } +} +``` + +```js +// src/legacy/core_plugins/my_plugin/migrations.js +export const migrations = { + 'first-type': { + '1.0.0': migrateFirstTypeToV1, + '2.0.0': migrateFirstTypeToV2, + }, + 'second-type': { + '1.5.0': migrateSecondTypeToV15, + } +} +``` + +To migrate this, we will have to regroup the declaration per-type. That would become: + +First type: + +```typescript +// src/plugins/my_plugin/server/saved_objects/first_type.ts +import { SavedObjectsType } from 'src/core/server'; + +export const firstType: SavedObjectsType = { + name: 'first-type', + hidden: false, + namespaceAgnostic: true, + mappings: { + properties: { + someField: { + type: 'text', + }, + anotherField: { + type: 'text', + }, + }, + }, + migrations: { + '1.0.0': migrateFirstTypeToV1, + '2.0.0': migrateFirstTypeToV2, + }, +}; +``` + +Second type: + +```typescript +// src/plugins/my_plugin/server/saved_objects/second_type.ts +import { SavedObjectsType } from 'src/core/server'; + +export const secondType: SavedObjectsType = { + name: 'second-type', + hidden: true, + namespaceAgnostic: false, + mappings: { + properties: { + textField: { + type: 'text', + }, + boolField: { + type: 'boolean', + }, + }, + }, + migrations: { + '1.5.0': migrateSecondTypeToV15, + }, +}; +``` + +Registration in the plugin's setup phase: + +```typescript +// src/plugins/my_plugin/server/plugin.ts +import { firstType, secondType } from './saved_objects'; + +export class MyPlugin implements Plugin { + setup({ savedObjects }) { + savedObjects.registerType(firstType); + savedObjects.registerType(secondType); + } +} +``` + +### Changes in structure compared to legacy + +The NP `registerType` expected input is very close to the legacy format. However, there are some minor changes: + +- The `schema.isNamespaceAgnostic` property has been renamed: `SavedObjectsType.namespaceAgnostic` + +- The `schema.indexPattern` was accepting either a `string` or a `(config: LegacyConfig) => string`. `SavedObjectsType.indexPattern` only accepts a string, as you can access the configuration during your plugin's setup phase. + +- The migration function signature has changed: +In legacy, it was `(doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc;` +In new platform, it is now `(doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc;` + +With context being: + +```typescript +export interface SavedObjectMigrationContext { + log: SavedObjectsMigrationLogger; +} +``` + +The changes is very minor though. The legacy migration: + +```js +const migration = (doc, log) => {...} +``` + +Would be converted to: + +```typescript +const migration: SavedObjectMigrationFn = (doc, { log }) => {...} +``` \ No newline at end of file diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 52827b72ee0cc0..e45d4f28edcc37 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -201,6 +201,7 @@ export { SavedObjectsImportRetry, SavedObjectsImportUnknownError, SavedObjectsImportUnsupportedTypeError, + SavedObjectMigrationContext, SavedObjectsMigrationLogger, SavedObjectsRawDoc, SavedObjectSanitizedDoc, @@ -224,6 +225,7 @@ export { SavedObjectsTypeMappingDefinition, SavedObjectsMappingProperties, SavedObjectTypeRegistry, + ISavedObjectTypeRegistry, SavedObjectsType, SavedObjectMigrationMap, SavedObjectMigrationFn, diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index b2501496d87ef4..44f77b5ad215e7 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -263,6 +263,7 @@ export class LegacyService implements CoreService { createScopedRepository: startDeps.core.savedObjects.createScopedRepository, createInternalRepository: startDeps.core.savedObjects.createInternalRepository, createSerializer: startDeps.core.savedObjects.createSerializer, + getTypeRegistry: startDeps.core.savedObjects.getTypeRegistry, }, uiSettings: { asScopedToClient: startDeps.core.uiSettings.asScopedToClient }, }; @@ -298,6 +299,7 @@ export class LegacyService implements CoreService { savedObjects: { setClientFactoryProvider: setupDeps.core.savedObjects.setClientFactoryProvider, addClientWrapper: setupDeps.core.savedObjects.addClientWrapper, + registerType: setupDeps.core.savedObjects.registerType, }, uiSettings: { register: setupDeps.core.uiSettings.register, @@ -329,7 +331,6 @@ export class LegacyService implements CoreService { __internals: { hapiServer: setupDeps.core.http.server, kibanaMigrator: startDeps.core.savedObjects.migrator, - typeRegistry: startDeps.core.savedObjects.typeRegistry, uiPlugins: setupDeps.core.plugins.uiPlugins, elasticsearch: setupDeps.core.elasticsearch, rendering: setupDeps.core.rendering, diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index d6554babab53ea..b8380a3045962c 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -114,18 +114,12 @@ function createCoreSetupMock() { register: uiSettingsServiceMock.createSetupContract().register, }; - const savedObjectsService = savedObjectsServiceMock.createSetupContract(); - const savedObjectMock: jest.Mocked = { - addClientWrapper: savedObjectsService.addClientWrapper, - setClientFactoryProvider: savedObjectsService.setClientFactoryProvider, - }; - const mock: CoreSetupMockType = { capabilities: capabilitiesServiceMock.createSetupContract(), context: contextServiceMock.createSetupContract(), elasticsearch: elasticsearchServiceMock.createSetup(), http: httpMock, - savedObjects: savedObjectMock, + savedObjects: savedObjectsServiceMock.createInternalSetupContract(), uiSettings: uiSettingsMock, uuid: uuidServiceMock.createSetupContract(), getStartServices: jest diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index a7b555a9eba01d..a8a16713f69a41 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -169,6 +169,7 @@ export function createPluginSetupContext( savedObjects: { setClientFactoryProvider: deps.savedObjects.setClientFactoryProvider, addClientWrapper: deps.savedObjects.addClientWrapper, + registerType: deps.savedObjects.registerType, }, uiSettings: { register: deps.uiSettings.register, @@ -206,6 +207,7 @@ export function createPluginStartContext( createInternalRepository: deps.savedObjects.createInternalRepository, createScopedRepository: deps.savedObjects.createScopedRepository, createSerializer: deps.savedObjects.createSerializer, + getTypeRegistry: deps.savedObjects.getTypeRegistry, }, uiSettings: { asScopedToClient: deps.uiSettings.asScopedToClient, diff --git a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap b/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap index 7846e7f1a802a6..89ff2b542c60fb 100644 --- a/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap +++ b/src/core/server/saved_objects/__snapshots__/utils.test.ts.snap @@ -64,8 +64,8 @@ Array [ }, }, "migrations": Object { - "1.0.0": [MockFunction], - "2.0.4": [MockFunction], + "1.0.0": [Function], + "2.0.4": [Function], }, "name": "typeA", "namespaceAgnostic": true, @@ -100,7 +100,7 @@ Array [ }, }, "migrations": Object { - "1.5.3": [MockFunction], + "1.5.3": [Function], }, "name": "typeC", "namespaceAgnostic": false, diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index 5be4458bdf2af5..9bfe6580282581 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -64,7 +64,11 @@ export { SavedObjectsTypeMappingDefinitions, } from './mappings'; -export { SavedObjectMigrationMap, SavedObjectMigrationFn } from './migrations'; +export { + SavedObjectMigrationMap, + SavedObjectMigrationFn, + SavedObjectMigrationContext, +} from './migrations'; export { SavedObjectsType } from './types'; diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index 0e3a4780e12b6e..ef3f546b5e574d 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -585,7 +585,7 @@ describe('DocumentMigrator', () => { typeRegistry: createRegistry({ name: 'dog', migrations: { - '1.2.3': (doc, log) => { + '1.2.3': (doc, { log }) => { log.info(logTestMsg); log.warning(logTestMsg); return doc; diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index b5019b2874becb..0284f513a361c6 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -309,7 +309,8 @@ function wrapWithTry( ) { return function tryTransformDoc(doc: SavedObjectUnsanitizedDoc) { try { - const result = migrationFn(doc, new MigrationLogger(log)); + const context = { log: new MigrationLogger(log) }; + const result = migrationFn(doc, context); // A basic sanity check to help migration authors detect basic errors // (e.g. forgetting to return the transformed doc) diff --git a/src/core/server/saved_objects/migrations/index.ts b/src/core/server/saved_objects/migrations/index.ts index e96986bd702e6d..dc966f0797822c 100644 --- a/src/core/server/saved_objects/migrations/index.ts +++ b/src/core/server/saved_objects/migrations/index.ts @@ -18,4 +18,8 @@ */ export { KibanaMigrator, IKibanaMigrator } from './kibana'; -export { SavedObjectMigrationFn, SavedObjectMigrationMap } from './types'; +export { + SavedObjectMigrationFn, + SavedObjectMigrationMap, + SavedObjectMigrationContext, +} from './types'; diff --git a/src/core/server/saved_objects/migrations/types.ts b/src/core/server/saved_objects/migrations/types.ts index 01741dd2ded1a8..6bc085dde872e3 100644 --- a/src/core/server/saved_objects/migrations/types.ts +++ b/src/core/server/saved_objects/migrations/types.ts @@ -21,14 +21,41 @@ import { SavedObjectUnsanitizedDoc } from '../serialization'; import { SavedObjectsMigrationLogger } from './core/migration_logger'; /** - * A migration function defined for a {@link SavedObjectsType | saved objects type} - * used to migrate it's {@link SavedObjectUnsanitizedDoc | documents} + * A migration function for a {@link SavedObjectsType | saved object type} + * used to migrate it to a given version + * + * @example + * ```typescript + * const migrateProperty: SavedObjectMigrationFn = (doc, { log }) => { + * if(doc.attributes.someProp === null) { + * log.warn('Skipping migration'); + * } else { + * doc.attributes.someProp = migrateProperty(doc.attributes.someProp); + * } + * + * return doc; + * } + * ``` + * + * @public */ export type SavedObjectMigrationFn = ( doc: SavedObjectUnsanitizedDoc, - log: SavedObjectsMigrationLogger + context: SavedObjectMigrationContext ) => SavedObjectUnsanitizedDoc; +/** + * Migration context provided when invoking a {@link SavedObjectMigrationFn | migration handler} + * + * @public + */ +export interface SavedObjectMigrationContext { + /** + * logger instance to be used by the migration handler + */ + log: SavedObjectsMigrationLogger; +} + /** * A map of {@link SavedObjectMigrationFn | migration functions} to be used for a given type. * The map's keys must be valid semver versions. diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index 70f3d5a5b18e40..cbdff163245366 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -38,11 +38,13 @@ const createStartContractMock = () => { createInternalRepository: jest.fn(), createScopedRepository: jest.fn(), createSerializer: jest.fn(), + getTypeRegistry: jest.fn(), }; startContrat.getScopedClient.mockReturnValue(savedObjectsClientMock.create()); startContrat.createInternalRepository.mockReturnValue(savedObjectsRepositoryMock.create()); startContrat.createScopedRepository.mockReturnValue(savedObjectsRepositoryMock.create()); + startContrat.getTypeRegistry.mockReturnValue(typeRegistryMock.create()); return startContrat; }; @@ -52,7 +54,6 @@ const createInternalStartContractMock = () => { ...createStartContractMock(), clientProvider: savedObjectsClientProviderMock.create(), migrator: mockKibanaMigrator.create(), - typeRegistry: typeRegistryMock.create(), }; return internalStartContract; @@ -62,6 +63,7 @@ const createSetupContractMock = () => { const setupContract: jest.Mocked = { setClientFactoryProvider: jest.fn(), addClientWrapper: jest.fn(), + registerType: jest.fn(), }; return setupContract; @@ -70,7 +72,6 @@ const createSetupContractMock = () => { const createInternalSetupContractMock = () => { const internalSetupContract: jest.Mocked = { ...createSetupContractMock(), - registerType: jest.fn(), }; return internalSetupContract; }; diff --git a/src/core/server/saved_objects/saved_objects_service.test.ts b/src/core/server/saved_objects/saved_objects_service.test.ts index 0c7bedecf39f57..a1e2c1e8dbf263 100644 --- a/src/core/server/saved_objects/saved_objects_service.test.ts +++ b/src/core/server/saved_objects/saved_objects_service.test.ts @@ -130,7 +130,7 @@ describe('SavedObjectsService', () => { }); }); - describe('registerType', () => { + describe('#registerType', () => { it('registers the type to the internal typeRegistry', async () => { const coreContext = createCoreContext(); const soService = new SavedObjectsService(coreContext); @@ -231,5 +231,16 @@ describe('SavedObjectsService', () => { expect(startContract.migrator).toBe(migratorInstanceMock); expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1); }); + + describe('#getTypeRegistry', () => { + it('returns the internal type registry of the service', async () => { + const coreContext = createCoreContext({ skipMigration: false }); + const soService = new SavedObjectsService(coreContext); + await soService.setup(createSetupDeps()); + const { getTypeRegistry } = await soService.start({}); + + expect(getTypeRegistry()).toBe(typeRegistryInstanceMock); + }); + }); }); }); diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index fa2b67a3e43b2e..da8f7ab96d6891 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -53,26 +53,13 @@ import { registerRoutes } from './routes'; /** * Saved Objects is Kibana's data persistence mechanism allowing plugins to - * use Elasticsearch for storing and querying state. The - * SavedObjectsServiceSetup API exposes methods for creating and registering - * Saved Object client wrappers. + * use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods + * for registering Saved Object types, creating and registering Saved Object client wrappers and factories. * * @remarks - * Note: The Saved Object setup API's should only be used for creating and - * registering client wrappers. Constructing a Saved Objects client or - * repository for use within your own plugin won't have any of the registered - * wrappers applied and is considered an anti-pattern. Use the Saved Objects - * client from the - * {@link SavedObjectsServiceStart | SavedObjectsServiceStart#getScopedClient } - * method or the {@link RequestHandlerContext | route handler context} instead. - * * When plugins access the Saved Objects client, a new client is created using * the factory provided to `setClientFactory` and wrapped by all wrappers - * registered through `addClientWrapper`. To create a factory or wrapper, - * plugins will have to construct a Saved Objects client. First create a - * repository by calling `scopedRepository` or `internalRepository` and then - * use this repository as the argument to the {@link SavedObjectsClient} - * constructor. + * registered through `addClientWrapper`. * * @example * ```ts @@ -87,6 +74,18 @@ import { registerRoutes } from './routes'; * } * ``` * + * @example + * ```ts + * import { SavedObjectsClient, CoreSetup } from 'src/core/server'; + * import { mySoType } from './saved_objects' + * + * export class Plugin() { + * setup: (core: CoreSetup) => { + * core.savedObjects.registerType(mySoType); + * } + * } + * ``` + * * @public */ export interface SavedObjectsServiceSetup { @@ -104,14 +103,60 @@ export interface SavedObjectsServiceSetup { id: string, factory: SavedObjectsClientWrapperFactory ) => void; + + /** + * Register a {@link SavedObjectsType | savedObjects type} definition. + * + * See the {@link SavedObjectsTypeMappingDefinition | mappings format} and + * {@link SavedObjectMigrationMap | migration format} for more details about these. + * + * @example + * ```ts + * // src/plugins/my_plugin/server/saved_objects/my_type.ts + * import { SavedObjectsType } from 'src/core/server'; + * import * as migrations from './migrations'; + * + * export const myType: SavedObjectsType = { + * name: 'MyType', + * hidden: false, + * namespaceAgnostic: true, + * mappings: { + * properties: { + * textField: { + * type: 'text', + * }, + * boolField: { + * type: 'boolean', + * }, + * }, + * }, + * migrations: { + * '2.0.0': migrations.migrateToV2, + * '2.1.0': migrations.migrateToV2_1 + * }, + * }; + * + * // src/plugins/my_plugin/server/plugin.ts + * import { SavedObjectsClient, CoreSetup } from 'src/core/server'; + * import { myType } from './saved_objects'; + * + * export class Plugin() { + * setup: (core: CoreSetup) => { + * core.savedObjects.registerType(myType); + * } + * } + * ``` + * + * @remarks The type definition is an aggregation of the legacy savedObjects `schema`, `mappings` and `migration` concepts. + * This API is the single entry point to register saved object types in the new platform. + */ + registerType: (type: SavedObjectsType) => void; } /** * @internal */ -export interface InternalSavedObjectsServiceSetup extends SavedObjectsServiceSetup { - registerType: (type: SavedObjectsType) => void; -} +export type InternalSavedObjectsServiceSetup = SavedObjectsServiceSetup; /** * Saved Objects is Kibana's data persisentence mechanism allowing plugins to @@ -159,6 +204,11 @@ export interface SavedObjectsServiceStart { * Creates a {@link SavedObjectsSerializer | serializer} that is aware of all registered types. */ createSerializer: () => SavedObjectsSerializer; + /** + * Returns the {@link ISavedObjectTypeRegistry | registry} containing all registered + * {@link SavedObjectsType | saved object types} + */ + getTypeRegistry: () => ISavedObjectTypeRegistry; } export interface InternalSavedObjectsServiceStart extends SavedObjectsServiceStart { @@ -170,10 +220,6 @@ export interface InternalSavedObjectsServiceStart extends SavedObjectsServiceSta * @deprecated Exposed only for injecting into Legacy */ clientProvider: ISavedObjectsClientProvider; - /** - * @deprecated Exposed only for injecting into Legacy - */ - typeRegistry: ISavedObjectTypeRegistry; } /** @@ -359,6 +405,7 @@ export class SavedObjectsService const repository = repositoryFactory.createScopedRepository(request); return new SavedObjectsClient(repository); }, + typeRegistry: this.typeRegistry, }); if (this.clientFactoryProvider) { const clientFactory = this.clientFactoryProvider(repositoryFactory); @@ -371,11 +418,11 @@ export class SavedObjectsService return { migrator, clientProvider, - typeRegistry: this.typeRegistry, getScopedClient: clientProvider.getClient.bind(clientProvider), createScopedRepository: repositoryFactory.createScopedRepository, createInternalRepository: repositoryFactory.createInternalRepository, createSerializer: () => new SavedObjectsSerializer(this.typeRegistry), + getTypeRegistry: () => this.typeRegistry, }; } diff --git a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts b/src/core/server/saved_objects/saved_objects_type_registry.mock.ts index 6e11920db6b7d1..435e352335ecf4 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.mock.ts +++ b/src/core/server/saved_objects/saved_objects_type_registry.mock.ts @@ -17,9 +17,10 @@ * under the License. */ -import { ISavedObjectTypeRegistry } from './saved_objects_type_registry'; +import { ISavedObjectTypeRegistry, SavedObjectTypeRegistry } from './saved_objects_type_registry'; -const createRegistryMock = (): jest.Mocked => { +const createRegistryMock = (): jest.Mocked> => { const mock = { registerType: jest.fn(), getType: jest.fn(), diff --git a/src/core/server/saved_objects/saved_objects_type_registry.ts b/src/core/server/saved_objects/saved_objects_type_registry.ts index 3f26d696831fd3..b73c80ad9dff77 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.ts +++ b/src/core/server/saved_objects/saved_objects_type_registry.ts @@ -23,14 +23,17 @@ import { SavedObjectsType } from './types'; /** * See {@link SavedObjectTypeRegistry} for documentation. * - * @internal - * */ -export type ISavedObjectTypeRegistry = PublicMethodsOf; + * @public + */ +export type ISavedObjectTypeRegistry = Pick< + SavedObjectTypeRegistry, + 'getType' | 'getAllTypes' | 'getIndex' | 'isNamespaceAgnostic' | 'isHidden' +>; /** - * Registry holding information about all the registered {@link SavedObjectsType | savedObject types}. + * Registry holding information about all the registered {@link SavedObjectsType | saved object types}. * - * @internal + * @public */ export class SavedObjectTypeRegistry { private readonly types = new Map(); diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js index eb210b6843de01..aa9448e61009dc 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.test.js @@ -18,6 +18,7 @@ */ import { SavedObjectsClientProvider } from './scoped_client_provider'; +import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; test(`uses default client factory when one isn't set`, () => { const returnValue = Symbol(); @@ -26,6 +27,7 @@ test(`uses default client factory when one isn't set`, () => { const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry: typeRegistryMock.create(), }); const result = clientProvider.getClient(request); @@ -44,6 +46,7 @@ test(`uses custom client factory when one is set`, () => { const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry: typeRegistryMock.create(), }); clientProvider.setClientFactory(customClientFactoryMock); const result = clientProvider.getClient(request); @@ -68,6 +71,7 @@ test(`throws error when registering a wrapper with a duplicate id`, () => { const defaultClientFactoryMock = jest.fn(); const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry: typeRegistryMock.create(), }); const firstClientWrapperFactoryMock = jest.fn(); const secondClientWrapperFactoryMock = jest.fn(); @@ -80,9 +84,11 @@ test(`throws error when registering a wrapper with a duplicate id`, () => { test(`invokes and uses wrappers in specified order`, () => { const defaultClient = Symbol(); + const typeRegistry = typeRegistryMock.create(); const defaultClientFactoryMock = jest.fn().mockReturnValue(defaultClient); const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry, }); const firstWrappedClient = Symbol('first client'); const firstClientWrapperFactoryMock = jest.fn().mockReturnValue(firstWrappedClient); @@ -98,18 +104,22 @@ test(`invokes and uses wrappers in specified order`, () => { expect(firstClientWrapperFactoryMock).toHaveBeenCalledWith({ request, client: secondWrapperClient, + typeRegistry, }); expect(secondClientWrapperFactoryMock).toHaveBeenCalledWith({ request, client: defaultClient, + typeRegistry, }); }); test(`does not invoke or use excluded wrappers`, () => { const defaultClient = Symbol(); + const typeRegistry = typeRegistryMock.create(); const defaultClientFactoryMock = jest.fn().mockReturnValue(defaultClient); const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry, }); const firstWrappedClient = Symbol('first client'); const firstClientWrapperFactoryMock = jest.fn().mockReturnValue(firstWrappedClient); @@ -128,6 +138,7 @@ test(`does not invoke or use excluded wrappers`, () => { expect(firstClientWrapperFactoryMock).toHaveBeenCalledWith({ request, client: defaultClient, + typeRegistry, }); expect(secondClientWrapperFactoryMock).not.toHaveBeenCalled(); }); @@ -137,6 +148,7 @@ test(`allows all wrappers to be excluded`, () => { const defaultClientFactoryMock = jest.fn().mockReturnValue(defaultClient); const clientProvider = new SavedObjectsClientProvider({ defaultClientFactory: defaultClientFactoryMock, + typeRegistry: typeRegistryMock.create(), }); const firstWrappedClient = Symbol('first client'); const firstClientWrapperFactoryMock = jest.fn().mockReturnValue(firstWrappedClient); diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts index 8aadc4f57317c6..24813cd8d9ab8d 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts @@ -19,6 +19,7 @@ import { PriorityCollection } from './priority_collection'; import { SavedObjectsClientContract } from '../../types'; import { SavedObjectsRepositoryFactory } from '../../saved_objects_service'; +import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { KibanaRequest } from '../../../http'; /** @@ -27,6 +28,7 @@ import { KibanaRequest } from '../../../http'; */ export interface SavedObjectsClientWrapperOptions { client: SavedObjectsClientContract; + typeRegistry: ISavedObjectTypeRegistry; request: KibanaRequest; } @@ -84,9 +86,17 @@ export class SavedObjectsClientProvider { }>(); private _clientFactory: SavedObjectsClientFactory; private readonly _originalClientFactory: SavedObjectsClientFactory; - - constructor({ defaultClientFactory }: { defaultClientFactory: SavedObjectsClientFactory }) { + private readonly _typeRegistry: ISavedObjectTypeRegistry; + + constructor({ + defaultClientFactory, + typeRegistry, + }: { + defaultClientFactory: SavedObjectsClientFactory; + typeRegistry: ISavedObjectTypeRegistry; + }) { this._originalClientFactory = this._clientFactory = defaultClientFactory; + this._typeRegistry = typeRegistry; } addClientWrapperFactory( @@ -129,6 +139,7 @@ export class SavedObjectsClientProvider { return factory({ request, client: clientToWrap, + typeRegistry: this._typeRegistry, }); }, client); } diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 9c204784b0aeb3..495d896ad12cd4 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -34,6 +34,8 @@ export { } from './import/types'; import { LegacyConfig } from '../legacy'; +import { SavedObjectUnsanitizedDoc } from './serialization'; +import { SavedObjectsMigrationLogger } from './migrations/core/migration_logger'; export { SavedObjectAttributes, SavedObjectAttribute, @@ -273,9 +275,26 @@ export interface SavedObjectsLegacyMapping { * @deprecated */ export interface SavedObjectsLegacyMigrationDefinitions { - [type: string]: SavedObjectMigrationMap; + [type: string]: SavedObjectLegacyMigrationMap; } +/** + * @internal + * @deprecated + */ +export interface SavedObjectLegacyMigrationMap { + [version: string]: SavedObjectLegacyMigrationFn; +} + +/** + * @internal + * @deprecated + */ +export type SavedObjectLegacyMigrationFn = ( + doc: SavedObjectUnsanitizedDoc, + log: SavedObjectsMigrationLogger +) => SavedObjectUnsanitizedDoc; + /** * @internal * @deprecated diff --git a/src/core/server/saved_objects/utils.test.ts b/src/core/server/saved_objects/utils.test.ts index 1e2b9f6a0f6945..0a56535ac85097 100644 --- a/src/core/server/saved_objects/utils.test.ts +++ b/src/core/server/saved_objects/utils.test.ts @@ -20,7 +20,8 @@ import { legacyServiceMock } from '../legacy/legacy_service.mock'; import { convertLegacyTypes, convertTypesToLegacySchema } from './utils'; import { SavedObjectsLegacyUiExports, SavedObjectsType } from './types'; -import { LegacyConfig } from 'kibana/server'; +import { LegacyConfig, SavedObjectMigrationContext } from 'kibana/server'; +import { SavedObjectUnsanitizedDoc } from './serialization'; describe('convertLegacyTypes', () => { let legacyConfig: ReturnType; @@ -190,8 +191,48 @@ describe('convertLegacyTypes', () => { const converted = convertLegacyTypes(uiExports, legacyConfig); expect(converted.length).toEqual(2); - expect(converted[0].migrations).toEqual(migrationsA); - expect(converted[1].migrations).toEqual(migrationsB); + expect(Object.keys(converted[0]!.migrations!)).toEqual(Object.keys(migrationsA)); + expect(Object.keys(converted[1]!.migrations!)).toEqual(Object.keys(migrationsB)); + }); + + it('converts the migration to the new format', () => { + const legacyMigration = jest.fn(); + const migrationsA = { + '1.0.0': legacyMigration, + }; + + const uiExports: SavedObjectsLegacyUiExports = { + savedObjectMappings: [ + { + pluginId: 'pluginA', + properties: { + typeA: { + properties: { + fieldA: { type: 'text' }, + }, + }, + }, + }, + ], + savedObjectMigrations: { + typeA: migrationsA, + }, + savedObjectSchemas: {}, + savedObjectValidations: {}, + savedObjectsManagement: {}, + }; + + const converted = convertLegacyTypes(uiExports, legacyConfig); + expect(Object.keys(converted[0]!.migrations!)).toEqual(['1.0.0']); + + const migration = converted[0]!.migrations!['1.0.0']!; + + const doc = {} as SavedObjectUnsanitizedDoc; + const context = { log: {} } as SavedObjectMigrationContext; + migration(doc, context); + + expect(legacyMigration).toHaveBeenCalledTimes(1); + expect(legacyMigration).toHaveBeenCalledWith(doc, context.log); }); it('merges everything when all are present', () => { diff --git a/src/core/server/saved_objects/utils.ts b/src/core/server/saved_objects/utils.ts index 5c4d0ccb84b255..bb2c42c6a362c1 100644 --- a/src/core/server/saved_objects/utils.ts +++ b/src/core/server/saved_objects/utils.ts @@ -18,7 +18,12 @@ */ import { LegacyConfig } from '../legacy'; -import { SavedObjectsType, SavedObjectsLegacyUiExports } from './types'; +import { SavedObjectMigrationMap } from './migrations'; +import { + SavedObjectsType, + SavedObjectsLegacyUiExports, + SavedObjectLegacyMigrationMap, +} from './types'; import { SavedObjectsSchemaDefinition } from './schema'; /** @@ -49,7 +54,7 @@ export const convertLegacyTypes = ( ? schema.indexPattern(legacyConfig) : schema?.indexPattern, convertToAliasScript: schema?.convertToAliasScript, - migrations: migrations ?? {}, + migrations: convertLegacyMigrations(migrations ?? {}), }; }), ]; @@ -74,3 +79,14 @@ export const convertTypesToLegacySchema = ( }; }, {} as SavedObjectsSchemaDefinition); }; + +const convertLegacyMigrations = ( + legacyMigrations: SavedObjectLegacyMigrationMap +): SavedObjectMigrationMap => { + return Object.entries(legacyMigrations).reduce((migrated, [version, migrationFn]) => { + return { + ...migrated, + [version]: (doc, context) => migrationFn(doc, context.log), + }; + }, {} as SavedObjectMigrationMap); +}; diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index f717f30fdb0cfd..8f4feb7169651e 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -929,6 +929,9 @@ export type IsAuthenticated = (request: KibanaRequest | LegacyRequest) => boolea // @public export type ISavedObjectsRepository = Pick; +// @public +export type ISavedObjectTypeRegistry = Pick; + // @public export type IScopedClusterClient = Pick; @@ -1489,12 +1492,15 @@ export interface SavedObjectAttributes { // @public export type SavedObjectAttributeSingle = string | number | boolean | null | undefined | SavedObjectAttributes; +// @public +export interface SavedObjectMigrationContext { + log: SavedObjectsMigrationLogger; +} + // Warning: (ae-forgotten-export) The symbol "SavedObjectUnsanitizedDoc" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SavedObjectMigrationFn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "SavedObjectUnsanitizedDoc" // // @public -export type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, log: SavedObjectsMigrationLogger) => SavedObjectUnsanitizedDoc; +export type SavedObjectMigrationFn = (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => SavedObjectUnsanitizedDoc; // @public export interface SavedObjectMigrationMap { @@ -1619,6 +1625,8 @@ export interface SavedObjectsClientWrapperOptions { client: SavedObjectsClientContract; // (undocumented) request: KibanaRequest; + // (undocumented) + typeRegistry: ISavedObjectTypeRegistry; } // @public @@ -2013,8 +2021,6 @@ export class SavedObjectsSchema { // @public export class SavedObjectsSerializer { - // Warning: (ae-forgotten-export) The symbol "ISavedObjectTypeRegistry" needs to be exported by the entry point index.d.ts - // // @internal constructor(registry: ISavedObjectTypeRegistry); generateRawId(namespace: string | undefined, type: string, id?: string): string; @@ -2026,6 +2032,7 @@ export class SavedObjectsSerializer { // @public export interface SavedObjectsServiceSetup { addClientWrapper: (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void; + registerType: (type: SavedObjectsType) => void; setClientFactoryProvider: (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void; } @@ -2035,6 +2042,7 @@ export interface SavedObjectsServiceStart { createScopedRepository: (req: KibanaRequest, extraTypes?: string[]) => ISavedObjectsRepository; createSerializer: () => SavedObjectsSerializer; getScopedClient: (req: KibanaRequest, options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract; + getTypeRegistry: () => ISavedObjectTypeRegistry; } // @public (undocumented) @@ -2069,7 +2077,7 @@ export interface SavedObjectsUpdateResponse extends Omit { }, }, }; + + const coreStart = coreMock.createStart(); + coreStart.savedObjects.getTypeRegistry.mockReturnValue(typeRegistry); + mockKbnServer = { newPlatform: { __internals: { kibanaMigrator: migrator, savedObjectsClientProvider: clientProvider, - typeRegistry, }, setup: { core: coreMock.createSetup(), }, start: { - core: coreMock.createStart(), + core: coreStart, }, }, server: mockServer, From 457783e8395b622de80f7c176c95172d5ce21c3b Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 26 Feb 2020 08:25:03 -0700 Subject: [PATCH 73/73] [kbn/ui-shared-deps] load base css file (#58520) Co-authored-by: Elastic Machine --- packages/kbn-ui-shared-deps/index.d.ts | 5 +++++ packages/kbn-ui-shared-deps/index.js | 1 + packages/kbn-ui-shared-deps/scripts/build.js | 7 +++++-- src/legacy/ui/ui_render/ui_render_mixin.js | 1 + tasks/config/karma.js | 1 + 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/kbn-ui-shared-deps/index.d.ts b/packages/kbn-ui-shared-deps/index.d.ts index 132445bbde7451..7ee96050a1248a 100644 --- a/packages/kbn-ui-shared-deps/index.d.ts +++ b/packages/kbn-ui-shared-deps/index.d.ts @@ -27,6 +27,11 @@ export const distDir: string; */ export const distFilename: string; +/** + * Filename of the unthemed css file in the distributable directory + */ +export const baseCssDistFilename: string; + /** * Filename of the dark-theme css file in the distributable directory */ diff --git a/packages/kbn-ui-shared-deps/index.js b/packages/kbn-ui-shared-deps/index.js index c7c004bd55794d..d1bb93ddecd0a4 100644 --- a/packages/kbn-ui-shared-deps/index.js +++ b/packages/kbn-ui-shared-deps/index.js @@ -21,6 +21,7 @@ const Path = require('path'); exports.distDir = Path.resolve(__dirname, 'target'); exports.distFilename = 'kbn-ui-shared-deps.js'; +exports.baseCssDistFilename = 'kbn-ui-shared-deps.css'; exports.lightCssDistFilename = 'kbn-ui-shared-deps.light.css'; exports.darkCssDistFilename = 'kbn-ui-shared-deps.dark.css'; exports.externals = { diff --git a/packages/kbn-ui-shared-deps/scripts/build.js b/packages/kbn-ui-shared-deps/scripts/build.js index 8b7c22dac24ff3..e45b3dbed1748f 100644 --- a/packages/kbn-ui-shared-deps/scripts/build.js +++ b/packages/kbn-ui-shared-deps/scripts/build.js @@ -64,8 +64,11 @@ run( }); compiler.hooks.watchRun.tap('report on start', () => { - process.stdout.cursorTo(0, 0); - process.stdout.clearScreenDown(); + if (process.stdout.isTTY) { + process.stdout.cursorTo(0, 0); + process.stdout.clearScreenDown(); + } + log.info('Running webpack compilation...'); }); diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index 21c10bb20962fb..0a1b95c23450b4 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -112,6 +112,7 @@ export function uiRenderMixin(kbnServer, server, config) { ); const styleSheetPaths = [ ...dllStyleChunks, + `${basePath}/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, ...(darkMode ? [ `${basePath}/bundles/kbn-ui-shared-deps/${UiSharedDeps.darkCssDistFilename}`, diff --git a/tasks/config/karma.js b/tasks/config/karma.js index 9992dafed41c5f..24e97aa081e510 100644 --- a/tasks/config/karma.js +++ b/tasks/config/karma.js @@ -64,6 +64,7 @@ module.exports = function(grunt) { ? `http://localhost:5610/bundles/tests.bundle.js` : `http://localhost:5610/bundles/tests.bundle.js?shards=${TOTAL_CI_SHARDS}&shard_num=${shardNum}`, + `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`, // this causes tilemap tests to fail, probably because the eui styles haven't been // included in the karma harness a long some time, if ever // `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}`,

ufUdkMWXl>|PBtPjqT>MV4p+N>=w`{+aU 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