From 6e6be37f2bfaf55b578d67747f10c6e24e63f2b1 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 30 Jan 2019 10:20:56 -0700 Subject: [PATCH 01/40] update to eui 6.7.4 (#29560) * update to eui 6.7.4 * remove use of euiHeaderChildSizeMobile for xs header check --- package.json | 2 +- x-pack/package.json | 2 +- x-pack/plugins/gis/public/_main.scss | 6 ------ yarn.lock | 8 ++++---- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index ca5bdedd29744..186a1c1942b69 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ }, "dependencies": { "@elastic/datemath": "5.0.2", - "@elastic/eui": "6.7.2", + "@elastic/eui": "6.7.4", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "2.3.2", diff --git a/x-pack/package.json b/x-pack/package.json index 79ead4b403719..48d39046fbf97 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -120,7 +120,7 @@ }, "dependencies": { "@elastic/datemath": "5.0.2", - "@elastic/eui": "6.7.2", + "@elastic/eui": "6.7.4", "@elastic/node-crypto": "0.1.2", "@elastic/numeral": "2.3.2", "@kbn/babel-preset": "1.0.0", diff --git a/x-pack/plugins/gis/public/_main.scss b/x-pack/plugins/gis/public/_main.scss index 5e8b75daad1c6..f7794072b8e74 100644 --- a/x-pack/plugins/gis/public/_main.scss +++ b/x-pack/plugins/gis/public/_main.scss @@ -8,12 +8,6 @@ overflow: hidden; } -@include euiBreakpoint('xs') { - #gis-plugin { - height: calc(100vh - #{$euiHeaderChildSizeMobile}); - } -} - #react-gis-root { flex-grow: 1; display: flex; diff --git a/yarn.lock b/yarn.lock index 284562eae507e..b45d7700f7cdf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -803,10 +803,10 @@ tabbable "^1.1.0" uuid "^3.1.0" -"@elastic/eui@6.7.2": - version "6.7.2" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-6.7.2.tgz#3cf70915deafc9f9a5c63dc04509845f23704de6" - integrity sha512-ssZGkbXFWEBPpB4OscqzPaaH9oTAhR8BnCivqggykCAuchRlKni8yy5D+BuF+Nns2FS5WZ7342Fzs5qphEULjA== +"@elastic/eui@6.7.4": + version "6.7.4" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-6.7.4.tgz#04fb02cfee7d7851ca90659eae121555f56ff83a" + integrity sha512-h0542LAqKjFdbyV8heiwQOlGe6fkThNagPCr7wymFBF/HYBWvIcJSplSVVRNgwgNRvWEXEGLOGrVLInn0Atfpg== dependencies: "@types/lodash" "^4.14.116" "@types/numeral" "^0.0.25" From 85d8f38cd59a6185ba44af340e191bdc8d6f7ab2 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 30 Jan 2019 09:33:04 -0800 Subject: [PATCH 02/40] [chrome/breadcrumbs] add push/filter methods (#29566) --- src/ui/public/chrome/api/breadcrumbs.ts | 128 ++++++++++++++---------- src/ui/public/chrome/index.d.ts | 5 +- 2 files changed, 78 insertions(+), 55 deletions(-) diff --git a/src/ui/public/chrome/api/breadcrumbs.ts b/src/ui/public/chrome/api/breadcrumbs.ts index c493b36960868..494989462ca89 100644 --- a/src/ui/public/chrome/api/breadcrumbs.ts +++ b/src/ui/public/chrome/api/breadcrumbs.ts @@ -18,21 +18,11 @@ */ import { IRootScopeService } from 'angular'; - -// @ts-ignore -import { uiModules } from 'ui/modules'; import { fatalError } from 'ui/notify/fatal_error'; import { Breadcrumb, ChromeStartContract } from '../../../../core/public/chrome'; export { Breadcrumb }; -export interface BreadcrumbsApi { - get$(): ReturnType; - set(newBreadcrumbs: Breadcrumb[]): void; -} - -export interface WithBreadcrumbsApi { - breadcrumbs: BreadcrumbsApi; -} +export type BreadcrumbsApi = ReturnType['breadcrumbs']; let newPlatformChrome: ChromeStartContract; export function __newPlatformInit__(instance: ChromeStartContract) { @@ -43,62 +33,94 @@ export function __newPlatformInit__(instance: ChromeStartContract) { newPlatformChrome = instance; } -export function initBreadcrumbsApi( - chrome: { [key: string]: any }, - internals: { [key: string]: any } -) { +function createBreadcrumbsApi(chrome: { [key: string]: any }) { // A flag used to determine if we should automatically // clear the breadcrumbs between angular route changes. let breadcrumbSetSinceRouteChange = false; + let currentBreadcrumbs: Breadcrumb[] = []; // reset breadcrumbSetSinceRouteChange any time the breadcrumbs change, even // if it was done directly through the new platform newPlatformChrome.getBreadcrumbs$().subscribe({ - next() { + next(nextBreadcrumbs) { breadcrumbSetSinceRouteChange = true; + currentBreadcrumbs = nextBreadcrumbs; }, }); - chrome.breadcrumbs = { - get$() { - return newPlatformChrome.getBreadcrumbs$(); + return { + breadcrumbs: { + /** + * Get an observerable that emits the current list of breadcrumbs + * and emits each update to the breadcrumbs + */ + get$() { + return newPlatformChrome.getBreadcrumbs$(); + }, + + /** + * Replace the set of breadcrumbs with a new set + */ + set(newBreadcrumbs: Breadcrumb[]) { + newPlatformChrome.setBreadcrumbs(newBreadcrumbs); + }, + + /** + * Add a breadcrumb to the end of the list of breadcrumbs + */ + push(breadcrumb: Breadcrumb) { + newPlatformChrome.setBreadcrumbs([...currentBreadcrumbs, breadcrumb]); + }, + + /** + * Filter the current set of breadcrumbs with a function. Works like Array#filter() + */ + filter(fn: (breadcrumb: Breadcrumb, i: number, all: Breadcrumb[]) => boolean) { + newPlatformChrome.setBreadcrumbs(currentBreadcrumbs.filter(fn)); + }, }, - set(newBreadcrumbs: Breadcrumb[]) { - newPlatformChrome.setBreadcrumbs(newBreadcrumbs); + /** + * internal angular run function that will be called when angular bootstraps and + * lets us integrate with the angular router so that we can automatically clear + * the breadcrumbs if we switch to a Kibana app that does not use breadcrumbs correctly + */ + $setupBreadcrumbsAutoClear: ($rootScope: IRootScopeService, $injector: any) => { + const uiSettings = chrome.getUiSettingsClient(); + const $route = $injector.has('$route') ? $injector.get('$route') : {}; + + $rootScope.$on('$routeChangeStart', () => { + breadcrumbSetSinceRouteChange = false; + }); + + $rootScope.$on('$routeChangeSuccess', () => { + const current = $route.current || {}; + + if (breadcrumbSetSinceRouteChange || (current.$$route && current.$$route.redirectTo)) { + return; + } + + const k7BreadcrumbsProvider = current.k7Breadcrumbs; + if (!k7BreadcrumbsProvider || !uiSettings.get('k7design')) { + newPlatformChrome.setBreadcrumbs([]); + return; + } + + try { + chrome.breadcrumbs.set($injector.invoke(k7BreadcrumbsProvider)); + } catch (error) { + fatalError(error); + } + }); }, }; +} - // define internal angular run function that will be called when angular - // bootstraps and lets us integrate with the angular router so that we can - // automatically clear the breadcrumbs if we switch to a Kibana app that - // does not use breadcrumbs correctly - internals.$setupBreadcrumbsAutoClear = ($rootScope: IRootScopeService, $injector: any) => { - const uiSettings = chrome.getUiSettingsClient(); - const $route = $injector.has('$route') ? $injector.get('$route') : {}; - - $rootScope.$on('$routeChangeStart', () => { - breadcrumbSetSinceRouteChange = false; - }); - - $rootScope.$on('$routeChangeSuccess', () => { - const current = $route.current || {}; - - if (breadcrumbSetSinceRouteChange || (current.$$route && current.$$route.redirectTo)) { - return; - } - - const k7BreadcrumbsProvider = current.k7Breadcrumbs; - if (!k7BreadcrumbsProvider || !uiSettings.get('k7design')) { - newPlatformChrome.setBreadcrumbs([]); - return; - } - - try { - chrome.breadcrumbs.set($injector.invoke(k7BreadcrumbsProvider)); - } catch (error) { - fatalError(error); - } - }); - }; +export function initBreadcrumbsApi( + chrome: { [key: string]: any }, + internals: { [key: string]: any } +) { + const { breadcrumbs, $setupBreadcrumbsAutoClear } = createBreadcrumbsApi(chrome); + chrome.breadcrumbs = breadcrumbs; + internals.$setupBreadcrumbsAutoClear = $setupBreadcrumbsAutoClear; } diff --git a/src/ui/public/chrome/index.d.ts b/src/ui/public/chrome/index.d.ts index 5f32e179de068..a30bd94f8fc4d 100644 --- a/src/ui/public/chrome/index.d.ts +++ b/src/ui/public/chrome/index.d.ts @@ -18,14 +18,15 @@ */ import { Brand } from '../../../core/public/chrome'; -import { WithBreadcrumbsApi } from './api/breadcrumbs'; +import { BreadcrumbsApi } from './api/breadcrumbs'; export { Breadcrumb } from './api/breadcrumbs'; interface IInjector { get(injectable: string): T; } -declare interface Chrome extends WithBreadcrumbsApi { +declare interface Chrome { + breadcrumbs: BreadcrumbsApi; addBasePath(path: T): T; dangerouslyGetActiveInjector(): Promise; getBasePath(): string; From 6e04960b71b92f467c692c6632c099154f0e2796 Mon Sep 17 00:00:00 2001 From: kaiyan-sheng Date: Wed, 30 Jan 2019 11:11:35 -0700 Subject: [PATCH 03/40] Add AWS Metricbeat Module Home Tutorial (#29488) * Add Kibana Home Tutorial for AWS Metricbeat Module * register awsMetrics * Add screenshot and link dashboard to home tutorial * Change dashboard name from aws to AWS --- .../aws_metrics/screenshot.png | Bin 0 -> 401525 bytes .../server/tutorials/aws_metrics/index.js | 64 ++++++++++++++++++ .../kibana/server/tutorials/register.js | 2 + 3 files changed, 66 insertions(+) create mode 100644 src/legacy/core_plugins/kibana/public/home/tutorial_resources/aws_metrics/screenshot.png create mode 100644 src/legacy/core_plugins/kibana/server/tutorials/aws_metrics/index.js diff --git a/src/legacy/core_plugins/kibana/public/home/tutorial_resources/aws_metrics/screenshot.png b/src/legacy/core_plugins/kibana/public/home/tutorial_resources/aws_metrics/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..9d179622189a2f13e0e91979c792066de1ea9b8b GIT binary patch literal 401525 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

Y6t$NrON{kcocmQkbB7-a*SB`#o}V;VK!>rN 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�y;&a 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 z zf>0**E0~wFsmzGE^DxLXWTG+Da)?A`@4aQQ+4P&hz|NMYiewX$o~FGrW54ov)c1+ZGO@2J zrQ3};t7umPIuJRoKAQ*O(MRo9l&Y4(c+*N^(kC{@$Z0oCgH`=nYu#|PsnKAf@|(f* zq_ON*u08hmN@_>EdnwjX9%7SJhUp_ZiEpP&s?PW|wOHf$XS;;UX+&|P(Aq-i_uM$6 zA>`(CDS<0LCGY-9TuR~G+tY~>6R^kW15I90d5d7d zm!BU*y?<@yXK4pD0jnwbw$SqIgCrbd{P9NzHjUT69H5Fp{pF=X8qoszK>wYId{b=J2`udn5~ zEKO~v#t`}q$3FRM8~KD^Nu6!v($6`e5|zZrNIj>4r0==q0_74Sg6f;NexXaV(fIfE{&c-g*@0%qw98J+-K($4sExtL~iZL{E)a&!pE#8Ica!2 z7vK4A6XRz_va_tK$A*+!pV`${Nn6JD^Y+JQ4HntDofK%uv*|V)HOdHW<-Q#4$Fv?A z{Bo75`!I}eD8NySR$2Z7a{noLx&0wgaOdI~TaedpGp)LVB(9CYg z%2{ZbveIW$=bkWhvY+)X;!(m9t48Q|8U7M;MqYZ2l=oI_pFG&p_!P0i34#hkAT#VX zsVp30q%+5}B5r${Q_fMz>;zJkxx@Y3^y$)_JoOF(55n$~&Z(cN)7y@D^L+1?y$y<5 zM%A2D^zqkIGl36lii89LI%4q8ia=RokfDFZ+Hq#C6`Tkea2YgJGd%Y?F9&|CVcX!x@Jf-EcpR?#U_#zof}s^O+}(J$qEPv}1#uRg z=QZ~Ko`wcWiudml4S(CF%&VV;Y6dE!BOpqf=MV_yNLnRTy zD+_;@p5ouh45J+UihXlm`i%3<-xT7>NQI{sQMirtS}^U$MjxR-&tl0w-!@*oAx4)& z$K$$ZnucO7{GFja%bMcIP`i=F>gzeOA1m7aN(DN$x|8U;7x>$LJbip^Ccc6|aY=Jk9!ubZg+> zC`6rPy!frzRypc``(5)l4h7X3>;LnTVCVo$U}1r{AQ9`Hs_IFnEOZmTNilGWINlt4 zcDlb<((Y4NX*;9-xp<)*9(6K%v5{5M>yr9#5tPSk;0qmJnx)`j2cY=0<(_y#BJS6~ zx*t_#)`gQM=3D3G3%m3zgwl(W+~Ix`4Z*{5m-AP8hjk~-Imep>X3Z2L2H#q8^#j(@dc z^Bua&%b2&2vA)0Z^?%t{Dh83USfLUE=eQJtGzm;9$~}-8;CYb7Z$xxOfiMi=O4CAe^S6rGeH(w` zjHf;MV{Zp}KhmZSvMA&Z_SU#uI3=kSPu(LHwDfW5#xLlIhY4=g?&{JJ=+5JlZttv> zX|yL*@yt);6QnKgtkulRTbglr&)8PqPkpAGp?d0P*A4G|)SP*jj{j_;NbAw}05%q= z0-kDZ_~1?uUl*HM=x|@ZUS5cSM@h1D)njwTiio}jxPtV>Z_JrGcvO1*AEAw0^wyo3 zxt+8j^?NoL^@XA{JIBGX?|&;ttxGw~$jqWFbkXmMEq0DAHqov^{(bVy(umfFj1?1N z7}Uw;`JTP_v98-nJ4TYDigM66 z`kbGv<~_Nga+!)w`PiMbUt{P^)Khn2^Vw+k&u9O;+chi{_y1aC85%4^NAm>>GF7Nc z4+JiCavEr*Lz%hTFHg1+`ee#Im{zS}tklfN_l@wOEqax&3Krv)U}2H2NigSVBebwY z?~|>y-)~I|x82`*oovCQDa5i;ri$L&<~6TIwul2BE6cY<<(Y-{1>)}f%hR{p$wj`0 zbuo=m8vM`w#}?P#K-?AnS15`=0r)7&doN&y`*a@Joc_7MW5dx;ujlJ@HzbV{n;>dv z*_7qiGk}Zr$9#9TvY5$Zgu0y?U8+COmD@OP9d3B#(QGr__2-9}jbLdoGBlbz^#8LE zoK87Qd&#}zQo}l}NFj^(?acNlIgC$mK{KEWu}W^^!~K&Z-<=`ktSO7fRQ5rvJzBa0 z2AM22)W?9F>?`Ng+B&bi>X~Gs2K9e1wB@KNHr|-S{w`%~W8Y3oOS?zW!&f!z)JZN3 zXS7N#VH!bs-hxn^+yhb_eWe(GQH5g&kIi~kk8CXAHresEw z``^+mZ{l*EG9p^;M3H4upzE^p6b}18h|R3<@HbhfU{vgPpdrn#6-blcJxGj)RzC826B}%g`p!xtDSGz_s<93b=?o3QxjRH zUQys4&pWIY9^dP!cRY4qpv7JbId*2ASLgcldp}5$yfYX<-~ zp0MO7A)nz##3~!^S<&yWS4huhNH`tO986BTYFO?UJ7y*w;_D0%xfw^lZ(Zq|i9ldS zGBi}^C=5?Nr6M^1@9c8G)LN_g2Ut9QPXsyLo>D;tl)3en`S%09&;$jyga54p9>La+ z?#F^QlWbGvt-p1mU2lqi+z&XcY5G%%C8o21)nnB!?f@rm zql>k4-G~43swxhmS$fP*2uYSs3~`9{8OF-ipnHkG$_Q1)jE{&;feFz|<#D~H`&9@_ z?e)M2B%rf`t}+HGf9m<~2e=@>PBj8Z`bsk()oRaH+N6Y55^V#O4>{oeP5a=%0~TK# zYB4sjQC5~LKU#9KQ{IfPfD;Zm_RdYw2O+am%a6qt;TASYub zqXhEVOnz}40v+(X!XeqHD9DYWL4!gi*^L3~FNNHvKJ)xqXSlm|Q_vNfVg89J5lBw|MJqXDb)d$_*I93h@9 z$KRt#1C5sjLk&^}q?c9w{m;6gwHvtre{=#4f~-hO z2!o}QtqG^KBprDmqNj0*On(fjl6o*@F{pFf-6CP?c!4PFgY?8LW%&=RYdBGuDGu-H z{1O>kjCaq@#~vQ~zd_7p*pEbLmc^h^rRopz={ufvu1^)&X9mL?jmIbr_Upx3}4YQEr zFe=&)JlQ)O&=DPH0?kFBF00*-{{sL_$$;4V)v2|c?S-zc^;@998T;hscufAepyP^+ z^>k^r*FI>Ew~UWF?*2U-UEGjvN3GcZu)8jt%X&e<6t4%Dwc}LGdzZ)Vj)xp4ua4ad zL|ab&i+Rkyo%#YZBswU?%!;1+*!1@}oo$4p21=Y+1&5Z9w(c_qy+Zhq3XkLXwcD)wa$ zs7EEf!6N>eWnZ(5YQ4}^`7Qb+AkUnWN*|0BI7Tx0HB!Wv<*;EAa3_KLrT{&pok zuGYz28Hv4(38SvX`mf+%LtLVE4}e4M39hBPWB{(${kQ)QP;_nk%D`=~rsrPc5qX~n zi+I+CSy%LXpO4)_|K;L6M0kQ{d#tcv@n;#7034#;rxkT3J1ZSg@QJTlEYe{(l&k>d zch0~G`T@f5n_@tnB)Uh(1DzM2{SPmJt~OIi!%?Kmzl4)r4&Bo3c6HWmvu^Vl>?P7V z^vb%8NfH0P8+tn!s`_LhKWlaQSxNoJ=0>^)K#8Z4e6!Wb?8wO?6+j9PW5ZU0hwJX$hY+#4LOzvt{}3`K!VfN~LR zdv@xuKGgU6oz6y2!Gyv%mEQe}n(^0O7Gg9T6tuDdLld;Fih=#CO#akAE0s?B{pC*k zvx&)d7GK2P zp2g4pSNrh%J$k6128jN)3TLL?SzQ}4-3@irV9Q-C!&zmZ@?$&Y09E_bC$rn!Mmf99 z>bgTUEDw$hQvQLNIRLC}{SF}5i__J^)h>kitUQGv7&vNi2u9jnHRpBL8P6w}dR5!s z$jnAJu|)pN9-snak4m&S)A7$4*NvO@%}MNc*JhDt!V6w0E_J)#xR1X4(eCXTDs#^Z z!ya9vl8E$3ng3&yI1qbX;&Xh9TA2{3z5A=7elK}lCp!9k&`RuI7Jvl;&KEdfld6yx zB+U+!Z0H9+KG5Q$AayFi#(UlGuYUIN&FUK@6{!8F<7Y<7xwi4gXD8J$0hdq+?cYym z2Q6|4)4hOOdgK|TjiD?~a5xgFM7_?lXdcpQ`)^>C+mC#6vba-7l)YNiW5%9!f2XbU zR_=v|@Vsiff>PP4dG%ONOeeW;aevb#Uv%sC*4c5-D3MZO+U&@mYcFomZ&ecpvW>}N z%|FE`&ooVTdYX{)`6yfX4hy&i0*e;ztbYn(J;Svzy%nu@e>4YVT9X{g2D0*0j>R%} z@WVuFJDxH&>|8ybhZ|4LxaN0!Y1*w}YEXdg#kiJZQbn-Z=e@(C25T&WO{#POkcRJa9jw!FLK5)a{cWW)% znon}t`i&=awwG0aF}ZjrS}^}H`|;jP*O5pub$dYFiYwc1e*#X%m-46F{>2fLW&}Od z6W*8nzxkVM*?Fz(Y_?q4$g%6+b&~R%iYJx3?^C(T@!Kyv*|a3EYGk_6HoarHYA+H@ zn0GUvxFRQaX;mwI4fVgOw3_$dtr09t*b@1f?svtsU$maVxM$t;+(?@5n^!n7J^yi5 zTJ&Mk=wdtTMfJxVsVdum?82con zoOW~e)Utd+XEetu+yu3bnNVYQeg3}a9nLtS(Lmqe=JE%Ei zX+Q5(sX1B16m0y0QC*jGS82rS-%qE3-jhJg)0MJ;;i&R*;tbvran=mCX{-xkx`Fv` zy3x@@hSZ5|_5&9hO)PFz#<|ZM{U2OJ16@D>Eb5Tol&du-K3Da|iH%ssazhY73Q~yH z7I_$Zev^g8^YU(I-afq}S>8WnM)Ezc;l-xpcX`E)Y*Nkh1 z>7JRJKOW^zBdzS;%{7O~&*U3Zs4y9tnoIVD7L|SIJiIv*_@)!zh@aMm-}GgsIn8>+ zPQ}gms~m-C$DW9df$5_j6RJ})i^!v(?Bzi+V>0h!SXNA#{oV*IDn6ITbZn7v@5#%{ zep(F6ylIy@s>u@leA}(jlR3hl_)Gc53%!;FDZ%lgC3(&BI3-injmGOY9>==nKf_dR z4Ba?Agy0(N9F&Z^uP-a`hnX|p+U5wGeZD2Pf&pw* z&8!UGwHULY-SWIDku?5F3;(BgO5_4x8(sJ2bm7(t<~rZX==D35v9K}^l`O54*j}5M z%GZN+tIL|33E^Z~2|-&gSG#{oU+)#Xr%k^=)zzo-woWTCA|=Xk&}BF{twe9QxR_ z@3?Xvx5xMWjQK!W!5LYKjq-fL*P@!qYL0EM${Bd4B-saxC+|tIU7wJXI`ZA}ZKqZf z;hv%Kww1M2+F4{)a&hxuQ0rAcRi-L_=SCp@jp)|lh<@}q$Zzz_JvM)_<^uD-e2YX! z1MYlm%6kF#bKcQ#-JDFp2Yv*PRw$X2bFG?;D zuV37dLulck^uN%K2ceB196g-VhtXHx*hCiIO^C8MyI)PJpx(WWM5bxAFS z(50&?-!7c3+mxGiCX{bf3Slm%+SYqkX21WM z@N{~0g1pA31Mq2y5 zVQNC&>H2%0%ZuTTf7kdj6#wx)5G{UnMn!|nuNgsQpw6pSL3*hOrIr7A zzE?O??zN#zI{PV%#~Z+ta;tT&pB27auwpkSMb1uZ>ItD%J7LuA1h6+ZYY2tOupS;? zLiiXcG88O4e#~0qbiKppNceorce-L>uifvW=a-^rtXv~9OAh;>x17o~TFMsq8gef~~Y6>TXJH|r0gnZ0jI7hk`5>20xWbAs$oyyH5ja4qw8)f#w zzxe**3OfnwTNYam`FTnyG7d8*tE@IKGrDT`+r3x!+V(RlCVyCX|6+x16&M6k>Q`wx z9^UTFk2YCrkUA+dJsT1Pp5olsx$Yb)4TX~D7?N_{L{5k z9{1^)`YG|tn8!Zl{maMqe_P^+Pt`WLP43S>qRteg1(%Z6&#XGrH^){B27W?Yuf$c$ z>_hO*e}9Vo1$J1RI!P^MJcxfN{*@*gc}ATC>X`1kEB`wc)<*;kmo7g+gAVle{PB*Z zMS$1k8rTP~@mV3rdcIBG4~+rDNSa7QMGgwXoa#T8yl+r0+ITQ|M;6r%)NgHboBxEt zQ!R6{+IBLpe?Il!pdRBIdhQ=KBl6}uyS&ddVygYuivaK^B4f9Pvx9wr#c48t_y}=m z1{D#-XX)Q&XiOE-9mmQF?NZ5n7m<+P-Lv)T;?K#{qaWSGz;E^|wn6ki)Cc{EQ=5nD zUE}U%!5YrJGnK#K87s7zn)m6vKiGD49{uQMm*(`RJ*Rl6Lq50#2naCi7-zz~rO>DH zRj7?afd{AYEg)F;=E@}$I)c6W&pxZ$D$Q~vOz;4--V zdhzbY*m|y}?2^*g$oE7GG`l9+KVzswS&c78Q*zZlJ=ML+X#;95^y1gcxNAXJ9I96W z_X4PW4g#ae_*m^eL;*zp_Ig9S4@>|Pxg3^T-;{fuyqdsWMZ+e0NWiEV_h(34+>Y%O zq2a8Iak*~kbcwljzM93)(S8j5)u7+XEZ52HreCn`upPr z8oiwecMI(zJ@^cw59%(eUiexXqaosRUfKY(NTB$4U%wT<13*RHYuvJCp9?3?jZAlQ z&<}p4mMH}u;VFF__5Jw6B1)xTVuRpEjK8P=&!YhrN8Dbs>%EwHT>4Qr2~ z6fp;ypqS5m4`^FY!QJwxCqw`3Nu3EEN1jnMlsbKKniR_ z>GJ4dNO=zWS>J4og_9&5Bem0QHvlKGDi`RK80iWz9GEOc<5in=#Ux#xjD1%Ru0{?6 zf6-W2MJet#=lY>ASeDTE3J4s2Np0Az`bpub$N49uQ3U~cML}Ciy#+&0=kKkRy-3&vF@<5{mxGHOsVhXdfbmLmemIa>yN{- zc9fKLtNT3%N)O&0_Re8(xp^&h*Dc#v|CQiLRNp_6;->&^Z^|4!zTE)wkx}v)uI?&i?hbEcWzDSPl97?4@2Ag zu`Hx~TV10)JZAyh#N9BQo&e`TwI&anF-GgLnzH-5?_jvU=%qg;G#c^hw=xdtz7RF9 za;Z*pC%>v(N{tv>+po~Suceu5A$k<#J?UF>KDg`U)W@8jEHwPV_c8U1 zIqyLB_ZiRbm2C#?@5}3!IMtj}0*rSYuG}bsul-e!S3md^JA9XH+(Y8cFLV!YmQQKk zmn@H8Url%Pj^W|tV_JMe>i#kszooCrKBdle>q`-ZxT934>mJ)8iI4UDtkYTs5olib zE<(O5*SOj5gCsN%BOX8eY5wW3G;Yu56yYvB6la8}5oK3UVj37lJ+_%tylK1wauWH^ z2{{KSwm&z&hrqUPe?Jpfhe}o$1NC>nTeSDQ+O1BKz-?azYBKK}BLLl57qQlw8yDYl z-?UK?J566Q?-f453twPDT-D8&Up9S4pzmcp{03M0siR zem5BA4)TUkZ(r#ZSfX{vq?S^R7TL&fR=XpakHnRBU2Oqc- z7fntSmv=B*!z9l`kh6?_5;q;(>)2R=EZ>|h?z^Ub1s-;;R$rzafw)aC$ZO+)Vh(nK z4dKXvup!CB)QIkA}ZAu`1S5@NW~z; zNt-mqLV^UXOLI#ef_J0gQ8Ta#=j!baZXPs` zP4UbbW&)Me8Q?Y(Hc;@A8_!qh-ZlW)%;y$aRwJd^K2^rzwR4|Q;QduYyT1Y;;xxY? zMx;3KhFp=Gi^}a^v7K_b$2ETdrkB1q-^(SHQQco-!h9|naJYh2bhKCR(5LNb{=?>I zIYI+7e0_pxEhf8d?Hx`5-O15YmZti}YWplYOvhG|UkX))zGN8YdI(KR26?bd-jv_n zj*tgoy`q+}gh@(DSQ67o4xb_n1fUOQ_JFIOaFQdo6my&p4cUmqq++J9mPEgWupB17 zdIB2^S2*+1BFDISv^pUJnbU;}bMySseQT3_P3Yr|?ortE~EbMFB?aRryN zZ^k$BnROG`=T?CalwG8MS@CD^zd%Ws;=L@K2_P#KN4S0m$P*7<7&{N} zu@ca=&wAkI&yUdLN*h#KjkKl{F(pWr=Fn=;l;37A?o>8yI{uFfF!TLEc5Gm#iog@d(<_)W!%@310O4b9avzJTcW{Nz!oNh z2Pw!K>Fn!0PlRVq_IVMbQu>#jw|Ucq4avo~c!?UVfo21qfg6%18148zNO!N|8Oxsr zY4o`Pf?w;D9?tDf6X< zac(y2_L%8}Xy=(MS##Qb69Sxv+r5u!(J?+bFyR2sLnENh-{b7+?=<@<9`_)DD*gfa z6br*m(hXTC5;U z6!LbR^l9YHXo5OK%{|uZmx{vkTp+Gp&Guky@$S|gP&K^LFJ40>TtZ&r=9bTwc-Vuw z1IkTB7V-|ZmL2%=%}ZRSEJu7&KfW8ZR)Q))47AKrKHj4nP%kIP0u43o>Un@i@(>5T zFn=c_M?J5~L+*%ymnG`gFGQ<}Qd>+euXT5vFRt{SGko!o0U7-a2o4KdT*$a7##K2o ziUuRLAW$P}&ZC$Ac>4Hk!kLb%i4#}G!fsWnGXeb9wzejP|-dvX!=KN!1`D4LMfAkx-!;dp1 zb#;2L8&9+qT0+itpb`y4Ay{n-w}-L*U)rKzF*D@t@n4<>SWxA>QTmb^;8eOaz4PER zO$`)ny&C^{)3w2tXUn!EI-1Et9;x&J!b{)7C}YhqURSJE7Re=49Ov#h+EJhYTT#>u zD%&jx`#BdnWL_S3JMhwhT_$9Sms?q2K!El;efi5Ejmar!4G%@#Btz~=szD8tf%KOT z(7;FK#ztUysmTyaKR%F)`t;nW0RkAld;p7u|K^&l`r$XP@L)omW{b& z)%@>xNCJRp9#@9gU`~LPw+{xvq_K8KX8)fd;?qXcBbjcyIUEvkaYr6FX zz>am{>kZFR9w*WH?4ZK*Xl2E?;lnj`$)}PNveR^rlDsT3yZ*FPPHskS{}qL`cAIZH zMe5CG!qlzl>8|+V>1MmzB+X1J_<1wddp+roggAGGtF}cqZ%;)F>=>uM6}y!_D%(gu zVQ{@e72~^!7P2FmI+xfVX_;wVMDjLkPR6A;&0NRryPG|mea6TCwP3)H4A*Qig0*)x ztmoEZC-rKaAtm83rKQ78B|-?dSeGGRO!y(CSf-$7_1ZqJe8Qj0?l-t~DQ?lz6C|Y0 zi}RKG2mnR5(k#rj2@ zqCBLK(WEg`Ri5AoYKyQkH%DHMNO*tg@|dR*2>lwXYh(j`bzi3i%;${Z@e)CR7Zw%s zS$wj@xI~#qS`m$wIK;Ru3|HqyO}&-P4yp+JMhk!Lq5vCOeeoN>aB@D3@4~*HJ#LbNi?ob|l%5UQ~`^N)cxDL;6#6iD>8XvUWWL_5glt;^I&w z`0y;fy3EP=2@P5`ozDA|MTF19182ZeTJ(H<>L`EO{V$k z9H|520iOu&2#%hM1J0%vS!1&gi5G>BI%Yx>`8raGAL(d5hdZ&`C|BlL=P&5JwcE1m zhtHlXxgFw8DBPcNI%$nwt+=V<*oRbZeHv$tezVG#ly*x z3scqy{(PP5f6_gpU+|c+t5LewWhA*?ft9Fe0o8DiKb$=vy$&RJLv)adeZN%{ymtmCyKzvNpO6~Zx6 zZF4x-^=6yw-q#UVyq=iFPxy?Uek@iI*Gq^kgr1GhDH)eY_@Q?95lgvK$B(KZ!a&W) zg8|sr&*60yUj_(eNllsBQdok7e^T(73f&9A*JAK_LEoehfu$pvL~GvnFp>A#yffz3 zRA({!oD(k`6MA!d+fY}{cGGWFFi{$BAiP@iC6x+G})qH%W$WU&9%l5^ty`F9UJ z3_RBYOlRuu7*uX*WiA^enqF0_qj3zYjPTBgVa0*D{F`4@`kg-vGA>Vl+Uw^xWR^b= z9 zhPXV7fwp{9dl2h*Z3yk(xMH0aV7$&dVAR094b&X=o{ye)cwU@dt zQr*fR#zktf^FMGs;28?)6ES`3iiNthRjOyDdfga49Zar84}pJj~yf=yiF< z>gINlJJ@OtvT*nS#k$WcJ@#ScVl`T)opZ;DW-;|I`Zs}E1H!K|(gmzP5$)xp-w@nr zObN)|Mu<*^*CqHCNke+hPHvUBYd;8lw#Vmf8w?rX6J*tYXNI4%o9??kMW8R=kgpv7 z`B>phq4oBmSkLWbcG$1&%a>0vKg`DD`r|jhGX8m6c~R9_+`drg7+SQB6e&}fdnx}j zRk$iImans&SE!llJA50tw6dJrp2w0KEu_>;IFMPI+l$BUk9 zPo;bx6z+?f(au6}!+p=@^La>u4ER*if@EZSG>#>ak)jlBx}DJ91D37Tz$ZEF484vI zTa!hP?f@J*QD7HWK$A>U95gUfPDJ;Iy4~1{c{h?Rpf1oy`T{cpIt8~l{2;cpZ1aZ> zQzX#?sUS+@D>E80#dp3j@l%b>^-Y_M^QNt@-x8;BS2}<*-PeMfxY`-po{g(C6bGZp zK_#qF|In>_C&24SoHqGmck2cipBNi~JmU}#ph$JxcvxGc8JW`{F9wAc z1_(-EEo=Z$ZOsN^l&9xD*bD2xU|l<_w(>WQ*?|xR1kAxGZJMzKr(mKg=SOM8SxU2=46avgxSKu#nkGX}I z#I*dj0z&wt>D(0r?ilE6IV>gJbeJPrMw3FjZMPc?Lgzv^06Gt)5^v@3!yWc zvoH7MSjkh=^w>w#Qk>hoCnDJFPQ}*uS!+{^P%_e=etspNSI6tG(qNRZ%R0kU=H#TP zM4fcd&x)1LRG6j$-ySvQNxLIUi+hzPnmJmn2j^GF6hDM(@t95KV#JfK1t9V^>QR&+`X;WIspLPCj;71l_eQs>OYXB3!~*UI-dGPga^5h+KMc*$GTN?#jLRA$={foK^TOm8?YAEN8cl&+PSCaptQm zcKr&M2IJh7EHBZtYOKblru>I{;><#N&RGtz{)VWJZ~V;WQ4$7u&Fa>hGzjjBr{qJo zd+KiA`F@>jqR+?Ck^AYGr8#Ejy$;5AH3g417anOHyrZL&4>!>?(qdYEr@_MkS!%`2@M}) zi%f1p8`=e@6M-0l=8S(e#^(xj4x}(_o3_|VKFwC@=LSiz>u~l)%UfH|yOFS8!?V>% zYe~Bz3PYT?`H!2~BuUC15CtxB8a(8kDmts|o|qp@;xv4xH`z9Y@^pg+D)Gmq^u5(^ zh7LihpjyO^7Y)hbEMRygbr0GyI|n(@&nQQkM%SXED@1?m(Pqz4Sk2+=&A0{*q3U!J zC#f!%6~gdHf-$Rg7MttWKp{-cX0K4L7nvOqOr1bcDr*d3@wphx}Qkorir zAOut+F7sf?05+B2`;#GgUh1RW31q|Iv+>2}5Gsgx7SPbsmF(C!M>HrjAEb$ReLi$$ zYkl8j^Mlnb59i+mPp;)eg6WNj`xedA)|Dn<`MuHs0M{iN5XIic57F4&y1K zJovB_US6q~@lNOz;LN@LONA}CpVIHk8-H4cRd5(*+KFoXMl-_v?4wg`VD0!-a3}hX zw?mo(Dv{tUeJWPCpC2eN@wt|-B!2^iiV#xwNe<~_)^oGP2Ab0SfvL6mE~;dWZz;@% z&;QWU=ML}*^rj(m4D?-RJZwTgK$i0H)eq0)HX2pCS?YOa-WFUilUL`rDKfg(IYiic zFFqr|kwC6Gso$zoq32`lPAj#Y5vP5LpFZo)iWI<(d*(*1#^W$4uXUoZSB_^x?NDYlUOJoUwtCvl!vXll)vtt1*5N_=&Sca z&UsofQw7Z&jnJb9X=k$lf90VL@n(Jlg^nuQdi}WfYkEWMOo*ZVyFfph<0lq~^c_NX zn>E28FH~cW+1qre-vX0tca_$FT+rcTz6X~|iUz=R-aEJ3(2Qx9FdTc`oH)( z>$obLwcjsNy1PLM0VSoSJ4HfD1f(13?oe8~q@=q;y1OJKqy;3TyUr~2+3&meIs5$S zM_AnVteI=B{QmOuQ#9Z4d?mv|#vtKjD3`-t!>Z2`=S0#;ojVide4tw%0QVTeOnrf^ zn>@OS?W7C&`g0$WA>o2_ORm3p$(rVM_8&x?0kIjKi}E)SB#)nyxiGXEyRLXPjhG$D zc`?!@3IL|`Ld-iP<+8oNV38g+RVG_=EPTE=8eK3S=BS4`JNmSlGtfxvO;nhhsw0?s5T%$+JDg4Q!s1H9VA zUU_9gSd$#+P(OkZUW{i>L-epNWBi`00f3pH#JFv!sFFPD$or}qN=`7nF8emkp__^= zRPR;*_}Egk>S7xOxr8T7wHBhy6l-*ozmU`H!V*ABG7ch}^@p8Ys=TzCz{>$xqJRU= zeyKWU+l{71v{H(^bDtqSo|Phrm#75HQT)H^#hTN8er8+jHB-T2=0Qf!#O>0|)f>T^ zH%dmOSEGK3!U&oCoUO7R26!((Hkne>htoe^>?7GQ;55+ zObAJa<)^>bPX{gFm5QX-*brkT_tn79oO{>5oLeoT4;5=gbx<>(kcgMm*Y4(hjz)*D z!LL$wC>Y{H%)s=kjaCvX8$}Yk@)57J7_oKgJIO)yLfXC?eG)Mky~HMLa&5o_B7gIv z^W_!)zc>H`-7l|r|3w3OSCM!(g7EzQt^G>pQ5*s*66Hp%ilGivrZ9I=Qu9Tb=GY6P z6@YtvrFrXsD0odW3-7aR(MF#M8>j;9Ux-rx6|2g{AlskG7NyD_m;> zv-IEL+R*dc9bnT4U+ZhQzZqUzapWHVd><0li)6Uz&!X&$(1eGP>*qW)-DE49C}yvz zc)WtefDxzbvJyBOud@GELG|7EEZm-d3rK+%%Hk&_6Iu_OHEGhq5p(z^B@D$R%9)IG zJ&QznT7P!3VuJ#C3^~EO*;OThzsPt+vXI@vxJI{4!CZP9maw`?o-jqkZFgvBch>Im z7-PgvI}kwhBfadds*YCL3xz{JeXlMM;B=DDsMw&Q@4z*rRMeUqJn)lF7I3ZH{Z=6s zM<@cPjC`2doOEn1ia~rwl`rZq{B!Wl-MhJZVh&@ZE=8=w1|z~Qs^ib>eL@`bNpyw| z#Q4Q)>OrarrpPpqYEsOs2YGeM>_mAQuW7!pftH2bo z_}+Mj!EXJny#1=OL-*?2j)E~5hn5Za5X93dpo^?pW)V<8iQuDuBKkXz!ExH+iX ze0bO?@`5`8?Un->Qo$vg@Du{XU+ff@3a0nHNltuXDl7Ze9x z%iTkjoo>y52a%`u z#*i?%N8*-%9vhn2DQfU^jqXuINCmK|kF2S2+x-K#0=iOev@{;-ZJ7BWkF4D!!R*TTSJsC0sD=i z_Y#Q0b)gT4s6xr%^RXsxf%5ySLxgu^;&cPsJ`6*TAVW@mL`hW9Dmdbap z*9&v%US{21`BW0U?pk^+s5xpCj4l0K8PiE<8*ETd46GK+@ z2oeI*Cs*VPyC!m?EPNG%JP$(%=jQ7c zj|RqUzYSpJKGXutPyR=GFCf6igv7PHqx!2Jq%6|HBsYYr<$stC4Sk^U68j*aLf36o=$v-RZ5MqzD(1x31ze~)lKM1^!A5cL# z_QCf}&)#bpk_FgSfx$0d8-qp<8?O01)WlVx1=Oeps$Z)@dH~x20D`t5JqA?iRR$}P zqbV7!&&BXVBTk%|7ZM$DPwdr045obVBI5X~tie1Ain1>MdRMTTdSA6RiaiwNm7kX@=5 z>@$8E$e+`ilW0WphFpyca6&4DTQaHxW5NN8NjqLR>=Ib%5_q>u0!XqZ-YpWu5m9&- zofvXxQ;R4s+_h?0=Sc~s!m^4%!XrI`HszGW%`@cr8;?T?3B43_!^J$o(}HiP5MSDz zJRjzNdI3VDRUr8?qFtnlr}IiwP|%zaVwc&arIEu5hvAOcO=DU_5D^}Iral}y1e(Qs z7nqhWF^kPo0aD<(&y!@y=6h3Cg^ftY@{ht3zV zllRET$Kg++k;@-a)-xhKY*wY}=gx!2ZIAKo9dd$>c9;Bi2VbvX?P;2%#np=Gq%0>; zL2i1uTc|;YoxONFkQetr8^B+KFuRx=k^tSUQWHX-eX%%Vp(msiUK=QKO8_uY3*y&u zm&&2tWq;2kUIC?fqlI+p@t4KQ)D!tdax1Cwt zN2_y=z69h`%_$3xhZ4R$$^KxVw9%nd<-K;SfDbEH4z|2VvMb-L!g4NxD^^D4dg0TA z46DU*eg6UD;P`@SmcG z_ga#OY-Et7HMIx5P12AuMZonP%09wK`(t|{o_v6q%l|;I+;1DAT4$Mb=l@QhUNJQa z#8ncDp69RCKAu+eQdC)TbbCXw8LKi)2Zp>4q~PhGa1kDq!*p$8GkgBP<=ChxOws2D z#rcMruG;j1Xg4@l)=Mp~)yNwFW9I7^m)u_RO>%Sg8<-5g$%NSa^hW2xm*vkOH(nyayu(&yf*)l#gAccO@P(E*RQYtYmfcdw8s@)EtV8 z0wS9U4ZxiW{ArGQayA9venhBV0C{*J66)!i{#XI6c(z8a<#x4LI8?~?RQl&^r37%b zGk`ZBXhW?+)JKMub`M$~KD(d)@?%F|x|*(o&oLa|O}gW>dw>2y7GHA=+|zVY5oF5t z0vF5v=BX;Px+=n35*jA)s_mPisk>yHrcqa^NcvMy$+Eca(}xgv%^;QUeYP$@5w%Dq zn}-eM+V&%UUJ+3AC_MB1+E2Aoo=fLSP4)#e-Imx<=~7epkD;X-joZ@TKT4#t0HBME zY4{#0Cr}i65{yY157e=lV2Cy(I~%b+iQEL=QPqvTC`I^TBrM4rSKN-Qj}-)R0c=#A z!VA7S-2x0x;FPJ7!MCmVp?(W=a-jS~>p;t~)^|VN7%n*wdy|Usz>7g5CerxB$%3?~ zUU+dVm<3hYfgR;@+(ruU24iT^AgC4x;zPMZ6*19NC)iS^ZHSut%czEu0rw6%*S1yM@NDGJr`pHM${Vb`yc-ON2T< zjF_(W>J@6`n+}XvT*>|ws2XPBN$n!XG%N+Cz=01*1d-1k)#JULcI(tDshj1iJCF-B z5BDY4=(T>p2hpwya}c~C3*vI& z5*w8sJqML3z`T7T)#=Sw&YmnwVn3L*5{c(LFg8^TR@;LH5@2GmOfWASlt+}jZq_K7 zC?M#mL>G^5A`t~)os2DhM-B|v)yq#A2!lEs5+B?=7|8TJj-ZlzK@K`PJ;l6;;5jy}8h0na`_1E;fN1&xyMTq}U|A6qO(R_+=YSVq``qOHY z16>Pv)*|M}Wqd5A<>fXeo@cGFZM~GXoGk%6Yyi|_o+{Z)e7_mT#q2k;ee z+T(PJsixSzNloY5MP*vE6YQr|s1Om$aEj-1*o0M|Wpa5%UMPah7c%)cE4_FO)`X!s z)}l!HgG~GoHl$%6$67?1SE$uZbNQQ-pR1Dam0N@19D(ADwB{lhKA!mk$R}#9#24fN z#{fW$kBq#EL2E;e)M?_3bO1%hNOwY8?vY{at#sjiu-M!lJKN71B|Lt)C{Tc^j4NKG zm1r%%vK`XTb))_ z-!Z&%0eAl`hpn+p(1CE=y@LN1uwLt5lX?iAznckBqP*f4Y&ogKy_!dr9p4udl3EJ( zassef5vD88pZlxVtOFiIf-@^))GnO1i1|0mwAUmU!y?N;qqi3~k)uji2N@|305^4* zIlxVT@rAHFf^U|!2I}ld(<8Zwomp4*GJ%*hRIxJ=Pajs5SP|P0S)w+$YuMJn0XSU} z3}?l3!RJm*{_~4_qAiw0A{h^S4Y3rFgCTb1v!N_)Mxb|On!Pt1)4q}tR$bL|TvSvZ zR%8oG>7UuV#D@Hut?DgYhbcwZq~~}>FUU+&J`P?Y=vfranO!2PA2GbyacL^Ra_@SLO%gN1G~X+9qCV&`d4n@<>GDB_7_Aig{UeSq#LD*-XJRJ3-m z(?1=az}sUftYDFJSvUH&b(yJztex=0t|K&jKwKe1QjB_MEEX?>bmE{cajmO=Zz6Q9 zsg|Y2UBz5Z7%X_Tl|2EbTBh*x8tpz38NC@o^ritWLkhzii}*SbGU0>w#vi+QDp1?8 z&Mb_r;D3g*H)27uTzOA_8Byj!uzqmK%b&P}5L5HOU+zs(-H0Ju)LFoI!ON5>jqmW< z8W684a12r}iWM)f^99&aHSgsJ2{S?mS(LEv^vPs(#5j#=e+(uR;fU#yTtqG1{&JRu zgd`#mM_h31O^u>Z2`c;bc@=8K6cBNE-MHYJm?}L#jct6|#A)~?Ad21khwq>WB!peC zUOg%kA6--s$t}&}{Wa4nEc)tKp#8x#eoSi9w8F#6&*B_@agy1( zwkF5IpV``+fp;r-Vt?YfW%A&pjAeG2U&;(OR z>%%Wfz|WHI+Fs}LP^1$^AWekztDr-!NF96UGK1|m9Gw`~3@m%UV3AW4)sQ|q-3cyJ z(!C$=fy0xCIeVRo5vs4S#T!MAwPS{+;G088>Haup*XUFJ37gz6w+hYUw<5f>Awuo_ zjpRWHz?#gT`8OwBu&RO(dwRX#L^sL~b0$vk#a^w{ux8Rtg7y*=I0LPjU!d3;En9Ou z;}&H8N@V+yL8aMdNia0>cr`u$6dCw#o&cu&EHYtCHzul6K{BsCP^O-G#qhbczy%K7 zJSDH-R@_)L$kN;4>TkxiIrPXO3rDtp3`-&6sR+^5Yr@0cC3@0b|2U1~zTCE=DUsQA z#aKd+%u|ULVZ8|u(0tVM?Y z#^Gl%(dFvFUrgbX^r{XIwaq22EB^b$AXmvN{-MSGbgL8lyYjFO`4i`V(V2fb=Q14Y zd!1`--7P0@_QL!^5Rl+f5XVaKv(;aI_yQYFAk2E1w$e^tWOpsGg9;LXde_-%x*W2= zLtExSbY-TCZ-2G&1Ep#(S+hTw_aPYo6;uHd$W~wY_)Xuo&rvJDUErm%a+6w1LX)dB zo6$9GCF=DQoe!Fc5G1kdI)LEdH#UtAhd6Nb@p`CXDL6h9E40KcphAPJV6qU4k=~}lOSvW+gx-Jn zAsrQn#pmbH``!YHYj)N5FC#MKMSEtZ<#2|G|7QT>fKpRLG;@G@&u3&2g%PM|oouMR zA#S(XHE91G=q7wq3`_O*3`^!BZQ82~lzRUga3j%*@Wh@gVD(h+mYl`gcpm*W4L!4? zMM~Yq%R9EWU(*IjSDH{O`D0fb*Z}sK9{!wkcrZNhbFPJ6t!yabYmuN)ylq zChOK0-S-t9r;}12o0%j2CKzEs4CeWrf2nH9j`D7j(ZYMIzNgng@YxD|r`YF(0+aE) z6F%e~faMB@Fc|P7c6~0F!B+Z13!Kix20U-qZrIz`6nDAlgPo&IkqHUuAkIJGc2@We z7NMe4*YJ?zbq86Kd3hMU$IXP9HPIA!v=UL8dZ1$|Vipb%iJ?HW1Yil}z@^6iD}r*J zX8i^$X`miCnuA6UWsMdfnKIvprC{;VcG0oviteUjrS#MzSJ<19fWho&F-X$niw#7- ze0d|MhjnZu%uwe638Fwq$zv-_r}Sx;5u(%T)y%lRr%ppe`?-BK^Mn)Lr=H-b{g3}( z$QXwqf0?SL%Z>R5z%}r;uBjBfj9bE=e5h?5;16K=-cSn*GJ9(TS>*z^c<}+q%^#ae z@3kwyuT#t3_{lraEO1$VqXJ1>P-Xip80N1DCZZp(5ZGXX5{N!|UK}Wa92u{icep$j z=&{rBwZoMvd#42bWEh$#8|YVI2Py<>^Si09f%|&g@#o=QKoa+vp3EHsAlKa8vBmS- zJ;Dmpv%K`|pLH4PKx!g7bc5%LKiMmL>dz;=(18wX&&i@dLU+pgN{v6hXW)Jb2=Ud; zrV|mgJ`Z;`#z;pnkusf?^U(~O0tU#V*@EnFiC+bFyy%f*SOC;3BJOB=V)Wm9Gb~>m z02nz4tAg16<;ru~7~()SI#$d+l|}twvf=22QR{vLpcW@Z82Rj0RERlJ-sg0&tytJ( zac@Gb1uR7c@8Ge=obUhOQ$&M*vt$Ec+r}C=QxVzV^muMxTB{$zi8ibK7V-d{uu=IyS}-I>4o$@Rq2_&K$+@E;IN;BVyqlWa)&f#8R36e?V()+C5I z;s6g_21J8j&uYxR(t*h}0y#);$J)vQybx8uR~G#mV2{*C1LmLhDAeELa_tbY=pRdS z?&>dycPdqX{PT{op-}rV0^8TEDPYhQ1_fjBX!-BL`GXhXX zSs!9ZtaRK_cfGsZj4Plbx7&6B+12fTA-QC5xc=MwL%%b4=(B?Rs4q6Svu?i5=9O(N z0Dh5ob>Ev3zIKS#0rl#~FRoV(oOZua1I^1<3yVM>;xjnK=B1)#qz>U!Y~5`C^(i@i zKP5d1q;vOs)Er`^-P!IeBW{K@7ObvaH$L+%>C5zS=KuC|;=e5s9)b_wwJz|$jKH*f zsoFED9_=QV3Q!?r><$M`LmZ%L@-|L01p~(Dem_%L6Ah54`3UtPzP;#ktQi-X4v}U4 zs`%gjhRbgr#U>~Mp$_cE1VNCdK#^1y=q z6-Z(gD$ie0kAHUTf4uUg=pWuni$I&}zdz&uKJ*{nLvOQrX&61W=I)yR$IrEKz}hsQ z#&5RlO8+sxzmPz)jnK=3KctD+6f@@kTnr4PD9pDSzaQ(!U%25wpX3P&b4g3Uun?W0XAQ05y$}PoGN$LN6GgOEG*(pn%{&4VHFATuX0W6;iL}S%w z?dZQR7xPs~`wAd%MxcoE4kWq@ii=~R&;=51YcjnbU06fTV3U|l=0|G@sT^Ba=wlB|no3 zZ@9bK$pKuwh&BIj+k;q6XJNuvZ(?bzsa|w9LRB@^7NP7>FsdH0=~?xb6+R1x#rjLi zbN5=yg?eQYPE#sC;pk(CzzD*UNCe!OzxZC6&kbo zkA#j52xL>gMQAlK>(sx1j>@&QFO>m|PZ4uA6&IDMGtLCzgZ?8eT1Gp6%U(e2jt6!& zUp`uE_W|27Kw`vxrGoA9MPV6z`Qyiro4s1R!*|PVFhAVCKW#b?jXT9o606w+^w}6n6xARxNm>3rl4Ul!rQNO^_)0YwF&!db7ndtvCB2}4Vv5!o1=gR34PTY zc`p`jp$E6jT7^4W^K!p;=8vnt%R4x1LI&b9s3|)H&{xV_Y+%+~DzIHlu;>L&CsoXE zfC9%8;BQoK_$?!J5FUq0#}2z3_0vx!OapX$1Jzo(^y1FJp^>{$s@(nroa&B~bK|i9(JN4J|IkoTQdL zG+4^G?R<>j<15-Wlab$zTDj>*CH4i3J-`z;eftn89J{&!s00awZ#MGu5pJb ziELufdT9fI^uMf((JLN_H9{%0r7;1>phA`a?5jb=rn93#mLir0pg~a7LqnR80vRhS z@rA5VDIr~)N<3aeB<)CmRa_M`)b`83x8wD=utkA9cU|(%%kK_dq!!PDj@j?d)yTc* z!M6)b)JN94XInNAk6lIZUZV1l;u??izFA}JWY9Ll3VFG(wV5vBk62(CZ45_kwyIk6 zPcJ}FVuuLoq6G?}TuvBaoe9pa(;u0RxmXkZ)>;CLXMb=;(2L&o4={;2Rq0*Y?7tTA zg92Iab$5B}9i0-90BrV#$&q`zXLvMNyvv3K4|1@UuTX#Ozto*s@ASJ4fA|-P+wvRt zO9Ry7xVd2WEkRa*5pE8sFsKo5y8ks`;{#`P`kjbz3VR>ro+>BF?Lwz>pp~1C&#;c) zl5J8}sxeXO^hqrdEfrRJO4_?O*^QH{>6VQu4)r<{04s5=1 zY>dhy7gDkupbhE+mBm3`r=Dh)b8?%1;{F5Gm!UiSu5z$oat8!dMgy^r8Tpq%#K8dg z$Ag68slCD(v4fgRKnjQrTzKZ`h!Y;>^PK2h|FrC)N448#nccHy}kGnR`@n#Lok z1-gLye%4LEtdRlls|edhRf`B4=wC^L)kT=|A;mIf{4g9X5l9f~Beq%kAh-w>9##Ua z0oscqmAr@nr@3-{G1se~c?e0$NpVcVR4!yVH7>rwc;c0Jr0?Z@cpTBFm+x)%1={us z2X2~Q3Y#2$G zCS>2k7dlyga@#Jj1qMor_2ydaCBjrRuh30X*QilABgc9A`h`nJMp}Y+T6*SXL#lmS zD}PZ*trkPo^dYu{^J5rfX<^t-$&BLV0vKCXCDEjG{T^9v#;WP|&w@@xjGeZ{tKTC& z^6A@)s)biw>3&gJx;QQD*7hvbN&Wg-EwrvttHA|RD|M=KpnLqwBP#H5di6-LQ=K>n z=sul}6pf4MdrvMU-WGA$%S6d+1c9I`5TKM=&1$l5P9H|_&?K8&_@-j&-@J1N@SDh~ zJCbm9#5Q(|J(4I~&POlk2;MqcYX!2}*fsZ3xCab#%@2i~`wHWa$}Muys7d{RtHg&~ z+X`>z7SFlLOf?!0C*xCiU96ZIj6T@wW+T+@E@?H%Gv7oc0fDy?5AY0Vh`iM23}X~J z6u7_R-76Xyjtm1t*cGaE>WHA}CT$>fjea|i#}Hd@0HA*dvs;ko={wHjMESr!dSM4^ zgrJ1(<4=6SF4P$oXRT^n;xFU5tF9KbqS39LR(``-lNnswK>q6%wKeIr~Yb3 zV8frl z1pp@t0-UF(B-e?khe7e}VE~cbvc{+>f$k$QGlx%RV=bE@yO}#ncR>qd5_dLPttYVT z1IMX#@^k3bVbh~=hO#!bb+~uwSP?~LMNYaCt=f;JNv*1tEr}Hn$}CD7=)7Fx)YOrQ zR@shuuEa9TH|dn6mn^mmnpV(lLe!+lZ>d>LHv?ZU0^pB62n+2xK|iCn2Jq%r(+7)d zgeFtfV1K{P*qcAAavLr;J3DxTmc6JEfA($ZRgOy$ZoCkST3FT9;>G*AE1gS?gei)i z?WH}BylwNeZqKon$f96J0->^au(njbE012NW6E)ILNGQP7@CV{g5s}Gd<1quvpEJ7 zLt;Lf#`adS9yo{zT2eyjKErc1Tv`@pJd59Ah2usPsuXkpYGI{ur?jZX`L$V2T$oEb zlImX5XJ!XRR&v+%=$Zj5b;#~ln1YmA^UWVwp-)i&987MZ8<2v?(7Vk9K#6Sy$hC)f ze+MKlxD8<`Z}962!uo&)wgR*u6 z5)-AxuVO8*UwU3OO-&7SyN@l-Y=e~2*6TleMd$Zk@dJB>5A*eY5aq=PFnJnNk#9J; z*+rD8_Xt}rB&47Cd=)ED71e%oH=5!39f+oqd21?Yudw4s&Z$9|zf6~k@V38%FLbab z3H${BafNCdh1|PD+l#pQ6RxhnXmmc#OU0ok1II=`{MmFqjAoOI-Hn&bpo132%gf1e zcUUz(mR&*QumV}@=h2fBRd-8ci!r229O`=u3r_P^`oOVaGX;nDjfVH_=~_Byi=Zs} zI-!`HUX<@rEYf^#;vO}EIwh*azgJx^qZPCddO7u1yWZC*I9E+C#@I_j4G>P0@I6v2 zzQ8lc84KO_p@rd5*6r}`QIsj}MR@y?0h7p~X(^1|nx17E^4hP}z~&kaZ*?guiVMA@ zYA%D?p0U5S=i;~RK?b(RnXYk8dEjE1aCn$;c&r19`g4-2FE3FHox+FvRv@y_0m2VL zZK_{Yqd+h>06B2x+Xy72qCBOBKsSW2_R)(RdzIE`ok{+KHn>i{o#MCE*Ye=R(b^DJ zOsQ)l$a|Z;fWfl!6`|!WbW|=tuBys*25YSQ&5@6z`T}G*wvn(3*q`)#YCfAQ%J#-} zmvX!?DV%8NpK080x$a3%IBGvn15;b{bQ-2)d!w`DvBw`n(-MUX@RGegDe~`kYh8TN(3CzwwZ$m=5gw)P;{nf(7 z2Vj;jT`&jE?M};&*iICGFENoItkG$?xG3E6LE8IL=U723@Fc$~5MB#ny#&6~?uDFb z7;1`TrOf=M@{_1S-|!6!XL}|%y*rW8R~A-v6mM)4!2;0jb%ZTe@Q7uX^mVb_ldK)`?_e*i0HPxj(6VsKpwU`%+RY56 zK!G-I7?AR5>6Vsvpgc)Wm_y)hyaO>-xV_4=qFGZD$nFoVFNoYD^jk*ESDw~LQwt6D zoq+8}oSkcCae`^1HZlnKY}ndaGng&Tpa5rILC*KY=go2QOaL(Ff+WrtUYlD_z)}!8 zJ-1nGvIRN9-YVPmXsL(`?q8rI$g%!(TDxR@dj8>rZEay{icbFL?tSy35`fwU=%m;6 zpndE)x2FL2TUT8Q@0-Jes`OjtJNHU3q7(cboXmps)}6ZVgEeQ^1uAmTGv))|Nb_eW z;h(iEE)1sYUzL!azANzzkU~ief0;zI&9*}BSWuZ11NhNlgGt0Y>llCIw2X75WOuVN>cqGP+ANBOh zZe@LZLi4VX{=8LPNl7S*ADEzv@U}S{wAQr%3)-#q#qY=PGuY;kZqu}sg&Qf_L9hla zp9$byrP=b#H?~Kq%O+gSBz#=}wm1>h5FrhV~l>?5DqUt!5jz^(;l112k zHV%@uo_kB(>i1`-*gxu%8)Y{){xSZX5e5t+MUdP#PS^t4Q|J3gkyEby-HNNwZc%P4 z^oa4MS4+6pQWHrj*e=@zc?L&qj77!lu~DoGP_!1x{pp)~d}$JG$0@Z=AgItObhjpi zsHMdZb%7jYf4fuVDihhxw;H!iQ>MY&;kS|QajVev6;OQ)UEj6TU&UbC{x$u*?!~`N z|6BDM{@~Y`MOp$nW$=$!FQ6BInF$Hxfl$xe$__Bz$$tYnGa^TOAb}!`HSOyOksuf0 zq5<-?78WT&-d;RFtmCcRGH9lP*P6=l^~E}-e516+;(aN{iOY_`zgu3uk!-=WV8S@H zxSgyx!$&9F+b_l+-mQ^JDtH5JgN%@zcIqTZ+e30Zcf%i%D4r!L3ZwZXHj&*v ze35f}1a{`LS_dnxZH2?z?2REcUhYW2D^vLvX&}5oe7KnlM%r2F3|aHhxGkoOb2nJC zzd!e_;9)6fw*NA9eC&K@qmXA|#obzVp3nvk1uke{Z@q|$Q4(xeBRKGgyx8DwC02ZX zIyol_r41f{ArK+U>T$_H!uvd-+s8LMt#=kpca(Q4lpO@xmTarK^1U7yQ2uFlbY#0p zJJhG#ZN0xkFH$k6y#&BNGN?m^eSAo4H~6HExv9s2TBr(i9lnWNIzIYv^3%~vh7G9J z*e=-hJ~`#H$Q16%iG$9a$PtcQ-*4`Foqr+nuWS18#A>aNSSDGlRDx5BY39hQFNWZ& zBat)EFbT39em2wfNNR-6-?R0+dEbiY8anB+604&4eujg!>uzu9&Z@w>*HzFY`Hi_C zxVh{E!@9uK;oD-grmO9u$TMuBn$0-qH5;K7BKti5D{%Hjxn)Ur97=M0&@L6y*vUeH z?xa|SmJCf%)l2jk3Z z{i~)(3`rV6K8=Uy@Ar8f9$W+3F!9*<#HLrZ5Q@-x|LtYfIK`OC1^KhUj}xAt#ogpY zb}WevU2rA~E{nJ3Yelk|p~NV%1$AcKY~$rEye{T+5~c$QXNmC~Mr*M5p2Zu|=7*3e0r*G7|z=u?D%m=9p z-m(5|(Byyu*dw-0n0sexWo~M1Hshi7PKD?Z+b};@I-y4snFQia6sDi@!REpvMz+<( z*!w2Cm$c@N^c9ZjJ4BBvuWlw?>}f5F5^U3Va8#}GtE9r&?WDw+%~Q`7X8N^)pD6m* zrYjn-5o{tVKX|Kn)tiSe6h;v4#l~kkRMhlIM2My2TW(cXFl>vI=99{M`U=_2KuqpL z%nN;9biw>XoBX(_D{u89det8b2QVKorBy!+J=hGA{rI@wz~N_jYhL)7Yd@1fZI;3+ zx>dJ*l`Fjkxpy>KG5PWAgYl?Cf65yw%huboKtgGL3WLbR8Pl6h?>m#5p($%yA$+=h zFt!%7BkTb9$1Qjgea3Hd;?zHE2oK3$>V*^S5bf>-;3|fsQ(t=Zj7kH)%Dk=#yKK{* z>kIMPS1{FKo-6R_9E`4&v{7JZ>{pNjglo+|l{Xx_3)fzxKgSUl0dV2v`fG*}NpSdP5lJnvSXQd&Bt-;+xk)`1rErC%2Bi2sBQ3_IrK=4Oo`sM(`BOJFRY_)^gr2+C(KhV+pk*`l#4VV_C|tSqs~2SFpsRSOVI+Tdlr zd#KZxu>ZxN)AmPEyWKndfApRy2z zaay#DvQ+S+b`9CHhy@-J=3uiz8!%^TuXDMZA17M@viT2}TprTXef~xIkUBK>Z0x>q ze(7R)Nu|ceP2e@HNf}#Oy#f0?WdCuGHW+RY&gI^WHz!U9Fk*87y>FrCujeJgj}U&R zHnPd`KSu7Xn`G;R+NYeBGO(KVTPyLi#V{Zvi! z0P2)wjr93&(>?nX{FB*aBw6dH)Avuqiof>7F|)NOkq3qgzgN&3glS?lZ&|##o_m?g z!^z00gIE^x?L$&*Rmb&v4hd1KFYTkx%YX28l`g)Jv6L=e1hfKklb}^RO5iYAR8ap+ z>d;FS(#@8W)grW$-=P}kGt(6aH6TdUpKkMdS;=dm7m+1XaY->~?!U)_zP$rIJCq=i zM4~xE`#Zk-9qj)J_15BrKl!GZz`zACo6i|gAyL>5v8}wNyw*@rR8`9}G8f!N_X#Cr ziRd7o?Iv1!XU8_WZDn{Qx6>sck!zYA-<*bc2>hwY>umF6_1I_yM?4xpDnT0gqx(l=8%Yxa znApu}{amfV@}}@NHwzuGbV&6LFXk-M8Z_hve?33@_O?LI-rp!Y?2zV~^2FkIJon&v zWvSAi5bw`2fP8>GZ1Y5?78@OPlv6X>N0}X_vozO@B$(zb-3Qr?K=_*N)l^E;2=8WU zauQ3KM?wmELA6wtg`jDY+sU|8FU!=cA&Z*eqOz98cs=P3yV(dQqKPs5`JbVeS{Dnq znV6mowVaX`VoH|WM~2#Sv@v}t79oHZz27mvcvj1UPR?-#S{9sC&Q4D&-870M+QU8X z&+1yy0ee7c*YG3fx26vAMx6eoN15@>B*G@Ii7zUJ{5wBVZyw;0Z`Bb^QRd(iXz$ z2J2cB8v@nZLjhlN6-e!tpjih;))UrhZoUvFzN-Rsr^fj4`j%pf_~~32Th6R?j^9bt zKjGS+eCiOgfLCYDN(-tN$;KOZSC^|#Usm1XQ(AO29Isz@RC{8etJE&mZd!;VwI2i= zhN+_)TGf)e(pho5C4XX8(5IfRnL4U4B_jTeFYV2T-!-usu4Pz)P4zsR9+m z^`t@Gs;;+Pet}FywbEB#b6ejWZs+MQ(s)*hOJ!DF~#5Tnq`(}~N)wws) zZ`!07*8k1;z`Jq)yI9ki15VFc_u*i(ZuJk3m>=>Mv2N`gODej7ktXk)c%>w?Aa!p$ z-B-!?U8FpeUi^%7{47%IWbW-B_4>0peJeyyP%_(Hufraz$?VB<5NO294F$eg+&o=n z3VPM0M+6#<79zScT6CeA6P|o*$3H2xf3{bf1~!qB8&Nv)Z?_uEbaX57gA~Mja*_+n zNP>WsZIBHJNgo~$8Kc`qe<>rj{dpcC{d#>#ib^K5JS&G;ZGqJpjE30-Mle|9&dmd-iZq72Zr=J! z?K!Pgg{FZudv6*@;IBYE%*k-KXu}03eTAnC*}*mL1o*IQk?f}Usm{2U zI8+&|ZY3l}vzPTOGnw08OskW*e`<#_QV?h=3DvaIj8cYLKpoW* z5=bwNxuD9wpE4hK$+$MFH@wuK#_(~PXt)PR4Wp;D+^al)O__0`+`orBqb3>GjUSh`98?HM{AwC3%k*H#Tmqr{WNZNv!W((ncP4M;NDA`>2ojpZ zG6sE7^1k|t-Z0^oSm=2vy(i^n_Cf4ML36rV+AMZBnS=JBGXS^i-`}3wn2r>gysSoG z@*_?vtA_Nz&qg+%oj`)IhP{x+tJ`QpiPng%#FL3ffoQ@ft!XZID^;t*2|1SVz0WCX zCu`4rh$6?N=5-3$k95%7n^_?ShTZwS$7VHO1{jOPEgN{F3BKO%-`}>1K5@XBDF(9#g4D*Akfm|BRcDP4FPq4MH#gxZqt`d*%&yxu)CplJ; zGf+14K@fKnweF0xg}8fG3exd2l1IofYroO8 zzH$}am{=|AWL;OQ+p<_dF}*$OdMYHJqWW4Mu@}ffGMek923|dyV!xJY)M5Ezy8gZ- zoKKBYn;ubvk(`~Ci)(vsVt3KY!r$myM9*{R)x(AElZ{QAPW_)(&s)jmD@+PXiiT}( z)aTwcX-??#9xJUVueH}{x<0^R@ML7mFX~8J(B1u*;be#8S{hG>tc36CG7eMgIGIBp z;a;TQU#7o3dwl+|Ya9as7bolC27P6g*)w^%XWl)_lKim_EIZ3P)yEl(G!{L0{TDzD zfsko1CweY2$~ARP?tsKVbMaF>l6R@=&0%l$B_?%A(pbogL6SaQ#iSnSJa?ylF!}Tt zd{k?8ry+^27zDtT zv!aNJX(P$9L(A`(Ya|T+{CPfrVG=$<+}HA$>D~AR3rt-@Xh) z4AL5kKHUoq{q%)V=M~h7XasIG{>@fH6a3Ip7bj8}{qwK@ks(JJi>wqlH!|aVfJ$Uq z&E-I7#NrzV`Bl;~i5-H(y7SQube#|QIci5^_czHrerz@RW}Y zvLPw9@!4G4xa)RO&M7S}jP&rPR2!4B3W8+!3cPcl=V+zy^L_o*sj6O`@3F%!#R#_I>D zbJQ_Jqb)D*A)G8=hrorp+8Ir}xFjBx#0?-@2hPUR9mmU=k3gq1OPT$Q@cEeAv7NiI zE9R;dH6TJaa1TUEB$T|5uaiV~-%jz?#~SONco&LD-w#tB(R_XVLKIg+ILVi`CnfCPWRJ(MX8iLS-J$qAfG-3zxJo5pO$C+o}mIgCALOIeLp zEak?NCRHUjI!4=5oF-g+WX*SIQum-(`4XHM-Jw+OsEOhSZi{$_T%d&!T3Bc>Tyv3(yJVs*rlsoN{-6s#tSX%q0bQ&X;?E^( z>>-DvLj&!8exP0`sCSoEs9T8Nlw1`(wB+{hg~f+j6?E9RBu&-$F@2gvA3*nwU&T!) zsbz;zi}wu@DZ8e6>;_p%KYF{h{^kqz7w32UlD-z80*4c?hbQ;({V3TrDx#?Gkz&|p z#OuvjYDUcmz#TNH?WHsjDq~(hARB-wo|FN2z2Dk{YX|-j*vN)#{3S`8(cR{cO&_#6 zS6yo}asuYt@`$^og_-(9s1sl^vhoYJxfL6)4j_-xt|U_o`EdlR24et;Rr&uny#HS69TfX3O^pcFzBE?!^uwh@CQ z1EU@IK~=yHx^5$={+DG3Bsh>ulP|Z^R7T{&92uRt*}Go1y6Y5Qf2#aB^QmHRfizw( zE~-gKJYI!rD=g3j%Z_mNY3iY26K1zD8h1*ZCN>RUpA{X6T|5p|><7qB1Txl$b$=_!Sl#AA!s)=E8LHobf03)G%_9LsI-;@}m|P_z9P=>AX^TsJtv9?GAcvY~ zB}wy^;OPjI^BMM}q9~O;DaTl#jp(!D8ndPiM7U2Fc4cTUgA4kuva~Eow)b#?tZ+<| z=}wP%5%$P4c3gorRx3k&3nSQJPk^8*!O;lY&5>B*Ch`?34!0**+~`mWL^JqxseLWz zT%SEib)E^T3@tq#%ap!3ESEy^yurr-U)zL~;vBonj&lfytL+xhNT|g7ooTAoo{66SSa(C|`@Zk|e-JTy+5#WacK7|4BtYI1RwvRkskAk8hyJiIfd%`Jr1tczDtS#km? z^OMKXAX*43>B>nsHV)Jf-($hQ0}MzFiB3h=mSgK}rmNT~#dF?Rb)Ck_S_c3aT4!o+ z+9$f6Ovpqeg~XkvIo=w5kn_~eWjIalIIQQ>q0MgL_4R3L^Jn`uOfgBO%Ui6Ml%uRb zc(v)k?!FRcIrbgQ(%@q*cs_i;8758k6x8Fn1rfas8yd~e;@7jNNzw8ZQAKa%ROLYO;LExSGHF5-eBy*7;h+A1E}E% z)PRyym?(9+eg@%t0B35$A-K9Q)bF2wX^6Ug38U+p8bw>I6mM1x&P#sDD2+@wo)Y^U zNxT+W0{kupTs|bQKWxN$afYd$cB=N>cS5SC9O4);k_G}7Prxt$?eO_#PF3~lq`v@Q`K+-btkQl!K`1n z`f!(QM6yKCT(1m#{3?P^H$sr1_FW%eUxrVd;zg2VAL`et&t;8{ZS`x9F);?iZ{#UE zg&OZI#-Ov^rmwxG9YKX@N988MLi;vO{cSu?uc&k%-87M<)g8(ED3orZWMU?bm{MiU z2T|MU2Uf)U4gjo5kulLPYr*(|!A$o-s(pdu-a@MggS!5eoA?x*oceqKF;ISRInfbV zH^=W+e1{fCs0WYeNQQw-E1R;F$SVL z%EW=h3t_CqNN;|#c*%`f)yZg45giVhxoLD3x1 z7lefS;$p_7bk=k_CK+6fySwJS4v_`lQ}$|Jt<9@O8%)OYzDq)4P56$>)3$2$tTyFd zuNXSGzHe^LFcL59Mv=6UVoq>fgt`U#=-3IpHdspQbZ2x6GbbxEcCFPJI|SLizNo@WrCz`GD6vj;m3!Mnw@ z%sduZ4;*o7D-oecxE^t+_c0?1qIp70Wn~bb{g80)l0TQzxTlOliMcH8bF2I*7w)}W z^XT^@ia25=E3deRL+n^d?ErqVZ-f&TF8R#e|1{G4Cmsmp^C{F!*?xV_h9B3(-;!f% z>>SYpT)}T|aatc5p%NEcQ~ ziy5LXyYT@H72Yg)!hlR^Gio5^NE_wWzNNLB)~MFkivVHA%hATF4(mAA1=Zk`r}8M; zFylHbRI%g-_D32$rXM>t>Io{PjCXwZXK)XbWL|pY=`^etfEUNb&N~4v9or;A?v#&E zt*5=4#Ncb~`Z1{yj1~H1pHy>vS8m#PO|NqQaH~7w@&(N@P38}ea1kd-mn+St)%1Ub zk#Non_E`Zt(00*`wpj%UGHyV4BijSxpwi_}E)LZ!;DR44t%Txm(DA}o&MG0)0E>&p zS?Tmrb#B5PFlANhOV57jPg2c7Y3Vp_F%B zg58Qd!WFwfKLN1^Jbjx2g-3aAR#o${iR#f6SXNHPk}EsxXu_P*UBpiWz}>5^SaC@! z@}1Snm)I^48bw(c(yo`YcP!YwJhIn^&3UHyc#bN*Yv*^mG%ok%R!A3z^iT{qR&oGw zRN>SP`S-DIhyKdLEoUtxd2YPc`?%+o+h4n{5T==ODS?xuiPVUNW{GMpsvy~9idvE@ z580p98K4&YpqxOi9y)D&w8|U*u|p?tu`3z?`os)qk_k_+@tBGLT z&+Xvqz=Tzwj*rwUhhT~<{+B1(DYfIFBzAq_b79u*1_k(rtC78Jjai_0Bntl@CJhgyAZpxgaE!-#)E`%a6NnbsEIf)lg5M z;M~Ry2UXe1OyJC}y&j=6=uK~3t2T=X$=LvHH(pamz8i`ya=Zi>`oS6>9Naz12Gq%3 zk3%W4=?;$WP?CN0hywYHoC6(@##TFIWqrBZ(#*RknrAj)v7cscWS*y;s;z*TbE&FV zl5BuCi;yiJ>8Wl;@Z(p>k7V)Wx{nAgFbt0G zEt+0_;eWAW8TOLgzs_&riJ+*FXKCyStb_dPXM5Uu6*a_~*p!}>?0K-Pkhl5*kr`XRga?34+8@8cy~T&Ft6;s>j@&wmF1?R%;Cz!> z+mquhGT-P}5J&+qsir@~RxFw?96cQdv;JE3fI`j}C{Nh+le7a@t4lHY@m}u58hw2| zHz3R9>k6AvIsx}b%deTr)vqJriMs71R6kTRI~Ezz0|vf?RGCVIu0LDRT-)s?722!n z_5*bfzSYu?inao4+sX@>Vi#S>UyEYMOKR&_WCp|xpp6#P%Oc_+cI1Mo-xw+UiRS&4 z9rs4PNZ`DBP&HlcRA0Wav+u`IZ>t$!yi*RjA`Fbq)S;9IlnZcHkd1zt-WI}*6(||M zLM)->O1a^_Bt{Xe*7Uih@qu(E!xVG_rzvJ8ldNDo3ex4f_wdsJS3W|Db;)+$jjgDm zTR$(d2tn<@EGr4hkeE;n)T(C%q1l1ien=PJVozfdTt+4+kS9i0M>w}IrsHA0w*PUs zugvO8@R-VtawXp6jz?G(3GrL*ar=+uuN9aKP1{4^NvL8eQbzo_wY`l`Fm--(Op!Mm zq_mmFOn0tGV0yc7y#<*I0b{=s!mdUgx3$ZA61z+V?6LQa6NYpB%_AXSIfED&!bOSj zT4ITFO2uEy>>7tbkktgd&#oficS~hVT)38uI~v-Mf8W^dNb{qei*64)FVXN8rk<}0 z>Y+O&H#9gpT-RJpnPvP*k^C5OvV*Uzrw`0T{y8*YZpNY%C7oKBG>4kPOR7IJ3)du) z`fUAU<9bh z7|j8JrdsZd696)`pw?xsWYUg2NSYR0&@g%KkggMxRMw-{V^j_qW#NXh6bVda!gA zaxD6LSsg9ktd&P0?G-WGpRY?%H*}&AIZrd&7Jco9&OPSOqmZ2dO8-c>zC4Oa{O$mqb&c1+OR>lseh=B z8o^BtD z>ziMBKk9PnJ`r^fND`{K z8S|r%QLiXVUA^pAZA_C&(2G86khhW$@KD2-0aa|*d-|fz8d__iVX?WBCBDMSxxw@f z+!5B5EQXMj-_{Ji+F>9-N6@DibP^EOxUQ_Fh`w;mr}DOD(}$ zf|4uu*E^xPz-{qd4-7XRggOWI?4UK&WPNY~7ZT$czf*mU<3o%Tzo-1h7Nj+XeAgw1 zxO1@sb7Ht}2QG)9buaD!M{Y<*QoQ9#+xyX2n^xykeRYK=u{WDZkhrkeKS5zEcRud0 zRm77Yt|yS2G^xQInSZ<-fO^glf!8eSxf5pc3DUomeA4|fK6{DOdso~9i=iv)t%-yD zqxj*z1`xqk=sC;zS2}Js!MFhS^jrQjaX#R}jaarl^D~Y`dnsIPSJdUs+6_Qsb>HYX z{XhviV|;cNOmGv)2uVsHO;Sk4xB0l@;#Y6H7kL=sSqb1;1I&8$P{+f^ou;_TIU4J0 z$?tI2R*aVC zsyere)CtP^Kyp1zlnC+z2>~x%A7(z)&;Yk=&OfvsP(M9d#UFi|xCx#_hQB{!+gj>*=HsERZl7WFz1^uHqY)Qs=zCruyP0 z-;|=HSFmk$1YsZgprPmx&V&-gYm&)35V|i>9SqH=?q^aJcOM;{Agq_0ybfCovk2%XEh-e7UICmwhtqzaOAgo|~Vw1{O5Q2Qb<2xcjI{3j(^3?P;XPsZ=b~ zQUbcX2PLEF%_utDCPTKqgTxBm~U&?8D~)$HA?Bt%N$nRE&^BMP|`DS@X2`2yE0Hi zagS~=+4q-xbD*1~rhh1DSdvVwzxJhe>dT3Y5 zZbz%;)D7Pxi5-q6)}2hqd`>=Sid9hh*6~XlL#+;I?r{SZv@Fv%>L>2~b$M@!qU%&+ z`7;-VuHQ*?1s#Qci>o_+hpZhqlI~Me=L^$?D)(Hkc3nG7y%FP}1{(_Q6@S%bNuW0G zjeVAC@!m$FL3}lLMEFk2`#{_e-TJEH?OIiXU(P=vTM+SO5NBAI6SXX<jaG5d&B zPu`N!n<9}CHVcP@T!rOs^mZR7NS;ub}e#5UA?sEiu9&;YpNdp_Hm`s%)n>) zp2q=IL3$j_s?CN7Ox~A{w`wO=C_7KehrH6t_Dm4(xQYpfA$YDlmpCyGt=D`uvjehZ zJ>3Zxx9k~@f-LsOQtd%6@kiG(T@(+DwO}9h7Sfe4uUdERMCF5VnnbaT+P5%8Q-Yke zhj>h39%&w#wP}87B4vHr`nFbapo0t1Dn^#RQJX#2PY6|CXt3FQPw$vQzX5dGn3vbJw zYC4bBaL_klw8-Q}A(XsDA#`(Z3q|VFj!Wuk1eB(Q95HEQS^4F0s{j6w4tYx5Vj=JN zqmM%vc~H|B`~`L=TDd1AyjNiyRO5;8REyJ=@gmje6tM#HdTdv7Al|2k4n_9e~=bmd+t@)pcFZ-E?Se z&->Y31j=Cp=-B~kO!_TDT0l;fdO&-B**z$SMm&T{4kDF}F}v;-bB9Bfc`&cnV#?w$ z@@+i0J?r7sQS**eA)ztQGgsyYX7k{G0TZRa29EY^LGavf7_}fd#|u>tH@hE9X6NcA z(q7Qc-`r@z!RhEdX{c|SjSwQ&3RWhGC}Z7g^uuUkZ@)>f*uB>^lC!=Ckgcunzy;@A z`2f~O6Wg%zpgp;iNsh+D1H|MQdHKb%58J;tpx~emzMWdJ(bDs~ED88RgJ{L9xvZC? z>IcBV;ea7I$`7S#K<{WX7oN#NcErj@C84Y9pf0}wg3SKGlJ)A9RtGN94jh)j)~UD> z#==VdxvD-{Mh61YFEM`<#=KGeBTq?*OO94Si*#W-*_$+#RF_ZH++D!S?beGw<9S&E zs49Nm9CkBof()W^C<`*wEX5gA`!xoE38nTdj0=++I}$jWKpVj&1=szCNU4<|5Xpyo z`%gava2N``KDlntuF=#8uIFeAPY+N8I}8Kk>H<0Bj!K?*>Ql5rp8uCH$LSvYrE=#;1$)q=hm&ScwG zl3sf!fR`H@S$~PJ>jn)Kc+B8(WdD^^E(>*c0j$AY0IfYiP$=waAIoEULQOY@1E%mk ze$cpOkq_Mi?x%b7`5qP`D-3u>);0YWV9YcIxOdI-?hmM$Y#3yblUj@O8eB^LBoXZ$ znbXG67|e=Q*t_A zqlX`1*pa{FXodEt@OVG1cnrYr@as##2q%B2btqB~x`JbnnIFJFP%a~V%=RMJodkfj z^s2~QH$Y*rj}8XDO|VL!!fl%Ir1}}=vv%Qr+{xO$HyOMUFxb^Y8F3NSO*~spEKE0G z4(-PH-KK8s!#!#gFAH=;gZ?HZcNZuof(kEdDh$-%n#N@sOz-8D{p5H?Hq@^p0AHc( zb^~D(zpIcX5c;$^+p}MY0EN;b^TQOFv_-};30k`J9RwE)uye5hV&?~lnZmvNk=Uk) z9s<}Eh56ph#{N1%VBz(y94=l*SZz+C-YX*L(R%KgRo%-^kgVzY4}DN z+5A>b{XQLhBag>YubO{^*t6L6QTP+AM$lc!kv_mUu*h6B7mcU3(dQB0${I00 zfHaC{ttx`}K_2Q*il+lw$wn23v?%T(MV7(CA%zxOeXR_AAtZiMUDsnLOUG;JML;^$ z>$(AJJd`O2TLix+gioQlz7E(Z%7O>2!Pr8kTLJU)UZjqa+uWC&1GxEdyMQV~^XejG zAAd0h_-jx2i86!p7uPWZLr96rCCDXcugE1>Pj=Fc`}5QAq7%_$202Uh+uC7Z2_GLi zu+xLjUi**l=1m&P%K4Wjy>NtjGbARbMa9U(aiCPmqD;L^Mc8oc9lT+N_R zi-v;%e=tIoDiU!G1)j_Beuz~GsO&=gdx2TN8qDU<3t=i>x?wc3*%uopa=8J7x)sSnL0&FpwTJ%O2O}1U ztB}3M8^8;A3yZG^Fe3^zgw0h0{XlaF@}?S}2}cA7?vAjZ_$YsnyZ=;Pw{JosXsRR} z_N6hcwSx9m_4u7x3#s=*zwI@2fczⅈU%68{)@tBD3bm65wQV?W>TWHZjcQIJPih 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

l5iM&eDlY$*y1nU* zRlAVJN9~H(c?HFyfR!GBKSBElJ8-h|J>-NuP#x}nq{81@7_rTI=NTtV<(!SJhWzCQ zzmP_#KGYP!gpNVP9PVs({o(n3^(zBQy^Xnn2!9o-c4!1tXwn)4DmFE4e85&FpmIBCI$z@4kRkoWm zEi9!-o`N?Yl(OEgu+eiq3^Hl7V~K}Jkwtbt{V&U#D+f;i&;Gzzd;KPd%cJ;Ywc{ip zQ&LGP6|3lRL}$B1p?E$z%X-=%$*@0D;zB3+LgT(Z{De{A_6tnvqk7@20Oiev!zV{#Ql#eH# z^9#Q(zD0951o{?}7xWsNFX;6(%jkX040=8PB~#|mMTPTt)AiNBao^Vgrtg=f7tdDQ z*TvzNc8Uryy}uo#czN1tgtl34&J@}70^!#W^)?)4cAZ{%NV1Z;P%rv+kNQ7Y0+Yrk zOI)eLi%LF}UMSQ{^`PnS-O#mGgi<^!TO^*gakf_Miv@wRB|?CXRn}GG9-1(BGQ%Mg z8xqiP0`jQJW+K7n}u5W*sEZ3)y<6k?Qo{_>?=>6ufK}_%7B_1=;_~zqliq3Bj zD>9McJYwU;WUdp8XGsHX4;k{&P*XKGthkp>e Date: Wed, 30 Jan 2019 11:39:32 -0700 Subject: [PATCH 04/40] [Infra UI] Custom Field Grouping for Waffle Map (#28949) * [Infra UI] Add Support for Grouping By Custom Field * fixiing typescript errors * Serializing custom options to url so they persist accross reloads * Fixing more errors * removing label; moving custom field to top of menu * fixing typescript error * Adding intl formatMessage to strings --- .../components/waffle/custom_field_panel.tsx | 78 +++++++++++++++++++ .../waffle/waffle_group_by_controls.tsx | 60 ++++++++++++-- .../containers/waffle/nodes_to_wafflemap.ts | 11 ++- .../containers/waffle/with_waffle_options.tsx | 32 +++++++- .../infra/public/graphql/introspection.json | 5 +- x-pack/plugins/infra/public/graphql/types.ts | 3 +- x-pack/plugins/infra/public/lib/lib.ts | 7 ++ .../infra/public/pages/home/toolbar.tsx | 49 ++++++++---- .../store/local/waffle_options/actions.ts | 2 + .../store/local/waffle_options/reducer.ts | 10 ++- .../store/local/waffle_options/selector.ts | 1 + .../infra/server/graphql/nodes/schema.gql.ts | 1 + x-pack/plugins/infra/server/graphql/types.ts | 5 +- .../adapters/nodes/lib/extract_group_paths.ts | 10 ++- 14 files changed, 237 insertions(+), 37 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx diff --git a/x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx b/x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx new file mode 100644 index 0000000000000..0c676e587a774 --- /dev/null +++ b/x-pack/plugins/infra/public/components/waffle/custom_field_panel.tsx @@ -0,0 +1,78 @@ +/* + * 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 { EuiButton, EuiComboBox, EuiForm, EuiFormRow } from '@elastic/eui'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import React from 'react'; +import { InfraIndexField } from 'x-pack/plugins/infra/server/graphql/types'; +interface Props { + onSubmit: (field: string) => void; + fields: InfraIndexField[]; + intl: InjectedIntl; +} + +interface SelectedOption { + label: string; +} + +const initialState = { + selectedOptions: [] as SelectedOption[], +}; + +type State = Readonly; + +export const CustomFieldPanel = injectI18n( + class extends React.PureComponent { + public static displayName = 'CustomFieldPanel'; + public readonly state: State = initialState; + public render() { + const { fields, intl } = this.props; + const options = fields + .filter(f => f.aggregatable && f.type === 'string') + .map(f => ({ label: f.name })); + return ( +
+ + + + + + Add + + +
+ ); + } + + private handleSubmit = () => { + this.props.onSubmit(this.state.selectedOptions[0].label); + }; + + private handleFieldSelection = (selectedOptions: SelectedOption[]) => { + this.setState({ selectedOptions }); + }; + } +); diff --git a/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx b/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx index e492e153c67a0..6832460aa4f7a 100644 --- a/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx +++ b/x-pack/plugins/infra/public/components/waffle/waffle_group_by_controls.tsx @@ -8,22 +8,28 @@ import { EuiBadge, EuiContextMenu, EuiContextMenuPanelDescriptor, + EuiContextMenuPanelItemDescriptor, EuiFilterButton, EuiFilterGroup, EuiPopover, } from '@elastic/eui'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; import React from 'react'; -import { InfraNodeType, InfraPathInput, InfraPathType } from '../../graphql/types'; +import { InfraIndexField, InfraNodeType, InfraPathInput, InfraPathType } from '../../graphql/types'; +import { InfraGroupByOptions } from '../../lib/lib'; +import { CustomFieldPanel } from './custom_field_panel'; interface Props { nodeType: InfraNodeType; groupBy: InfraPathInput[]; onChange: (groupBy: InfraPathInput[]) => void; + onChangeCustomOptions: (options: InfraGroupByOptions[]) => void; + fields: InfraIndexField[]; intl: InjectedIntl; + customOptions: InfraGroupByOptions[]; } -let OPTIONS: { [P in InfraNodeType]: Array<{ text: string; type: InfraPathType; field: string }> }; +let OPTIONS: { [P in InfraNodeType]: InfraGroupByOptions[] }; const getOptions = ( nodeType: InfraNodeType, intl: InjectedIntl @@ -143,7 +149,7 @@ export const WaffleGroupByControls = injectI18n( public render() { const { nodeType, groupBy, intl } = this.props; - const options = getOptions(nodeType, intl); + const options = getOptions(nodeType, intl).concat(this.props.customOptions); if (!options.length) { throw Error( @@ -165,11 +171,35 @@ export const WaffleGroupByControls = injectI18n( id: 'xpack.infra.waffle.selectTwoGroupingsTitle', defaultMessage: 'Select up to two groupings', }), - items: options.map(o => { - const icon = groupBy.some(g => g.field === o.field) ? 'check' : 'empty'; - const panel = { name: o.text, onClick: this.handleClick(o.field), icon }; - return panel; + items: [ + { + name: intl.formatMessage({ + id: 'xpack.infra.waffle.customGroupByOptionName', + defaultMessage: 'Custom Field', + }), + icon: 'empty', + panel: 'customPanel', + }, + ...options.map(o => { + const icon = groupBy.some(g => g.field === o.field) ? 'check' : 'empty'; + const panel = { + name: o.text, + onClick: this.handleClick(o.field), + icon, + } as EuiContextMenuPanelItemDescriptor; + return panel; + }), + ], + }, + { + id: 'customPanel', + title: intl.formatMessage({ + id: 'xpack.infra.waffle.customGroupByPanelTitle', + defaultMessage: 'Group By Custom Field', }), + content: ( + + ), }, ]; const buttonBody = @@ -228,6 +258,8 @@ export const WaffleGroupByControls = injectI18n( private handleRemove = (field: string) => () => { const { groupBy } = this.props; this.props.onChange(groupBy.filter(g => g.field !== field)); + const options = this.props.customOptions.filter(g => g.field !== field); + this.props.onChangeCustomOptions(options); // We need to close the panel after we rmeove the pill icon otherwise // it will remain open because the click is still captured by the EuiFilterButton setTimeout(() => this.handleClose()); @@ -241,6 +273,20 @@ export const WaffleGroupByControls = injectI18n( this.setState(state => ({ isPopoverOpen: !state.isPopoverOpen })); }; + private handleCustomField = (field: string) => { + const options = [ + ...this.props.customOptions, + { + text: field, + field, + type: InfraPathType.custom, + }, + ]; + this.props.onChangeCustomOptions(options); + const fn = this.handleClick(field); + fn(); + }; + private handleClick = (field: string) => () => { const { groupBy } = this.props; if (groupBy.some(g => g.field === field)) { diff --git a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts b/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts index 56f2ffa0bc5d9..59a015d6d5ca3 100644 --- a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts +++ b/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts @@ -44,6 +44,7 @@ function findOrCreateGroupWithNodes( if (isWaffleMapGroupWithNodes(existingGroup)) { return existingGroup; } + const lastPath = last(path); return { id, name: @@ -51,7 +52,7 @@ function findOrCreateGroupWithNodes( ? i18n.translate('xpack.infra.nodesToWaffleMap.groupsWithNodes.allName', { defaultMessage: 'All', }) - : last(path).label, + : (lastPath && lastPath.label) || 'No Group', count: 0, width: 0, squareSize: 0, @@ -68,6 +69,7 @@ function findOrCreateGroupWithGroups( if (isWaffleMapGroupWithGroups(existingGroup)) { return existingGroup; } + const lastPath = last(path); return { id, name: @@ -75,7 +77,7 @@ function findOrCreateGroupWithGroups( ? i18n.translate('xpack.infra.nodesToWaffleMap.groupsWithGroups.allName', { defaultMessage: 'All', }) - : last(path).label, + : (lastPath && lastPath.label) || 'No Group', count: 0, width: 0, squareSize: 0, @@ -85,11 +87,14 @@ function findOrCreateGroupWithGroups( function createWaffleMapNode(node: InfraNode): InfraWaffleMapNode { const nodePathItem = last(node.path); + if (!nodePathItem) { + throw new Error('There must be a minimum of one path'); + } return { pathId: node.path.map(p => p.value).join('/'), path: node.path, id: nodePathItem.value, - name: nodePathItem.label, + name: nodePathItem.label || nodePathItem.value, metric: node.metric, }; } diff --git a/x-pack/plugins/infra/public/containers/waffle/with_waffle_options.tsx b/x-pack/plugins/infra/public/containers/waffle/with_waffle_options.tsx index b03f1e003fc4b..508d356666941 100644 --- a/x-pack/plugins/infra/public/containers/waffle/with_waffle_options.tsx +++ b/x-pack/plugins/infra/public/containers/waffle/with_waffle_options.tsx @@ -14,6 +14,7 @@ import { InfraNodeType, InfraPathType, } from '../../graphql/types'; +import { InfraGroupByOptions } from '../../lib/lib'; import { State, waffleOptionsActions, waffleOptionsSelectors } from '../../store'; import { asChildFunctionRenderer } from '../../utils/typed_react'; import { bindPlainActionCreators } from '../../utils/typed_redux'; @@ -23,10 +24,12 @@ const selectOptionsUrlState = createSelector( waffleOptionsSelectors.selectMetric, waffleOptionsSelectors.selectGroupBy, waffleOptionsSelectors.selectNodeType, - (metric, groupBy, nodeType) => ({ + waffleOptionsSelectors.selectCustomOptions, + (metric, groupBy, nodeType, customOptions) => ({ metric, groupBy, nodeType, + customOptions, }) ); @@ -35,12 +38,14 @@ export const withWaffleOptions = connect( metric: waffleOptionsSelectors.selectMetric(state), groupBy: waffleOptionsSelectors.selectGroupBy(state), nodeType: waffleOptionsSelectors.selectNodeType(state), + customOptions: waffleOptionsSelectors.selectCustomOptions(state), urlState: selectOptionsUrlState(state), }), bindPlainActionCreators({ changeMetric: waffleOptionsActions.changeMetric, changeGroupBy: waffleOptionsActions.changeGroupBy, changeNodeType: waffleOptionsActions.changeNodeType, + changeCustomOptions: waffleOptionsActions.changeCustomOptions, }) ); @@ -54,11 +59,12 @@ interface WaffleOptionsUrlState { metric?: ReturnType; groupBy?: ReturnType; nodeType?: ReturnType; + customOptions?: ReturnType; } export const WithWaffleOptionsUrlState = () => ( - {({ changeMetric, urlState, changeGroupBy, changeNodeType }) => ( + {({ changeMetric, urlState, changeGroupBy, changeNodeType, changeCustomOptions }) => ( ( if (newUrlState && newUrlState.nodeType) { changeNodeType(newUrlState.nodeType); } + if (newUrlState && newUrlState.customOptions) { + changeCustomOptions(newUrlState.customOptions); + } }} onInitialize={initialUrlState => { if (initialUrlState && initialUrlState.metric) { @@ -84,6 +93,9 @@ export const WithWaffleOptionsUrlState = () => ( if (initialUrlState && initialUrlState.nodeType) { changeNodeType(initialUrlState.nodeType); } + if (initialUrlState && initialUrlState.customOptions) { + changeCustomOptions(initialUrlState.customOptions); + } }} /> )} @@ -96,6 +108,7 @@ const mapToUrlState = (value: any): WaffleOptionsUrlState | undefined => metric: mapToMetricUrlState(value.metric), groupBy: mapToGroupByUrlState(value.groupBy), nodeType: mapToNodeTypeUrlState(value.nodeType), + customOptions: mapToCustomOptionsUrlState(value.customOptions), } : undefined; @@ -107,6 +120,15 @@ const isInfraPathInput = (subject: any): subject is InfraPathType => { return subject != null && subject.type != null && InfraPathType[subject.type] != null; }; +const isInfraGroupByOption = (subject: any): subject is InfraGroupByOptions => { + return ( + subject != null && + subject.text != null && + subject.field != null && + InfraPathType[subject.type] != null + ); +}; + const mapToMetricUrlState = (subject: any) => { return subject && isInfraMetricInput(subject) ? subject : undefined; }; @@ -118,3 +140,9 @@ const mapToGroupByUrlState = (subject: any) => { const mapToNodeTypeUrlState = (subject: any) => { return subject && InfraNodeType[subject] ? subject : undefined; }; + +const mapToCustomOptionsUrlState = (subject: any) => { + return subject && Array.isArray(subject) && subject.every(isInfraGroupByOption) + ? subject + : undefined; +}; diff --git a/x-pack/plugins/infra/public/graphql/introspection.json b/x-pack/plugins/infra/public/graphql/introspection.json index eb04a6d14e227..5fad4b5cdc2b6 100644 --- a/x-pack/plugins/infra/public/graphql/introspection.json +++ b/x-pack/plugins/infra/public/graphql/introspection.json @@ -11,7 +11,7 @@ "fields": [ { "name": "source", - "description": "Get an infrastructure data source by id.\n\nThe resolution order for the source configuration attributes is as follows\nwith the first defined value winning:\n\n1. The attributes of the saved object with the given 'id'.\n2. The attributes defined in the static Kibana configuration key\n 'xpack.infra.sources.default'.\n3. The hard-coded default values.\n\nAs a consequence, querying a source without a corresponding saved object\ndoesn't error out, but returns the configured or hardcoded defaults.", + "description": "Get an infrastructure data source by id.\n\nThe resolution order for the source configuration attributes is as follows\nwith the first defined value winning:\n\n1. The attributes of the saved object with the given 'id'.\n2. The attributes defined in the static Kibana configuration key\n 'xpack.infra.sources.default'.\n3. The hard-coded default values.\n\nAs a consequence, querying a source that doesn't exist doesn't error out,\nbut returns the configured or hardcoded defaults.", "args": [ { "name": "id", @@ -1480,7 +1480,8 @@ "description": "", "isDeprecated": false, "deprecationReason": null - } + }, + { "name": "custom", "description": "", "isDeprecated": false, "deprecationReason": null } ], "possibleTypes": null }, diff --git a/x-pack/plugins/infra/public/graphql/types.ts b/x-pack/plugins/infra/public/graphql/types.ts index eff2698106f43..ce622a3283304 100644 --- a/x-pack/plugins/infra/public/graphql/types.ts +++ b/x-pack/plugins/infra/public/graphql/types.ts @@ -9,7 +9,7 @@ // ==================================================== export interface Query { - /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source without a corresponding saved objectdoesn't error out, but returns the configured or hardcoded defaults. */ + /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source that doesn't exist doesn't error out,but returns the configured or hardcoded defaults. */ source: InfraSource; /** Get a list of all infrastructure data sources */ allSources: InfraSource[]; @@ -456,6 +456,7 @@ export enum InfraPathType { hosts = 'hosts', pods = 'pods', containers = 'containers', + custom = 'custom', } export enum InfraMetricType { diff --git a/x-pack/plugins/infra/public/lib/lib.ts b/x-pack/plugins/infra/public/lib/lib.ts index 35c58c7576158..9819c55a5a281 100644 --- a/x-pack/plugins/infra/public/lib/lib.ts +++ b/x-pack/plugins/infra/public/lib/lib.ts @@ -15,6 +15,7 @@ import { InfraNodeMetric, InfraNodePath, InfraPathInput, + InfraPathType, InfraTimerangeInput, SourceQuery, } from '../graphql/types'; @@ -204,3 +205,9 @@ export enum InfraWaffleMapDataFormat { bitsBinaryJEDEC = 'bitsBinaryJEDEC', abbreviatedNumber = 'abbreviatedNumber', } + +export interface InfraGroupByOptions { + text: string; + type: InfraPathType; + field: string; +} diff --git a/x-pack/plugins/infra/public/pages/home/toolbar.tsx b/x-pack/plugins/infra/public/pages/home/toolbar.tsx index aa519564509cf..16ac4c0a19638 100644 --- a/x-pack/plugins/infra/public/pages/home/toolbar.tsx +++ b/x-pack/plugins/infra/public/pages/home/toolbar.tsx @@ -109,22 +109,41 @@ export const HomeToolbar = injectI18n(({ intl }) => ( )} - - {({ changeMetric, changeGroupBy, groupBy, metric, nodeType }) => ( - - - - - - - - + + {({ derivedIndexPattern }) => ( + + {({ + changeMetric, + changeGroupBy, + changeCustomOptions, + customOptions, + groupBy, + metric, + nodeType, + }) => ( + + + + + + + + + )} + )} - + {({ currentTime, isAutoReloading, jumpToTime, startAutoReload, stopAutoReload }) => ( diff --git a/x-pack/plugins/infra/public/store/local/waffle_options/actions.ts b/x-pack/plugins/infra/public/store/local/waffle_options/actions.ts index 229b915db07db..79a47736e3ef4 100644 --- a/x-pack/plugins/infra/public/store/local/waffle_options/actions.ts +++ b/x-pack/plugins/infra/public/store/local/waffle_options/actions.ts @@ -7,9 +7,11 @@ import actionCreatorFactory from 'typescript-fsa'; import { InfraMetricInput, InfraNodeType, InfraPathInput } from '../../../graphql/types'; +import { InfraGroupByOptions } from '../../../lib/lib'; const actionCreator = actionCreatorFactory('x-pack/infra/local/waffle_options'); export const changeMetric = actionCreator('CHANGE_METRIC'); export const changeGroupBy = actionCreator('CHANGE_GROUP_BY'); +export const changeCustomOptions = actionCreator('CHANGE_CUSTOM_OPTIONS'); export const changeNodeType = actionCreator('CHANGE_NODE_TYPE'); diff --git a/x-pack/plugins/infra/public/store/local/waffle_options/reducer.ts b/x-pack/plugins/infra/public/store/local/waffle_options/reducer.ts index f474462245f4d..e6404f6b3213b 100644 --- a/x-pack/plugins/infra/public/store/local/waffle_options/reducer.ts +++ b/x-pack/plugins/infra/public/store/local/waffle_options/reducer.ts @@ -13,18 +13,21 @@ import { InfraNodeType, InfraPathInput, } from '../../../graphql/types'; -import { changeGroupBy, changeMetric, changeNodeType } from './actions'; +import { InfraGroupByOptions } from '../../../lib/lib'; +import { changeCustomOptions, changeGroupBy, changeMetric, changeNodeType } from './actions'; export interface WaffleOptionsState { metric: InfraMetricInput; groupBy: InfraPathInput[]; nodeType: InfraNodeType; + customOptions: InfraGroupByOptions[]; } export const initialWaffleOptionsState: WaffleOptionsState = { metric: { type: InfraMetricType.cpu }, groupBy: [], nodeType: InfraNodeType.host, + customOptions: [], }; const currentMetricReducer = reducerWithInitialState(initialWaffleOptionsState.metric).case( @@ -32,6 +35,10 @@ const currentMetricReducer = reducerWithInitialState(initialWaffleOptionsState.m (current, target) => target ); +const currentCustomOptionsReducer = reducerWithInitialState( + initialWaffleOptionsState.customOptions +).case(changeCustomOptions, (current, target) => target); + const currentGroupByReducer = reducerWithInitialState(initialWaffleOptionsState.groupBy).case( changeGroupBy, (current, target) => target @@ -46,4 +53,5 @@ export const waffleOptionsReducer = combineReducers({ metric: currentMetricReducer, groupBy: currentGroupByReducer, nodeType: currentNodeTypeReducer, + customOptions: currentCustomOptionsReducer, }); diff --git a/x-pack/plugins/infra/public/store/local/waffle_options/selector.ts b/x-pack/plugins/infra/public/store/local/waffle_options/selector.ts index 6889cd6150ab7..d5c4f4826e8b4 100644 --- a/x-pack/plugins/infra/public/store/local/waffle_options/selector.ts +++ b/x-pack/plugins/infra/public/store/local/waffle_options/selector.ts @@ -8,4 +8,5 @@ import { WaffleOptionsState } from './reducer'; export const selectMetric = (state: WaffleOptionsState) => state.metric; export const selectGroupBy = (state: WaffleOptionsState) => state.groupBy; +export const selectCustomOptions = (state: WaffleOptionsState) => state.customOptions; export const selectNodeType = (state: WaffleOptionsState) => state.nodeType; diff --git a/x-pack/plugins/infra/server/graphql/nodes/schema.gql.ts b/x-pack/plugins/infra/server/graphql/nodes/schema.gql.ts index b8002963925c3..ba47ccbc2be22 100644 --- a/x-pack/plugins/infra/server/graphql/nodes/schema.gql.ts +++ b/x-pack/plugins/infra/server/graphql/nodes/schema.gql.ts @@ -60,6 +60,7 @@ export const nodesSchema: any = gql` hosts pods containers + custom } input InfraPathInput { diff --git a/x-pack/plugins/infra/server/graphql/types.ts b/x-pack/plugins/infra/server/graphql/types.ts index 84c4eb3518fa0..10193b2998ee6 100644 --- a/x-pack/plugins/infra/server/graphql/types.ts +++ b/x-pack/plugins/infra/server/graphql/types.ts @@ -37,7 +37,7 @@ export type SubscriptionResolver { - /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source without a corresponding saved objectdoesn't error out, but returns the configured or hardcoded defaults. */ + /** Get an infrastructure data source by id.The resolution order for the source configuration attributes is as followswith the first defined value winning:1. The attributes of the saved object with the given 'id'.2. The attributes defined in the static Kibana configuration key'xpack.infra.sources.default'.3. The hard-coded default values.As a consequence, querying a source that doesn't exist doesn't error out,but returns the configured or hardcoded defaults. */ source?: SourceResolver; /** Get a list of all infrastructure data sources */ allSources?: AllSourcesResolver; diff --git a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts index 1ea42536b86a9..7e1a7857ced34 100644 --- a/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts +++ b/x-pack/plugins/infra/server/lib/adapters/nodes/lib/extract_group_paths.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { InfraNode, InfraPathInput } from '../../../../graphql/types'; +import { InfraNode, InfraNodePath, InfraPathInput } from '../../../../graphql/types'; import { InfraBucket, InfraNodeRequestOptions } from '../adapter_types'; import { createNodeItem } from './create_node_item'; @@ -27,10 +27,11 @@ export function extractGroupPaths( bucket.path_1.buckets.map( (b: InfraBucket): InfraNode => { const innerNode = createNodeItem(options, node, b); - const nodePath = [ + const groupPaths: InfraNodePath[] = [ { value: bucket.key.toString(), label: bucket.key.toString() }, { value: b.key.toString(), label: b.key.toString() }, - ].concat(innerNode.path); + ]; + const nodePath = groupPaths.concat(innerNode.path); return { ...innerNode, path: nodePath, @@ -40,7 +41,8 @@ export function extractGroupPaths( ); } const nodeItem = createNodeItem(options, node, bucket); - const path = [{ value: key, label: key }].concat(nodeItem.path); + const currentPath: InfraNodePath[] = [{ value: key, label: key }]; + const path = currentPath.concat(nodeItem.path); return acc.concat({ ...nodeItem, path, From 9595ef819dc373adcf08d44b5d15fffabaca6df6 Mon Sep 17 00:00:00 2001 From: Joe Fleming Date: Wed, 30 Jan 2019 11:59:50 -0700 Subject: [PATCH 05/40] fix: wrap url check in retry.try (#29536) since the url changes are async, keep testing the url until it passes or fails enough times --- x-pack/test/functional/apps/canvas/smoke_test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/x-pack/test/functional/apps/canvas/smoke_test.js b/x-pack/test/functional/apps/canvas/smoke_test.js index e94001a6e0508..45552e1a4067d 100644 --- a/x-pack/test/functional/apps/canvas/smoke_test.js +++ b/x-pack/test/functional/apps/canvas/smoke_test.js @@ -46,8 +46,10 @@ export default function canvasSmokeTest({ getService, getPageObjects }) { await retry.waitFor('workpad page', () => testSubjects.exists('canvasWorkpadPage')); // check that workpad loaded in url - const url = await browser.getCurrentUrl(); - expect(parse(url).hash).to.equal(`#/workpad/${testWorkpadId}/page/1`); + await retry.try(async () => { + const url = await browser.getCurrentUrl(); + expect(parse(url).hash).to.equal(`#/workpad/${testWorkpadId}/page/1`); + }); }); it('renders elements on workpad', async () => { From 15f95e8b8e32521dc841e1a00ce1195c09340e90 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Wed, 30 Jan 2019 14:25:32 -0500 Subject: [PATCH 06/40] Fix issue where the date format isn't passed in properly (#29637) --- .../logstash/pipeline_listing/pipeline_listing.js | 10 +++++----- .../public/views/logstash/node/pipelines/index.js | 2 ++ .../public/views/logstash/pipelines/index.js | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js index 99dc8afadaf12..73a78434e7116 100644 --- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js +++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js @@ -16,8 +16,8 @@ import { injectI18n } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; class PipelineListingUI extends Component { - tooltipXValueFormatter(xValue) { - return moment(xValue).format(this.props.dateFormat); + tooltipXValueFormatter(xValue, dateFormat) { + return moment(xValue).format(dateFormat); } tooltipYValueFormatter(yValue, format, units) { @@ -25,7 +25,7 @@ class PipelineListingUI extends Component { } getColumns() { - const { onBrush } = this.props; + const { onBrush, dateFormat } = this.props; const { kbnUrl, scope } = this.props.angular; return [ @@ -66,7 +66,7 @@ class PipelineListingUI extends Component { series={throughput.data} onBrush={onBrush} tooltip={{ - xValueFormatter: value => this.tooltipXValueFormatter(value), + xValueFormatter: value => this.tooltipXValueFormatter(value, dateFormat), yValueFormatter: partialRight(this.tooltipYValueFormatter, throughput.metric.format, throughput.metric.units) }} options={{ xaxis: throughput.timeRange }} @@ -100,7 +100,7 @@ class PipelineListingUI extends Component { series={nodesCount.data} onBrush={onBrush} tooltip={{ - xValueFormatter: this.tooltipXValueFormatter, + xValueFormatter: value => this.tooltipXValueFormatter(value, dateFormat), yValueFormatter: partialRight(this.tooltipYValueFormatter, nodesCount.metric.format, nodesCount.metric.units) }} options={{ xaxis: nodesCount.timeRange }} diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js index d4ee051772899..f3adea3ecb75a 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js @@ -72,6 +72,7 @@ uiRoutes controller: class extends MonitoringViewBaseEuiTableController { constructor($injector, $scope, i18n) { const kbnUrl = $injector.get('kbnUrl'); + const config = $injector.get('config'); super({ defaultData: {}, @@ -103,6 +104,7 @@ uiRoutes sorting={this.sorting} pagination={this.pagination} onTableChange={this.onTableChange} + dateFormat={config.get('dateFormat')} upgradeMessage={makeUpgradeMessage(data.nodeSummary.version, i18n)} angular={{ kbnUrl, diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js index 1e88cc678b904..d800e565ba502 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js @@ -78,6 +78,7 @@ uiRoutes const $route = $injector.get('$route'); const kbnUrl = $injector.get('kbnUrl'); + const config = $injector.get('config'); this.data = $route.current.locals.pageData; const globalState = $injector.get('globalState'); $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); @@ -110,6 +111,7 @@ uiRoutes pagination={this.pagination} onTableChange={this.onTableChange} upgradeMessage={upgradeMessage} + dateFormat={config.get('dateFormat')} angular={{ kbnUrl, scope: $scope, From 74babb2f76fc799dc8ebc753a05f70bed3139167 Mon Sep 17 00:00:00 2001 From: Robert Monfera Date: Wed, 30 Jan 2019 20:26:04 +0100 Subject: [PATCH 07/40] Fix: keep element selection after layer move up/down (#29634) --- x-pack/plugins/canvas/public/state/middleware/aeroelastic.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/state/middleware/aeroelastic.js b/x-pack/plugins/canvas/public/state/middleware/aeroelastic.js index ac69230861f3e..052df02d43e8c 100644 --- a/x-pack/plugins/canvas/public/state/middleware/aeroelastic.js +++ b/x-pack/plugins/canvas/public/state/middleware/aeroelastic.js @@ -344,7 +344,10 @@ export const aeroelastic = ({ dispatch, getState }) => { populateWithElements(page); } - if (action.type !== setMultiplePositions.toString()) { + if ( + action.type !== setMultiplePositions.toString() && + action.type !== elementLayer.toString() + ) { unselectShape(prevPage); } From 6eeccb89b6422ba3b4d22926636dbbcb58b00849 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Wed, 30 Jan 2019 14:40:04 -0500 Subject: [PATCH 08/40] Update title to stack monitoring (#29638) --- x-pack/plugins/monitoring/public/services/title.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/monitoring/public/services/title.js b/x-pack/plugins/monitoring/public/services/title.js index 21e994ce970a2..15e9b0a6c8c4c 100644 --- a/x-pack/plugins/monitoring/public/services/title.js +++ b/x-pack/plugins/monitoring/public/services/title.js @@ -16,8 +16,8 @@ uiModule.service('title', (Private, i18n) => { clusterName = (clusterName) ? `- ${clusterName}` : ''; suffix = (suffix) ? `- ${suffix}` : ''; docTitle.change( - i18n('xpack.monitoring.monitoringDocTitle', { - defaultMessage: 'Monitoring {clusterName} {suffix}', + i18n('xpack.monitoring.stackMonitoringDocTitle', { + defaultMessage: 'Stack Monitoring {clusterName} {suffix}', values: { clusterName, suffix } }), true); }; From cc0e2d0d7df487601b0922785a1f8f9c5dc7cadb Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Wed, 30 Jan 2019 13:05:06 -0700 Subject: [PATCH 09/40] Removed file_upload component (#29007) Moved filepicker style to main.scss. Removed workpad_upload component Added filepicker to asset manager Removed check for assets in workpad header to always show asset manager button Deduped image uploads in asset manager. Added loading indicator to asset manager Added empty prompt to display when there are no assets Adds additional image upload type checking Updated verbiage Undid CSS changes to workpad_loader filepicker --- .../uis/arguments/image_upload/forms/file.js | 16 +++- .../uis/arguments/image_upload/index.js | 26 +++--- x-pack/plugins/canvas/common/lib/constants.js | 1 + .../components/asset_manager/asset_manager.js | 86 +++++++++++++++---- .../asset_manager/asset_manager.scss | 17 +++- .../public/components/asset_manager/index.js | 33 ++++++- .../components/file_upload/file_upload.js | 19 ---- .../public/components/function_form/index.js | 5 +- .../public/components/workpad_header/index.js | 2 - .../workpad_header/workpad_header.js | 10 +-- .../workpad_loader/workpad_loader.js | 16 +++- .../workpad_loader/workpad_upload.js | 24 ------ .../index.js => lib/find_existing_asset.js} | 7 +- 13 files changed, 166 insertions(+), 96 deletions(-) delete mode 100644 x-pack/plugins/canvas/public/components/file_upload/file_upload.js delete mode 100644 x-pack/plugins/canvas/public/components/workpad_loader/workpad_upload.js rename x-pack/plugins/canvas/public/{components/file_upload/index.js => lib/find_existing_asset.js} (52%) diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/forms/file.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/forms/file.js index af8dc1cf37d13..c51c949568dc2 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/forms/file.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/forms/file.js @@ -5,11 +5,21 @@ */ import React from 'react'; import PropTypes from 'prop-types'; +import { EuiFilePicker } from '@elastic/eui'; import { Loading } from '../../../../../public/components/loading/loading'; -import { FileUpload } from '../../../../../public/components/file_upload'; -export const FileForm = ({ loading, onUpload }) => - loading ? : ; +export const FileForm = ({ loading, onChange }) => + loading ? ( + + ) : ( + + ); FileForm.propTypes = { loading: PropTypes.bool, diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js index d40182a1121cd..e667169b99815 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/image_upload/index.js @@ -7,6 +7,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { EuiSpacer, EuiButtonGroup } from '@elastic/eui'; +import { get } from 'lodash'; import { AssetPicker } from '../../../../public/components/asset_picker'; import { elasticOutline } from '../../../lib/elastic_outline'; import { resolveFromArgs } from '../../../../common/lib/resolve_dataurl'; @@ -14,6 +15,7 @@ import { isValidHttpUrl } from '../../../../common/lib/httpurl'; import { encode } from '../../../../common/lib/dataurl'; import { templateFromReactComponent } from '../../../../public/lib/template_from_react_component'; import './image_upload.scss'; +import { VALID_IMAGE_TYPES } from '../../../../common/lib/constants'; import { FileForm, LinkForm } from './forms'; class ImageUpload extends React.Component { @@ -71,17 +73,21 @@ class ImageUpload extends React.Component { handleUpload = files => { const { onAssetAdd } = this.props; - const [upload] = files; - this.setState({ loading: true }); // start loading indicator + const [file] = files; - encode(upload) - .then(dataurl => onAssetAdd('dataurl', dataurl)) - .then(assetId => { - this.updateAST(assetId); + const [type, subtype] = get(file, 'type', '').split('/'); + if (type === 'image' && VALID_IMAGE_TYPES.indexOf(subtype) >= 0) { + this.setState({ loading: true }); // start loading indicator - // this component can go away when onValueChange is called, check for _isMounted - this._isMounted && this.setState({ loading: false }); // set loading state back to false - }); + encode(file) + .then(dataurl => onAssetAdd('dataurl', dataurl)) + .then(assetId => { + this.updateAST(assetId); + + // this component can go away when onValueChange is called, check for _isMounted + this._isMounted && this.setState({ loading: false }); // set loading state back to false + }); + } }; changeUrlType = optionId => { @@ -119,7 +125,7 @@ class ImageUpload extends React.Component { ); const forms = { - file: , + file: , link: ( this.setState({ isModalVisible: true }); closeModal = () => this.setState({ isModalVisible: false }); @@ -52,6 +59,13 @@ export class AssetManager extends React.PureComponent { this.props.removeAsset(this.state.deleteId); }; + handleFileUpload = files => { + this.setState({ loading: true }); + Promise.all(Array.from(files).map(file => this.props.onAssetAdd(file))).finally(() => { + this._isMounted && this.setState({ loading: false }); + }); + }; + addElement = assetId => { this.props.addImageElement(assetId); }; @@ -132,16 +146,32 @@ export class AssetManager extends React.PureComponent { ); render() { - const { isModalVisible } = this.state; + const { isModalVisible, loading } = this.state; + const { assets } = this.props; const assetMaxLimit = 25000; const assetsTotal = Math.round( - this.props.assets.reduce((total, asset) => total + asset.value.length, 0) / 1024 + assets.reduce((total, asset) => total + asset.value.length, 0) / 1024 ); const percentageUsed = Math.round((assetsTotal / assetMaxLimit) * 100); + const emptyAssets = ( + + No available assets} + titleSize="s" + body={ + +

Upload your assets above to get started

+
+ } + /> +
+ ); + const assetModal = isModalVisible ? ( Manage workpad assets + + + {loading ? ( + + ) : ( + + )} + + + + + +

+ Below are the image assets that you added to this workpad. To reclaim space, delete + assets that you no longer need. Unfortunately, any assets that are actually in use + cannot be determined at this time. +

+
+ + {assets.length ? ( + + {assets.map(this.renderAsset)} + + ) : ( + emptyAssets + )} +
+ {percentageUsed}% space used - - - -

- Below are the image assets that you added to this workpad. To reclaim space, delete - assets that you no longer need. Unfortunately, any assets that are actually in use - cannot be determined at this time. -

-
- - {this.props.assets.map(this.renderAsset)} - -
- Close diff --git a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.scss b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.scss index 80ab585c963c2..84534971d0ec5 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.scss +++ b/x-pack/plugins/canvas/public/components/asset_manager/asset_manager.scss @@ -1,5 +1,4 @@ .canvasAssetManager { - .canvasAssetManager__modalHeader { flex-wrap: wrap; } @@ -15,8 +14,6 @@ flex-grow: 0; min-width: 40%; align-items: center; - justify-content: flex-end; - padding-right: $euiSize; @include euiBreakpoint('xs', 's') { flex-grow: 1; @@ -27,6 +24,11 @@ margin: 0; } + .canvasAssetManager__fileUploadWrapper { + justify-content: flex-end; + padding-right: $euiSize; + } + // ASSETS LIST .canvasAssetManager__asset { @@ -34,6 +36,11 @@ overflow: hidden; // hides image from outer panel boundaries } + .canvasAssetManager__emptyPanel { + max-width: 400px; + margin: 0 auto; + } + .canvasAssetManager__thumb { margin: -$euiSizeS; margin-bottom: 0; @@ -52,4 +59,8 @@ opacity: 0; // only show the background image (which will properly keep proportions) } } + + .canvasAssetManager__modalFooter { + justify-content: space-between; + } } diff --git a/x-pack/plugins/canvas/public/components/asset_manager/index.js b/x-pack/plugins/canvas/public/components/asset_manager/index.js index 2417e572e1a02..878928a452c56 100644 --- a/x-pack/plugins/canvas/public/components/asset_manager/index.js +++ b/x-pack/plugins/canvas/public/components/asset_manager/index.js @@ -6,14 +6,18 @@ import { connect } from 'react-redux'; import { compose, withProps } from 'recompose'; -import { set } from 'lodash'; +import { set, get } from 'lodash'; import { fromExpression, toExpression } from '@kbn/interpreter/common'; import { notify } from '../../lib/notify'; import { getAssets } from '../../state/selectors/assets'; -import { removeAsset } from '../../state/actions/assets'; +import { removeAsset, createAsset } from '../../state/actions/assets'; import { elementsRegistry } from '../../lib/elements_registry'; import { addElement } from '../../state/actions/elements'; import { getSelectedPage } from '../../state/selectors/workpad'; +import { encode } from '../../../common/lib/dataurl'; +import { getId } from '../../lib/get_id'; +import { findExistingAsset } from '../../lib/find_existing_asset'; +import { VALID_IMAGE_TYPES } from '../../../common/lib/constants'; import { AssetManager as Component } from './asset_manager'; const mapStateToProps = state => ({ @@ -44,15 +48,40 @@ const mapDispatchToProps = dispatch => ({ imageElement.expression = toExpression(newAST); dispatch(addElement(pageId, imageElement)); }, + onAssetAdd: (type, content) => { + // make the ID here and pass it into the action + const assetId = getId('asset'); + dispatch(createAsset(type, content, assetId)); + + // then return the id, so the caller knows the id that will be created + return assetId; + }, removeAsset: assetId => dispatch(removeAsset(assetId)), }); const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { assets } = stateProps; + const { onAssetAdd } = dispatchProps; return { ...ownProps, ...stateProps, ...dispatchProps, addImageElement: dispatchProps.addImageElement(stateProps.selectedPage), + onAssetAdd: file => { + const [type, subtype] = get(file, 'type', '').split('/'); + if (type === 'image' && VALID_IMAGE_TYPES.indexOf(subtype) >= 0) { + return encode(file).then(dataurl => { + const type = 'dataurl'; + const existingId = findExistingAsset(type, dataurl, assets); + if (existingId) { + return existingId; + } + return onAssetAdd(type, dataurl); + }); + } + + return false; + }, }; }; diff --git a/x-pack/plugins/canvas/public/components/file_upload/file_upload.js b/x-pack/plugins/canvas/public/components/file_upload/file_upload.js deleted file mode 100644 index 9640ab01bd158..0000000000000 --- a/x-pack/plugins/canvas/public/components/file_upload/file_upload.js +++ /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 React from 'react'; -import PropTypes from 'prop-types'; -import { EuiFilePicker } from '@elastic/eui'; - -export const FileUpload = ({ id = '', className = 'canvasFileUpload', onUpload }) => ( - -); - -FileUpload.propTypes = { - id: PropTypes.string, - className: PropTypes.string, - onUpload: PropTypes.func.isRequired, -}; diff --git a/x-pack/plugins/canvas/public/components/function_form/index.js b/x-pack/plugins/canvas/public/components/function_form/index.js index fbde896361cb6..5ca12b26e48c7 100644 --- a/x-pack/plugins/canvas/public/components/function_form/index.js +++ b/x-pack/plugins/canvas/public/components/function_form/index.js @@ -21,6 +21,7 @@ import { getContextForIndex, } from '../../state/selectors/workpad'; import { getAssets } from '../../state/selectors/assets'; +import { findExistingAsset } from '../../lib/find_existing_asset'; import { FunctionForm as Component } from './function_form'; const mapStateToProps = (state, { expressionIndex }) => ({ @@ -93,9 +94,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { onValueAdd: addArgument(element, pageId), onValueRemove: deleteArgument(element, pageId), onAssetAdd: (type, content) => { - const existingId = Object.keys(assets).find( - assetId => assets[assetId].type === type && assets[assetId].value === content - ); + const existingId = findExistingAsset(type, content, assets); if (existingId) { return existingId; } diff --git a/x-pack/plugins/canvas/public/components/workpad_header/index.js b/x-pack/plugins/canvas/public/components/workpad_header/index.js index fec9c874744f3..e724b97b0bb4f 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/index.js +++ b/x-pack/plugins/canvas/public/components/workpad_header/index.js @@ -9,7 +9,6 @@ import { connect } from 'react-redux'; import { canUserWrite } from '../../state/selectors/app'; import { getWorkpadName, getSelectedPage, isWriteable } from '../../state/selectors/workpad'; import { setWriteable } from '../../state/actions/workpad'; -import { getAssets } from '../../state/selectors/assets'; import { addElement } from '../../state/actions/elements'; import { WorkpadHeader as Component } from './workpad_header'; @@ -18,7 +17,6 @@ const mapStateToProps = state => ({ canUserWrite: canUserWrite(state), workpadName: getWorkpadName(state), selectedPage: getSelectedPage(state), - hasAssets: Object.keys(getAssets(state)).length ? true : false, }); const mapDispatchToProps = dispatch => ({ diff --git a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.js b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.js index c4fa1ce706229..88f92f7eb69e6 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.js +++ b/x-pack/plugins/canvas/public/components/workpad_header/workpad_header.js @@ -27,7 +27,6 @@ export const WorkpadHeader = ({ isWriteable, canUserWrite, toggleWriteable, - hasAssets, addElement, setShowElementModal, showElementModal, @@ -115,11 +114,9 @@ export const WorkpadHeader = ({ {isWriteable ? ( - {hasAssets && ( - - - - )} + + + date && moment(date).format('MMM D, YYYY @ h:mma'); @@ -79,7 +80,7 @@ export class WorkpadLoader extends React.PureComponent { }; // create new workpad from uploaded JSON - uploadWorkpad = async workpad => { + onUpload = async workpad => { this.setState({ createPending: true }); await this.props.createWorkpad(workpad); this._isMounted && this.setState({ createPending: false }); @@ -232,7 +233,7 @@ export class WorkpadLoader extends React.PureComponent { return ( - + + uploadWorkpad(file, this.onUpload)} + accept="application/json" + disabled={createPending || !canUserWrite} + /> ); if (!canUserWrite) { diff --git a/x-pack/plugins/canvas/public/components/workpad_loader/workpad_upload.js b/x-pack/plugins/canvas/public/components/workpad_loader/workpad_upload.js deleted file mode 100644 index 9c4372175b89f..0000000000000 --- a/x-pack/plugins/canvas/public/components/workpad_loader/workpad_upload.js +++ /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 React from 'react'; -import PropTypes from 'prop-types'; -import { EuiFilePicker } from '@elastic/eui'; -import { uploadWorkpad } from './upload_workpad'; - -export const WorkpadUpload = ({ onUpload, ...rest }) => ( - uploadWorkpad(file, onUpload)} - /> -); - -WorkpadUpload.propTypes = { - onUpload: PropTypes.func.isRequired, -}; diff --git a/x-pack/plugins/canvas/public/components/file_upload/index.js b/x-pack/plugins/canvas/public/lib/find_existing_asset.js similarity index 52% rename from x-pack/plugins/canvas/public/components/file_upload/index.js rename to x-pack/plugins/canvas/public/lib/find_existing_asset.js index 68c0f6150521b..470d7797e6feb 100644 --- a/x-pack/plugins/canvas/public/components/file_upload/index.js +++ b/x-pack/plugins/canvas/public/lib/find_existing_asset.js @@ -4,4 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -export { FileUpload } from './file_upload'; +export const findExistingAsset = (type, content, assets) => { + const existingId = Object.keys(assets).find( + assetId => assets[assetId].type === type && assets[assetId].value === content + ); + return existingId; +}; From c443fee919a6364be82708fb312558348b6663f9 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Wed, 30 Jan 2019 15:21:06 -0500 Subject: [PATCH 10/40] [Monitoring] Refactor index patterns from configurable to constants (#29528) * Move away from index patterns as configs and move them into constants * Refactor more usages of the index patterns * Remove debug * Update comment * Fix mocha tests * PR feedback --- x-pack/plugins/monitoring/common/constants.js | 7 ++++ x-pack/plugins/monitoring/config.js | 10 ------ .../server/lib/__tests__/ccs_utils.js | 35 +++++++------------ .../monitoring/server/lib/ccs_utils.js | 5 ++- .../elasticsearch/verify_monitoring_auth.js | 4 +-- .../server/routes/api/v1/alerts/index.js | 5 +-- .../server/routes/api/v1/apm/instance.js | 3 +- .../server/routes/api/v1/apm/instances.js | 3 +- .../server/routes/api/v1/apm/overview.js | 3 +- .../server/routes/api/v1/beats/beat_detail.js | 3 +- .../server/routes/api/v1/beats/beats.js | 3 +- .../server/routes/api/v1/beats/overview.js | 3 +- .../server/routes/api/v1/cluster/cluster.js | 19 ++++++---- .../server/routes/api/v1/cluster/clusters.js | 19 ++++++---- .../server/routes/api/v1/elasticsearch/ccr.js | 3 +- .../routes/api/v1/elasticsearch/ccr_shard.js | 3 +- .../api/v1/elasticsearch/index_detail.js | 3 +- .../routes/api/v1/elasticsearch/indices.js | 3 +- .../routes/api/v1/elasticsearch/ml_jobs.js | 3 +- .../api/v1/elasticsearch/node_detail.js | 3 +- .../routes/api/v1/elasticsearch/nodes.js | 3 +- .../routes/api/v1/elasticsearch/overview.js | 3 +- .../server/routes/api/v1/kibana/instance.js | 3 +- .../server/routes/api/v1/kibana/instances.js | 3 +- .../server/routes/api/v1/kibana/overview.js | 3 +- .../server/routes/api/v1/logstash/node.js | 3 +- .../server/routes/api/v1/logstash/nodes.js | 3 +- .../server/routes/api/v1/logstash/overview.js | 3 +- .../server/routes/api/v1/logstash/pipeline.js | 3 +- .../logstash/pipelines/cluster_pipelines.js | 3 +- .../v1/logstash/pipelines/node_pipelines.js | 3 +- x-pack/plugins/xpack_main/common/constants.js | 6 ++++ .../telemetry/monitoring/get_beats_stats.js | 5 ++- .../telemetry/monitoring/get_cluster_uuids.js | 3 +- .../lib/telemetry/monitoring/get_es_stats.js | 3 +- .../monitoring/get_high_level_stats.js | 22 +++++++++++- 36 files changed, 131 insertions(+), 81 deletions(-) diff --git a/x-pack/plugins/monitoring/common/constants.js b/x-pack/plugins/monitoring/common/constants.js index 372f0bd492d24..d87bb2c8be8fe 100644 --- a/x-pack/plugins/monitoring/common/constants.js +++ b/x-pack/plugins/monitoring/common/constants.js @@ -152,3 +152,10 @@ export const DEBOUNCE_FAST_MS = 10; // roughly how long it takes to render a fra export const CLUSTER_ALERTS_ADDRESS_CONFIG_KEY = 'cluster_alerts.email_notifications.email_address'; export const STANDALONE_CLUSTER_CLUSTER_UUID = '__standalone_cluster__'; + +export const INDEX_PATTERN = '.monitoring-*-6-*'; +export const INDEX_PATTERN_KIBANA = '.monitoring-kibana-6-*'; +export const INDEX_PATTERN_LOGSTASH = '.monitoring-logstash-6-*'; +export const INDEX_PATTERN_BEATS = '.monitoring-beats-6-*'; +export const INDEX_ALERTS = '.monitoring-alerts-6'; +export const INDEX_PATTERN_ELASTICSEARCH = '.monitoring-es-6-*'; diff --git a/x-pack/plugins/monitoring/config.js b/x-pack/plugins/monitoring/config.js index 6074b8c34b232..0775d219c0238 100644 --- a/x-pack/plugins/monitoring/config.js +++ b/x-pack/plugins/monitoring/config.js @@ -30,23 +30,14 @@ export const config = (Joi) => { }).default() }).default() }).default(), - index_pattern: Joi.string().default('.monitoring-*-6-*'), kibana: Joi.object({ - index_pattern: Joi.string().default('.monitoring-kibana-6-*'), collection: Joi.object({ enabled: Joi.boolean().default(true), interval: Joi.number().default(10000) // op status metrics get buffered at `ops.interval` and flushed to the bulk endpoint at this interval }).default() }).default(), - logstash: Joi.object({ - index_pattern: Joi.string().default('.monitoring-logstash-6-*') - }).default(), - beats: Joi.object({ - index_pattern: Joi.string().default('.monitoring-beats-6-*') - }).default(), cluster_alerts: Joi.object({ enabled: Joi.boolean().default(true), - index: Joi.string().default('.monitoring-alerts-6'), email_notifications: Joi.object({ enabled: Joi.boolean().default(true), email_address: Joi.string().email(), @@ -62,7 +53,6 @@ export const config = (Joi) => { }).default(), elasticsearch: Joi.object({ customHeaders: Joi.object().default({}), - index_pattern: Joi.string().default('.monitoring-es-6-*'), logQueries: Joi.boolean().default(false), requestHeadersWhitelist: Joi.array().items().single().default(DEFAULT_REQUEST_HEADERS), sniffOnStart: Joi.boolean().default(false), diff --git a/x-pack/plugins/monitoring/server/lib/__tests__/ccs_utils.js b/x-pack/plugins/monitoring/server/lib/__tests__/ccs_utils.js index 8b2ae13803782..e2aa07ad78ee1 100644 --- a/x-pack/plugins/monitoring/server/lib/__tests__/ccs_utils.js +++ b/x-pack/plugins/monitoring/server/lib/__tests__/ccs_utils.js @@ -10,76 +10,65 @@ import { parseCrossClusterPrefix, prefixIndexPattern } from '../ccs_utils'; describe('ccs_utils', () => { describe('prefixIndexPattern', () => { - const indexPatternName = 'xyz'; const indexPattern = '.monitoring-xyz-1-*,.monitoring-xyz-2-*'; it('returns the index pattern if ccs is not enabled', () => { const get = sinon.stub(); const config = { get }; - get.withArgs(indexPatternName).returns(indexPattern); get.withArgs('xpack.monitoring.ccs.enabled').returns(false); // falsy string values should be ignored - const allPattern = prefixIndexPattern(config, indexPatternName, '*'); - const onePattern = prefixIndexPattern(config, indexPatternName, 'do_not_use_me'); + const allPattern = prefixIndexPattern(config, indexPattern, '*'); + const onePattern = prefixIndexPattern(config, indexPattern, 'do_not_use_me'); expect(allPattern).to.be(indexPattern); expect(onePattern).to.be(indexPattern); - // uses the config and indexPatternName supplied - expect(get.callCount).to.eql(4); + expect(get.callCount).to.eql(2); }); it('returns the index pattern if ccs is not used', () => { const get = sinon.stub(); const config = { get }; - get.withArgs(indexPatternName).returns(indexPattern); get.withArgs('xpack.monitoring.ccs.enabled').returns(true); // falsy string values should be ignored - const undefinedPattern = prefixIndexPattern(config, indexPatternName); - const nullPattern = prefixIndexPattern(config, indexPatternName, null); - const blankPattern = prefixIndexPattern(config, indexPatternName, ''); + const undefinedPattern = prefixIndexPattern(config, indexPattern); + const nullPattern = prefixIndexPattern(config, indexPattern, null); + const blankPattern = prefixIndexPattern(config, indexPattern, ''); expect(undefinedPattern).to.be(indexPattern); expect(nullPattern).to.be(indexPattern); expect(blankPattern).to.be(indexPattern); - // uses the config and indexPatternName supplied - expect(get.callCount).to.eql(6); + expect(get.callCount).to.eql(3); }); it('returns the ccs-prefixed index pattern', () => { const get = sinon.stub(); const config = { get }; - get.withArgs(indexPatternName).returns(indexPattern); get.withArgs('xpack.monitoring.ccs.enabled').returns(true); - const abcPattern = prefixIndexPattern(config, indexPatternName, 'aBc'); - const underscorePattern = prefixIndexPattern(config, indexPatternName, 'cluster_one'); + const abcPattern = prefixIndexPattern(config, indexPattern, 'aBc'); + const underscorePattern = prefixIndexPattern(config, indexPattern, 'cluster_one'); expect(abcPattern).to.eql('aBc:.monitoring-xyz-1-*,aBc:.monitoring-xyz-2-*'); expect(underscorePattern).to.eql('cluster_one:.monitoring-xyz-1-*,cluster_one:.monitoring-xyz-2-*'); - - // uses the config and indexPatternName supplied, but only calls once - expect(get.callCount).to.eql(4); + expect(get.callCount).to.eql(2); }); it('returns the ccs-prefixed index pattern when wildcard and the local cluster pattern', () => { const get = sinon.stub(); const config = { get }; - get.withArgs(indexPatternName).returns(indexPattern); get.withArgs('xpack.monitoring.ccs.enabled').returns(true); - const pattern = prefixIndexPattern(config, indexPatternName, '*'); + const pattern = prefixIndexPattern(config, indexPattern, '*'); // it should have BOTH patterns so that it searches all CCS clusters and the local cluster expect(pattern).to.eql('*:.monitoring-xyz-1-*,*:.monitoring-xyz-2-*' + ',' + indexPattern); - - // uses the config and indexPatternName supplied, but only calls once - expect(get.callCount).to.eql(2); + expect(get.callCount).to.eql(1); }); }); diff --git a/x-pack/plugins/monitoring/server/lib/ccs_utils.js b/x-pack/plugins/monitoring/server/lib/ccs_utils.js index d879a8d51c100..30409960edd9e 100644 --- a/x-pack/plugins/monitoring/server/lib/ccs_utils.js +++ b/x-pack/plugins/monitoring/server/lib/ccs_utils.js @@ -11,13 +11,12 @@ * which means that the index pattern will be returned without using {@code ccs}. * * @param {Object} config The Kibana configuration object. - * @param {String} indexPatternName The index pattern name (e.g., 'xpack.monitoring.elasticsearch.index_pattern') + * @param {String} indexPattern The index pattern name * @param {String} ccs The optional cluster-prefix to prepend. * @return {String} The index pattern with the {@code cluster} prefix appropriately prepended. */ -export function prefixIndexPattern(config, indexPatternName, ccs) { +export function prefixIndexPattern(config, indexPattern, ccs) { const ccsEnabled = config.get('xpack.monitoring.ccs.enabled'); - const indexPattern = config.get(indexPatternName); if (!ccsEnabled || !ccs) { return indexPattern; diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js index 609fc9d46394a..5462cd492fbc8 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/verify_monitoring_auth.js @@ -6,6 +6,7 @@ import { get } from 'lodash'; import Boom from 'boom'; +import { INDEX_PATTERN } from '../../../common/constants'; /* * Check the currently logged-in user's privileges for "read" privileges on the @@ -36,7 +37,6 @@ export async function verifyMonitoringAuth(req) { */ async function verifyHasPrivileges(req) { const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring'); - const config = req.server.config(); const response = await callWithRequest(req, 'transport.request', { method: 'POST', @@ -44,7 +44,7 @@ async function verifyHasPrivileges(req) { body: { index: [ { - names: [ config.get('xpack.monitoring.index_pattern') ], // uses wildcard + names: [ INDEX_PATTERN ], // uses wildcard privileges: [ 'read' ] } ] diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/index.js b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/index.js index d9cea7f88b322..093e71e66ee2d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/alerts/index.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/alerts/index.js @@ -9,6 +9,7 @@ import { alertsClusterSearch } from '../../../../cluster_alerts/alerts_cluster_s import { checkLicense } from '../../../../cluster_alerts/check_license'; import { getClusterLicense } from '../../../../lib/cluster/get_cluster_license'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_ELASTICSEARCH, INDEX_ALERTS } from '../../../../../common/constants'; /* * Cluster Alerts route. @@ -35,8 +36,8 @@ export function clusterAlertsRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); - const alertsIndex = prefixIndexPattern(config, 'xpack.monitoring.cluster_alerts.index', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); + const alertsIndex = prefixIndexPattern(config, INDEX_ALERTS, ccs); const options = { start: req.payload.timeRange.min, end: req.payload.timeRange.max diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js index 7f9a79046d994..fad9e59902eed 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js @@ -10,6 +10,7 @@ import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_overview'; import { handleError } from '../../../../lib/errors'; import { getApmInfo } from '../../../../lib/apm'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function apmInstanceRoute(server) { server.route({ @@ -35,7 +36,7 @@ export function apmInstanceRoute(server) { const config = server.config(); const clusterUuid = req.params.clusterUuid; const ccs = req.payload.ccs; - const apmIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const apmIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); try { const [ metrics, apmSummary ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js index ec8c3cdd8d861..6a5ab2c45b9dc 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js @@ -8,6 +8,7 @@ import Joi from 'joi'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { getStats, getApms } from '../../../../lib/apm'; import { handleError } from '../../../../lib/errors'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function apmInstancesRoute(server) { server.route({ @@ -31,7 +32,7 @@ export function apmInstancesRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const apmIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const apmIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); try { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js index ecad1a444f7b0..66e39ce61ff77 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js @@ -10,6 +10,7 @@ import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_overview'; import { handleError } from '../../../../lib/errors'; import { getApmClusterStatus } from './_get_apm_cluster_status'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function apmOverviewRoute(server) { server.route({ @@ -33,7 +34,7 @@ export function apmOverviewRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const apmIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const apmIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); try { const [ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js index 7bce52319c7e9..b8020fd007ba9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js @@ -10,6 +10,7 @@ import { getBeatSummary } from '../../../../lib/beats'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors'; import { metricSet } from './metric_set_detail'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function beatsDetailRoute(server) { server.route({ @@ -36,7 +37,7 @@ export function beatsDetailRoute(server) { const beatUuid = req.params.beatUuid; const config = server.config(); const ccs = req.payload.ccs; - const beatsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const beatsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); const summaryOptions = { clusterUuid, diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js index f2e7a46f0278a..282bbf7a353a4 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js @@ -8,6 +8,7 @@ import Joi from 'joi'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { getStats, getBeats } from '../../../../lib/beats'; import { handleError } from '../../../../lib/errors'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function beatsListingRoute(server) { server.route({ @@ -32,7 +33,7 @@ export function beatsListingRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const beatsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const beatsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); try { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js index b2f0267265538..0fc32f5c3de58 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js @@ -10,6 +10,7 @@ import { getMetrics } from '../../../../lib/details/get_metrics'; import { getLatestStats, getStats } from '../../../../lib/beats'; import { handleError } from '../../../../lib/errors'; import { metricSet } from './metric_set_overview'; +import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; export function beatsOverviewRoute(server) { server.route({ @@ -34,7 +35,7 @@ export function beatsOverviewRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const beatsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); + const beatsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); try { const [ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/cluster/cluster.js b/x-pack/plugins/monitoring/server/routes/api/v1/cluster/cluster.js index 1b0d3d83f1316..7c3344626f852 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/cluster/cluster.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/cluster/cluster.js @@ -8,6 +8,13 @@ import Joi from 'joi'; import { getClustersFromRequest } from '../../../../lib/cluster/get_clusters_from_request'; import { handleError } from '../../../../lib/errors'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { + INDEX_PATTERN_KIBANA, + INDEX_PATTERN_ELASTICSEARCH, + INDEX_PATTERN_LOGSTASH, + INDEX_PATTERN_BEATS, + INDEX_ALERTS +} from '../../../../../common/constants'; export function clusterRoute(server) { /* @@ -33,12 +40,12 @@ export function clusterRoute(server) { handler: (req) => { const config = server.config(); const ccs = req.payload.ccs; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); - const kbnIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.kibana.index_pattern', ccs); - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); - const beatsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); - const apmIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); - const alertsIndex = prefixIndexPattern(config, 'xpack.monitoring.cluster_alerts.index', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); + const kbnIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_KIBANA, ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); + const beatsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); + const apmIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); + const alertsIndex = prefixIndexPattern(config, INDEX_ALERTS, ccs); const indexPatterns = { esIndexPattern, kbnIndexPattern, lsIndexPattern, beatsIndexPattern, apmIndexPattern, alertsIndex }; const options = { clusterUuid: req.params.clusterUuid, diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/cluster/clusters.js b/x-pack/plugins/monitoring/server/routes/api/v1/cluster/clusters.js index 5d3a903ab38d7..2ce91020623df 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/cluster/clusters.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/cluster/clusters.js @@ -9,6 +9,13 @@ import { getClustersFromRequest } from '../../../../lib/cluster/get_clusters_fro import { verifyMonitoringAuth } from '../../../../lib/elasticsearch/verify_monitoring_auth'; import { handleError } from '../../../../lib/errors'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { + INDEX_PATTERN_ELASTICSEARCH, + INDEX_PATTERN_KIBANA, + INDEX_PATTERN_LOGSTASH, + INDEX_PATTERN_BEATS, + INDEX_ALERTS +} from '../../../../../common/constants'; export function clustersRoute(server) { /* @@ -40,12 +47,12 @@ export function clustersRoute(server) { // wildcard means to search _all_ clusters const ccs = '*'; const config = server.config(); - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); - const kbnIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.kibana.index_pattern', ccs); - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); - const beatsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); - const apmIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.beats.index_pattern', ccs); - const alertsIndex = prefixIndexPattern(config, 'xpack.monitoring.cluster_alerts.index', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); + const kbnIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_KIBANA, ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); + const beatsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); + const apmIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_BEATS, ccs); + const alertsIndex = prefixIndexPattern(config, INDEX_ALERTS, ccs); const indexPatterns = { esIndexPattern, kbnIndexPattern, lsIndexPattern, beatsIndexPattern, apmIndexPattern, alertsIndex }; clusters = await getClustersFromRequest(req, indexPatterns); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.js index b3e85cdcee1e8..9047d1f676e85 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.js @@ -9,6 +9,7 @@ import moment from 'moment'; import { get, groupBy } from 'lodash'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; function getBucketScript(max, min) { return { @@ -185,7 +186,7 @@ export function ccrRoute(server) { async handler(req) { const config = server.config(); const ccs = req.payload.ccs; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); try { const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring'); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.js index cc8268a359911..955c32d5b6a79 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.js @@ -10,6 +10,7 @@ import Joi from 'joi'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { getMetrics } from '../../../../lib/details/get_metrics'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; function getFormattedLeaderIndex(leaderIndex) { let leader = leaderIndex; @@ -92,7 +93,7 @@ export function ccrShardRoute(server) { const index = req.params.index; const shardId = req.params.shardId; const ccs = req.payload.ccs; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); const filters = [ { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js index e27ec33db86ab..76ba483b0fdd7 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js @@ -13,6 +13,7 @@ import { getShardAllocation, getShardStats } from '../../../../lib/elasticsearch import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSet } from './metric_set_index_detail'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSet; @@ -45,7 +46,7 @@ export function esIndexRoute(server) { const indexUuid = req.params.id; const start = req.payload.timeRange.min; const end = req.payload.timeRange.max; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); const isAdvanced = req.payload.is_advanced; const metricSet = isAdvanced ? metricSetAdvanced : metricSetOverview; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js index 4e9d434372bae..22ad4f6e330c4 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js @@ -11,6 +11,7 @@ import { getIndices } from '../../../../lib/elasticsearch/indices'; import { getShardStats } from '../../../../lib/elasticsearch/shards'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; export function esIndicesRoute(server) { server.route({ @@ -38,7 +39,7 @@ export function esIndicesRoute(server) { const { clusterUuid } = req.params; const { show_system_indices: showSystemIndices } = req.query; const { ccs } = req.payload; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); try { const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js index f6387bd1fa25e..a84e63539554e 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js @@ -11,6 +11,7 @@ import { getMlJobs } from '../../../../lib/elasticsearch/get_ml_jobs'; import { getShardStats } from '../../../../lib/elasticsearch/shards'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; export function mlJobRoute(server) { server.route({ @@ -34,7 +35,7 @@ export function mlJobRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); try { const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js index 6f5d37930e7c1..2bec1646f896e 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js @@ -13,6 +13,7 @@ import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSets } from './metric_set_node_detail'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSets; @@ -45,7 +46,7 @@ export function esNodeRoute(server) { const nodeUuid = req.params.nodeUuid; const start = req.payload.timeRange.min; const end = req.payload.timeRange.max; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); const isAdvanced = req.payload.is_advanced; let metricSet; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js index 7fe93e1394b21..217cc3d2262c9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js @@ -11,6 +11,7 @@ import { getNodes } from '../../../../lib/elasticsearch/nodes'; import { getShardStats } from '../../../../lib/elasticsearch/shards'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; export function esNodesRoute(server) { server.route({ @@ -34,7 +35,7 @@ export function esNodesRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); try { const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid); diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js index ad1d65c67b6b0..068c36f5064e9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js @@ -13,6 +13,7 @@ import { getShardStats } from '../../../../lib/elasticsearch/shards'; import { handleError } from '../../../../lib/errors/handle_error'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSet } from './metric_set_overview'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; export function esOverviewRoute(server) { server.route({ @@ -36,7 +37,7 @@ export function esOverviewRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const esIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.elasticsearch.index_pattern', ccs); + const esIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_ELASTICSEARCH, ccs); try { const [ clusterStats, metrics, shardActivity ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.js b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.js index 6486ea530d53f..39d16c4e6fa97 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.js @@ -10,6 +10,7 @@ import { handleError } from '../../../../lib/errors'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSet } from './metric_set_instance'; +import { INDEX_PATTERN_KIBANA } from '../../../../../common/constants'; /** * Kibana instance: This will fetch all data required to display a Kibana @@ -41,7 +42,7 @@ export function kibanaInstanceRoute(server) { const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; const kibanaUuid = req.params.kibanaUuid; - const kbnIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.kibana.index_pattern', ccs); + const kbnIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_KIBANA, ccs); try { const [ metrics, kibanaSummary ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js index 580172ecd7ece..ca076fd8aec64 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js @@ -9,6 +9,7 @@ import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { getKibanaClusterStatus } from './_get_kibana_cluster_status'; import { getKibanas } from '../../../../lib/kibana/get_kibanas'; import { handleError } from '../../../../lib/errors'; +import { INDEX_PATTERN_KIBANA } from '../../../../../common/constants'; export function kibanaInstancesRoute(server) { /** @@ -35,7 +36,7 @@ export function kibanaInstancesRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const kbnIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.kibana.index_pattern', ccs); + const kbnIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_KIBANA, ccs); try { const [ clusterStatus, kibanas ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js index b7f396eef138f..275ac81127b97 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js @@ -10,6 +10,7 @@ import { getKibanaClusterStatus } from './_get_kibana_cluster_status'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_overview'; import { handleError } from '../../../../lib/errors'; +import { INDEX_PATTERN_KIBANA } from '../../../../../common/constants'; export function kibanaOverviewRoute(server) { /** @@ -36,7 +37,7 @@ export function kibanaOverviewRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const kbnIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.kibana.index_pattern', ccs); + const kbnIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_KIBANA, ccs); try { const [ clusterStatus, metrics ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js index 6916fa871e810..28755903c82b8 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js @@ -10,6 +10,7 @@ import { handleError } from '../../../../lib/errors'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSets } from './metric_set_node'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; const { advanced: metricSetAdvanced, overview: metricSetOverview } = metricSets; @@ -50,7 +51,7 @@ export function logstashNodeRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); const logstashUuid = req.params.logstashUuid; let metricSet; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js index 34e3b6cb2a4cc..f0af65bccaff5 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js @@ -9,6 +9,7 @@ import { getClusterStatus } from '../../../../lib/logstash/get_cluster_status'; import { getNodes } from '../../../../lib/logstash/get_nodes'; import { handleError } from '../../../../lib/errors'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; /* * Logstash Nodes route. @@ -45,7 +46,7 @@ export function logstashNodesRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); try { const [ clusterStatus, nodes ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js index 35fe0271a1885..c8cfc5b74c9fc 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js @@ -10,6 +10,7 @@ import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; import { metricSet } from './metric_set_overview'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; /* * Logstash Overview route. @@ -46,7 +47,7 @@ export function logstashOverviewRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); try { const [ metrics, clusterStatus ] = await Promise.all([ diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js index 3a93dd57a9818..433c48f02b3ea 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js @@ -8,6 +8,7 @@ import Joi from 'joi'; import { handleError } from '../../../../lib/errors'; import { getPipeline } from '../../../../lib/logstash/get_pipeline'; import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; /* * Logstash Pipeline route. @@ -41,7 +42,7 @@ export function logstashPipelineRoute(server) { const config = server.config(); const ccs = req.payload.ccs; const clusterUuid = req.params.clusterUuid; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); const pipelineId = req.params.pipelineId; // Optional params default to empty string, set to null to be more explicit. diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js index 5a90e4ec9e9dc..247e734360dc9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js @@ -9,6 +9,7 @@ import { getClusterStatus } from '../../../../../lib/logstash/get_cluster_status import { getPipelines, processPipelinesAPIResponse } from '../../../../../lib/logstash/get_pipelines'; import { handleError } from '../../../../../lib/errors'; import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../../common/constants'; /** * Retrieve pipelines for a cluster @@ -35,7 +36,7 @@ export function logstashClusterPipelinesRoute(server) { const config = server.config(); const { ccs } = req.payload; const clusterUuid = req.params.clusterUuid; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); const throughputMetric = 'logstash_cluster_pipeline_throughput'; const nodesCountMetric = 'logstash_cluster_pipeline_nodes_count'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js index 8aace30bb61f3..faec0791d7c32 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js @@ -9,6 +9,7 @@ import { getNodeInfo } from '../../../../../lib/logstash/get_node_info'; import { getPipelines, processPipelinesAPIResponse } from '../../../../../lib/logstash/get_pipelines'; import { handleError } from '../../../../../lib/errors'; import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { INDEX_PATTERN_LOGSTASH } from '../../../../../../common/constants'; /** * Retrieve pipelines for a node @@ -36,7 +37,7 @@ export function logstashNodePipelinesRoute(server) { const config = server.config(); const { ccs } = req.payload; const { clusterUuid, logstashUuid } = req.params; - const lsIndexPattern = prefixIndexPattern(config, 'xpack.monitoring.logstash.index_pattern', ccs); + const lsIndexPattern = prefixIndexPattern(config, INDEX_PATTERN_LOGSTASH, ccs); const throughputMetric = 'logstash_node_pipeline_throughput'; const nodesCountMetric = 'logstash_node_pipeline_nodes_count'; const metricSet = [ diff --git a/x-pack/plugins/xpack_main/common/constants.js b/x-pack/plugins/xpack_main/common/constants.js index 5f0b956fb1da6..1dec1a2264ea0 100644 --- a/x-pack/plugins/xpack_main/common/constants.js +++ b/x-pack/plugins/xpack_main/common/constants.js @@ -34,6 +34,12 @@ export const KIBANA_SYSTEM_ID = 'kibana'; */ export const BEATS_SYSTEM_ID = 'beats'; +/** + * The name of the Apm System ID used to publish and look up Apm stats through the Monitoring system. + * @type {string} + */ +export const APM_SYSTEM_ID = 'beats'; + /** * The name of the Kibana System ID used to look up Logstash stats through the Monitoring system. * @type {string} diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_beats_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_beats_stats.js index 321e2ebdad642..d38d8f519c047 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_beats_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_beats_stats.js @@ -6,6 +6,7 @@ import { get } from 'lodash'; import { createQuery } from './create_query'; +import { INDEX_PATTERN_BEATS } from '../../../../../monitoring/common/constants'; const HITS_SIZE = 10000; // maximum hits to receive from ES with each search @@ -173,10 +174,8 @@ export function processResults(results = [], { clusters, clusterHostSets, cluste * @return {Promise} */ async function fetchBeatsByType(server, callCluster, clusterUuids, start, end, { page = 0, ...options } = {}, type) { - const config = server.config(); - const params = { - index: config.get('xpack.monitoring.beats.index_pattern'), + index: INDEX_PATTERN_BEATS, ignoreUnavailable: true, filterPath: [ 'hits.hits._source.cluster_uuid', diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_cluster_uuids.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_cluster_uuids.js index f573a71b77d5e..9f8aac44a4728 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_cluster_uuids.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_cluster_uuids.js @@ -6,6 +6,7 @@ import { get } from 'lodash'; import { createQuery } from './create_query'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../monitoring/common/constants'; /** * Get a list of Cluster UUIDs that exist within the specified timespan. @@ -33,7 +34,7 @@ export function getClusterUuids(server, callCluster, start, end) { export function fetchClusterUuids(server, callCluster, start, end) { const config = server.config(); const params = { - index: config.get('xpack.monitoring.elasticsearch.index_pattern'), + index: INDEX_PATTERN_ELASTICSEARCH, size: 0, ignoreUnavailable: true, filterPath: 'aggregations.cluster_uuids.buckets.key', diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_es_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_es_stats.js index 377ce8160f2b4..55198a5ec85d4 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_es_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_es_stats.js @@ -5,6 +5,7 @@ */ import { get } from 'lodash'; +import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../monitoring/common/constants'; /** * Get statistics for all selected Elasticsearch clusters. @@ -30,7 +31,7 @@ export function getElasticsearchStats(server, callCluster, clusterUuids) { export function fetchElasticsearchStats(server, callCluster, clusterUuids) { const config = server.config(); const params = { - index: config.get('xpack.monitoring.elasticsearch.index_pattern'), + index: INDEX_PATTERN_ELASTICSEARCH, size: config.get('xpack.monitoring.max_bucket_size'), ignoreUnavailable: true, filterPath: [ diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_high_level_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_high_level_stats.js index b845fb5115492..fbbb81d6fd89e 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_high_level_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/get_high_level_stats.js @@ -6,6 +6,8 @@ import { get } from 'lodash'; import { createQuery } from './create_query'; +import { INDEX_PATTERN_KIBANA, INDEX_PATTERN_BEATS, INDEX_PATTERN_LOGSTASH } from '../../../../../monitoring/common/constants'; +import { KIBANA_SYSTEM_ID, BEATS_SYSTEM_ID, APM_SYSTEM_ID, LOGSTASH_SYSTEM_ID } from '../../../../common/constants'; /** * Update a counter associated with the {@code key}. @@ -139,6 +141,24 @@ function mapToList(map, keyName) { return list; } +/** + * Returns the right index pattern to find monitoring documents based on the product id + * + * @param {*} product The product id, which should be in the constants file + */ +function getIndexPatternForStackProduct(product) { + switch (product) { + case KIBANA_SYSTEM_ID: + return INDEX_PATTERN_KIBANA; + case BEATS_SYSTEM_ID: + case APM_SYSTEM_ID: + return INDEX_PATTERN_BEATS; + case LOGSTASH_SYSTEM_ID: + return INDEX_PATTERN_LOGSTASH; + } + return null; +} + /** * Get statistics about selected Elasticsearch clusters, for the selected {@code product}. * @@ -170,7 +190,7 @@ export function getHighLevelStats(server, callCluster, clusterUuids, start, end, export function fetchHighLevelStats(server, callCluster, clusterUuids, start, end, product) { const config = server.config(); const params = { - index: config.get(`xpack.monitoring.${product}.index_pattern`), + index: getIndexPatternForStackProduct(product), size: config.get('xpack.monitoring.max_bucket_size'), ignoreUnavailable: true, filterPath: [ From ee32e89324881a2faaf87ac69eb0436d9d634f80 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Wed, 30 Jan 2019 21:42:43 +0100 Subject: [PATCH 11/40] Enable KQL support for TSVB (#26006) * Use buildEsQuery for table, series and annotations * Fix query test. Using the buildEsQuery changed a bit the order of the must.bool array on the query * Remove console.log * Remove console.error and comment * Fix wrong merge of PR #26510 * Fix default/empty index_pattern When the user save the visualization without configuring manually an index_pattern, a default empty string is used instead of the default pattern. This leads to an empty visualization after the refactoring done in #24832. Now it will update the index_pattern field with the default index pattern in visualize editor and on dashboard. * Remove unnecessary wrapping query in an array * Enable query bar on tsvb * Remove unnecessary setDefaultIndexPattern After fixing the null index pattern issue in kql there is no need to use set the default index pattern before rendering. * fix(tsvb-server): Ignore query bar search on ignore_global_filters param This commit mimic the behaviour of the ignore_global_filters currently used with lucene syntax: if you enable the ignore_global_filter option on data or on annotations, data or annotations are filtered out when using the filter bar and the search bar * Disable showQueryBar --- .../metrics/public/components/_error.scss | 2 +- .../public/kbn_vis_types/editor_controller.js | 3 +- .../public/kbn_vis_types/request_handler.js | 8 +- .../lib/vis_data/build_annotation_request.js | 4 +- .../server/lib/vis_data/get_annotations.js | 41 +++++---- .../server/lib/vis_data/get_panel_data.js | 4 +- .../server/lib/vis_data/get_series_data.js | 63 +++++++------ .../server/lib/vis_data/get_table_data.js | 15 +++- .../helpers/get_es_query_uisettings.js | 28 ++++++ .../lib/vis_data/helpers/get_index_pattern.js | 41 +++++++++ .../request_processors/annotations/query.js | 38 +++----- .../series/__tests__/query.js | 90 ++++++++++++------- .../request_processors/series/query.js | 30 +++---- .../request_processors/table/query.js | 28 +++--- .../series/__tests__/build_request_body.js | 31 ++++--- .../lib/vis_data/series/build_request_body.js | 4 +- .../lib/vis_data/series/get_request_params.js | 26 +++--- .../lib/vis_data/table/build_request_body.js | 4 +- 18 files changed, 278 insertions(+), 182 deletions(-) create mode 100644 src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_query_uisettings.js create mode 100644 src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_index_pattern.js diff --git a/src/legacy/core_plugins/metrics/public/components/_error.scss b/src/legacy/core_plugins/metrics/public/components/_error.scss index 607863ccbf048..b9905c1011363 100644 --- a/src/legacy/core_plugins/metrics/public/components/_error.scss +++ b/src/legacy/core_plugins/metrics/public/components/_error.scss @@ -5,7 +5,7 @@ display: flex; align-items: center; justify-content: center; - + flex-direction: column; // Calculate colors similar to EuiCallout $tempBackgroundColor: tintOrShade($euiColorDanger, 90%, 70%); background-color: $tempBackgroundColor; diff --git a/src/legacy/core_plugins/metrics/public/kbn_vis_types/editor_controller.js b/src/legacy/core_plugins/metrics/public/kbn_vis_types/editor_controller.js index 89c859fdd421c..af40856fb20df 100644 --- a/src/legacy/core_plugins/metrics/public/kbn_vis_types/editor_controller.js +++ b/src/legacy/core_plugins/metrics/public/kbn_vis_types/editor_controller.js @@ -42,7 +42,8 @@ function ReactEditorControllerProvider(Private, config) { isEditorMode={true} appState={params.appState} /> - , this.el); + , + this.el); } resize() { diff --git a/src/legacy/core_plugins/metrics/public/kbn_vis_types/request_handler.js b/src/legacy/core_plugins/metrics/public/kbn_vis_types/request_handler.js index 59bc50b7d4562..08ec1d627fe1c 100644 --- a/src/legacy/core_plugins/metrics/public/kbn_vis_types/request_handler.js +++ b/src/legacy/core_plugins/metrics/public/kbn_vis_types/request_handler.js @@ -20,7 +20,6 @@ import { validateInterval } from '../lib/validate_interval'; import { timezoneProvider } from 'ui/vis/lib/timezone'; import { timefilter } from 'ui/timefilter'; -import { buildEsQuery } from '@kbn/es-query'; const MetricsRequestHandlerProvider = function (Private, Notifier, config, $http, i18n) { const notify = new Notifier({ location: i18n('tsvb.requestHandler.notifier.locationNameTitle', { defaultMessage: 'Metrics' }) }); @@ -35,14 +34,11 @@ const MetricsRequestHandlerProvider = function (Private, Notifier, config, $http const parsedTimeRange = timefilter.calculateBounds(timeRange); const scaledDataFormat = config.get('dateFormat:scaled'); const dateFormat = config.get('dateFormat'); - const esQueryConfigs = { - allowLeadingWildcards: config.get('query:allowLeadingWildcards'), - queryStringOptions: config.get('query:queryString:options'), - }; if (panel && panel.id) { const params = { timerange: { timezone, ...parsedTimeRange }, - filters: [buildEsQuery(undefined, query, filters, esQueryConfigs)], + query, + filters, panels: [panel], state: uiStateObj }; diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/build_annotation_request.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/build_annotation_request.js index 92902a999b43f..1796f3a0a7927 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/build_annotation_request.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/build_annotation_request.js @@ -20,8 +20,8 @@ import buildProcessorFunction from './build_processor_function'; import processors from './request_processors/annotations'; -export default function buildAnnotationRequest(req, panel, annotation) { - const processor = buildProcessorFunction(processors, req, panel, annotation); +export default function buildAnnotationRequest(req, panel, annotation, esQueryConfig, indexPattern) { + const processor = buildProcessorFunction(processors, req, panel, annotation, esQueryConfig, indexPattern); const doc = processor({}); return doc; } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_annotations.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_annotations.js index 96d65febf7657..cdb08f5289d88 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_annotations.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_annotations.js @@ -19,6 +19,7 @@ import buildAnnotationRequest from './build_annotation_request'; import handleAnnotationResponse from './handle_annotation_response'; +import { getIndexPatternObject } from './helpers/get_index_pattern'; function validAnnotation(annotation) { return annotation.index_pattern && @@ -28,27 +29,19 @@ function validAnnotation(annotation) { annotation.template; } -export default async (req, panel) => { +export default async (req, panel, esQueryConfig) => { const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('data'); - const bodies = panel.annotations + const bodiesPromises = panel.annotations .filter(validAnnotation) .map(annotation => { - - const indexPattern = annotation.index_pattern; - const bodies = []; - - bodies.push({ - index: indexPattern, - ignoreUnavailable: true, - }); - - const body = buildAnnotationRequest(req, panel, annotation); - body.timeout = '90s'; - bodies.push(body); - return bodies; + return getAnnotationBody(req, panel, annotation, esQueryConfig); }); - - if (!bodies.length) return { responses: [] }; + const bodies = await Promise.all(bodiesPromises); + if (!bodies.length) { + return { + responses: [], + }; + } try { const includeFrozen = await req.getUiSettingsService().get('search:includeFrozen'); const resp = await callWithRequest(req, 'msearch', { @@ -68,6 +61,18 @@ export default async (req, panel) => { if (error.message === 'missing-indices') return { responses: [] }; throw error; } - }; +async function getAnnotationBody(req, panel, annotation, esQueryConfig) { + const indexPatternString = annotation.index_pattern; + const indexPatternObject = await getIndexPatternObject(req, indexPatternString); + const request = buildAnnotationRequest(req, panel, annotation, esQueryConfig, indexPatternObject); + request.timeout = '90s'; + return [ + { + index: indexPatternString, + ignoreUnavailable: true, + }, + request, + ]; +} \ No newline at end of file diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_panel_data.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_panel_data.js index d22ca5e2ff4d9..865e97f370288 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_panel_data.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_panel_data.js @@ -21,7 +21,9 @@ import { getTableData } from './get_table_data'; import { getSeriesData } from './get_series_data'; export default function getPanelData(req) { return panel => { - if (panel.type === 'table') return getTableData(req, panel); + if (panel.type === 'table') { + return getTableData(req, panel); + } return getSeriesData(req, panel); }; } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_series_data.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_series_data.js index fe1eaf22a0a7a..2594db2c5db6d 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_series_data.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_series_data.js @@ -21,36 +21,45 @@ import getRequestParams from './series/get_request_params'; import handleResponseBody from './series/handle_response_body'; import handleErrorResponse from './handle_error_response'; import getAnnotations from './get_annotations'; +import { getEsQueryConfig } from './helpers/get_es_query_uisettings'; + export async function getSeriesData(req, panel) { const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('data'); const includeFrozen = await req.getUiSettingsService().get('search:includeFrozen'); - const bodies = panel.series.map(series => getRequestParams(req, panel, series)); - const params = { - rest_total_hits_as_int: true, - ignore_throttled: !includeFrozen, - body: bodies.reduce((acc, items) => acc.concat(items), []) - }; - return callWithRequest(req, 'msearch', params) - .then(resp => { - const series = resp.responses.map(handleResponseBody(panel)); - return { - [panel.id]: { - id: panel.id, - series: series.reduce((acc, series) => acc.concat(series), []) - } - }; - }) - .then(resp => { - if (!panel.annotations || panel.annotations.length === 0) return resp; - return getAnnotations(req, panel).then(annotations => { - resp[panel.id].annotations = annotations; + const esQueryConfig = await getEsQueryConfig(req); + + try { + const bodiesPromises = panel.series.map(series => getRequestParams(req, panel, series, esQueryConfig)); + const bodies = await Promise.all(bodiesPromises); + const params = { + rest_total_hits_as_int: true, + ignore_throttled: !includeFrozen, + body: bodies.reduce((acc, items) => acc.concat(items), []) + }; + return callWithRequest(req, 'msearch', params) + .then(resp => { + const series = resp.responses.map(handleResponseBody(panel)); + return { + [panel.id]: { + id: panel.id, + series: series.reduce((acc, series) => acc.concat(series), []) + } + }; + }) + .then(resp => { + if (!panel.annotations || panel.annotations.length === 0) return resp; + return getAnnotations(req, panel, esQueryConfig).then(annotations => { + resp[panel.id].annotations = annotations; + return resp; + }); + }) + .then(resp => { + resp.type = panel.type; return resp; - }); - }) - .then(resp => { - resp.type = panel.type; - return resp; - }) - .catch(handleErrorResponse(panel)); + }) + .catch(handleErrorResponse(panel)); + } catch(e) { + return handleErrorResponse(e); + } } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_table_data.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_table_data.js index ad464505806c4..a979a6669e74d 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/get_table_data.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/get_table_data.js @@ -16,18 +16,25 @@ * specific language governing permissions and limitations * under the License. */ - +import { get } from 'lodash'; import buildRequestBody from './table/build_request_body'; import handleErrorResponse from './handle_error_response'; -import { get } from 'lodash'; import processBucket from './table/process_bucket'; +import { getIndexPatternObject } from './helpers/get_index_pattern'; +import { getEsQueryConfig } from './helpers/get_es_query_uisettings'; + + export async function getTableData(req, panel) { const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('data'); const includeFrozen = await req.getUiSettingsService().get('search:includeFrozen'); + const indexPatternString = panel.index_pattern; + + const esQueryConfig = await getEsQueryConfig(req); + const indexPatternObject = await getIndexPatternObject(req, indexPatternString); const params = { - index: panel.index_pattern, + index: indexPatternString, ignore_throttled: !includeFrozen, - body: buildRequestBody(req, panel) + body: buildRequestBody(req, panel, esQueryConfig, indexPatternObject) }; try { const resp = await callWithRequest(req, 'search', params); diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_query_uisettings.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_query_uisettings.js new file mode 100644 index 0000000000000..f5ee2335cd121 --- /dev/null +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_query_uisettings.js @@ -0,0 +1,28 @@ +/* + * 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 async function getEsQueryConfig(req) { + const uiSettings = req.getUiSettingsService(); + const allowLeadingWildcards = await uiSettings.get('query:allowLeadingWildcards'); + const queryStringOptions = await uiSettings.get('query:queryString:options'); + return { + allowLeadingWildcards, + queryStringOptions: JSON.parse(queryStringOptions), + }; +} diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_index_pattern.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_index_pattern.js new file mode 100644 index 0000000000000..391f36cd439ba --- /dev/null +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_index_pattern.js @@ -0,0 +1,41 @@ +/* + * 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 async function getIndexPatternObject(req, indexPatternString) { + // getting the matching index pattern + const savedObjectClient = req.getSavedObjectsClient(); + const indexPatternObjects = await savedObjectClient.find({ + type: 'index-pattern', + fields: ['title', 'fields'], + search: `"${indexPatternString}"`, + search_fields: ['title'], + }); + + // getting the index pattern fields + const indexPatterns = indexPatternObjects.saved_objects + .filter(obj => obj.attributes.title === indexPatternString) + .map(indexPattern => { + const { title, fields } = indexPattern.attributes; + return { + title, + fields: JSON.parse(fields), + }; + }); + return indexPatterns.length === 1 ? indexPatterns[0] : null; +} diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/annotations/query.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/annotations/query.js index 922a945883dd0..2e4f765b21321 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/annotations/query.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/annotations/query.js @@ -19,29 +19,26 @@ import getBucketSize from '../../helpers/get_bucket_size'; import getTimerange from '../../helpers/get_timerange'; -export default function query(req, panel, annotation) { +import { buildEsQuery } from '@kbn/es-query'; + +export default function query(req, panel, annotation, esQueryConfig, indexPattern) { return next => doc => { const timeField = annotation.time_field; - const { - bucketSize - } = getBucketSize(req, 'auto'); + const { bucketSize } = getBucketSize(req, 'auto'); const { from, to } = getTimerange(req); doc.size = 0; - doc.query = { - bool: { - must: [] - } - }; - + const queries = !annotation.ignore_global_filters ? req.payload.query : []; + const filters = !annotation.ignore_global_filters ? req.payload.filters : []; + doc.query = buildEsQuery(indexPattern, queries, filters, esQueryConfig); const timerange = { range: { [timeField]: { gte: from.valueOf(), - lte: to.valueOf() - (bucketSize * 1000), + lte: to.valueOf() - bucketSize * 1000, format: 'epoch_millis', - } - } + }, + }, }; doc.query.bool.must.push(timerange); @@ -49,22 +46,17 @@ export default function query(req, panel, annotation) { doc.query.bool.must.push({ query_string: { query: annotation.query_string, - analyze_wildcard: true - } + analyze_wildcard: true, + }, }); } - const globalFilters = req.payload.filters; - if (!annotation.ignore_global_filters) { - doc.query.bool.must = doc.query.bool.must.concat(globalFilters); - } - if (!annotation.ignore_panel_filters && panel.filter) { doc.query.bool.must.push({ query_string: { query: panel.filter, - analyze_wildcard: true - } + analyze_wildcard: true, + }, }); } @@ -76,7 +68,5 @@ export default function query(req, panel, annotation) { } return next(doc); - }; } - diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/__tests__/query.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/__tests__/query.js index a889c8b3e96b6..dd18d1c865e1b 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/__tests__/query.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/__tests__/query.js @@ -26,6 +26,10 @@ describe('query(req, panel, series)', () => { let panel; let series; let req; + const config = { + allowLeadingWildcards: true, + queryStringOptions: {}, + }; beforeEach(() => { req = { payload: { @@ -45,17 +49,18 @@ describe('query(req, panel, series)', () => { it('calls next when finished', () => { const next = sinon.spy(); - query(req, panel, series)(next)({}); + query(req, panel, series, config)(next)({}); expect(next.calledOnce).to.equal(true); }); it('returns doc with query for timerange', () => { const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ { range: { @@ -66,7 +71,9 @@ describe('query(req, panel, series)', () => { } } } - ] + ], + must_not: [], + should: [], } } }); @@ -75,11 +82,12 @@ describe('query(req, panel, series)', () => { it('returns doc with query for timerange (offset by 1h)', () => { series.offset_time = '1h'; const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ { range: { @@ -90,7 +98,9 @@ describe('query(req, panel, series)', () => { } } } - ] + ], + must_not: [], + should: [], } } }); @@ -111,21 +121,13 @@ describe('query(req, panel, series)', () => { } ]; const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ - { - range: { - timestamp: { - gte: 1483228800000, - lte: 1483232400000, - format: 'epoch_millis' - } - } - }, { bool: { must: [ @@ -136,8 +138,19 @@ describe('query(req, panel, series)', () => { } ] } - } - ] + }, + { + range: { + timestamp: { + gte: 1483228800000, + lte: 1483232400000, + format: 'epoch_millis' + } + } + }, + ], + must_not: [], + should: [], } } }); @@ -146,11 +159,12 @@ describe('query(req, panel, series)', () => { it('returns doc with series filter', () => { series.filter = 'host:web-server'; const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ { range: { @@ -166,8 +180,10 @@ describe('query(req, panel, series)', () => { query: series.filter, analyze_wildcard: true } - } - ] + }, + ], + must_not: [], + should: [], } } }); @@ -188,21 +204,13 @@ describe('query(req, panel, series)', () => { ]; panel.filter = 'host:web-server'; const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ - { - range: { - timestamp: { - gte: 1483228800000, - lte: 1483232400000, - format: 'epoch_millis' - } - } - }, { bool: { must: [ @@ -214,13 +222,24 @@ describe('query(req, panel, series)', () => { ] } }, + { + range: { + timestamp: { + gte: 1483228800000, + lte: 1483232400000, + format: 'epoch_millis' + } + } + }, { query_string: { query: panel.filter, analyze_wildcard: true } } - ] + ], + must_not: [], + should: [], } } }); @@ -243,11 +262,12 @@ describe('query(req, panel, series)', () => { panel.filter = 'host:web-server'; panel.ignore_global_filter = true; const next = doc => doc; - const doc = query(req, panel, series)(next)({}); + const doc = query(req, panel, series, config)(next)({}); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ { range: { @@ -263,8 +283,10 @@ describe('query(req, panel, series)', () => { query: panel.filter, analyze_wildcard: true } - } - ] + }, + ], + must_not: [], + should: [], } } }); diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/query.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/query.js index 65813ff42a808..9a08aec011cc5 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/query.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/series/query.js @@ -19,17 +19,17 @@ import offsetTime from '../../offset_time'; import getIntervalAndTimefield from '../../get_interval_and_timefield'; -export default function query(req, panel, series) { +import { buildEsQuery } from '@kbn/es-query'; + +export default function query(req, panel, series, esQueryConfig, indexPattern) { return next => doc => { const { timeField } = getIntervalAndTimefield(panel, series); const { from, to } = offsetTime(req, series.offset_time); doc.size = 0; - doc.query = { - bool: { - must: [] - } - }; + const queries = !panel.ignore_global_filter ? req.payload.query : []; + const filters = !panel.ignore_global_filter ? req.payload.filters : []; + doc.query = buildEsQuery(indexPattern, queries, filters, esQueryConfig); const timerange = { range: { @@ -37,22 +37,17 @@ export default function query(req, panel, series) { gte: from.valueOf(), lte: to.valueOf(), format: 'epoch_millis', - } - } + }, + }, }; doc.query.bool.must.push(timerange); - const globalFilters = req.payload.filters; - if (globalFilters && !panel.ignore_global_filter) { - doc.query.bool.must = doc.query.bool.must.concat(globalFilters); - } - if (panel.filter) { doc.query.bool.must.push({ query_string: { query: panel.filter, - analyze_wildcard: true - } + analyze_wildcard: true, + }, }); } @@ -60,12 +55,11 @@ export default function query(req, panel, series) { doc.query.bool.must.push({ query_string: { query: series.filter, - analyze_wildcard: true - } + analyze_wildcard: true, + }, }); } return next(doc); - }; } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/table/query.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/table/query.js index 77a970003d93c..ece96f19c3607 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/table/query.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/request_processors/table/query.js @@ -16,20 +16,20 @@ * specific language governing permissions and limitations * under the License. */ - +import { buildEsQuery } from '@kbn/es-query'; import getTimerange from '../../helpers/get_timerange'; import getIntervalAndTimefield from '../../get_interval_and_timefield'; -export default function query(req, panel) { + +export default function query(req, panel, esQueryConfig, indexPattern) { return next => doc => { const { timeField } = getIntervalAndTimefield(panel); const { from, to } = getTimerange(req); doc.size = 0; - doc.query = { - bool: { - must: [] - } - }; + + const queries = !panel.ignore_global_filter ? req.payload.query : []; + const filters = !panel.ignore_global_filter ? req.payload.filters : []; + doc.query = buildEsQuery(indexPattern, queries, filters, esQueryConfig); const timerange = { range: { @@ -37,26 +37,20 @@ export default function query(req, panel) { gte: from.valueOf(), lte: to.valueOf(), format: 'epoch_millis', - } - } + }, + }, }; doc.query.bool.must.push(timerange); - const globalFilters = req.payload.filters; - if (globalFilters && !panel.ignore_global_filter) { - doc.query.bool.must = doc.query.bool.must.concat(globalFilters); - } - if (panel.filter) { doc.query.bool.must.push({ query_string: { query: panel.filter, - analyze_wildcard: true - } + analyze_wildcard: true, + }, }); } return next(doc); - }; } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/__tests__/build_request_body.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/__tests__/build_request_body.js index 31699e3c41831..cb944bb8363fa 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/__tests__/build_request_body.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/__tests__/build_request_body.js @@ -82,21 +82,17 @@ describe('buildRequestBody(req)', () => { it('returns a valid body', () => { const panel = body.panels[0]; const series = panel.series[0]; - const doc = buildRequestBody({ payload: body }, panel, series); + const config = { + allowLeadingWildcards: true, + queryStringOptions: {}, + }; + const doc = buildRequestBody({ payload: body }, panel, series, config); expect(doc).to.eql({ size: 0, query: { bool: { + filter: [], must: [ - { - range: { - '@timestamp': { - gte: 1485463055881, - lte: 1485463955881, - format: 'epoch_millis' - } - } - }, { bool: { must: [ @@ -109,8 +105,19 @@ describe('buildRequestBody(req)', () => { ], must_not: [] } - } - ] + }, + { + range: { + '@timestamp': { + gte: 1485463055881, + lte: 1485463955881, + format: 'epoch_millis' + } + } + }, + ], + must_not: [], + should: [], } }, aggs: { diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/build_request_body.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/build_request_body.js index 0afe2869b72fa..c25127b68a6bc 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/build_request_body.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/build_request_body.js @@ -20,8 +20,8 @@ import buildProcessorFunction from '../build_processor_function'; import processors from '../request_processors/series'; -function buildRequestBody(req, panel, series) { - const processor = buildProcessorFunction(processors, req, panel, series); +function buildRequestBody(req, panel, series, esQueryConfig, indexPattern) { + const processor = buildProcessorFunction(processors, req, panel, series, esQueryConfig, indexPattern); const doc = processor({}); return doc; } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/get_request_params.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/get_request_params.js index ed56035d859b8..598ebed73b94c 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/series/get_request_params.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/series/get_request_params.js @@ -18,18 +18,18 @@ */ import buildRequestBody from './build_request_body'; +import { getIndexPatternObject } from '../helpers/get_index_pattern'; -export default (req, panel, series) => { - const indexPattern = series.override_index_pattern && series.series_index_pattern || panel.index_pattern; - const bodies = []; - - bodies.push({ - index: indexPattern, - ignoreUnavailable: true, - }); - - const body = buildRequestBody(req, panel, series); - body.timeout = '90s'; - bodies.push(body); - return bodies; +export default async (req, panel, series, esQueryConfig) => { + const indexPatternString = series.override_index_pattern && series.series_index_pattern || panel.index_pattern; + const indexPatternObject = await getIndexPatternObject(req, indexPatternString); + const request = buildRequestBody(req, panel, series, esQueryConfig, indexPatternObject); + request.timeout = '90s'; + return [ + { + index: indexPatternString, + ignoreUnavailable: true, + }, + request, + ]; }; diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/build_request_body.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/table/build_request_body.js index 8a71a7ba79f0a..7e509a5ebf2e5 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/table/build_request_body.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/table/build_request_body.js @@ -20,8 +20,8 @@ import buildProcessorFunction from '../build_processor_function'; import processors from '../request_processors/table'; -function buildRequestBody(req, panel) { - const processor = buildProcessorFunction(processors, req, panel); +function buildRequestBody(req, panel, esQueryConfig, indexPattern) { + const processor = buildProcessorFunction(processors, req, panel, esQueryConfig, indexPattern); const doc = processor({}); return doc; } From 410c094547e235d5805a94f066117a05381ab5a4 Mon Sep 17 00:00:00 2001 From: Matt Bargar Date: Wed, 30 Jan 2019 15:48:31 -0500 Subject: [PATCH 12/40] Migrate filter bar to React, EUI, and Typescript (#25563) Rewrites the filter bar in React, EUI, and Typescript. Updates the look and feel of the filter bar and makes it consistent with the rest of K7. --- packages/kbn-es-query/README.md | 94 ++++ packages/kbn-es-query/package.json | 5 +- packages/kbn-es-query/src/filters/exists.js | 1 + .../kbn-es-query/src/filters/index.d.ts | 43 +- packages/kbn-es-query/src/filters/index.js | 1 + .../src/filters/lib/custom_filter.ts | 9 +- .../src/filters/lib/exists_filter.ts | 26 + .../filters/lib/geo_bounding_box_filter.ts | 17 +- .../src/filters/lib/geo_polygon_filter.ts | 30 ++ .../kbn-es-query/src/filters/lib/index.ts | 50 ++ .../src/filters/lib/meta_filter.ts | 100 ++++ .../src/filters/lib/phrase_filter.ts | 30 ++ .../src/filters/lib/phrases_filter.ts | 28 ++ .../src/filters/lib/query_string_filter.ts | 26 + .../src/filters/lib/range_filter.ts | 35 ++ packages/kbn-es-query/src/filters/phrase.js | 1 + packages/kbn-es-query/src/filters/phrases.js | 2 + packages/kbn-es-query/src/filters/query.js | 1 + packages/kbn-es-query/src/filters/range.js | 2 + packages/kbn-es-query/src/index.d.ts | 1 + packages/kbn-es-query/tsconfig.json | 8 +- .../filters/scripted_phrase_filter.js | 42 -- .../kibana/public/context/app.html | 7 +- .../core_plugins/kibana/public/context/app.js | 1 + .../context/query_parameters/actions.js | 7 + .../public/dashboard/dashboard_app.html | 21 +- .../kibana/public/dashboard/dashboard_app.js | 53 +- .../public/discover/controllers/discover.js | 21 +- .../kibana/public/discover/index.html | 25 +- .../public/visualize/editor/editor.html | 32 +- .../kibana/public/visualize/editor/editor.js | 26 +- src/ui/public/_index.scss | 1 + .../agg_types/filter/agg_type_filters.test.ts | 2 +- .../apply_filters/apply_filters_popover.tsx | 128 +++++ src/ui/public/apply_filters/directive.html | 7 + src/ui/public/apply_filters/directive.js | 59 +++ .../index.js => apply_filters/index.ts} | 4 +- .../public/doc_table/components/table_row.js | 2 +- .../index.d.ts} | 2 +- .../public/filter_bar/__tests__/filter_bar.js | 228 --------- .../__tests__/filter_bar_click_handler.js | 80 --- .../filter_bar/_global_filter_group.scss | 22 + .../filter_bar/_global_filter_item.scss | 37 ++ src/ui/public/filter_bar/_index.scss | 2 + .../public/filter_bar/directive.js} | 30 +- src/ui/public/filter_bar/filter_bar.html | 149 ------ src/ui/public/filter_bar/filter_bar.js | 213 -------- src/ui/public/filter_bar/filter_bar.less | 226 --------- src/ui/public/filter_bar/filter_bar.tsx | 217 ++++++++ .../filter_bar/filter_bar_click_handler.js | 89 ---- .../filter_editor/generic_combo_box.tsx | 61 +++ .../public/filter_bar/filter_editor/index.tsx | 471 ++++++++++++++++++ .../lib/filter_editor_utils.test.ts | 314 ++++++++++++ .../filter_editor/lib/filter_editor_utils.ts | 178 +++++++ .../filter_editor/lib/filter_operators.ts | 106 ++++ .../lib/fixtures/exists_filter.ts} | 25 +- .../lib/fixtures/phrase_filter.ts} | 22 +- .../lib/fixtures/phrases_filter.ts} | 33 +- .../lib/fixtures/range_filter.ts | 39 ++ .../filter_editor/phrase_suggestor.tsx | 73 +++ .../filter_editor/phrase_value_input.tsx | 88 ++++ .../filter_editor/phrases_values_input.tsx | 67 +++ .../filter_editor/range_value_input.tsx | 121 +++++ .../filter_editor/value_input_type.tsx | 120 +++++ src/ui/public/filter_bar/filter_item.tsx | 226 +++++++++ .../filter_bar/filter_pill/filter_pill.html | 97 ---- .../filter_bar/filter_pill/filter_pill.js | 57 --- .../public/filter_bar/filter_view/index.tsx | 103 ++++ src/ui/public/filter_bar/index.ts | 22 + .../lib/__tests__/disable_filter.js | 140 ------ .../__tests__/filter_applied_and_unwrap.js | 38 -- .../__tests__/filter_out_time_based_filter.js | 57 --- .../lib/filter_out_time_based_filter.js | 33 -- src/ui/public/filter_bar/lib/map_phrase.js | 8 +- src/ui/public/filter_bar/query_filter.js | 29 +- .../public/filter_editor/filter_editor.html | 148 ------ src/ui/public/filter_editor/filter_editor.js | 161 ------ .../public/filter_editor/filter_editor.less | 36 -- .../filter_editor/filter_field_select.html | 27 - .../filter_editor/filter_field_select.js | 52 -- .../filter_editor/filter_operator_select.html | 12 - .../filter_editor/filter_operator_select.js | 42 -- .../filter_query_dsl_editor.html | 13 - .../filter_editor/filter_query_dsl_editor.js | 59 --- .../lib/__tests__/filter_editor_utils.js | 396 --------------- .../filter_editor/lib/filter_editor_utils.js | 111 ----- .../filter_editor/lib/filter_operators.js | 72 --- .../params_editor/filter_params_editor.html | 19 - .../params_editor/filter_params_editor.js | 37 -- .../filter_params_input_type.html | 50 -- .../params_editor/filter_params_input_type.js | 49 -- .../filter_params_phrase_controller.js | 57 --- .../filter_params_phrase_editor.html | 45 -- .../filter_params_phrase_editor.js | 42 -- .../filter_params_phrases_editor.html | 28 -- .../filter_params_phrases_editor.js | 39 -- .../filter_params_range_editor.html | 30 -- src/ui/public/index_patterns/_field.d.ts | 26 + .../public/index_patterns/_index_pattern.d.ts | 9 +- .../public/index_patterns/fixtures/index.ts | 79 +++ src/ui/public/index_patterns/index.d.ts | 7 +- .../static_utils/__tests__/index.js | 54 +- .../index_patterns/static_utils/index.d.ts | 11 +- .../index_patterns/static_utils/index.js | 10 +- .../__snapshots__/query_bar.test.tsx.snap | 3 - .../query_bar/components/query_bar.test.tsx | 20 +- .../public/query_bar/components/query_bar.tsx | 7 +- .../components/typeahead/_suggestion.scss | 5 +- .../search_bar/components/filter_options.tsx | 184 +++++++ .../components/index.tsx} | 2 +- .../search_bar/components/search_bar.tsx | 178 +++++++ .../directive/index.js} | 26 +- src/ui/public/search_bar/index.tsx | 22 + src/ui/public/styles/bootstrap_dark.less | 1 - src/ui/public/timefilter/get_time.ts | 8 +- src/ui/public/value_suggestions/index.ts | 24 + .../value_suggestions.test.ts | 131 +++++ .../value_suggestions/value_suggestions.ts | 53 ++ .../config/editor_config_providers.test.ts | 17 +- .../apps/dashboard/_dashboard_filter_bar.js | 22 +- .../apps/dashboard/_dashboard_filtering.js | 2 +- test/functional/apps/discover/_discover.js | 2 +- .../apps/management/_scripted_fields.js | 9 +- .../functional/page_objects/dashboard_page.js | 4 - test/functional/page_objects/discover_page.js | 7 - .../services/dashboard/expectations.js | 10 +- test/functional/services/filter_bar.js | 86 ++-- .../beats_management/types/kibana.d.ts | 16 - .../autocomplete_providers/__tests__/value.js | 149 +++--- .../public/autocomplete_providers/field.js | 7 +- .../public/autocomplete_providers/operator.js | 4 +- .../public/autocomplete_providers/value.js | 35 +- .../plugins/ml/public/explorer/explorer.html | 8 +- .../ml/public/explorer/explorer_controller.js | 18 +- x-pack/plugins/ml/public/util/index_utils.js | 2 +- .../dashboard_mode/dashboard_view_mode.js | 5 +- 136 files changed, 4131 insertions(+), 3428 deletions(-) create mode 100644 packages/kbn-es-query/README.md rename src/ui/public/filter_bar/lib/disable_filter.js => packages/kbn-es-query/src/filters/index.d.ts (50%) rename src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js => packages/kbn-es-query/src/filters/lib/custom_filter.ts (87%) create mode 100644 packages/kbn-es-query/src/filters/lib/exists_filter.ts rename src/fixtures/filters/index.js => packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts (75%) create mode 100644 packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts create mode 100644 packages/kbn-es-query/src/filters/lib/index.ts create mode 100644 packages/kbn-es-query/src/filters/lib/meta_filter.ts create mode 100644 packages/kbn-es-query/src/filters/lib/phrase_filter.ts create mode 100644 packages/kbn-es-query/src/filters/lib/phrases_filter.ts create mode 100644 packages/kbn-es-query/src/filters/lib/query_string_filter.ts create mode 100644 packages/kbn-es-query/src/filters/lib/range_filter.ts delete mode 100644 src/fixtures/filters/scripted_phrase_filter.js create mode 100644 src/ui/public/apply_filters/apply_filters_popover.tsx create mode 100644 src/ui/public/apply_filters/directive.html create mode 100644 src/ui/public/apply_filters/directive.js rename src/ui/public/{filter_bar/index.js => apply_filters/index.ts} (86%) rename src/ui/public/{filter_bar/filter_pill/index.js => documentation_links/index.d.ts} (94%) delete mode 100644 src/ui/public/filter_bar/__tests__/filter_bar.js delete mode 100644 src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js create mode 100644 src/ui/public/filter_bar/_global_filter_group.scss create mode 100644 src/ui/public/filter_bar/_global_filter_item.scss create mode 100644 src/ui/public/filter_bar/_index.scss rename src/{fixtures/filters/range_filter.js => ui/public/filter_bar/directive.js} (71%) delete mode 100644 src/ui/public/filter_bar/filter_bar.html delete mode 100644 src/ui/public/filter_bar/filter_bar.js create mode 100644 src/ui/public/filter_bar/filter_bar.tsx delete mode 100644 src/ui/public/filter_bar/filter_bar_click_handler.js create mode 100644 src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/index.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts create mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts create mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts rename src/{fixtures/filters/exists_filter.js => ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts} (73%) rename src/{fixtures/filters/phrase_filter.js => ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts} (80%) rename src/{fixtures/filters/phrases_filter.js => ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts} (70%) create mode 100644 src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts create mode 100644 src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/range_value_input.tsx create mode 100644 src/ui/public/filter_bar/filter_editor/value_input_type.tsx create mode 100644 src/ui/public/filter_bar/filter_item.tsx delete mode 100644 src/ui/public/filter_bar/filter_pill/filter_pill.html delete mode 100644 src/ui/public/filter_bar/filter_pill/filter_pill.js create mode 100644 src/ui/public/filter_bar/filter_view/index.tsx create mode 100644 src/ui/public/filter_bar/index.ts delete mode 100644 src/ui/public/filter_bar/lib/__tests__/disable_filter.js delete mode 100644 src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js delete mode 100644 src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js delete mode 100644 src/ui/public/filter_bar/lib/filter_out_time_based_filter.js delete mode 100644 src/ui/public/filter_editor/filter_editor.html delete mode 100644 src/ui/public/filter_editor/filter_editor.js delete mode 100644 src/ui/public/filter_editor/filter_editor.less delete mode 100644 src/ui/public/filter_editor/filter_field_select.html delete mode 100644 src/ui/public/filter_editor/filter_field_select.js delete mode 100644 src/ui/public/filter_editor/filter_operator_select.html delete mode 100644 src/ui/public/filter_editor/filter_operator_select.js delete mode 100644 src/ui/public/filter_editor/filter_query_dsl_editor.html delete mode 100644 src/ui/public/filter_editor/filter_query_dsl_editor.js delete mode 100644 src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js delete mode 100644 src/ui/public/filter_editor/lib/filter_editor_utils.js delete mode 100644 src/ui/public/filter_editor/lib/filter_operators.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_editor.html delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_editor.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_input_type.html delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_input_type.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js delete mode 100644 src/ui/public/filter_editor/params_editor/filter_params_range_editor.html create mode 100644 src/ui/public/index_patterns/_field.d.ts create mode 100644 src/ui/public/index_patterns/fixtures/index.ts create mode 100644 src/ui/public/search_bar/components/filter_options.tsx rename src/ui/public/{filter_editor/index.js => search_bar/components/index.tsx} (95%) create mode 100644 src/ui/public/search_bar/components/search_bar.tsx rename src/ui/public/{filter_editor/params_editor/filter_params_range_editor.js => search_bar/directive/index.js} (69%) create mode 100644 src/ui/public/search_bar/index.tsx create mode 100644 src/ui/public/value_suggestions/index.ts create mode 100644 src/ui/public/value_suggestions/value_suggestions.test.ts create mode 100644 src/ui/public/value_suggestions/value_suggestions.ts diff --git a/packages/kbn-es-query/README.md b/packages/kbn-es-query/README.md new file mode 100644 index 0000000000000..53f082b864d73 --- /dev/null +++ b/packages/kbn-es-query/README.md @@ -0,0 +1,94 @@ +# kbn-es-query + +This module is responsible for generating Elasticsearch queries for Kibana. See explanations below for each of the subdirectories. + +## es_query + +This folder contains the code that combines Lucene/KQL queries and filters into an Elasticsearch query. + +```javascript +buildEsQuery(indexPattern, queries, filters, config) +``` + +Generates the Elasticsearch query DSL from combining the queries and filters provided. + +```javascript +buildQueryFromFilters(filters, indexPattern) +``` + +Generates the Elasticsearch query DSL from the given filters. + +```javascript +luceneStringToDsl(query) +``` + +Generates the Elasticsearch query DSL from the given Lucene query. + +```javascript +migrateFilter(filter, indexPattern) +``` + +Migrates a filter from a previous version of Elasticsearch to the current version. + +```javascript +decorateQuery(query, queryStringOptions) +``` + +Decorates an Elasticsearch query_string query with the given options. + +## filters + +This folder contains the code related to Kibana Filter objects, including their definitions, and helper functions to create them. Filters in Kibana always contain a `meta` property which describes which `index` the filter corresponds to, as well as additional data about the specific filter. + +The object that is created by each of the following functions corresponds to a Filter object in the `lib` directory (e.g. `PhraseFilter`, `RangeFilter`, etc.) + +```javascript +buildExistsFilter(field, indexPattern) +``` + +Creates a filter (`ExistsFilter`) where the given field exists. + +```javascript +buildPhraseFilter(field, value, indexPattern) +``` + +Creates an filter (`PhraseFilter`) where the given field matches the given value. + +```javascript +buildPhrasesFilter(field, params, indexPattern) +``` + +Creates a filter (`PhrasesFilter`) where the given field matches one or more of the given values. `params` should be an array of values. + +```javascript +buildQueryFilter(query, index) +``` + +Creates a filter (`CustomFilter`) corresponding to a raw Elasticsearch query DSL object. + +```javascript +buildRangeFilter(field, params, indexPattern) +``` + +Creates a filter (`RangeFilter`) where the value for the given field is in the given range. `params` should contain `lt`, `lte`, `gt`, and/or `gte`. + +## kuery + +This folder contains the code corresponding to generating Elasticsearch queries using the Kibana query language. + +It also contains code corresponding to the original implementation of Kuery (released in 6.0) which should be removed at some point (see legacy_kuery.js, legacy_kuery.peg). + +In general, you will only need to worry about the following functions from the `ast` folder: + +```javascript +fromExpression(expression) +``` + +Generates an abstract syntax tree corresponding to the raw Kibana query `expression`. + +```javascript +toElasticsearchQuery(node, indexPattern) +``` + +Takes an abstract syntax tree (generated from the previous method) and generates the Elasticsearch query DSL using the given `indexPattern`. Note that if no `indexPattern` is provided, then an Elasticsearch query DSL will still be generated, ignoring things like the index pattern scripted fields, field types, etc. + diff --git a/packages/kbn-es-query/package.json b/packages/kbn-es-query/package.json index ce3e96cc8219c..ec4226f6b1e75 100644 --- a/packages/kbn-es-query/package.json +++ b/packages/kbn-es-query/package.json @@ -5,14 +5,15 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build": "babel src --out-dir target", + "build": "tsc && babel src --out-dir target", "kbn:bootstrap": "yarn build --quiet", "kbn:watch": "yarn build --watch" - }, +}, "dependencies": { "lodash": "npm:@elastic/lodash@3.10.1-kibana1" }, "devDependencies": { + "typescript": "^3.0.3", "@kbn/babel-preset": "1.0.0", "babel-cli": "^6.26.0", "expect.js": "0.3.1" diff --git a/packages/kbn-es-query/src/filters/exists.js b/packages/kbn-es-query/src/filters/exists.js index dd0d62f36c146..0c82279fb4417 100644 --- a/packages/kbn-es-query/src/filters/exists.js +++ b/packages/kbn-es-query/src/filters/exists.js @@ -17,6 +17,7 @@ * under the License. */ +// Creates a filter where the given field exists export function buildExistsFilter(field, indexPattern) { return { meta: { diff --git a/src/ui/public/filter_bar/lib/disable_filter.js b/packages/kbn-es-query/src/filters/index.d.ts similarity index 50% rename from src/ui/public/filter_bar/lib/disable_filter.js rename to packages/kbn-es-query/src/filters/index.d.ts index 815bc4eb2a83a..c46a767e38ea4 100644 --- a/src/ui/public/filter_bar/lib/disable_filter.js +++ b/packages/kbn-es-query/src/filters/index.d.ts @@ -17,28 +17,31 @@ * under the License. */ -export function disableFilter(filter) { - return setFilterDisabled(filter, true); -} +import { Field, IndexPattern } from 'ui/index_patterns'; +import { CustomFilter, ExistsFilter, PhraseFilter, PhrasesFilter, RangeFilter } from './lib'; +import { RangeFilterParams } from './lib/range_filter'; -export function enableFilter(filter) { - return setFilterDisabled(filter, false); -} +export * from './lib'; -export function toggleFilterDisabled(filter) { - const { meta: { disabled = false } = {} } = filter; +export function buildExistsFilter(field: Field, indexPattern: IndexPattern): ExistsFilter; - return setFilterDisabled(filter, !disabled); -} +export function buildPhraseFilter( + field: Field, + value: string, + indexPattern: IndexPattern +): PhraseFilter; -function setFilterDisabled(filter, disabled) { - const { meta = {} } = filter; +export function buildPhrasesFilter( + field: Field, + values: string[], + indexPattern: IndexPattern +): PhrasesFilter; - return { - ...filter, - meta: { - ...meta, - disabled, - } - }; -} +export function buildQueryFilter(query: any, index: string): CustomFilter; + +export function buildRangeFilter( + field: Field, + params: RangeFilterParams, + indexPattern: IndexPattern, + formattedValue?: string +): RangeFilter; diff --git a/packages/kbn-es-query/src/filters/index.js b/packages/kbn-es-query/src/filters/index.js index dfd8924736862..d7d092eabd8a2 100644 --- a/packages/kbn-es-query/src/filters/index.js +++ b/packages/kbn-es-query/src/filters/index.js @@ -22,3 +22,4 @@ export * from './phrase'; export * from './phrases'; export * from './query'; export * from './range'; +export * from './lib'; diff --git a/src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js b/packages/kbn-es-query/src/filters/lib/custom_filter.ts similarity index 87% rename from src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js rename to packages/kbn-es-query/src/filters/lib/custom_filter.ts index 843ff6daf1049..1003cc984a90f 100644 --- a/src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js +++ b/packages/kbn-es-query/src/filters/lib/custom_filter.ts @@ -17,9 +17,8 @@ * under the License. */ -import _ from 'lodash'; - -export function filterAppliedAndUnwrap(filters) { - return _.filter(filters, 'meta.apply'); -} +import { Filter } from './meta_filter'; +export type CustomFilter = Filter & { + query: any; +}; diff --git a/packages/kbn-es-query/src/filters/lib/exists_filter.ts b/packages/kbn-es-query/src/filters/lib/exists_filter.ts new file mode 100644 index 0000000000000..356d039f4d19b --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/exists_filter.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 { Filter, FilterMeta } from './meta_filter'; + +export type ExistsFilterMeta = FilterMeta; + +export type ExistsFilter = Filter & { + meta: ExistsFilterMeta; +}; diff --git a/src/fixtures/filters/index.js b/packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts similarity index 75% rename from src/fixtures/filters/index.js rename to packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts index e8f823c4e8cbe..c83e146b093a3 100644 --- a/src/fixtures/filters/index.js +++ b/packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts @@ -17,8 +17,15 @@ * under the License. */ -export { phraseFilter } from './phrase_filter'; -export { scriptedPhraseFilter } from './scripted_phrase_filter'; -export { phrasesFilter } from './phrases_filter'; -export { rangeFilter } from './range_filter'; -export { existsFilter } from './exists_filter'; +import { Filter, FilterMeta, LatLon } from './meta_filter'; + +export type GeoBoundingBoxFilterMeta = FilterMeta & { + params: { + bottom_right: LatLon; + top_left: LatLon; + }; +}; + +export type GeoBoundingBoxFilter = Filter & { + meta: GeoBoundingBoxFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts b/packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts new file mode 100644 index 0000000000000..80b606e13bb3d --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts @@ -0,0 +1,30 @@ +/* + * 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 { Filter, FilterMeta, LatLon } from './meta_filter'; + +export type GeoPolygonFilterMeta = FilterMeta & { + params: { + points: LatLon[]; + }; +}; + +export type GeoPolygonFilter = Filter & { + meta: GeoPolygonFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/lib/index.ts b/packages/kbn-es-query/src/filters/lib/index.ts new file mode 100644 index 0000000000000..fdf87c84eb5ca --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/index.ts @@ -0,0 +1,50 @@ +/* + * 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. + */ + +// The interface the other filters extend +export * from './meta_filter'; + +// The actual filter types +import { CustomFilter } from './custom_filter'; +import { ExistsFilter } from './exists_filter'; +import { GeoBoundingBoxFilter } from './geo_bounding_box_filter'; +import { GeoPolygonFilter } from './geo_polygon_filter'; +import { PhraseFilter } from './phrase_filter'; +import { PhrasesFilter } from './phrases_filter'; +import { QueryStringFilter } from './query_string_filter'; +import { RangeFilter } from './range_filter'; +export { + CustomFilter, + ExistsFilter, + GeoBoundingBoxFilter, + GeoPolygonFilter, + PhraseFilter, + PhrasesFilter, + QueryStringFilter, + RangeFilter, +}; + +// Any filter associated with a field (used in the filter bar/editor) +export type FieldFilter = + | ExistsFilter + | GeoBoundingBoxFilter + | GeoPolygonFilter + | PhraseFilter + | PhrasesFilter + | RangeFilter; diff --git a/packages/kbn-es-query/src/filters/lib/meta_filter.ts b/packages/kbn-es-query/src/filters/lib/meta_filter.ts new file mode 100644 index 0000000000000..db5b308a01da3 --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/meta_filter.ts @@ -0,0 +1,100 @@ +/* + * 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 enum FilterStateStore { + APP_STATE = 'appState', + GLOBAL_STATE = 'globalState', +} + +export interface FilterState { + store: FilterStateStore; +} + +export interface FilterMeta { + // index and type are optional only because when you create a new filter, there are no defaults + index?: string; + type?: string; + disabled: boolean; + negate: boolean; + alias: string | null; + key?: string; + value?: string; +} + +export interface Filter { + $state: FilterState; + meta: FilterMeta; + query?: any; +} + +export interface LatLon { + lat: number; + lon: number; +} + +export function buildEmptyFilter(isPinned: boolean, index?: string): Filter { + const meta: FilterMeta = { + disabled: false, + negate: false, + alias: null, + index, + }; + const $state: FilterState = { + store: isPinned ? FilterStateStore.GLOBAL_STATE : FilterStateStore.APP_STATE, + }; + return { meta, $state }; +} + +export function isFilterPinned(filter: Filter) { + return filter.$state.store === FilterStateStore.GLOBAL_STATE; +} + +export function toggleFilterDisabled(filter: Filter) { + const disabled = !filter.meta.disabled; + const meta = { ...filter.meta, disabled }; + return { ...filter, meta }; +} + +export function toggleFilterNegated(filter: Filter) { + const negate = !filter.meta.negate; + const meta = { ...filter.meta, negate }; + return { ...filter, meta }; +} + +export function toggleFilterPinned(filter: Filter) { + const store = isFilterPinned(filter) ? FilterStateStore.APP_STATE : FilterStateStore.GLOBAL_STATE; + const $state = { ...filter.$state, store }; + return { ...filter, $state }; +} + +export function enableFilter(filter: Filter) { + return !filter.meta.disabled ? filter : toggleFilterDisabled(filter); +} + +export function disableFilter(filter: Filter) { + return filter.meta.disabled ? filter : toggleFilterDisabled(filter); +} + +export function pinFilter(filter: Filter) { + return isFilterPinned(filter) ? filter : toggleFilterPinned(filter); +} + +export function unpinFilter(filter: Filter) { + return !isFilterPinned(filter) ? filter : toggleFilterPinned(filter); +} diff --git a/packages/kbn-es-query/src/filters/lib/phrase_filter.ts b/packages/kbn-es-query/src/filters/lib/phrase_filter.ts new file mode 100644 index 0000000000000..a8613190ce786 --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/phrase_filter.ts @@ -0,0 +1,30 @@ +/* + * 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 { Filter, FilterMeta } from './meta_filter'; + +export type PhraseFilterMeta = FilterMeta & { + params: { + query: string; // The unformatted value + }; +}; + +export type PhraseFilter = Filter & { + meta: PhraseFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/lib/phrases_filter.ts b/packages/kbn-es-query/src/filters/lib/phrases_filter.ts new file mode 100644 index 0000000000000..cc36ad54c8dc4 --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/phrases_filter.ts @@ -0,0 +1,28 @@ +/* + * 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 { Filter, FilterMeta } from './meta_filter'; + +export type PhrasesFilterMeta = FilterMeta & { + params: string[]; // The unformatted values +}; + +export type PhrasesFilter = Filter & { + meta: PhrasesFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/lib/query_string_filter.ts b/packages/kbn-es-query/src/filters/lib/query_string_filter.ts new file mode 100644 index 0000000000000..1f6a95844437a --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/query_string_filter.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 { Filter, FilterMeta } from './meta_filter'; + +export type QueryStringFilterMeta = FilterMeta; + +export type QueryStringFilter = Filter & { + meta: QueryStringFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/lib/range_filter.ts b/packages/kbn-es-query/src/filters/lib/range_filter.ts new file mode 100644 index 0000000000000..214652fb3f332 --- /dev/null +++ b/packages/kbn-es-query/src/filters/lib/range_filter.ts @@ -0,0 +1,35 @@ +/* + * 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 { Filter, FilterMeta } from './meta_filter'; + +export interface RangeFilterParams { + gt?: number | string; + gte?: number | string; + lte?: number | string; + lt?: number | string; +} + +export type RangeFilterMeta = FilterMeta & { + params: RangeFilterParams; +}; + +export type RangeFilter = Filter & { + meta: RangeFilterMeta; +}; diff --git a/packages/kbn-es-query/src/filters/phrase.js b/packages/kbn-es-query/src/filters/phrase.js index 8677fde87ceda..b71724ab60d76 100644 --- a/packages/kbn-es-query/src/filters/phrase.js +++ b/packages/kbn-es-query/src/filters/phrase.js @@ -17,6 +17,7 @@ * under the License. */ +// Creates an filter where the given field matches the given value export function buildPhraseFilter(field, value, indexPattern) { const filter = { meta: { index: indexPattern.id } }; const convertedValue = getConvertedValueForField(field, value); diff --git a/packages/kbn-es-query/src/filters/phrases.js b/packages/kbn-es-query/src/filters/phrases.js index 0d85669e65fcd..f02b3763f37bb 100644 --- a/packages/kbn-es-query/src/filters/phrases.js +++ b/packages/kbn-es-query/src/filters/phrases.js @@ -19,6 +19,8 @@ import { getPhraseScript } from './phrase'; +// Creates a filter where the given field matches one or more of the given values +// params should be an array of values export function buildPhrasesFilter(field, params, indexPattern) { const index = indexPattern.id; const type = 'phrases'; diff --git a/packages/kbn-es-query/src/filters/query.js b/packages/kbn-es-query/src/filters/query.js index 428d656364987..cfb1a6d36d9e2 100644 --- a/packages/kbn-es-query/src/filters/query.js +++ b/packages/kbn-es-query/src/filters/query.js @@ -17,6 +17,7 @@ * under the License. */ +// Creates a filter corresponding to a raw Elasticsearch query DSL object export function buildQueryFilter(query, index) { return { query: query, diff --git a/packages/kbn-es-query/src/filters/range.js b/packages/kbn-es-query/src/filters/range.js index ec3fc167f75d4..88be09c997154 100644 --- a/packages/kbn-es-query/src/filters/range.js +++ b/packages/kbn-es-query/src/filters/range.js @@ -36,6 +36,8 @@ function formatValue(field, params) { return _.map(params, (val, key) => operators[key] + format(field, val)).join(' '); } +// Creates a filter where the value for the given field is in the given range +// params should be an object containing `lt`, `lte`, `gt`, and/or `gte` export function buildRangeFilter(field, params, indexPattern, formattedValue) { const filter = { meta: { index: indexPattern.id } }; if (formattedValue) filter.meta.formattedValue = formattedValue; diff --git a/packages/kbn-es-query/src/index.d.ts b/packages/kbn-es-query/src/index.d.ts index 79e6903b18644..873636a28889f 100644 --- a/packages/kbn-es-query/src/index.d.ts +++ b/packages/kbn-es-query/src/index.d.ts @@ -18,3 +18,4 @@ */ export * from './kuery'; +export * from './filters'; diff --git a/packages/kbn-es-query/tsconfig.json b/packages/kbn-es-query/tsconfig.json index 9a22ea4fc44aa..c2b6e3075dc67 100644 --- a/packages/kbn-es-query/tsconfig.json +++ b/packages/kbn-es-query/tsconfig.json @@ -1,7 +1,11 @@ { - "extends": "../../tsconfig.json", + "extends": "../../tsconfig.browser.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./target" + }, "include": [ "index.d.ts", - "src/**/*.d.ts" + "src/**/*.ts" ] } diff --git a/src/fixtures/filters/scripted_phrase_filter.js b/src/fixtures/filters/scripted_phrase_filter.js deleted file mode 100644 index f21a6356de19f..0000000000000 --- a/src/fixtures/filters/scripted_phrase_filter.js +++ /dev/null @@ -1,42 +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. - */ - -export const scriptedPhraseFilter = { - 'meta': { - 'negate': false, - 'index': 'logstash-*', - 'field': 'script string', - 'type': 'phrase', - 'key': 'script string', - 'value': 'i am a string', - 'disabled': false - }, - 'script': { - 'script': { - 'inline': 'boolean compare(Supplier s, def v) {return s.get() == v;}compare(() -> { \'i am a string\' }, params.value);', - 'lang': 'painless', - 'params': { - 'value': 'i am a string' - } - } - }, - '$state': { - 'store': 'appState' - } -}; diff --git a/src/legacy/core_plugins/kibana/public/context/app.html b/src/legacy/core_plugins/kibana/public/context/app.html index 9bdd538b850bb..ea9b66ac29e56 100644 --- a/src/legacy/core_plugins/kibana/public/context/app.html +++ b/src/legacy/core_plugins/kibana/public/context/app.html @@ -19,7 +19,12 @@ - +
(predecessorCount) => ( @@ -65,6 +67,10 @@ export function QueryParameterActionsProvider(indexPatterns, Private) { ) ); + const updateFilters = () => filters => { + queryFilter.setFilters(filters); + }; + const addFilter = (state) => async (field, values, operation) => { const indexPatternId = state.queryParameters.indexPatternId; filterManager.add(field, values, operation, indexPatternId); @@ -74,6 +80,7 @@ export function QueryParameterActionsProvider(indexPatterns, Private) { return { addFilter, + updateFilters, increasePredecessorCount, increaseSuccessorCount, setPredecessorCount, diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html index 0aa3c6eb930cc..67774b3400816 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html @@ -30,22 +30,25 @@
- + filters="model.filters" + on-filters-updated="onFiltersUpdated" + show-filter-bar="showFilterBar()" + watch-depth="reference" + >
- - +
0) { + $scope.indexPatterns = panelIndexPatterns; + } + else { + indexPatterns.getDefault().then((defaultIndexPattern) => { + $scope.$evalAsync(() => { + $scope.indexPatterns = [defaultIndexPattern]; + }); + }); + } }; // Part of the exposed plugin API - do not remove without careful consideration. @@ -153,7 +167,7 @@ app.directive('dashboardApp', function ($injector) { query: '', language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage') }, - filterBar.getFilters() + queryFilter.getFilters() ); timefilter.enableAutoRefreshSelector(); @@ -224,11 +238,31 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.requestReload(); } else { $scope.model.query = migrateLegacyQuery(query); - dashboardStateManager.applyFilters($scope.model.query, filterBar.getFilters()); + dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters); } $scope.refresh(); }; + $scope.onFiltersUpdated = filters => { + // The filters will automatically be set when the queryFilter emits an update event (see below) + queryFilter.setFilters(filters); + }; + + $scope.onCancelApplyFilters = () => { + $scope.appState.$newFilters = []; + }; + + $scope.onApplyFilters = filters => { + queryFilter.addFiltersAndChangeTimeFilter(filters); + $scope.appState.$newFilters = []; + }; + + $scope.$watch('appState.$newFilters', (filters = []) => { + if (filters.length === 1) { + $scope.onApplyFilters(filters); + } + }); + $scope.indexPatterns = []; $scope.onPanelRemoved = (panelIndex) => { @@ -347,7 +381,7 @@ app.directive('dashboardApp', function ($injector) { }); } - $scope.showFilterBar = () => filterBar.getFilters().length > 0 || !dashboardStateManager.getFullScreenMode(); + $scope.showFilterBar = () => $scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode(); $scope.showAddPanel = () => { dashboardStateManager.setFullScreenMode(false); @@ -458,12 +492,13 @@ app.directive('dashboardApp', function ($injector) { updateViewMode(dashboardStateManager.getViewMode()); // update root source when filters update - $scope.$listen(filterBar, 'update', function () { - dashboardStateManager.applyFilters($scope.model.query, filterBar.getFilters()); + $scope.$listen(queryFilter, 'update', function () { + $scope.model.filters = queryFilter.getFilters(); + dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters); }); // update data when filters fire fetch event - $scope.$listen(filterBar, 'fetch', $scope.refresh); + $scope.$listen(queryFilter, 'fetch', $scope.refresh); $scope.$on('$destroy', () => { dashboardStateManager.destroy(); diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index cedaa5fbb232a..5845625163cd3 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -33,7 +33,7 @@ import 'ui/filters/moment'; import 'ui/index_patterns'; import 'ui/state_management/app_state'; import { timefilter } from 'ui/timefilter'; -import 'ui/query_bar'; +import 'ui/search_bar'; import { hasSearchStategyForIndexPattern, isDefaultTypeIndexPattern } from 'ui/courier'; import { toastNotifications } from 'ui/notify'; import { VisProvider } from 'ui/vis'; @@ -351,6 +351,24 @@ function discoverController( const $state = $scope.state = new AppState(getStateDefaults()); + $scope.filters = queryFilter.getFilters(); + + $scope.onFiltersUpdated = filters => { + // The filters will automatically be set when the queryFilter emits an update event (see below) + queryFilter.setFilters(filters); + }; + + $scope.applyFilters = filters => { + queryFilter.addFiltersAndChangeTimeFilter(filters); + $scope.state.$newFilters = []; + }; + + $scope.$watch('state.$newFilters', (filters = []) => { + if (filters.length === 1) { + $scope.applyFilters(filters); + } + }); + const getFieldCounts = async () => { // the field counts aren't set until we have the data back, // so we wait for the fetch to be done before proceeding @@ -488,6 +506,7 @@ function discoverController( // update data source when filters update $scope.$listen(queryFilter, 'update', function () { + $scope.filters = queryFilter.getFilters(); return $scope.updateDataSource().then(function () { $state.save(); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index f9fae245a6469..b11097a07ce02 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -30,23 +30,20 @@

- + filters="filters" + on-filters-updated="onFiltersUpdated" + watch-depth="reference" + >

-
- -
- + + +
{ + // The filters will automatically be set when the queryFilter emits an update event (see below) + queryFilter.setFilters(filters); + }; + + $scope.onCancelApplyFilters = () => { + $scope.state.$newFilters = []; + }; + + $scope.onApplyFilters = filters => { + queryFilter.addFiltersAndChangeTimeFilter(filters); + $scope.state.$newFilters = []; + }; + + $scope.$watch('state.$newFilters', (filters = []) => { + if (filters.length === 1) { + $scope.onApplyFilters(filters); + } + }); + function init() { // export some objects $scope.savedVis = savedVis; @@ -353,6 +376,7 @@ function VisEditor( // update the searchSource when filters update $scope.$listen(queryFilter, 'update', function () { + $scope.filters = queryFilter.getFilters(); $scope.fetch(); }); diff --git a/src/ui/public/_index.scss b/src/ui/public/_index.scss index fc8e02aadc8da..88726b1a69e5e 100644 --- a/src/ui/public/_index.scss +++ b/src/ui/public/_index.scss @@ -26,6 +26,7 @@ @import './notify/index'; @import './partials/index'; @import './query_bar/index'; +@import './filter_bar/index'; @import './style_compile/index'; // The following are prefixed with "vis" diff --git a/src/ui/public/agg_types/filter/agg_type_filters.test.ts b/src/ui/public/agg_types/filter/agg_type_filters.test.ts index 47e7bebf9f365..416e9c1b45fd2 100644 --- a/src/ui/public/agg_types/filter/agg_type_filters.test.ts +++ b/src/ui/public/agg_types/filter/agg_type_filters.test.ts @@ -21,7 +21,7 @@ import { AggTypeFilters } from './agg_type_filters'; describe('AggTypeFilters', () => { let registry: AggTypeFilters; - const indexPattern = {}; + const indexPattern = { id: '1234', fields: [], title: 'foo' }; const aggConfig = {}; beforeEach(() => { diff --git a/src/ui/public/apply_filters/apply_filters_popover.tsx b/src/ui/public/apply_filters/apply_filters_popover.tsx new file mode 100644 index 0000000000000..67f78b0951f19 --- /dev/null +++ b/src/ui/public/apply_filters/apply_filters_popover.tsx @@ -0,0 +1,128 @@ +/* + * 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 { + EuiButton, + EuiButtonEmpty, + EuiForm, + EuiFormRow, + EuiModal, + EuiModalBody, + EuiModalFooter, + EuiModalHeader, + EuiModalHeaderTitle, + EuiOverlayMask, + EuiSwitch, +} from '@elastic/eui'; +import { Filter } from '@kbn/es-query'; +import { FormattedMessage } from '@kbn/i18n/react'; +import React, { Component } from 'react'; +import { getFilterDisplayText } from '../filter_bar/filter_view'; + +interface Props { + filters: Filter[]; + onCancel: () => void; + onSubmit: (filters: Filter[]) => void; +} + +interface State { + isFilterSelected: boolean[]; +} + +export class ApplyFiltersPopover extends Component { + public static defaultProps = { + filters: [], + }; + + public constructor(props: Props) { + super(props); + this.state = { + isFilterSelected: props.filters.map(() => true), + }; + } + + public render() { + if (this.props.filters.length === 0) { + return ''; + } + + const form = ( + + {this.props.filters.map((filter, i) => ( + + this.toggleFilterSelected(i)} + /> + + ))} + + ); + + return ( + + + + + + + + + {form} + + + + + + + + + + + + ); + } + + private isFilterSelected = (i: number) => { + return this.state.isFilterSelected[i]; + }; + + private toggleFilterSelected = (i: number) => { + const isFilterSelected = [...this.state.isFilterSelected]; + isFilterSelected[i] = !isFilterSelected[i]; + this.setState({ isFilterSelected }); + }; + + private onSubmit = () => { + const selectedFilters = this.props.filters.filter( + (filter, i) => this.state.isFilterSelected[i] + ); + this.props.onSubmit(selectedFilters); + }; +} diff --git a/src/ui/public/apply_filters/directive.html b/src/ui/public/apply_filters/directive.html new file mode 100644 index 0000000000000..ed7a5d70a2b80 --- /dev/null +++ b/src/ui/public/apply_filters/directive.html @@ -0,0 +1,7 @@ + diff --git a/src/ui/public/apply_filters/directive.js b/src/ui/public/apply_filters/directive.js new file mode 100644 index 0000000000000..d364a1843494a --- /dev/null +++ b/src/ui/public/apply_filters/directive.js @@ -0,0 +1,59 @@ +/* + * 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 'ngreact'; +import { uiModules } from '../modules'; +import template from './directive.html'; +import { ApplyFiltersPopover } from './apply_filters_popover'; +import { FilterBarLibMapAndFlattenFiltersProvider } from '../filter_bar/lib/map_and_flatten_filters'; + +const app = uiModules.get('app/kibana', ['react']); + +app.directive('applyFiltersPopoverComponent', (reactDirective) => { + return reactDirective(ApplyFiltersPopover); +}); + +app.directive('applyFiltersPopover', (reactDirective, Private) => { + const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); + + return { + template, + restrict: 'E', + scope: { + filters: '=', + onCancel: '=', + onSubmit: '=', + }, + link: function ($scope) { + $scope.state = {}; + + // Each time the new filters change we want to rebuild (not just re-render) the "apply filters" + // popover, because it has to reset its state whenever the new filters change. Setting a `key` + // property on the component accomplishes this due to how React handles the `key` property. + $scope.$watch('filters', filters => { + mapAndFlattenFilters(filters).then(mappedFilters => { + $scope.state = { + filters: mappedFilters, + key: Date.now(), + }; + }); + }); + } + }; +}); diff --git a/src/ui/public/filter_bar/index.js b/src/ui/public/apply_filters/index.ts similarity index 86% rename from src/ui/public/filter_bar/index.js rename to src/ui/public/apply_filters/index.ts index 082a17b501ed9..4346316e62374 100644 --- a/src/ui/public/filter_bar/index.js +++ b/src/ui/public/apply_filters/index.ts @@ -17,6 +17,6 @@ * under the License. */ -import './filter_bar'; // directive +import './directive'; -export { disableFilter, enableFilter, toggleFilterDisabled } from './lib/disable_filter'; +export { ApplyFiltersPopover } from './apply_filters_popover'; diff --git a/src/ui/public/doc_table/components/table_row.js b/src/ui/public/doc_table/components/table_row.js index b7c5768bbaa9a..f16be56778355 100644 --- a/src/ui/public/doc_table/components/table_row.js +++ b/src/ui/public/doc_table/components/table_row.js @@ -27,7 +27,7 @@ import { noWhiteSpace } from '../../../../legacy/core_plugins/kibana/common/util import openRowHtml from './table_row/open.html'; import detailsHtml from './table_row/details.html'; import { uiModules } from '../../modules'; -import { disableFilter } from '../../filter_bar'; +import { disableFilter } from '@kbn/es-query'; import { dispatchRenderComplete } from '../../render_complete'; const module = uiModules.get('app/discover'); diff --git a/src/ui/public/filter_bar/filter_pill/index.js b/src/ui/public/documentation_links/index.d.ts similarity index 94% rename from src/ui/public/filter_bar/filter_pill/index.js rename to src/ui/public/documentation_links/index.d.ts index 3db610588eb75..b37021b497de3 100644 --- a/src/ui/public/filter_bar/filter_pill/index.js +++ b/src/ui/public/documentation_links/index.d.ts @@ -17,4 +17,4 @@ * under the License. */ -import './filter_pill'; +export function getDocLink(id: string): string; diff --git a/src/ui/public/filter_bar/__tests__/filter_bar.js b/src/ui/public/filter_bar/__tests__/filter_bar.js deleted file mode 100644 index a17875a3d8837..0000000000000 --- a/src/ui/public/filter_bar/__tests__/filter_bar.js +++ /dev/null @@ -1,228 +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 ngMock from 'ng_mock'; -import expect from 'expect.js'; -import sinon from 'sinon'; - -import MockState from 'fixtures/mock_state'; -import $ from 'jquery'; -import '..'; -import { FilterBarLibMapFilterProvider } from '../lib/map_filter'; -import { FilterBarQueryFilterProvider } from '../query_filter'; - -describe('Filter Bar Directive', function () { - let $rootScope; - let $compile; - let Promise; - let appState; - let mapFilter; - let $el; - let $scope; - - beforeEach(ngMock.module('kibana/global_state', function ($provide) { - $provide.service('getAppState', _.constant(_.constant( - appState = new MockState({ filters: [] }) - ))); - })); - - beforeEach(function () { - // load the application - ngMock.module('kibana'); - - ngMock.module('kibana/courier', function ($provide) { - $provide.service('indexPatterns', require('fixtures/mock_index_patterns')); - }); - - ngMock.inject(function (Private, $injector, _$rootScope_, _$compile_) { - $rootScope = _$rootScope_; - $compile = _$compile_; - Promise = $injector.get('Promise'); - mapFilter = Private(FilterBarLibMapFilterProvider); - - const queryFilter = Private(FilterBarQueryFilterProvider); - queryFilter.getFilters = function () { - return appState.filters; - }; - }); - }); - - describe('Element rendering', function () { - beforeEach(function (done) { - const filters = [ - { meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'apache' } } } }, - { meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'nginx' } } } }, - { meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } }, - { meta: { index: 'logstash-*' }, missing: { field: 'host' }, disabled: true }, - { meta: { index: 'logstash-*', alias: 'foo' }, query: { match: { '_type': { query: 'nginx' } } } }, - ]; - - Promise.map(filters, mapFilter).then(function (filters) { - appState.filters = filters; - $el = $compile('')($rootScope); - $scope = $el.isolateScope(); - }); - - const off = $rootScope.$on('filterbar:updated', function () { - off(); - // force a nextTick so it continues *after* the $digest loop completes - setTimeout(done, 0); - }); - - // kick off the digest loop - $rootScope.$digest(); - }); - - it('should render all the filters in state', function () { - const filters = $el.find('.filter'); - expect(filters).to.have.length(5); - expect($(filters[0]).find('span')[0].innerHTML).to.equal('_type:'); - expect($(filters[0]).find('span')[1].innerHTML).to.equal('"apache"'); - expect($(filters[1]).find('span')[0].innerHTML).to.equal('_type:'); - expect($(filters[1]).find('span')[1].innerHTML).to.equal('"nginx"'); - expect($(filters[2]).find('span')[0].innerHTML).to.equal('@timestamp:'); - expect($(filters[2]).find('span')[1].innerHTML).to.equal('"exists"'); - expect($(filters[3]).find('span')[0].innerHTML).to.equal('host:'); - expect($(filters[3]).find('span')[1].innerHTML).to.equal('"missing"'); - }); - - it('should be able to set an alias', function () { - const filter = $el.find('.filter')[4]; - expect($(filter).find('span')[0].innerHTML).to.equal('foo'); - }); - - describe('editing filters', function () { - beforeEach(function () { - $scope.editFilter(appState.filters[3]); - $scope.$digest(); - }); - - it('should be able to edit a filter', function () { - expect($el.find('.filter-edit-container').length).to.be(1); - }); - - it('should be able to stop editing a filter', function () { - $scope.cancelEdit(); - $scope.$digest(); - expect($el.find('.filter-edit-container').length).to.be(0); - }); - - it('should remove old filter and add new filter when saving', function () { - sinon.spy($scope, 'removeFilter'); - sinon.spy($scope, 'addFilters'); - - $scope.saveEdit(appState.filters[3], appState.filters[3], false); - expect($scope.removeFilter.called).to.be(true); - expect($scope.addFilters.called).to.be(true); - }); - }); - - describe('show and hide filters', function () { - let scope; - - beforeEach(() => { - scope = $rootScope.$new(); - }); - - function create(attrs) { - const template = ` -
- - -
`; - - const element = $compile(template)(scope); - - scope.$apply(() => { - Object.assign(scope, attrs); - }); - - return element; - } - - - describe('collapse filters', function () { - let element; - - beforeEach(function () { - element = create({ - filterNavToggle: { - isOpen: false - } - }); - }); - - it('should be able to collapse filters', function () { - expect(element.hasClass('filter-panel-close')).to.be(true); - }); - - it('should be able to see `actions`', function () { - expect(element.find('.filter-link.pull-right').hasClass('action-show')).to.be(true); - }); - - it('should be able to view the same button for `expand`', function () { - expect(element.find('.filter-nav-link__icon').hasClass('filter-nav-link--close')).to.be(true); - }); - }); - - describe('expand filters', function () { - let element; - - beforeEach(function () { - element = create({ - filterNavToggle: { - isOpen: true - } - }); - }); - - it('should be able to expand filters', function () { - expect(element.hasClass('filter-panel-close')).to.be(false); - }); - - it('should be able to view the `actions` at the bottom of the filter-bar', function () { - expect(element.find('.filter-link.pull-right').hasClass('action-show')).to.be(false); - }); - - it('should be able to view the same button for `collapse`', function () { - expect(element.find('.filter-nav-link__icon').hasClass('filter-nav-link--close')).to.be(false); - }); - }); - - }); - - }); -}); diff --git a/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js b/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js deleted file mode 100644 index 612956327c18f..0000000000000 --- a/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js +++ /dev/null @@ -1,80 +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 ngMock from 'ng_mock'; -import expect from 'expect.js'; - -import MockState from 'fixtures/mock_state'; -import { toastNotifications } from '../../notify'; -import AggConfigResult from '../../vis/agg_config_result'; - -import { VisProvider } from '../../vis'; -import StubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -import { FilterBarClickHandlerProvider } from '../filter_bar_click_handler'; - -describe('filterBarClickHandler', function () { - let setup = null; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - setup = function () { - const Vis = Private(VisProvider); - const createClickHandler = Private(FilterBarClickHandlerProvider); - const indexPattern = Private(StubbedLogstashIndexPatternProvider); - - const vis = new Vis(indexPattern, { - type: 'histogram', - aggs: [ - { type: 'count', schema: 'metric' }, - { - type: 'terms', - schema: 'segment', - params: { field: 'non-filterable' } - } - ] - }); - const aggConfigResult = new AggConfigResult(vis.aggs[1], void 0, 'apache', 'apache'); - - const $state = new MockState({ filters: [] }); - const clickHandler = createClickHandler($state); - - return { clickHandler, $state, aggConfigResult }; - }; - })); - - beforeEach(function () { - toastNotifications.list.splice(0); - }); - - describe('on non-filterable fields', function () { - it('warns about trying to filter on a non-filterable field', function () { - const { clickHandler, aggConfigResult } = setup(); - expect(toastNotifications.list).to.have.length(0); - clickHandler({ point: { aggConfigResult } }); - expect(toastNotifications.list).to.have.length(1); - }); - - it('does not warn if the event is click is being simulated', function () { - const { clickHandler, aggConfigResult } = setup(); - expect(toastNotifications.list).to.have.length(0); - clickHandler({ point: { aggConfigResult } }, true); - expect(toastNotifications.list).to.have.length(0); - }); - }); -}); diff --git a/src/ui/public/filter_bar/_global_filter_group.scss b/src/ui/public/filter_bar/_global_filter_group.scss new file mode 100644 index 0000000000000..9ed40964a95b4 --- /dev/null +++ b/src/ui/public/filter_bar/_global_filter_group.scss @@ -0,0 +1,22 @@ +// SASSTODO: Probably not the right file for this selector, but temporary until the files get re-organized +.globalQueryBar { + padding-bottom: $euiSizeS; +} + +.globalFilterGroup__filterBar { + margin-top: $euiSizeM; +} + +// sass-lint:disable quotes +.globalFilterGroup__branch { + padding: $euiSize $euiSize $euiSizeS $euiSizeS; + background-repeat: no-repeat; + background-position: right top; + background-image: url("data:image/svg+xml,%0A%3Csvg width='28px' height='28px' viewBox='0 0 28 28' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='#{hexToRGB($euiColorLightShade)}'%3E%3Crect x='14' y='27' width='14' height='1'%3E%3C/rect%3E%3Crect x='0' y='0' width='1' height='14'%3E%3C/rect%3E%3C/g%3E%3C/svg%3E"); +} + +.globalFilterGroup__wrapper { + line-height: 1; // Override kuiLocalNav & kuiLocalNavRow + overflow: hidden; + transition: height $euiAnimSpeedNormal $euiAnimSlightResistance; +} diff --git a/src/ui/public/filter_bar/_global_filter_item.scss b/src/ui/public/filter_bar/_global_filter_item.scss new file mode 100644 index 0000000000000..b3bc510be0c74 --- /dev/null +++ b/src/ui/public/filter_bar/_global_filter_item.scss @@ -0,0 +1,37 @@ +@import '@elastic/eui/src/components/form/mixins'; +@import '@elastic/eui/src/components/form/variables'; + +.globalFilterItem { + line-height: $euiSizeL + $euiSizeXS; + border: none; + color: $euiTextColor; + + &:not(.globalFilterItem-isDisabled) { + @include euiFormControlDefaultShadow; + } +} + +.globalFilterItem-isDisabled { + background-color: transparentize($euiColorLightShade, .4); + text-decoration: line-through; + font-weight: $euiFontWeightRegular; + font-style: italic; +} + +.globalFilterItem-isPinned { + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: $euiSizeXS; + background-color: $euiColorVis0; + } +} + +.globalFilterItem__editorForm { + padding: $euiSizeM; +} diff --git a/src/ui/public/filter_bar/_index.scss b/src/ui/public/filter_bar/_index.scss new file mode 100644 index 0000000000000..3c57b7fe2ca3a --- /dev/null +++ b/src/ui/public/filter_bar/_index.scss @@ -0,0 +1,2 @@ +@import 'global_filter_group'; +@import 'global_filter_item'; diff --git a/src/fixtures/filters/range_filter.js b/src/ui/public/filter_bar/directive.js similarity index 71% rename from src/fixtures/filters/range_filter.js rename to src/ui/public/filter_bar/directive.js index c18b6c98a5639..afb598de5a7b1 100644 --- a/src/fixtures/filters/range_filter.js +++ b/src/ui/public/filter_bar/directive.js @@ -17,23 +17,13 @@ * under the License. */ -export const rangeFilter = { - 'meta': { - 'index': 'logstash-*', - 'negate': false, - 'disabled': false, - 'alias': null, - 'type': 'range', - 'key': 'bytes', - 'value': '0 to 10' - }, - 'range': { - 'bytes': { - 'gte': 0, - 'lt': 10 - } - }, - '$state': { - 'store': 'appState' - } -}; +import 'ngreact'; +import { uiModules } from '../modules'; +import { FilterBar } from './filter_bar'; +import { injectI18nProvider } from '@kbn/i18n/react'; + +const app = uiModules.get('app/kibana', ['react']); + +app.directive('filterBar', reactDirective => { + return reactDirective(injectI18nProvider(FilterBar)); +}); diff --git a/src/ui/public/filter_bar/filter_bar.html b/src/ui/public/filter_bar/filter_bar.html deleted file mode 100644 index 5cd239781d192..0000000000000 --- a/src/ui/public/filter_bar/filter_bar.html +++ /dev/null @@ -1,149 +0,0 @@ -
-
-
-
    -
  • Apply these filters?
  • -
  • - NOT {{ filter.meta.key }}: {{ filter.meta.value }} -
  • -
  • Change time to: {{changeTimeFilter.meta.value}}
  • -
  • -
    - - - -
    -
  • -
-
-
- -
-
- -
- - - - - - - -
- -
-
- -
-
- - - - - - - - -
-
-
diff --git a/src/ui/public/filter_bar/filter_bar.js b/src/ui/public/filter_bar/filter_bar.js deleted file mode 100644 index 0a1648ac75d4a..0000000000000 --- a/src/ui/public/filter_bar/filter_bar.js +++ /dev/null @@ -1,213 +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 template from './filter_bar.html'; -import '../directives/json_input'; -import '../filter_editor'; -import './filter_pill/filter_pill'; -import { filterAppliedAndUnwrap } from './lib/filter_applied_and_unwrap'; -import { FilterBarLibMapAndFlattenFiltersProvider } from './lib/map_and_flatten_filters'; -import { FilterBarLibMapFlattenAndWrapFiltersProvider } from './lib/map_flatten_and_wrap_filters'; -import { FilterBarLibExtractTimeFilterProvider } from './lib/extract_time_filter'; -import { FilterBarLibFilterOutTimeBasedFilterProvider } from './lib/filter_out_time_based_filter'; -import { changeTimeFilter } from './lib/change_time_filter'; -import { FilterBarQueryFilterProvider } from './query_filter'; -import { compareFilters } from './lib/compare_filters'; -import { uiModules } from '../modules'; - -export { disableFilter, enableFilter, toggleFilterDisabled } from './lib/disable_filter'; - - -const module = uiModules.get('kibana'); - -module.directive('filterBar', function (Private, Promise, getAppState) { - const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); - const mapFlattenAndWrapFilters = Private(FilterBarLibMapFlattenAndWrapFiltersProvider); - const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider); - const filterOutTimeBasedFilter = Private(FilterBarLibFilterOutTimeBasedFilterProvider); - const queryFilter = Private(FilterBarQueryFilterProvider); - - return { - template, - restrict: 'E', - scope: { - indexPatterns: '=', - tooltipContent: '=', - }, - link: function ($scope, $elem) { - // bind query filter actions to the scope - [ - 'addFilters', - 'toggleFilter', - 'toggleAll', - 'pinFilter', - 'pinAll', - 'invertFilter', - 'invertAll', - 'removeFilter', - 'removeAll' - ].forEach(function (method) { - $scope[method] = queryFilter[method]; - }); - - $scope.state = getAppState(); - - $scope.showCollapseLink = () => { - const pill = $elem.find('filter-pill'); - return pill[pill.length - 1].offsetTop > 10; - }; - - $scope.filterNavToggle = { - isOpen: true, - tooltipContent: 'Collapse filter bar \n to show less' - }; - - $scope.toggleFilterShown = () => { - const collapser = $elem.find('.filter-nav-link__collapser'); - const filterPanelPill = $elem.find('.filter-panel__pill'); - if ($scope.filterNavToggle.isOpen) { - $scope.filterNavToggle.tooltipContent = 'Expand filter bar \n to show more'; - collapser.attr('aria-expanded', 'false'); - filterPanelPill.attr('style', 'width: calc(100% - 80px)'); - } else { - $scope.filterNavToggle.tooltipContent = 'Collapse filter bar \n to show less'; - collapser.attr('aria-expanded', 'true'); - filterPanelPill.attr('style', 'width: auto'); - } - - $scope.filterNavToggle.isOpen = !$scope.filterNavToggle.isOpen; - }; - - $scope.applyFilters = function (filters) { - addAndInvertFilters(filterAppliedAndUnwrap(filters)); - $scope.newFilters = []; - - // change time filter - if ($scope.changeTimeFilter && $scope.changeTimeFilter.meta && $scope.changeTimeFilter.meta.apply) { - changeTimeFilter($scope.changeTimeFilter); - } - }; - - $scope.addFilter = () => { - $scope.editingFilter = { - meta: { isNew: true } - }; - }; - - $scope.deleteFilter = (filter) => { - $scope.removeFilter(filter); - if (filter === $scope.editingFilter) $scope.cancelEdit(); - }; - - $scope.editFilter = (filter) => { - $scope.editingFilter = filter; - }; - - $scope.cancelEdit = () => { - delete $scope.editingFilter; - }; - - $scope.saveEdit = (filter, newFilter, isPinned) => { - if (!filter.meta.isNew) $scope.removeFilter(filter); - delete $scope.editingFilter; - $scope.addFilters([newFilter], isPinned); - }; - - $scope.clearFilterBar = function () { - $scope.newFilters = []; - $scope.changeTimeFilter = null; - }; - - // update the scope filter list on filter changes - $scope.$listen(queryFilter, 'update', function () { - updateFilters(); - }); - - // when appState changes, update scope's state - $scope.$watch(getAppState, function (appState) { - $scope.state = appState; - }); - - $scope.$watch('state.$newFilters', function (filters) { - if (!filters) return; - - // If filters is not undefined and the length is greater than - // one we need to set the newFilters attribute and allow the - // users to decide what they want to apply. - if (filters.length > 1) { - return mapFlattenAndWrapFilters(filters) - .then(function (results) { - extractTimeFilter(results).then(function (filter) { - $scope.changeTimeFilter = filter; - }); - return results; - }) - .then(filterOutTimeBasedFilter) - .then(function (results) { - $scope.newFilters = results; - }); - } - - // Just add single filters to the state. - if (filters.length === 1) { - Promise.resolve(filters).then(function (filters) { - extractTimeFilter(filters) - .then(function (timeFilter) { - if (timeFilter) changeTimeFilter(timeFilter); - }); - return filters; - }) - .then(filterOutTimeBasedFilter) - .then(addAndInvertFilters); - } - }); - - function addAndInvertFilters(filters) { - const existingFilters = queryFilter.getFilters(); - const inversionFilters = _.filter(existingFilters, (existingFilter) => { - const newMatchingFilter = _.find(filters, _.partial(compareFilters, existingFilter)); - return newMatchingFilter - && newMatchingFilter.meta - && existingFilter.meta - && existingFilter.meta.negate !== newMatchingFilter.meta.negate; - }); - const newFilters = _.reject(filters, (filter) => { - return _.find(inversionFilters, _.partial(compareFilters, filter)); - }); - - _.forEach(inversionFilters, $scope.invertFilter); - $scope.addFilters(newFilters); - } - - function updateFilters() { - const filters = queryFilter.getFilters(); - mapAndFlattenFilters(filters).then(function (results) { - // used to display the current filters in the state - $scope.filters = _.sortBy(results, function (filter) { - return !filter.meta.pinned; - }); - $scope.$emit('filterbar:updated'); - }); - } - - updateFilters(); - } - }; -}); diff --git a/src/ui/public/filter_bar/filter_bar.less b/src/ui/public/filter_bar/filter_bar.less index 979ca42ea5dc1..e69de29bb2d1d 100644 --- a/src/ui/public/filter_bar/filter_bar.less +++ b/src/ui/public/filter_bar/filter_bar.less @@ -1,226 +0,0 @@ -// Variables ================================================================== -@filter-bar-confirm-bg: @gray-lighter; -@filter-bar-confirm-filter-color: @gray-darker; -@filter-bar-confirm-border: @gray-light; -@filter-bar-confirm-filter-bg: @gray-light; - -@filter-bar-bar-bg: @gray-lightest; -@filter-bar-bar-border: @gray-lighter; -@filter-bar-bar-condensed-bg: tint(@blue, 90%); - -@filter-bar-bar-filter-bg: @blue; -@filter-bar-bar-filter-color: @white; -@filter-bar-bar-filter-negate-bg: @brand-danger; -@filterBarDepth: 4; - -filter-bar { - z-index: @filterBarDepth !important; -} - -.filter-bar-confirm { - padding: 8px 10px 4px; - background: @filter-bar-confirm-bg; - border-bottom: 1px solid; - border-bottom-color: @filter-bar-confirm-border; - - ul { - margin-bottom: 0px; - } - - li { - display: inline-block; - } - - li:first-child { - font-weight: bold; - font-size: 1.2em; - } - - li button { - font-size: 0.9em; - padding: 2px 8px; - } - - .filter { - position: relative; - display: inline-block; - text-align: center; - // Number of filter icons multiplied by icon width - // Escaped to prevent less math - min-width: ~"calc(5*(1.414em + 13px))"; - vertical-align: middle; - font-size: @font-size-small; - background-color: @filter-bar-confirm-filter-bg; - color: @filter-bar-confirm-filter-color; - margin-right: 4px; - margin-bottom: 4px; - max-width: 100%; - - // Replace padding with border so absolute controls position correctly - padding: 4px 8px; - border-radius: 12px; - } -} - -.filter-panel { - position: relative; - - .filter-panel__pill { - display: inline; - } - -} - -.filter-panel--close { - max-height: 36px; - overflow-y: hidden; - min-width: 250px; - - .filter-panel__pill { - display: inline-block; - } -} - -.filter-bar { - padding: 6px 10px 1px 10px; - background: @filter-bar-bar-bg; - border-bottom: solid 1px @gray-lighter; - - .ace_editor { - height: 175px; - } - - .filter-edit-alias { - margin-top: 15px; - } - - .filter-link { - position: relative; - display: inline-block; - border: 4px solid transparent; - margin-bottom: 4px; - } - - .filter-description { - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: middle; - line-height: 1.5; - } - - .action-show { - position: absolute; - right: 30px; - bottom: 0; - } - - .filter-nav-link__icon { - display: inline; - position: absolute; - top: 10px; - right: 10px; - opacity: 0.75; - font-size: 16px; - - &:hover { - opacity: 1; - } - - .filter-nav-link__collapser { - border: none; - line-height: 1; - } - } - - .filter { - position: relative; - display: inline-block; - text-align: center; - // Number of filter icons multiplied by icon width - // Escaped to prevent less math - min-width: ~"calc(5*(1.414em + 13px))"; - font-size: @font-size-small; - background-color: @filter-bar-bar-filter-bg; - color: @filter-bar-bar-filter-color; - margin-right: 4px; - margin-bottom: 4px; - max-width: 100%; - vertical-align: middle; - - // Replace padding with border so absolute controls position correctly - padding: 4px 8px; - border-radius: 12px; - - .filter-actions { - font-size: 1.1em; - line-height: 1.4em; - position: absolute; - padding: 4px 8px; - top: 0; - left: 0; - width: 100%; - opacity: 0; - text-align: center; - white-space: nowrap; - display: flex; - - .action { - border: none; - border-right: 1px solid rgba(255, 255, 255, 0.4); - padding: 0; - background-color: transparent; - flex: 1 1 auto; - - &:last-child { - border-right: 0; - padding-right: 0; - margin-right: 0; - } - - .unpinned { - .opacity(.7); - } - - .fa-disabled { - opacity: 0.7; - cursor: not-allowed; - } - } - } - - .filter-actions-activated { - opacity: 1; - } - - .filter-description-deactivated { - opacity: 0.15; - background: transparent; - overflow: hidden; - } - - &.negate { - background-color: @filter-bar-bar-filter-negate-bg; - } - - a { - color: @filter-bar-bar-filter-color; - } - - &.disabled { - opacity: 0.6; - background-image: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,255,255,.3) 10px, rgba(255,255,255,.3) 20px); - } - - &.disabled:hover { - span { - text-decoration: none; - } - } - } -} - - .filter-bar-condensed { - padding: 6px 6px 2px 6px !important; - font-size: 0.9em; - background: @filter-bar-bar-condensed-bg; - } diff --git a/src/ui/public/filter_bar/filter_bar.tsx b/src/ui/public/filter_bar/filter_bar.tsx new file mode 100644 index 0000000000000..551114e0bf33a --- /dev/null +++ b/src/ui/public/filter_bar/filter_bar.tsx @@ -0,0 +1,217 @@ +/* + * 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 { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPopover } from '@elastic/eui'; +import { + buildEmptyFilter, + disableFilter, + enableFilter, + Filter, + pinFilter, + toggleFilterDisabled, + toggleFilterNegated, + unpinFilter, +} from '@kbn/es-query'; +import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import classNames from 'classnames'; +import React, { Component } from 'react'; +import chrome from 'ui/chrome'; +import { IndexPattern } from 'ui/index_patterns'; +import { FilterOptions } from 'ui/search_bar/components/filter_options'; +import { FilterEditor } from './filter_editor'; +import { FilterItem } from './filter_item'; + +const config = chrome.getUiSettingsClient(); + +interface Props { + filters: Filter[]; + onFiltersUpdated: (filters: Filter[]) => void; + className: string; + indexPatterns: IndexPattern[]; + intl: InjectedIntl; +} + +interface State { + isAddFilterPopoverOpen: boolean; +} + +class FilterBarUI extends Component { + public state = { + isAddFilterPopoverOpen: false, + }; + + public render() { + const classes = classNames('globalFilterBar', this.props.className); + + return ( + + + + + + + + {this.renderItems()} + {this.renderAddFilter()} + + + + ); + } + + private renderItems() { + return this.props.filters.map((filter, i) => ( + + this.onUpdate(i, newFilter)} + onRemove={() => this.onRemove(i)} + indexPatterns={this.props.indexPatterns} + /> + + )); + } + + private renderAddFilter() { + const isPinned = config.get('filters:pinnedByDefault'); + const [indexPattern] = this.props.indexPatterns; + const index = indexPattern && indexPattern.id; + const newFilter = buildEmptyFilter(isPinned, index); + + const button = ( + + +{' '} + + + ); + + return ( + + +
+ +
+
+
+ ); + } + + private onAdd = (filter: Filter) => { + this.onCloseAddFilterPopover(); + const filters = [...this.props.filters, filter]; + this.props.onFiltersUpdated(filters); + }; + + private onRemove = (i: number) => { + const filters = [...this.props.filters]; + filters.splice(i, 1); + this.props.onFiltersUpdated(filters); + }; + + private onUpdate = (i: number, filter: Filter) => { + const filters = [...this.props.filters]; + filters[i] = filter; + this.props.onFiltersUpdated(filters); + }; + + private onEnableAll = () => { + const filters = this.props.filters.map(enableFilter); + this.props.onFiltersUpdated(filters); + }; + + private onDisableAll = () => { + const filters = this.props.filters.map(disableFilter); + this.props.onFiltersUpdated(filters); + }; + + private onPinAll = () => { + const filters = this.props.filters.map(pinFilter); + this.props.onFiltersUpdated(filters); + }; + + private onUnpinAll = () => { + const filters = this.props.filters.map(unpinFilter); + this.props.onFiltersUpdated(filters); + }; + + private onToggleAllNegated = () => { + const filters = this.props.filters.map(toggleFilterNegated); + this.props.onFiltersUpdated(filters); + }; + + private onToggleAllDisabled = () => { + const filters = this.props.filters.map(toggleFilterDisabled); + this.props.onFiltersUpdated(filters); + }; + + private onRemoveAll = () => { + this.props.onFiltersUpdated([]); + }; + + private onOpenAddFilterPopover = () => { + this.setState({ + isAddFilterPopoverOpen: true, + }); + }; + + private onCloseAddFilterPopover = () => { + this.setState({ + isAddFilterPopoverOpen: false, + }); + }; +} + +export const FilterBar = injectI18n(FilterBarUI); diff --git a/src/ui/public/filter_bar/filter_bar_click_handler.js b/src/ui/public/filter_bar/filter_bar_click_handler.js deleted file mode 100644 index 060be79644d38..0000000000000 --- a/src/ui/public/filter_bar/filter_bar_click_handler.js +++ /dev/null @@ -1,89 +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 { dedupFilters } from './lib/dedup_filters'; -import { uniqFilters } from './lib/uniq_filters'; -import { findByParam } from '../utils/find_by_param'; -import { toastNotifications } from '../notify'; - -export function FilterBarClickHandlerProvider() { - - return function ($state) { - return function (event, simulate) { - if (!$state) return; - - let aggConfigResult; - - // Hierarchical and tabular data set their aggConfigResult parameter - // differently because of how the point is rewritten between the two. So - // we need to check if the point.orig is set, if not use try the point.aggConfigResult - if (event.point.orig) { - aggConfigResult = event.point.orig.aggConfigResult; - } else if (event.point.values) { - aggConfigResult = findByParam(event.point.values, 'aggConfigResult'); - } else { - aggConfigResult = event.point.aggConfigResult; - } - - if (aggConfigResult) { - const isLegendLabel = !!event.point.values; - let aggBuckets = _.filter(aggConfigResult.getPath(), { type: 'bucket' }); - - // For legend clicks, use the last bucket in the path - if (isLegendLabel) { - // series data has multiple values, use aggConfig on the first - // hierarchical data values is an object with the addConfig - const aggConfig = findByParam(event.point.values, 'aggConfig'); - aggBuckets = aggBuckets.filter((result) => result.aggConfig && result.aggConfig === aggConfig); - } - - let filters = _(aggBuckets) - .map(function (result) { - try { - return result.createFilter(); - } catch (e) { - if (!simulate) { - toastNotifications.addSuccess(e.message); - } - } - }) - .flatten() - .filter(Boolean) - .value(); - - if (!filters.length) return; - - if (event.negate) { - _.each(filters, function (filter) { - filter.meta = filter.meta || {}; - filter.meta.negate = true; - }); - } - - filters = dedupFilters($state.filters, uniqFilters(filters), { negate: true }); - - if (!simulate) { - $state.$newFilters = filters; - } - return filters; - } - }; - }; -} diff --git a/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx b/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx new file mode 100644 index 0000000000000..81b129d214e37 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx @@ -0,0 +1,61 @@ +/* + * 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 { EuiComboBox, EuiComboBoxOptionProps } from '@elastic/eui'; +import React from 'react'; + +export interface GenericComboBoxProps { + options: T[]; + selectedOptions: T[]; + getLabel: (value: T) => string; + onChange: (values: T[]) => void; + [propName: string]: any; +} + +/** + * A generic combo box. Instead of accepting a set of options that contain a `label`, it accepts + * any type of object. It also accepts a `getLabel` function that each object will be sent through + * to get the label to be passed to the combo box. The `onChange` will trigger with the actual + * selected objects, rather than an option object. + */ +export function GenericComboBox(props: GenericComboBoxProps) { + const { options, selectedOptions, getLabel, onChange, ...otherProps } = props; + + const labels = options.map(getLabel); + const euiOptions: EuiComboBoxOptionProps[] = labels.map(label => ({ label })); + const selectedEuiOptions = selectedOptions.map(option => { + return euiOptions[options.indexOf(option)]; + }); + + const onComboBoxChange = (newOptions: EuiComboBoxOptionProps[]) => { + const newValues = newOptions.map(({ label }) => { + return options[labels.indexOf(label)]; + }); + onChange(newValues); + }; + + return ( + + ); +} diff --git a/src/ui/public/filter_bar/filter_editor/index.tsx b/src/ui/public/filter_bar/filter_editor/index.tsx new file mode 100644 index 0000000000000..de301432b1b67 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/index.tsx @@ -0,0 +1,471 @@ +/* + * 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 { + EuiButton, + EuiButtonEmpty, + // @ts-ignore + EuiCodeEditor, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiForm, + EuiFormRow, + EuiPopoverTitle, + EuiSpacer, + EuiSwitch, +} from '@elastic/eui'; +import { FieldFilter, Filter } from '@kbn/es-query'; +import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { get } from 'lodash'; +import React, { Component } from 'react'; +import { Field, IndexPattern } from 'ui/index_patterns'; +import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; +import { + buildCustomFilter, + buildFilter, + getFieldFromFilter, + getFilterableFields, + getFilterParams, + getIndexPatternFromFilter, + getOperatorFromFilter, + getOperatorOptions, + getQueryDslFromFilter, + isFilterValid, +} from './lib/filter_editor_utils'; +import { Operator } from './lib/filter_operators'; +import { PhraseValueInput } from './phrase_value_input'; +import { PhrasesValuesInput } from './phrases_values_input'; +import { RangeValueInput } from './range_value_input'; + +interface Props { + filter: Filter; + indexPatterns: IndexPattern[]; + onSubmit: (filter: Filter) => void; + onCancel: () => void; + intl: InjectedIntl; +} + +interface State { + selectedIndexPattern?: IndexPattern; + selectedField?: Field; + selectedOperator?: Operator; + params: any; + useCustomLabel: boolean; + customLabel: string | null; + queryDsl: string; + isCustomEditorOpen: boolean; +} + +class FilterEditorUI extends Component { + public constructor(props: Props) { + super(props); + this.state = { + selectedIndexPattern: this.getIndexPatternFromFilter(), + selectedField: this.getFieldFromFilter(), + selectedOperator: this.getSelectedOperator(), + params: getFilterParams(props.filter), + useCustomLabel: props.filter.meta.alias !== null, + customLabel: props.filter.meta.alias, + queryDsl: JSON.stringify(getQueryDslFromFilter(props.filter), null, 2), + isCustomEditorOpen: this.isUnknownFilterType(), + }; + } + + public render() { + return ( +
+ + + + + + + + {this.state.isCustomEditorOpen ? ( + + ) : ( + + )} + + + + + +
+ + {this.renderIndexPatternInput()} + + {this.state.isCustomEditorOpen ? this.renderCustomEditor() : this.renderRegularEditor()} + + + + + + {this.state.useCustomLabel && ( +
+ + + + +
+ )} + + + + + + + + + + + + + + + + +
+
+
+ ); + } + + private renderIndexPatternInput() { + if (this.props.indexPatterns.length <= 1) { + return ''; + } + const { selectedIndexPattern } = this.state; + return ( + + + + indexPattern.title} + onChange={this.onIndexPatternChange} + singleSelection={{ asPlainText: true }} + isClearable={false} + /> + + + + ); + } + + private renderRegularEditor() { + return ( +
+ + {this.renderFieldInput()} + {this.renderOperatorInput()} + + +
{this.renderParamsEditor()}
+
+ ); + } + + private renderFieldInput() { + const { selectedIndexPattern, selectedField } = this.state; + const fields = selectedIndexPattern ? getFilterableFields(selectedIndexPattern) : []; + return ( + + field.name} + onChange={this.onFieldChange} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterFieldSuggestionList" + /> + + ); + } + + private renderOperatorInput() { + const { selectedField, selectedOperator } = this.state; + const operators = selectedField ? getOperatorOptions(selectedField) : []; + return ( + + message} + onChange={this.onOperatorChange} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterOperatorList" + /> + + ); + } + + private renderCustomEditor() { + return ( + + + + ); + } + + private renderParamsEditor() { + const indexPattern = this.state.selectedIndexPattern; + if (!indexPattern || !this.state.selectedOperator) { + return ''; + } + + switch (this.state.selectedOperator.type) { + case 'exists': + return ''; + case 'phrase': + return ( + + ); + case 'phrases': + return ( + + ); + case 'range': + return ( + + ); + } + } + + private toggleCustomEditor = () => { + const isCustomEditorOpen = !this.state.isCustomEditorOpen; + this.setState({ isCustomEditorOpen }); + }; + + private isUnknownFilterType() { + const { type } = this.props.filter.meta; + return !!type && !['phrase', 'phrases', 'range', 'exists'].includes(type); + } + + private getIndexPatternFromFilter() { + return getIndexPatternFromFilter(this.props.filter, this.props.indexPatterns); + } + + private getFieldFromFilter() { + const indexPattern = this.getIndexPatternFromFilter(); + return indexPattern && getFieldFromFilter(this.props.filter as FieldFilter, indexPattern); + } + + private getSelectedOperator() { + return getOperatorFromFilter(this.props.filter); + } + + private isFilterValid() { + const { + isCustomEditorOpen, + queryDsl, + selectedIndexPattern: indexPattern, + selectedField: field, + selectedOperator: operator, + params, + } = this.state; + + if (isCustomEditorOpen) { + try { + return Boolean(JSON.parse(queryDsl)); + } catch (e) { + return false; + } + } + + return isFilterValid(indexPattern, field, operator, params); + } + + private onIndexPatternChange = ([selectedIndexPattern]: IndexPattern[]) => { + const selectedField = undefined; + const selectedOperator = undefined; + const params = undefined; + this.setState({ selectedIndexPattern, selectedField, selectedOperator, params }); + }; + + private onFieldChange = ([selectedField]: Field[]) => { + const selectedOperator = undefined; + const params = undefined; + this.setState({ selectedField, selectedOperator, params }); + }; + + private onOperatorChange = ([selectedOperator]: Operator[]) => { + // Only reset params when the operator type changes + const params = + get(this.state.selectedOperator, 'type') === get(selectedOperator, 'type') + ? this.state.params + : undefined; + this.setState({ selectedOperator, params }); + }; + + private onCustomLabelSwitchChange = (event: React.ChangeEvent) => { + const useCustomLabel = event.target.checked; + const customLabel = event.target.checked ? '' : null; + this.setState({ useCustomLabel, customLabel }); + }; + + private onCustomLabelChange = (event: React.ChangeEvent) => { + const customLabel = event.target.value; + this.setState({ customLabel }); + }; + + private onParamsChange = (params: any) => { + this.setState({ params }); + }; + + private onQueryDslChange = (queryDsl: string) => { + this.setState({ queryDsl }); + }; + + private onSubmit = () => { + const { + selectedIndexPattern: indexPattern, + selectedField: field, + selectedOperator: operator, + params, + useCustomLabel, + customLabel, + isCustomEditorOpen, + queryDsl, + } = this.state; + + const { store } = this.props.filter.$state; + const alias = useCustomLabel ? customLabel : null; + + if (isCustomEditorOpen) { + const { index, disabled, negate } = this.props.filter.meta; + const newIndex = index || this.props.indexPatterns[0].id; + const body = JSON.parse(queryDsl); + const filter = buildCustomFilter(newIndex, body, disabled, negate, alias, store); + this.props.onSubmit(filter); + } else if (indexPattern && field && operator) { + const filter = buildFilter(indexPattern, field, operator, params, alias, store); + this.props.onSubmit(filter); + } + }; +} + +function IndexPatternComboBox(props: GenericComboBoxProps) { + return GenericComboBox(props); +} + +function FieldComboBox(props: GenericComboBoxProps) { + return GenericComboBox(props); +} + +function OperatorComboBox(props: GenericComboBoxProps) { + return GenericComboBox(props); +} + +export const FilterEditor = injectI18n(FilterEditorUI); diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts new file mode 100644 index 0000000000000..859f2fcc1535a --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts @@ -0,0 +1,314 @@ +/* + * 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 { FilterStateStore, toggleFilterNegated } from '@kbn/es-query'; +import { mockFields, mockIndexPattern } from 'ui/index_patterns/fixtures'; +import { + buildFilter, + getFieldFromFilter, + getFilterableFields, + getFilterParams, + getIndexPatternFromFilter, + getOperatorFromFilter, + getOperatorOptions, + getQueryDslFromFilter, + isFilterValid, +} from './filter_editor_utils'; +import { + doesNotExistOperator, + existsOperator, + isBetweenOperator, + isOneOfOperator, + isOperator, +} from './filter_operators'; +import { existsFilter } from './fixtures/exists_filter'; +import { phraseFilter } from './fixtures/phrase_filter'; +import { phrasesFilter } from './fixtures/phrases_filter'; +import { rangeFilter } from './fixtures/range_filter'; + +describe('Filter editor utils', () => { + describe('getQueryDslFromFilter', () => { + it('should return query DSL without meta and $state', () => { + const queryDsl = getQueryDslFromFilter(phraseFilter); + expect(queryDsl).not.toHaveProperty('meta'); + expect(queryDsl).not.toHaveProperty('$state'); + }); + }); + + describe('getIndexPatternFromFilter', () => { + it('should return the index pattern from the filter', () => { + const indexPattern = getIndexPatternFromFilter(phraseFilter, [mockIndexPattern]); + expect(indexPattern).toBe(mockIndexPattern); + }); + }); + + describe('getFieldFromFilter', () => { + it('should return the field from the filter', () => { + const field = getFieldFromFilter(phraseFilter, mockIndexPattern); + expect(field).not.toBeUndefined(); + expect(field && field.name).toBe(phraseFilter.meta.key); + }); + }); + + describe('getOperatorFromFilter', () => { + it('should return "is" for phrase filter', () => { + const operator = getOperatorFromFilter(phraseFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('phrase'); + expect(operator && operator.negate).toBe(false); + }); + + it('should return "is not" for phrase filter', () => { + const negatedPhraseFilter = toggleFilterNegated(phraseFilter); + const operator = getOperatorFromFilter(negatedPhraseFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('phrase'); + expect(operator && operator.negate).toBe(true); + }); + + it('should return "is one of" for phrases filter', () => { + const operator = getOperatorFromFilter(phrasesFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('phrases'); + expect(operator && operator.negate).toBe(false); + }); + + it('should return "is not one of" for negated phrases filter', () => { + const negatedPhrasesFilter = toggleFilterNegated(phrasesFilter); + const operator = getOperatorFromFilter(negatedPhrasesFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('phrases'); + expect(operator && operator.negate).toBe(true); + }); + + it('should return "is between" for range filter', () => { + const operator = getOperatorFromFilter(rangeFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('range'); + expect(operator && operator.negate).toBe(false); + }); + + it('should return "is not between" for negated range filter', () => { + const negatedRangeFilter = toggleFilterNegated(rangeFilter); + const operator = getOperatorFromFilter(negatedRangeFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('range'); + expect(operator && operator.negate).toBe(true); + }); + + it('should return "exists" for exists filter', () => { + const operator = getOperatorFromFilter(existsFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('exists'); + expect(operator && operator.negate).toBe(false); + }); + + it('should return "does not exists" for negated exists filter', () => { + const negatedExistsFilter = toggleFilterNegated(existsFilter); + const operator = getOperatorFromFilter(negatedExistsFilter); + expect(operator).not.toBeUndefined(); + expect(operator && operator.type).toBe('exists'); + expect(operator && operator.negate).toBe(true); + }); + }); + + describe('getFilterParams', () => { + it('should retrieve params from phrase filter', () => { + const params = getFilterParams(phraseFilter); + expect(params).toBe('ios'); + }); + + it('should retrieve params from phrases filter', () => { + const params = getFilterParams(phrasesFilter); + expect(params).toEqual(['win xp', 'osx']); + }); + + it('should retrieve params from range filter', () => { + const params = getFilterParams(rangeFilter); + expect(params).toEqual({ from: 0, to: 10 }); + }); + + it('should return undefined for exists filter', () => { + const params = getFilterParams(existsFilter); + expect(params).toBeUndefined(); + }); + }); + + describe('getFilterableFields', () => { + it('returns the list of fields from the given index pattern', () => { + const fieldOptions = getFilterableFields(mockIndexPattern); + expect(fieldOptions.length).toBeGreaterThan(0); + }); + + it('limits the fields to the filterable fields', () => { + const fieldOptions = getFilterableFields(mockIndexPattern); + const nonFilterableFields = fieldOptions.filter(field => !field.filterable); + expect(nonFilterableFields.length).toBe(0); + }); + }); + + describe('getOperatorOptions', () => { + it('returns range for number fields', () => { + const [field] = mockFields.filter(({ type }) => type === 'number'); + const operatorOptions = getOperatorOptions(field); + const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); + expect(rangeOperator).not.toBeUndefined(); + }); + + it('does not return range for string fields', () => { + const [field] = mockFields.filter(({ type }) => type === 'string'); + const operatorOptions = getOperatorOptions(field); + const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); + expect(rangeOperator).toBeUndefined(); + }); + }); + + describe('isFilterValid', () => { + it('should return false if index pattern is not provided', () => { + const isValid = isFilterValid(undefined, mockFields[0], isOperator, 'foo'); + expect(isValid).toBe(false); + }); + + it('should return false if field is not provided', () => { + const isValid = isFilterValid(mockIndexPattern, undefined, isOperator, 'foo'); + expect(isValid).toBe(false); + }); + + it('should return false if operator is not provided', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], undefined, 'foo'); + expect(isValid).toBe(false); + }); + + it('should return false for phrases filter without phrases', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], isOneOfOperator, []); + expect(isValid).toBe(false); + }); + + it('should return true for phrases filter with phrases', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], isOneOfOperator, ['foo']); + expect(isValid).toBe(true); + }); + + it('should return false for range filter without range', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, undefined); + expect(isValid).toBe(false); + }); + + it('should return true for range filter with from', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, { + from: 'foo', + }); + expect(isValid).toBe(true); + }); + + it('should return true for range filter with from/to', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, { + from: 'foo', + too: 'goo', + }); + expect(isValid).toBe(true); + }); + + it('should return true for exists filter without params', () => { + const isValid = isFilterValid(mockIndexPattern, mockFields[0], existsOperator); + expect(isValid).toBe(true); + }); + }); + + describe('buildFilter', () => { + it('should build phrase filters', () => { + const params = 'foo'; + const alias = 'bar'; + const state = FilterStateStore.APP_STATE; + const filter = buildFilter(mockIndexPattern, mockFields[0], isOperator, params, alias, state); + expect(filter.meta.negate).toBe(isOperator.negate); + expect(filter.meta.alias).toBe(alias); + expect(filter.$state.store).toBe(state); + }); + + it('should build phrases filters', () => { + const params = ['foo', 'bar']; + const alias = 'bar'; + const state = FilterStateStore.APP_STATE; + const filter = buildFilter( + mockIndexPattern, + mockFields[0], + isOneOfOperator, + params, + alias, + state + ); + expect(filter.meta.type).toBe(isOneOfOperator.type); + expect(filter.meta.negate).toBe(isOneOfOperator.negate); + expect(filter.meta.alias).toBe(alias); + expect(filter.$state.store).toBe(state); + }); + + it('should build range filters', () => { + const params = { from: 'foo', to: 'qux' }; + const alias = 'bar'; + const state = FilterStateStore.APP_STATE; + const filter = buildFilter( + mockIndexPattern, + mockFields[0], + isBetweenOperator, + params, + alias, + state + ); + expect(filter.meta.negate).toBe(isBetweenOperator.negate); + expect(filter.meta.alias).toBe(alias); + expect(filter.$state.store).toBe(state); + }); + + it('should build exists filters', () => { + const params = undefined; + const alias = 'bar'; + const state = FilterStateStore.APP_STATE; + const filter = buildFilter( + mockIndexPattern, + mockFields[0], + existsOperator, + params, + alias, + state + ); + expect(filter.meta.negate).toBe(existsOperator.negate); + expect(filter.meta.alias).toBe(alias); + expect(filter.$state.store).toBe(state); + }); + + it('should negate based on operator', () => { + const params = undefined; + const alias = 'bar'; + const state = FilterStateStore.APP_STATE; + const filter = buildFilter( + mockIndexPattern, + mockFields[0], + doesNotExistOperator, + params, + alias, + state + ); + expect(filter.meta.negate).toBe(doesNotExistOperator.negate); + expect(filter.meta.alias).toBe(alias); + expect(filter.$state.store).toBe(state); + }); + }); +}); diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts new file mode 100644 index 0000000000000..b1b456e482ac9 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts @@ -0,0 +1,178 @@ +/* + * 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 dateMath from '@elastic/datemath'; +import { + buildExistsFilter, + buildPhraseFilter, + buildPhrasesFilter, + buildRangeFilter, + FieldFilter, + Filter, + FilterMeta, + FilterStateStore, + PhraseFilter, + PhrasesFilter, + RangeFilter, +} from '@kbn/es-query'; +import { omit } from 'lodash'; +import { Field, IndexPattern } from 'ui/index_patterns'; +import { isFilterable } from 'ui/index_patterns/static_utils'; +import Ipv4Address from 'ui/utils/ipv4_address'; +import { FILTER_OPERATORS, Operator } from './filter_operators'; + +export function getIndexPatternFromFilter( + filter: Filter, + indexPatterns: IndexPattern[] +): IndexPattern | undefined { + return indexPatterns.find(indexPattern => indexPattern.id === filter.meta.index); +} + +export function getFieldFromFilter(filter: FieldFilter, indexPattern: IndexPattern) { + return indexPattern.fields.find(field => field.name === filter.meta.key); +} + +export function getOperatorFromFilter(filter: Filter) { + return FILTER_OPERATORS.find(operator => { + return filter.meta.type === operator.type && filter.meta.negate === operator.negate; + }); +} + +export function getQueryDslFromFilter(filter: Filter) { + return omit(filter, ['$state', 'meta']); +} + +export function getFilterableFields(indexPattern: IndexPattern) { + return indexPattern.fields.filter(isFilterable); +} + +export function getOperatorOptions(field: Field) { + return FILTER_OPERATORS.filter(operator => { + return !operator.fieldTypes || operator.fieldTypes.includes(field.type); + }); +} + +export function getFilterParams(filter: Filter) { + switch (filter.meta.type) { + case 'phrase': + return (filter as PhraseFilter).meta.params.query; + case 'phrases': + return (filter as PhrasesFilter).meta.params; + case 'range': + return { + from: (filter as RangeFilter).meta.params.gte, + to: (filter as RangeFilter).meta.params.lt, + }; + } +} + +export function validateParams(params: any, type: string) { + switch (type) { + case 'date': + const moment = typeof params === 'string' ? dateMath.parse(params) : null; + return Boolean(typeof params === 'string' && moment && moment.isValid()); + case 'ip': + try { + return Boolean(new Ipv4Address(params)); + } catch (e) { + return false; + } + default: + return true; + } +} + +export function isFilterValid( + indexPattern?: IndexPattern, + field?: Field, + operator?: Operator, + params?: any +) { + if (!indexPattern || !field || !operator) { + return false; + } + switch (operator.type) { + case 'phrase': + return validateParams(params, field.type); + case 'phrases': + if (!Array.isArray(params) || !params.length) { + return false; + } + return params.every(phrase => validateParams(phrase, field.type)); + case 'range': + if (typeof params !== 'object') { + return false; + } + return validateParams(params.from, field.type) || validateParams(params.to, field.type); + case 'exists': + return true; + default: + throw new Error(`Unknown operator type: ${operator.type}`); + } +} + +export function buildFilter( + indexPattern: IndexPattern, + field: Field, + operator: Operator, + params: any, + alias: string | null, + store: FilterStateStore +): Filter { + const filter = buildBaseFilter(indexPattern, field, operator, params); + filter.meta.alias = alias; + filter.meta.negate = operator.negate; + filter.$state = { store }; + return filter; +} + +function buildBaseFilter( + indexPattern: IndexPattern, + field: Field, + operator: Operator, + params: any +): Filter { + switch (operator.type) { + case 'phrase': + return buildPhraseFilter(field, params, indexPattern); + case 'phrases': + return buildPhrasesFilter(field, params, indexPattern); + case 'range': + const newParams = { gte: params.from, lt: params.to }; + return buildRangeFilter(field, newParams, indexPattern); + case 'exists': + return buildExistsFilter(field, indexPattern); + default: + throw new Error(`Unknown operator type: ${operator.type}`); + } +} + +export function buildCustomFilter( + index: string, + queryDsl: any, + disabled: boolean, + negate: boolean, + alias: string | null, + store: FilterStateStore +): Filter { + const meta: FilterMeta = { index, type: 'custom', disabled, negate, alias }; + const filter: Filter = { ...queryDsl, meta }; + filter.$state = { store }; + return filter; +} diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts new file mode 100644 index 0000000000000..b97f4a73901b6 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts @@ -0,0 +1,106 @@ +/* + * 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'; + +export interface Operator { + message: string; + type: string; + negate: boolean; + fieldTypes?: string[]; +} + +export const isOperator = { + message: i18n.translate('common.ui.filterEditor.isOperatorOptionLabel', { + defaultMessage: 'is', + }), + type: 'phrase', + negate: false, +}; + +export const isNotOperator = { + message: i18n.translate('common.ui.filterEditor.isNotOperatorOptionLabel', { + defaultMessage: 'is not', + }), + type: 'phrase', + negate: true, +}; + +export const isOneOfOperator = { + message: i18n.translate('common.ui.filterEditor.isOneOfOperatorOptionLabel', { + defaultMessage: 'is one of', + }), + type: 'phrases', + negate: false, + fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], +}; + +export const isNotOneOfOperator = { + message: i18n.translate('common.ui.filterEditor.isNotOneOfOperatorOptionLabel', { + defaultMessage: 'is not one of', + }), + type: 'phrases', + negate: true, + fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], +}; + +export const isBetweenOperator = { + message: i18n.translate('common.ui.filterEditor.isBetweenOperatorOptionLabel', { + defaultMessage: 'is between', + }), + type: 'range', + negate: false, + fieldTypes: ['number', 'date', 'ip'], +}; + +export const isNotBetweenOperator = { + message: i18n.translate('common.ui.filterEditor.isNotBetweenOperatorOptionLabel', { + defaultMessage: 'is not between', + }), + type: 'range', + negate: true, + fieldTypes: ['number', 'date', 'ip'], +}; + +export const existsOperator = { + message: i18n.translate('common.ui.filterEditor.existsOperatorOptionLabel', { + defaultMessage: 'exists', + }), + type: 'exists', + negate: false, +}; + +export const doesNotExistOperator = { + message: i18n.translate('common.ui.filterEditor.doesNotExistOperatorOptionLabel', { + defaultMessage: 'does not exist', + }), + type: 'exists', + negate: true, +}; + +export const FILTER_OPERATORS: Operator[] = [ + isOperator, + isNotOperator, + isOneOfOperator, + isNotOneOfOperator, + isBetweenOperator, + isNotBetweenOperator, + existsOperator, + doesNotExistOperator, +]; diff --git a/src/fixtures/filters/exists_filter.js b/src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts similarity index 73% rename from src/fixtures/filters/exists_filter.js rename to src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts index 0c4d6138a99b7..a17f767006f3e 100644 --- a/src/fixtures/filters/exists_filter.js +++ b/src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts @@ -17,19 +17,18 @@ * under the License. */ -export const existsFilter = { - 'meta': { - 'index': 'logstash-*', - 'negate': false, - 'disabled': false, - 'type': 'exists', - 'key': 'machine.os', - 'value': 'exists' +import { ExistsFilter, FilterStateStore } from '@kbn/es-query'; + +export const existsFilter: ExistsFilter = { + meta: { + index: 'logstash-*', + negate: false, + disabled: false, + type: 'exists', + key: 'machine.os', + alias: null, }, - 'exists': { - 'field': 'machine.os' + $state: { + store: FilterStateStore.APP_STATE, }, - '$state': { - 'store': 'appState' - } }; diff --git a/src/fixtures/filters/phrase_filter.js b/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts similarity index 80% rename from src/fixtures/filters/phrase_filter.js rename to src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts index 22f02347d94aa..77bb8e06c801a 100644 --- a/src/fixtures/filters/phrase_filter.js +++ b/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts @@ -17,24 +17,22 @@ * under the License. */ -export const phraseFilter = { +import { FilterStateStore, PhraseFilter } from '@kbn/es-query'; + +export const phraseFilter: PhraseFilter = { meta: { negate: false, index: 'logstash-*', type: 'phrase', key: 'machine.os', value: 'ios', - disabled: false - }, - query: { - match: { - 'machine.os': { - query: 'ios', - type: 'phrase' - } - } + disabled: false, + alias: null, + params: { + query: 'ios', + }, }, $state: { - store: 'appState' - } + store: FilterStateStore.APP_STATE, + }, }; diff --git a/src/fixtures/filters/phrases_filter.js b/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts similarity index 70% rename from src/fixtures/filters/phrases_filter.js rename to src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts index 184f1268c9da0..e86c3ee1318e3 100644 --- a/src/fixtures/filters/phrases_filter.js +++ b/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts @@ -17,37 +17,20 @@ * under the License. */ -export const phrasesFilter = { +import { FilterStateStore, PhrasesFilter } from '@kbn/es-query'; + +export const phrasesFilter: PhrasesFilter = { meta: { index: 'logstash-*', type: 'phrases', key: 'machine.os.raw', value: 'win xp, osx', - params: [ - 'win xp', - 'osx' - ], + params: ['win xp', 'osx'], negate: false, - disabled: false - }, - query: { - bool: { - should: [ - { - match_phrase: { - 'machine.os.raw': 'win xp' - } - }, - { - match_phrase: { - 'machine.os.raw': 'osx' - } - } - ], - minimum_should_match: 1 - } + disabled: false, + alias: null, }, $state: { - store: 'appState' - } + store: FilterStateStore.APP_STATE, + }, }; diff --git a/src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts b/src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts new file mode 100644 index 0000000000000..f6daf9cb36f11 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts @@ -0,0 +1,39 @@ +/* + * 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 { FilterStateStore, RangeFilter } from '@kbn/es-query'; + +export const rangeFilter: RangeFilter = { + meta: { + index: 'logstash-*', + negate: false, + disabled: false, + alias: null, + type: 'range', + key: 'bytes', + value: '0 to 10', + params: { + gte: 0, + lt: 10, + }, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, +}; diff --git a/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx b/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx new file mode 100644 index 0000000000000..75073def34281 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx @@ -0,0 +1,73 @@ +/* + * 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 { Component } from 'react'; +import chrome from 'ui/chrome'; +import { Field, IndexPattern } from 'ui/index_patterns'; +import { getSuggestions } from 'ui/value_suggestions'; +const config = chrome.getUiSettingsClient(); + +export interface PhraseSuggestorProps { + indexPattern: IndexPattern; + field?: Field; +} + +export interface PhraseSuggestorState { + suggestions: string[]; + isLoading: boolean; +} + +/** + * Since both "phrase" and "phrases" filter inputs suggest values (if enabled and the field is + * aggregatable), we pull out the common logic for requesting suggestions into this component + * which both of them extend. + */ +export class PhraseSuggestor extends Component< + T, + PhraseSuggestorState +> { + public state: PhraseSuggestorState = { + suggestions: [], + isLoading: false, + }; + + public componentDidMount() { + this.updateSuggestions(); + } + + protected isSuggestingValues() { + const shouldSuggestValues = config.get('filterEditor:suggestValues'); + const { field } = this.props; + return shouldSuggestValues && field && field.aggregatable && field.type === 'string'; + } + + protected onSearchChange = (value: string | number | boolean) => { + this.updateSuggestions(`${value}`); + }; + + protected async updateSuggestions(value: string = '') { + const { indexPattern, field } = this.props as PhraseSuggestorProps; + if (!field || !this.isSuggestingValues()) { + return; + } + this.setState({ isLoading: true }); + const suggestions = await getSuggestions(indexPattern.title, field, value); + this.setState({ suggestions, isLoading: false }); + } +} diff --git a/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx b/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx new file mode 100644 index 0000000000000..06b826d681d0c --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx @@ -0,0 +1,88 @@ +/* + * 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 { EuiFormRow } from '@elastic/eui'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { uniq } from 'lodash'; +import React from 'react'; +import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; +import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor'; +import { ValueInputType } from './value_input_type'; + +interface Props extends PhraseSuggestorProps { + value?: string; + onChange: (value: string | number | boolean) => void; + intl: InjectedIntl; +} + +class PhraseValueInputUI extends PhraseSuggestor { + public render() { + return ( + + {this.isSuggestingValues() ? ( + this.renderWithSuggestions() + ) : ( + + )} + + ); + } + + private renderWithSuggestions() { + const { suggestions } = this.state; + const { value, intl, onChange } = this.props; + const options = value ? uniq([value, ...suggestions]) : suggestions; + return ( + option} + selectedOptions={value ? [value] : []} + onChange={([newValue = '']) => onChange(newValue)} + onSearchChange={this.onSearchChange} + singleSelection={{ asPlainText: true }} + onCreateOption={onChange} + isClearable={false} + data-test-subj="filterParamsComboBox phraseParamsComboxBox" + /> + ); + } +} + +function StringComboBox(props: GenericComboBoxProps) { + return GenericComboBox(props); +} + +export const PhraseValueInput = injectI18n(PhraseValueInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx b/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx new file mode 100644 index 0000000000000..bef1433223e74 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx @@ -0,0 +1,67 @@ +/* + * 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 { EuiFormRow } from '@elastic/eui'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { uniq } from 'lodash'; +import React from 'react'; +import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; +import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor'; + +interface Props extends PhraseSuggestorProps { + values?: string[]; + onChange: (values: string[]) => void; + intl: InjectedIntl; +} + +class PhrasesValuesInputUI extends PhraseSuggestor { + public render() { + const { suggestions } = this.state; + const { values, intl, onChange } = this.props; + const options = values ? uniq([...values, ...suggestions]) : suggestions; + return ( + + option} + selectedOptions={values || []} + onCreateOption={(option: string) => onChange([...(values || []), option])} + onChange={onChange} + isClearable={false} + data-test-subj="filterParamsComboBox phrasesParamsComboxBox" + /> + + ); + } +} + +function StringComboBox(props: GenericComboBoxProps) { + return GenericComboBox(props); +} + +export const PhrasesValuesInput = injectI18n(PhrasesValuesInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/range_value_input.tsx b/src/ui/public/filter_bar/filter_editor/range_value_input.tsx new file mode 100644 index 0000000000000..7343c5722f226 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/range_value_input.tsx @@ -0,0 +1,121 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui'; +import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { get } from 'lodash'; +import { Component } from 'react'; +import React from 'react'; +import { getDocLink } from 'ui/documentation_links'; +import { Field } from 'ui/index_patterns'; +import { ValueInputType } from './value_input_type'; + +interface RangeParams { + from: number | string; + to: number | string; +} + +type RangeParamsPartial = Partial; + +interface Props { + field?: Field; + value?: RangeParams; + onChange: (params: RangeParamsPartial) => void; + intl: InjectedIntl; +} + +class RangeValueInputUI extends Component { + public constructor(props: Props) { + super(props); + } + + public render() { + const type = this.props.field ? this.props.field.type : 'string'; + + return ( +
+ + + + + + + + + + + + + {type === 'date' ? ( + + {' '} + + + ) : ( + '' + )} +
+ ); + } + + private onFromChange = (value: string | number | boolean) => { + if (typeof value !== 'string' && typeof value !== 'number') { + throw new Error('Range params must be a string or number'); + } + this.props.onChange({ from: value, to: get(this, 'props.value.to') }); + }; + + private onToChange = (value: string | number | boolean) => { + if (typeof value !== 'string' && typeof value !== 'number') { + throw new Error('Range params must be a string or number'); + } + this.props.onChange({ from: get(this, 'props.value.from'), to: value }); + }; +} + +export const RangeValueInput = injectI18n(RangeValueInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/value_input_type.tsx b/src/ui/public/filter_bar/filter_editor/value_input_type.tsx new file mode 100644 index 0000000000000..0a573c88eae70 --- /dev/null +++ b/src/ui/public/filter_bar/filter_editor/value_input_type.tsx @@ -0,0 +1,120 @@ +/* + * 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 { EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { isEmpty } from 'lodash'; +import React, { Component } from 'react'; +import { validateParams } from './lib/filter_editor_utils'; + +interface Props { + value?: string | number; + type: string; + onChange: (value: string | number | boolean) => void; + placeholder: string; + intl: InjectedIntl; +} + +class ValueInputTypeUI extends Component { + public render() { + const value = this.props.value; + let inputElement: React.ReactNode; + switch (this.props.type) { + case 'string': + inputElement = ( + + ); + break; + case 'number': + inputElement = ( + + ); + break; + case 'date': + inputElement = ( + + ); + break; + case 'ip': + inputElement = ( + + ); + break; + case 'boolean': + inputElement = ( + + ); + break; + default: + break; + } + + return inputElement; + } + + private onBoolChange = (event: React.ChangeEvent) => { + const boolValue = event.target.value === 'true'; + this.props.onChange(boolValue); + }; + + private onChange = (event: React.ChangeEvent) => { + const params = event.target.value; + this.props.onChange(params); + }; +} + +export const ValueInputType = injectI18n(ValueInputTypeUI); diff --git a/src/ui/public/filter_bar/filter_item.tsx b/src/ui/public/filter_bar/filter_item.tsx new file mode 100644 index 0000000000000..82ed8c692d549 --- /dev/null +++ b/src/ui/public/filter_bar/filter_item.tsx @@ -0,0 +1,226 @@ +/* + * 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 { EuiContextMenu, EuiPopover } from '@elastic/eui'; +import { + Filter, + isFilterPinned, + toggleFilterDisabled, + toggleFilterNegated, + toggleFilterPinned, +} from '@kbn/es-query'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import classNames from 'classnames'; +import React, { Component } from 'react'; +import { IndexPattern } from 'ui/index_patterns'; +import { FilterEditor } from './filter_editor'; +import { FilterView } from './filter_view'; + +interface Props { + id: string; + filter: Filter; + indexPatterns: IndexPattern[]; + className?: string; + onUpdate: (filter: Filter) => void; + onRemove: () => void; + intl: InjectedIntl; +} + +interface State { + isPopoverOpen: boolean; +} + +class FilterItemUI extends Component { + public state = { + isPopoverOpen: false, + }; + + public render() { + const { filter, id } = this.props; + const { negate, disabled } = filter.meta; + + const classes = classNames( + 'globalFilterItem', + { + 'globalFilterItem-isDisabled': disabled, + 'globalFilterItem-isPinned': isFilterPinned(filter), + 'globalFilterItem-isExcluded': negate, + }, + this.props.className + ); + + const dataTestSubjKey = filter.meta.key ? `filter-key-${filter.meta.key}` : ''; + const dataTestSubjValue = filter.meta.value ? `filter-value-${filter.meta.value}` : ''; + const dataTestSubjDisabled = `filter-${ + this.props.filter.meta.disabled ? 'disabled' : 'enabled' + }`; + + const badge = ( + this.props.onRemove()} + onClick={this.togglePopover} + data-test-subj={`filter ${dataTestSubjDisabled} ${dataTestSubjKey} ${dataTestSubjValue}`} + /> + ); + + const panelTree = [ + { + id: 0, + items: [ + { + name: isFilterPinned(filter) + ? this.props.intl.formatMessage({ + id: 'common.ui.filterBar.unpinFilterButtonLabel', + defaultMessage: 'Unpin', + }) + : this.props.intl.formatMessage({ + id: 'common.ui.filterBar.pinFilterButtonLabel', + defaultMessage: 'Pin across all apps', + }), + icon: 'pin', + onClick: () => { + this.closePopover(); + this.onTogglePinned(); + }, + 'data-test-subj': 'pinFilter', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.filterBar.editFilterButtonLabel', + defaultMessage: 'Edit filter', + }), + icon: 'pencil', + panel: 1, + 'data-test-subj': 'editFilter', + }, + { + name: negate + ? this.props.intl.formatMessage({ + id: 'common.ui.filterBar.includeFilterButtonLabel', + defaultMessage: 'Include results', + }) + : this.props.intl.formatMessage({ + id: 'common.ui.filterBar.excludeFilterButtonLabel', + defaultMessage: 'Exclude results', + }), + icon: negate ? 'plusInCircle' : 'minusInCircle', + onClick: () => { + this.closePopover(); + this.onToggleNegated(); + }, + 'data-test-subj': 'negateFilter', + }, + { + name: disabled + ? this.props.intl.formatMessage({ + id: 'common.ui.filterBar.enableFilterButtonLabel', + defaultMessage: 'Re-enable', + }) + : this.props.intl.formatMessage({ + id: 'common.ui.filterBar.disableFilterButtonLabel', + defaultMessage: 'Temporarily disable', + }), + icon: `${disabled ? 'eye' : 'eyeClosed'}`, + onClick: () => { + this.closePopover(); + this.onToggleDisabled(); + }, + 'data-test-subj': 'disableFilter', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.filterBar.deleteFilterButtonLabel', + defaultMessage: 'Delete', + }), + icon: 'trash', + onClick: () => { + this.closePopover(); + this.props.onRemove(); + }, + 'data-test-subj': 'deleteFilter', + }, + ], + }, + { + id: 1, + width: 400, + content: ( +
+ +
+ ), + }, + ]; + + return ( + + + + ); + } + + private closePopover = () => { + this.setState({ + isPopoverOpen: false, + }); + }; + + private togglePopover = () => { + this.setState({ + isPopoverOpen: !this.state.isPopoverOpen, + }); + }; + + private onSubmit = (filter: Filter) => { + this.closePopover(); + this.props.onUpdate(filter); + }; + + private onTogglePinned = () => { + const filter = toggleFilterPinned(this.props.filter); + this.props.onUpdate(filter); + }; + + private onToggleNegated = () => { + const filter = toggleFilterNegated(this.props.filter); + this.props.onUpdate(filter); + }; + + private onToggleDisabled = () => { + const filter = toggleFilterDisabled(this.props.filter); + this.props.onUpdate(filter); + }; +} + +export const FilterItem = injectI18n(FilterItemUI); diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.html b/src/ui/public/filter_bar/filter_pill/filter_pill.html deleted file mode 100644 index f79d42665e8fc..0000000000000 --- a/src/ui/public/filter_bar/filter_pill/filter_pill.html +++ /dev/null @@ -1,97 +0,0 @@ -
- -
- - NOT - {{ pill.filter.meta.alias }} - {{ pill.filter.meta.key }}: - "{{ pill.filter.meta.value }}" -
- -
- - - - - - - - - - -
-
diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.js b/src/ui/public/filter_bar/filter_pill/filter_pill.js deleted file mode 100644 index 03b19427af930..0000000000000 --- a/src/ui/public/filter_bar/filter_pill/filter_pill.js +++ /dev/null @@ -1,57 +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 template from './filter_pill.html'; -import { uiModules } from '../../modules'; - -const module = uiModules.get('kibana'); - -module.directive('filterPill', function () { - return { - template, - restrict: 'E', - scope: { - filter: '=', - onToggleFilter: '=', - onPinFilter: '=', - onInvertFilter: '=', - onDeleteFilter: '=', - onEditFilter: '=', - }, - bindToController: true, - controllerAs: 'pill', - controller: function filterPillController() { - - this.activateActions = () => { - this.areActionsActivated = true; - }; - - this.deactivateActions = () => { - this.areActionsActivated = false; - }; - - this.isControlledByPanel = () => { - return _.has(this.filter, 'meta.controlledBy'); - }; - - } - }; -}); - diff --git a/src/ui/public/filter_bar/filter_view/index.tsx b/src/ui/public/filter_bar/filter_view/index.tsx new file mode 100644 index 0000000000000..2421e7dcfab97 --- /dev/null +++ b/src/ui/public/filter_bar/filter_view/index.tsx @@ -0,0 +1,103 @@ +/* + * 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 { EuiBadge } from '@elastic/eui'; +import { Filter, isFilterPinned } from '@kbn/es-query'; +import { i18n } from '@kbn/i18n'; +import React, { SFC } from 'react'; +import { existsOperator, isOneOfOperator } from 'ui/filter_bar/filter_editor/lib/filter_operators'; + +interface Props { + filter: Filter; + [propName: string]: any; +} + +export const FilterView: SFC = ({ filter, ...rest }: Props) => { + let title = `Filter: ${getFilterDisplayText(filter)}. ${i18n.translate( + 'common.ui.filterBar.moreFilterActionsMessage', + { + defaultMessage: 'Select for more filter actions.', + } + )}`; + + if (isFilterPinned(filter)) { + title = `${i18n.translate('common.ui.filterBar.pinnedFilterPrefix', { + defaultMessage: 'Pinned', + })} ${title}`; + } + if (filter.meta.disabled) { + title = `${i18n.translate('common.ui.filterBar.disabledFilterPrefix', { + defaultMessage: 'Disabled', + })} ${title}`; + } + + return ( + + {getFilterDisplayText(filter)} + + ); +}; + +export function getFilterDisplayText(filter: Filter) { + if (filter.meta.alias !== null) { + return filter.meta.alias; + } + + const prefix = filter.meta.negate + ? ` ${i18n.translate('common.ui.filterBar.negatedFilterPrefix', { + defaultMessage: 'NOT ', + })}` + : ''; + + switch (filter.meta.type) { + case 'exists': + return `${prefix}${filter.meta.key} ${existsOperator.message}`; + case 'geo_bounding_box': + return `${prefix}${filter.meta.key}: ${filter.meta.value}`; + case 'geo_polygon': + return `${prefix}${filter.meta.key}: ${filter.meta.value}`; + case 'phrase': + return `${prefix}${filter.meta.key}: ${filter.meta.value}`; + case 'phrases': + return `${prefix}${filter.meta.key} ${isOneOfOperator.message} ${filter.meta.value}`; + case 'query_string': + return `${prefix}${filter.meta.value}`; + case 'range': + return `${prefix}${filter.meta.key}: ${filter.meta.value}`; + default: + return `${prefix}${JSON.stringify(filter.query)}`; + } +} diff --git a/src/ui/public/filter_bar/index.ts b/src/ui/public/filter_bar/index.ts new file mode 100644 index 0000000000000..cdf49a72e9554 --- /dev/null +++ b/src/ui/public/filter_bar/index.ts @@ -0,0 +1,22 @@ +/* + * 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 './directive'; + +export { FilterBar } from './filter_bar'; diff --git a/src/ui/public/filter_bar/lib/__tests__/disable_filter.js b/src/ui/public/filter_bar/lib/__tests__/disable_filter.js deleted file mode 100644 index 2541ec6cacae0..0000000000000 --- a/src/ui/public/filter_bar/lib/__tests__/disable_filter.js +++ /dev/null @@ -1,140 +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 expect from 'expect.js'; - -import { - disableFilter, - enableFilter, - toggleFilterDisabled, -} from '../disable_filter'; - - -describe('function disableFilter', function () { - it('should disable a filter that is explicitly enabled', function () { - const enabledFilter = { - meta: { - disabled: false, - }, - match_all: {}, - }; - - expect(disableFilter(enabledFilter).meta).to.have.property('disabled', true); - }); - - it('should disable a filter that is implicitly enabled', function () { - const enabledFilter = { - match_all: {}, - }; - - expect(disableFilter(enabledFilter).meta).to.have.property('disabled', true); - }); - - it('should preserve other properties', function () { - const enabledFilterWithProperties = { - meta: { - meta_property: 'META_PROPERTY', - }, - match_all: {}, - }; - - const disabledFilter = disableFilter(enabledFilterWithProperties); - expect(disabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); - expect(disabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); - }); -}); - -describe('function enableFilter', function () { - it('should enable a filter that is disabled', function () { - const disabledFilter = { - meta: { - disabled: true, - }, - match_all: {}, - }; - - expect(enableFilter(disabledFilter).meta).to.have.property('disabled', false); - }); - - it('should explicitly enable a filter that is implicitly enabled', function () { - const enabledFilter = { - match_all: {}, - }; - - expect(enableFilter(enabledFilter).meta).to.have.property('disabled', false); - }); - - it('should preserve other properties', function () { - const enabledFilterWithProperties = { - meta: { - meta_property: 'META_PROPERTY', - }, - match_all: {}, - }; - - const enabledFilter = enableFilter(enabledFilterWithProperties); - expect(enabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); - expect(enabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); - }); -}); - -describe('function toggleFilterDisabled', function () { - it('should enable a filter that is disabled', function () { - const disabledFilter = { - meta: { - disabled: true, - }, - match_all: {}, - }; - - expect(toggleFilterDisabled(disabledFilter).meta).to.have.property('disabled', false); - }); - - it('should disable a filter that is explicitly enabled', function () { - const enabledFilter = { - meta: { - disabled: false, - }, - match_all: {}, - }; - - expect(toggleFilterDisabled(enabledFilter).meta).to.have.property('disabled', true); - }); - - it('should disable a filter that is implicitly enabled', function () { - const enabledFilter = { - match_all: {}, - }; - - expect(toggleFilterDisabled(enabledFilter).meta).to.have.property('disabled', true); - }); - - it('should preserve other properties', function () { - const enabledFilterWithProperties = { - meta: { - meta_property: 'META_PROPERTY', - }, - match_all: {}, - }; - - const disabledFilter = toggleFilterDisabled(enabledFilterWithProperties); - expect(disabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); - expect(disabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); - }); -}); diff --git a/src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js b/src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js deleted file mode 100644 index 819035452837e..0000000000000 --- a/src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js +++ /dev/null @@ -1,38 +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 expect from 'expect.js'; -import { filterAppliedAndUnwrap } from '../filter_applied_and_unwrap'; - -describe('Filter Bar Directive', function () { - describe('filterAppliedAndUnwrap()', function () { - - const filters = [ - { meta: { apply: true }, exists: { field: '_type' } }, - { meta: { apply: false }, query: { query_string: { query: 'foo:bar' } } } - ]; - - it('should filter the applied and unwrap the filter', function () { - const results = filterAppliedAndUnwrap(filters); - expect(results).to.have.length(1); - expect(results[0]).to.eql(filters[0]); - }); - - }); -}); diff --git a/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js b/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js deleted file mode 100644 index 009683e3c07f4..0000000000000 --- a/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js +++ /dev/null @@ -1,57 +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 expect from 'expect.js'; -import ngMock from 'ng_mock'; -import { FilterBarLibFilterOutTimeBasedFilterProvider } from '../filter_out_time_based_filter'; - -describe('Filter Bar Directive', function () { - describe('filterOutTimeBasedFilter()', function () { - - let filterOutTimeBasedFilter; - let $rootScope; - - beforeEach(ngMock.module( - 'kibana', - 'kibana/courier', - function ($provide) { - $provide.service('indexPatterns', require('fixtures/mock_index_patterns')); - } - )); - - beforeEach(ngMock.inject(function (Private, _$rootScope_) { - filterOutTimeBasedFilter = Private(FilterBarLibFilterOutTimeBasedFilterProvider); - $rootScope = _$rootScope_; - })); - - it('should return the matching filter for the default time field', function (done) { - const filters = [ - { meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } }, - { meta: { index: 'logstash-*' }, range: { 'time': { gt: 1388559600000, lt: 1388646000000 } } } - ]; - filterOutTimeBasedFilter(filters).then(function (results) { - expect(results).to.have.length(1); - expect(results).to.not.contain(filters[1]); - done(); - }); - $rootScope.$apply(); - }); - - }); -}); diff --git a/src/ui/public/filter_bar/lib/filter_out_time_based_filter.js b/src/ui/public/filter_bar/lib/filter_out_time_based_filter.js deleted file mode 100644 index 0aa628e6ad069..0000000000000 --- a/src/ui/public/filter_bar/lib/filter_out_time_based_filter.js +++ /dev/null @@ -1,33 +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'; - -export function FilterBarLibFilterOutTimeBasedFilterProvider(indexPatterns, Promise) { - return Promise.method(function (filters) { - const id = _.get(filters, '[0].meta.index'); - if (id == null) return; - - return indexPatterns.get(id).then(function (indexPattern) { - return _.filter(filters, function (filter) { - return !(filter.range && filter.range[indexPattern.timeFieldName]); - }); - }); - }); -} diff --git a/src/ui/public/filter_bar/lib/map_phrase.js b/src/ui/public/filter_bar/lib/map_phrase.js index 25018d4746e2b..687c844f7eec7 100644 --- a/src/ui/public/filter_bar/lib/map_phrase.js +++ b/src/ui/public/filter_bar/lib/map_phrase.js @@ -30,8 +30,8 @@ export function FilterBarLibMapPhraseProvider(Promise, indexPatterns) { function getParams(indexPattern) { const type = 'phrase'; const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0]; - const params = isScriptedPhraseFilter ? filter.script.script.params : filter.query.match[key]; - const query = isScriptedPhraseFilter ? params.value : params.query; + const query = isScriptedPhraseFilter ? filter.script.script.params.value : filter.query.match[key].query; + const params = { query }; // Sometimes a filter will end up with an invalid index or field param. This could happen for a lot of reasons, // for example a user might manually edit the url or the index pattern's ID might change due to @@ -54,6 +54,6 @@ export function FilterBarLibMapPhraseProvider(Promise, indexPatterns) { } function isScriptedPhrase(filter) { - const params = _.get(filter, ['script', 'script', 'params']); - return params && params.value; + const value = _.get(filter, ['script', 'script', 'params', 'value']); + return typeof value !== 'undefined'; } diff --git a/src/ui/public/filter_bar/query_filter.js b/src/ui/public/filter_bar/query_filter.js index 0c1e68c084535..5b73013973fb8 100644 --- a/src/ui/public/filter_bar/query_filter.js +++ b/src/ui/public/filter_bar/query_filter.js @@ -24,10 +24,13 @@ import { uniqFilters } from './lib/uniq_filters'; import { compareFilters } from './lib/compare_filters'; import { EventsProvider } from '../events'; import { FilterBarLibMapAndFlattenFiltersProvider } from './lib/map_and_flatten_filters'; +import { FilterBarLibExtractTimeFilterProvider } from './lib/extract_time_filter'; +import { changeTimeFilter } from './lib/change_time_filter'; export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, globalState, config) { const EventEmitter = Private(EventsProvider); const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); + const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider); const queryFilter = new EventEmitter(); @@ -216,6 +219,24 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g executeOnFilters(pin); }; + queryFilter.setFilters = filters => { + return mapAndFlattenFilters(filters) + .then(mappedFilters => { + const appState = getAppState(); + const [globalFilters, appFilters] = _.partition(mappedFilters, filter => { + return filter.$state.store === 'globalState'; + }); + globalState.filters = globalFilters; + if (appState) appState.filters = appFilters; + }); + }; + + queryFilter.addFiltersAndChangeTimeFilter = async filters => { + const timeFilter = await extractTimeFilter(filters); + if (timeFilter) changeTimeFilter(timeFilter); + queryFilter.addFilters(filters.filter(filter => filter !== timeFilter)); + }; + initWatchers(); return queryFilter; @@ -268,7 +289,6 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g // ensure we don't mutate the filters passed in const globalFilters = gFilters ? _.cloneDeep(gFilters) : []; const appFilters = aFilters ? _.cloneDeep(aFilters) : []; - compareOptions = _.defaults(compareOptions || {}, { disabled: true }); // existing globalFilters should be mutated by appFilters _.each(appFilters, function (filter, i) { @@ -293,8 +313,8 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g return [ // Reverse filters after uniq again, so they are still in the order, they // were before updating them - uniqFilters(globalFilters, { disabled: true }).reverse(), - uniqFilters(appFilters, { disabled: true }).reverse() + uniqFilters(globalFilters).reverse(), + uniqFilters(appFilters).reverse() ]; } @@ -332,8 +352,7 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g // reconcile filter in global and app states const filters = mergeStateFilters(next[0], next[1]); - const globalFilters = filters[0]; - const appFilters = filters[1]; + const [globalFilters, appFilters] = filters; const appState = getAppState(); // save the state, as it may have updated diff --git a/src/ui/public/filter_editor/filter_editor.html b/src/ui/public/filter_editor/filter_editor.html deleted file mode 100644 index 0b69a1d5661d8..0000000000000 --- a/src/ui/public/filter_editor/filter_editor.html +++ /dev/null @@ -1,148 +0,0 @@ -
-
-
- Add - Edit - filter -
- - -
- -
- -
- - - -
-
- -
- -
- -
- -
- -
-
- - -
- - -

- Filters are built using the Elasticsearch Query DSL. -

-
-
- - -
-
- -
- - -
-
- - -
-
- -
- -
- - -
-
-
diff --git a/src/ui/public/filter_editor/filter_editor.js b/src/ui/public/filter_editor/filter_editor.js deleted file mode 100644 index ac55a253b594f..0000000000000 --- a/src/ui/public/filter_editor/filter_editor.js +++ /dev/null @@ -1,161 +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 { uiModules } from '../modules'; -import { callAfterBindingsWorkaround } from '../compat'; -import { FILTER_OPERATOR_TYPES } from './lib/filter_operators'; -import template from './filter_editor.html'; -import '../directives/documentation_href'; -import './filter_query_dsl_editor'; -import './filter_field_select'; -import './filter_operator_select'; -import './params_editor/filter_params_editor'; -import './filter_editor.less'; -import { - getQueryDslFromFilter, - getFieldFromFilter, - getOperatorFromFilter, - getParamsFromFilter, - isFilterValid, - buildFilter, - areIndexPatternsProvided, - isFilterPinned -} from './lib/filter_editor_utils'; -import * as filterBuilder from '@kbn/es-query'; -import { keyMap } from '../utils/key_map'; - -const module = uiModules.get('kibana'); -module.directive('filterEditor', function ($timeout, indexPatterns) { - return { - restrict: 'E', - template, - scope: { - indexPatterns: '=', - filter: '=', - onDelete: '&', - onCancel: '&', - onSave: '&' - }, - controllerAs: 'filterEditor', - bindToController: true, - controller: callAfterBindingsWorkaround(function ($scope, $element, config) { - const pinnedByDefault = config.get('filters:pinnedByDefault'); - - this.init = async () => { - if (!areIndexPatternsProvided(this.indexPatterns)) { - const defaultIndexPattern = await indexPatterns.getDefault(); - if (defaultIndexPattern) { - this.indexPatterns = [defaultIndexPattern]; - } - } - const { filter } = this; - this.alias = filter.meta.alias; - this.isEditingQueryDsl = false; - this.queryDsl = getQueryDslFromFilter(filter); - if (filter.meta.isNew) { - this.setFocus('field'); - } else { - getFieldFromFilter(filter, indexPatterns) - .then((field) => { - this.setField(field); - this.setOperator(getOperatorFromFilter(filter)); - this.params = getParamsFromFilter(filter); - }); - } - }; - - $scope.$watch(() => this.filter, this.init); - $scope.$watchCollection(() => this.filter.meta, this.init); - - this.setQueryDsl = (queryDsl) => { - this.queryDsl = queryDsl; - }; - - this.setField = (field) => { - this.field = field; - this.operator = null; - this.params = {}; - }; - - this.onFieldSelect = (field) => { - this.setField(field); - this.setFocus('operator'); - }; - - this.setOperator = (operator) => { - this.operator = operator; - }; - - this.onOperatorSelect = (operator) => { - this.setOperator(operator); - this.setFocus('params'); - }; - - this.setParams = (params) => { - this.params = params; - }; - - this.setFocus = (name) => { - $timeout(() => $scope.$broadcast(`focus-${name}`)); - }; - - this.toggleEditingQueryDsl = () => { - this.isEditingQueryDsl = !this.isEditingQueryDsl; - }; - - this.isQueryDslEditorVisible = () => { - const { type, isNew } = this.filter.meta; - return this.isEditingQueryDsl || (!isNew && !FILTER_OPERATOR_TYPES.includes(type)); - }; - - this.isValid = () => { - if (this.isQueryDslEditorVisible()) { - return _.isObject(this.queryDsl); - } - const { field, operator, params } = this; - return isFilterValid({ field, operator, params }); - }; - - this.save = () => { - const { filter, field, operator, params, alias } = this; - - let newFilter; - if (this.isQueryDslEditorVisible()) { - const meta = _.pick(filter.meta, ['negate', 'index']); - meta.index = meta.index || this.indexPatterns[0].id; - newFilter = Object.assign(this.queryDsl, { meta }); - } else { - const indexPattern = field.indexPattern; - newFilter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - } - newFilter.meta.disabled = filter.meta.disabled; - newFilter.meta.alias = alias; - const isPinned = isFilterPinned(filter, pinnedByDefault); - return this.onSave({ filter, newFilter, isPinned }); - }; - - $element.on('keydown', (event) => { - if (keyMap[event.keyCode] === 'escape') { - $timeout(() => this.onCancel()); - } - }); - }) - }; -}); diff --git a/src/ui/public/filter_editor/filter_editor.less b/src/ui/public/filter_editor/filter_editor.less deleted file mode 100644 index b45c0030b37d3..0000000000000 --- a/src/ui/public/filter_editor/filter_editor.less +++ /dev/null @@ -1,36 +0,0 @@ -.filterEditor { - position: absolute; - width: 600px; - z-index: 101; -} - -.filterEditor__labelBar { - display: flex; - align-items: center; - justify-content: space-between; -} - -.filterEditor__wideField { - min-width: 0; -} - -.filterEditorParamsInput { - min-width: 100px; -} - -.uiSelectChoices--autoWidth { - width: auto !important; - min-width: 100% !important; -} - -.uiSelectMatch--restrictToParent .ui-select-match-item { - max-width: 100%; -} - - .uiSelectMatch--pillWithTooltip { - display: block; - margin-right: 16px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } diff --git a/src/ui/public/filter_editor/filter_field_select.html b/src/ui/public/filter_editor/filter_field_select.html deleted file mode 100644 index 65c45b1bae7b0..0000000000000 --- a/src/ui/public/filter_editor/filter_field_select.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - {{$select.selected.name}} - - - -
-
-
diff --git a/src/ui/public/filter_editor/filter_field_select.js b/src/ui/public/filter_editor/filter_field_select.js deleted file mode 100644 index f1aeb276d58d1..0000000000000 --- a/src/ui/public/filter_editor/filter_field_select.js +++ /dev/null @@ -1,52 +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 'angular-ui-select'; -import { uiModules } from '../modules'; -import { getFilterableFields } from './lib/filter_editor_utils'; -import template from './filter_field_select.html'; -import '../directives/ui_select_focus_on'; -import '../directives/scroll_bottom'; -import '../filters/sort_prefix_first'; - -const module = uiModules.get('kibana'); -module.directive('filterFieldSelect', function () { - return { - restrict: 'E', - template, - scope: { - indexPatterns: '=', - field: '=', - onSelect: '&' - }, - link: function ($scope) { - $scope.$watch('indexPatterns', (indexPatterns) => { - $scope.fieldOptions = getFilterableFields(indexPatterns); - }); - - $scope.getFieldIndexPattern = (field) => { - return field.indexPattern.title; - }; - - $scope.increaseLimit = () => $scope.limit += 50; - $scope.resetLimit = () => $scope.limit = 50; - $scope.resetLimit(); - } - }; -}); diff --git a/src/ui/public/filter_editor/filter_operator_select.html b/src/ui/public/filter_editor/filter_operator_select.html deleted file mode 100644 index 78b730b93b58a..0000000000000 --- a/src/ui/public/filter_editor/filter_operator_select.html +++ /dev/null @@ -1,12 +0,0 @@ - - - {{$select.selected.name}} - - -
-
-
diff --git a/src/ui/public/filter_editor/filter_operator_select.js b/src/ui/public/filter_editor/filter_operator_select.js deleted file mode 100644 index 3d877aee869b7..0000000000000 --- a/src/ui/public/filter_editor/filter_operator_select.js +++ /dev/null @@ -1,42 +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 'angular-ui-select'; -import { uiModules } from '../modules'; -import { getOperatorOptions } from './lib/filter_editor_utils'; -import template from './filter_operator_select.html'; -import '../directives/ui_select_focus_on'; - -const module = uiModules.get('kibana'); -module.directive('filterOperatorSelect', function () { - return { - restrict: 'E', - template, - scope: { - field: '=', - operator: '=', - onSelect: '&' - }, - link: function ($scope) { - $scope.$watch('field', (field) => { - $scope.operatorOptions = getOperatorOptions(field); - }); - } - }; -}); diff --git a/src/ui/public/filter_editor/filter_query_dsl_editor.html b/src/ui/public/filter_editor/filter_query_dsl_editor.html deleted file mode 100644 index 999dae7c1df0c..0000000000000 --- a/src/ui/public/filter_editor/filter_query_dsl_editor.html +++ /dev/null @@ -1,13 +0,0 @@ -
diff --git a/src/ui/public/filter_editor/filter_query_dsl_editor.js b/src/ui/public/filter_editor/filter_query_dsl_editor.js deleted file mode 100644 index 16f763378ae05..0000000000000 --- a/src/ui/public/filter_editor/filter_query_dsl_editor.js +++ /dev/null @@ -1,59 +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 'ace'; -import _ from 'lodash'; -import { uiModules } from '../modules'; -import template from './filter_query_dsl_editor.html'; -import '../accessibility/kbn_ui_ace_keyboard_mode'; - -const module = uiModules.get('kibana'); -module.directive('filterQueryDslEditor', function () { - return { - restrict: 'E', - template, - scope: { - isVisible: '=', - filter: '=', - onChange: '&' - }, - link: { - pre: function ($scope) { - let aceEditor; - - $scope.queryDsl = _.omit($scope.filter, ['meta', '$state']); - $scope.aceLoaded = function (editor) { - aceEditor = editor; - editor.$blockScrolling = Infinity; - const session = editor.getSession(); - session.setTabSize(2); - session.setUseSoftTabs(true); - }; - - $scope.$watch('isVisible', isVisible => { - // Tell the editor to re-render itself now that it's visible, otherwise it won't - // show up in the UI. - if (isVisible && aceEditor) { - aceEditor.renderer.updateFull(); - } - }); - } - } - }; -}); diff --git a/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js b/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js deleted file mode 100644 index 61aadc4c07487..0000000000000 --- a/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js +++ /dev/null @@ -1,396 +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 expect from 'expect.js'; -import ngMock from 'ng_mock'; -import sinon from 'sinon'; -import Promise from 'bluebird'; -import { - phraseFilter, - scriptedPhraseFilter, - phrasesFilter, - rangeFilter, - existsFilter -} from 'fixtures/filters'; -import stubbedLogstashIndexPattern from 'fixtures/stubbed_logstash_index_pattern'; -import stubbedLogstashFields from 'fixtures/logstash_fields'; -import { FILTER_OPERATORS } from '../filter_operators'; -import { - getQueryDslFromFilter, - getFieldFromFilter, - getOperatorFromFilter, - getParamsFromFilter, - getFilterableFields, - getOperatorOptions, - isFilterValid, - buildFilter, - areIndexPatternsProvided, - isFilterPinned -} from '../filter_editor_utils'; - -describe('FilterEditorUtils', function () { - beforeEach(ngMock.module('kibana')); - - let indexPattern; - let fields; - beforeEach(function () { - ngMock.inject(function (Private) { - indexPattern = Private(stubbedLogstashIndexPattern); - fields = stubbedLogstashFields(); - }); - }); - - describe('getQueryDslFromFilter', function () { - it('should return query DSL without meta and $state', function () { - const queryDsl = getQueryDslFromFilter(phraseFilter); - expect(queryDsl).to.not.have.key('meta'); - expect(queryDsl).to.not.have.key('$state'); - expect(queryDsl).to.have.key('query'); - }); - }); - - describe('getFieldFromFilter', function () { - let indexPatterns; - beforeEach(function () { - indexPatterns = { - get: sinon.stub().returns(Promise.resolve(indexPattern)) - }; - }); - - it('should return the field from the filter', function (done) { - getFieldFromFilter(phraseFilter, indexPatterns) - .then((field) => { - expect(field).to.be.ok(); - done(); - }); - }); - }); - - describe('getOperatorFromFilter', function () { - it('should return "is" for phrase filter', function () { - const operator = getOperatorFromFilter(phraseFilter); - expect(operator.name).to.be('is'); - expect(operator.negate).to.be(false); - }); - - it('should return "is not" for negated phrase filter', function () { - const negate = phraseFilter.meta.negate; - phraseFilter.meta.negate = true; - const operator = getOperatorFromFilter(phraseFilter); - expect(operator.name).to.be('is not'); - expect(operator.negate).to.be(true); - phraseFilter.meta.negate = negate; - }); - - it('should return "is one of" for phrases filter', function () { - const operator = getOperatorFromFilter(phrasesFilter); - expect(operator.name).to.be('is one of'); - expect(operator.negate).to.be(false); - }); - - it('should return "is not one of" for negated phrases filter', function () { - const negate = phrasesFilter.meta.negate; - phrasesFilter.meta.negate = true; - const operator = getOperatorFromFilter(phrasesFilter); - expect(operator.name).to.be('is not one of'); - expect(operator.negate).to.be(true); - phrasesFilter.meta.negate = negate; - }); - - it('should return "is between" for range filter', function () { - const operator = getOperatorFromFilter(rangeFilter); - expect(operator.name).to.be('is between'); - expect(operator.negate).to.be(false); - }); - - it('should return "is not between" for negated range filter', function () { - const negate = rangeFilter.meta.negate; - rangeFilter.meta.negate = true; - const operator = getOperatorFromFilter(rangeFilter); - expect(operator.name).to.be('is not between'); - expect(operator.negate).to.be(true); - rangeFilter.meta.negate = negate; - }); - - it('should return "exists" for exists filter', function () { - const operator = getOperatorFromFilter(existsFilter); - expect(operator.name).to.be('exists'); - expect(operator.negate).to.be(false); - }); - - it('should return "does not exists" for negated exists filter', function () { - const negate = existsFilter.meta.negate; - existsFilter.meta.negate = true; - const operator = getOperatorFromFilter(existsFilter); - expect(operator.name).to.be('does not exist'); - expect(operator.negate).to.be(true); - existsFilter.meta.negate = negate; - }); - }); - - describe('getParamsFromFilter', function () { - it('should retrieve params from phrase filter', function () { - const params = getParamsFromFilter(phraseFilter); - expect(params.phrase).to.be('ios'); - }); - - it('should retrieve params from scripted phrase filter', function () { - const params = getParamsFromFilter(scriptedPhraseFilter); - expect(params.phrase).to.be('i am a string'); - }); - - it('should retrieve params from phrases filter', function () { - const params = getParamsFromFilter(phrasesFilter); - expect(params.phrases).to.eql(['win xp', 'osx']); - }); - - it('should retrieve params from range filter', function () { - const params = getParamsFromFilter(rangeFilter); - expect(params.range).to.eql({ from: 0, to: 10 }); - }); - - it('should return undefined for exists filter', function () { - const params = getParamsFromFilter(existsFilter); - expect(params.exists).to.not.be.ok(); - }); - }); - - describe('getFilterableFields', function () { - it('returns an empty array when no index patterns are provided', function () { - const fieldOptions = getFilterableFields(); - expect(fieldOptions).to.eql([]); - }); - - it('returns the list of fields from the given index patterns', function () { - const fieldOptions = getFilterableFields([indexPattern]); - expect(fieldOptions).to.be.an('array'); - expect(fieldOptions.length).to.be.greaterThan(0); - }); - - it('limits the fields to the filterable fields', function () { - const fieldOptions = getFilterableFields([indexPattern]); - const nonFilterableFields = fieldOptions.filter(field => !field.filterable); - expect(nonFilterableFields.length).to.be(0); - }); - }); - - describe('getOperatorOptions', function () { - it('returns range for number fields', function () { - const field = fields.find(field => field.type === 'number'); - const operatorOptions = getOperatorOptions(field); - const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); - expect(rangeOperator).to.be.ok(); - }); - - it('does not return range for string fields', function () { - const field = fields.find(field => field.type === 'string'); - const operatorOptions = getOperatorOptions(field); - const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); - expect(rangeOperator).to.not.be.ok(); - }); - - it('returns operators without field type restrictions', function () { - const operatorOptions = getOperatorOptions(); - const operatorsWithoutFieldTypes = FILTER_OPERATORS.filter(operator => !operator.fieldTypes); - expect(operatorOptions.length).to.be(operatorsWithoutFieldTypes.length); - }); - }); - - describe('isFilterValid', function () { - it('should return false if field is not provided', function () { - const field = null; - const operator = FILTER_OPERATORS[0]; - const params = { phrase: 'foo' }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.not.be.ok(); - }); - - it('should return false if operator is not provided', function () { - const field = fields[0]; - const operator = null; - const params = { phrase: 'foo' }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.not.be.ok(); - }); - - it('should return false for phrase filter without phrase', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); - const params = {}; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.not.be.ok(); - }); - - it('should return true for phrase filter with phrase', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); - const params = { phrase: 'foo' }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.be.ok(); - }); - - it('should return false for phrases filter without phrases', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); - const params = {}; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.not.be.ok(); - }); - - it('should return true for phrases filter with phrases', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); - const params = { phrases: ['foo', 'bar'] }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.be.ok(); - }); - - it('should return false for range filter without range', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); - const params = {}; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.not.be.ok(); - }); - - it('should return true for range filter with from', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); - const params = { range: { from: 0 } }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.be.ok(); - }); - - it('should return true for range filter with from/to', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); - const params = { range: { from: 0, to: 10 } }; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.be.ok(); - }); - - it('should return true for exists filter without params', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists'); - const params = {}; - const isValid = isFilterValid({ field, operator, params }); - expect(isValid).to.be.ok(); - }); - }); - - describe('buildFilter', function () { - let filterBuilder; - beforeEach(function () { - filterBuilder = { - buildExistsFilter: sinon.stub().returns(existsFilter), - buildPhraseFilter: sinon.stub().returns(phraseFilter), - buildPhrasesFilter: sinon.stub().returns(phrasesFilter), - buildRangeFilter: sinon.stub().returns(rangeFilter) - }; - }); - - it('should build phrase filters', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); - const params = { phrase: 'foo' }; - const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - expect(filter).to.be.ok(); - expect(filter.meta.negate).to.be(operator.negate); - expect(filterBuilder.buildPhraseFilter.called).to.be.ok(); - expect(filterBuilder.buildPhraseFilter.getCall(0).args[1]).to.be(params.phrase); - }); - - it('should build phrases filters', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); - const params = { phrases: ['foo', 'bar'] }; - const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - expect(filter).to.be.ok(); - expect(filter.meta.negate).to.be(operator.negate); - expect(filterBuilder.buildPhrasesFilter.called).to.be.ok(); - expect(filterBuilder.buildPhrasesFilter.getCall(0).args[1]).to.eql(params.phrases); - }); - - it('should build range filters', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); - const params = { range: { from: 0, to: 10 } }; - const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - expect(filter).to.be.ok(); - expect(filter.meta.negate).to.be(operator.negate); - expect(filterBuilder.buildRangeFilter.called).to.be.ok(); - const range = filterBuilder.buildRangeFilter.getCall(0).args[1]; - expect(range).to.have.property('gte'); - expect(range).to.have.property('lt'); - }); - - it('should build exists filters', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists'); - const params = {}; - const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - expect(filter).to.be.ok(); - expect(filter.meta.negate).to.be(operator.negate); - expect(filterBuilder.buildExistsFilter.called).to.be.ok(); - }); - - it('should negate based on operator', function () { - const field = fields[0]; - const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists' && operator.negate); - const params = {}; - const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); - expect(filter).to.be.ok(); - expect(filter.meta.negate).to.be(operator.negate); - expect(filterBuilder.buildExistsFilter.called).to.be.ok(); - }); - }); - - describe('areIndexPatternsProvided', function () { - it('should return false when index patterns are not provided', function () { - expect(areIndexPatternsProvided(undefined)).to.be(false); - expect(areIndexPatternsProvided([])).to.be(false); - expect(areIndexPatternsProvided([undefined])).to.be(false); - }); - - it('should return true when index patterns are provided', function () { - const indexPatternMock = {}; - expect(areIndexPatternsProvided([indexPatternMock])).to.be(true); - }); - }); - - describe('isFilterPinned', function () { - it('should return false when the store is appState', function () { - const filter = { $state: { store: 'appState' } }; - expect(isFilterPinned(filter, false)).to.be(false); - expect(isFilterPinned(filter, true)).to.be(false); - }); - - it('should return true when the store is globalState', function () { - const filter = { $state: { store: 'globalState' } }; - expect(isFilterPinned(filter, false)).to.be(true); - expect(isFilterPinned(filter, true)).to.be(true); - }); - - it('should return the default when the store does not exist', function () { - const filter = {}; - expect(isFilterPinned(filter, false)).to.be(false); - expect(isFilterPinned(filter, true)).to.be(true); - }); - }); -}); diff --git a/src/ui/public/filter_editor/lib/filter_editor_utils.js b/src/ui/public/filter_editor/lib/filter_editor_utils.js deleted file mode 100644 index 4c0067b62193d..0000000000000 --- a/src/ui/public/filter_editor/lib/filter_editor_utils.js +++ /dev/null @@ -1,111 +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 { FILTER_OPERATORS } from './filter_operators'; - -export function getQueryDslFromFilter(filter) { - return _(filter) - .omit(['meta', '$state']) - .cloneDeep(); -} - -export function getFieldFromFilter(filter, indexPatterns) { - const { index, key } = filter.meta; - return indexPatterns.get(index) - .then(indexPattern => indexPattern.id && indexPattern.fields.byName[key]); -} - -export function getOperatorFromFilter(filter) { - const { type, negate } = filter.meta; - return FILTER_OPERATORS.find((operator) => { - return operator.type === type && operator.negate === negate; - }); -} - -export function getParamsFromFilter(filter) { - const { type, key } = filter.meta; - let params; - if (type === 'phrase') { - params = filter.query ? filter.query.match[key].query : filter.script.script.params.value; - } else if (type === 'phrases') { - params = filter.meta.params; - } else if (type === 'range') { - const range = filter.range ? filter.range[key] : filter.script.script.params; - const from = _.has(range, 'gte') ? range.gte : range.gt; - const to = _.has(range, 'lte') ? range.lte : range.lt; - params = { from, to }; - } - return { - [type]: params - }; -} - -export function getFilterableFields(indexPatterns) { - return (indexPatterns || []).reduce((fields, indexPattern) => { - const filterableFields = indexPattern.fields.filter(field => field.filterable); - return [...fields, ...filterableFields]; - }, []); -} - -export function getOperatorOptions(field) { - const type = _.get(field, 'type'); - return FILTER_OPERATORS.filter((operator) => { - return !operator.fieldTypes || operator.fieldTypes.includes(type); - }); -} - -export function isFilterValid({ field, operator, params }) { - if (!field || !operator) { - return false; - } else if (operator.type === 'phrase') { - return _.has(params, 'phrase') && params.phrase !== ''; - } else if (operator.type === 'phrases') { - return _.has(params, 'phrases') && params.phrases.length > 0; - } else if (operator.type === 'range') { - const hasFrom = _.has(params, ['range', 'from']) && params.range.from !== ''; - const hasTo = _.has(params, ['range', 'to']) && params.range.to !== ''; - return hasFrom || hasTo; - } - return true; -} - -export function buildFilter({ indexPattern, field, operator, params, filterBuilder }) { - let filter; - if (operator.type === 'phrase') { - filter = filterBuilder.buildPhraseFilter(field, params.phrase, indexPattern); - } else if (operator.type === 'phrases') { - filter = filterBuilder.buildPhrasesFilter(field, params.phrases, indexPattern); - } else if (operator.type === 'range') { - filter = filterBuilder.buildRangeFilter(field, { gte: params.range.from, lt: params.range.to }, indexPattern); - } else if (operator.type === 'exists') { - filter = filterBuilder.buildExistsFilter(field, indexPattern); - } - filter.meta.negate = operator.negate; - return filter; -} - -export function areIndexPatternsProvided(indexPatterns) { - return _.compact(indexPatterns).length !== 0; -} - -export function isFilterPinned(filter, pinnedByDefault) { - if (!filter.hasOwnProperty('$state')) return pinnedByDefault; - return filter.$state.store === 'globalState'; -} diff --git a/src/ui/public/filter_editor/lib/filter_operators.js b/src/ui/public/filter_editor/lib/filter_operators.js deleted file mode 100644 index 140928eb1912d..0000000000000 --- a/src/ui/public/filter_editor/lib/filter_operators.js +++ /dev/null @@ -1,72 +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'; - -export const FILTER_OPERATORS = [ - { - name: 'is', - type: 'phrase', - negate: false, - }, - { - name: 'is not', - type: 'phrase', - negate: true, - }, - { - name: 'is one of', - type: 'phrases', - negate: false, - fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] - }, - { - name: 'is not one of', - type: 'phrases', - negate: true, - fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] - }, - { - name: 'is between', - type: 'range', - negate: false, - fieldTypes: ['number', 'date', 'ip'], - }, - { - name: 'is not between', - type: 'range', - negate: true, - fieldTypes: ['number', 'date', 'ip'], - }, - { - name: 'exists', - type: 'exists', - negate: false, - }, - { - name: 'does not exist', - type: 'exists', - negate: true, - }, -]; - -export const FILTER_OPERATOR_TYPES = _(FILTER_OPERATORS) - .map('type') - .uniq() - .value(); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_editor.html deleted file mode 100644 index f242ce2af5a2f..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_editor.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - diff --git a/src/ui/public/filter_editor/params_editor/filter_params_editor.js b/src/ui/public/filter_editor/params_editor/filter_params_editor.js deleted file mode 100644 index d0397d4f7508e..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_editor.js +++ /dev/null @@ -1,37 +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 { uiModules } from '../../modules'; -import template from './filter_params_editor.html'; -import './filter_params_phrase_editor'; -import './filter_params_phrases_editor'; -import './filter_params_range_editor'; - -const module = uiModules.get('kibana'); -module.directive('filterParamsEditor', function () { - return { - restrict: 'E', - template, - scope: { - field: '=', - operator: '=', - params: '=' - } - }; -}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_input_type.html b/src/ui/public/filter_editor/params_editor/filter_params_input_type.html deleted file mode 100644 index 1d1a89bbb0df9..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_input_type.html +++ /dev/null @@ -1,50 +0,0 @@ -
- - - - -
- -
-
diff --git a/src/ui/public/filter_editor/params_editor/filter_params_input_type.js b/src/ui/public/filter_editor/params_editor/filter_params_input_type.js deleted file mode 100644 index 1278e8b508be3..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_input_type.js +++ /dev/null @@ -1,49 +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 { uiModules } from '../../modules'; -import template from './filter_params_input_type.html'; -import '../../directives/validate_date_math'; -import '../../directives/validate_ip'; -import '../../directives/string_to_number'; - -const module = uiModules.get('kibana'); -module.directive('filterParamsInputType', function () { - return { - restrict: 'E', - template, - scope: { - type: '=', - placeholder: '@', - value: '=', - onChange: '&' - }, - link: function (scope) { - scope.boolOptions = [true, false]; - scope.setDefaultBool = () => { - if (scope.value == null) { - scope.value = scope.boolOptions[0]; - scope.onChange({ - value: scope.value - }); - } - }; - } - }; -}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js b/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js deleted file mode 100644 index cbcd2d8ab5223..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js +++ /dev/null @@ -1,57 +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 chrome from '../../chrome'; - -const baseUrl = chrome.addBasePath('/api/kibana/suggestions/values'); - -export function filterParamsPhraseController($http, $scope, config) { - const shouldSuggestValues = this.shouldSuggestValues = config.get('filterEditor:suggestValues'); - - this.compactUnion = _.flow(_.union, _.compact); - - this.getValueSuggestions = _.memoize(getValueSuggestions, getFieldQueryHash); - - this.refreshValueSuggestions = (query) => { - return this.getValueSuggestions($scope.field, query) - .then(suggestions => $scope.valueSuggestions = suggestions); - }; - - this.refreshValueSuggestions(); - - function getValueSuggestions(field, query) { - if (!shouldSuggestValues || !_.get(field, 'aggregatable') || field.type !== 'string') { - return Promise.resolve([]); - } - - const params = { - query, - field: field.name - }; - - return $http.post(`${baseUrl}/${field.indexPattern.title}`, params) - .then(response => response.data) - .catch(() => []); - } - - function getFieldQueryHash(field, query = '') { - return `${field.indexPattern.id}/${field.name}/${query}`; - } -} diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html deleted file mode 100644 index 36d509f28dece..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - {{$select.selected}} - - - -
-
-
- - - - - - Accepted date formats - - diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js deleted file mode 100644 index d7b166e7990f7..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js +++ /dev/null @@ -1,42 +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 'angular-ui-select'; -import { uiModules } from '../../modules'; -import template from './filter_params_phrase_editor.html'; -import { filterParamsPhraseController } from './filter_params_phrase_controller'; -import './filter_params_input_type'; -import '../../directives/documentation_href'; -import '../../directives/ui_select_focus_on'; -import '../../directives/focus_on'; -import '../../filters/sort_prefix_first'; - -const module = uiModules.get('kibana'); -module.directive('filterParamsPhraseEditor', function () { - return { - restrict: 'E', - template, - scope: { - field: '=', - params: '=' - }, - controllerAs: 'filterParamsPhraseEditor', - controller: filterParamsPhraseController - }; -}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html deleted file mode 100644 index 4a2935c4ba0b7..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - {{$item}} - - - -
-
-
diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js deleted file mode 100644 index ca4f67b28caf5..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js +++ /dev/null @@ -1,39 +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 'angular-ui-select'; -import { uiModules } from '../../modules'; -import template from './filter_params_phrases_editor.html'; -import { filterParamsPhraseController } from './filter_params_phrase_controller'; -import '../../directives/ui_select_focus_on'; -import '../../filters/sort_prefix_first'; - -const module = uiModules.get('kibana'); -module.directive('filterParamsPhrasesEditor', function () { - return { - restrict: 'E', - template, - scope: { - field: '=', - params: '=' - }, - controllerAs: 'filterParamsPhrasesEditor', - controller: filterParamsPhraseController - }; -}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html deleted file mode 100644 index 483d6c7408bd8..0000000000000 --- a/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html +++ /dev/null @@ -1,30 +0,0 @@ -
- -
- -
- -
- - - - Accepted date formats - - diff --git a/src/ui/public/index_patterns/_field.d.ts b/src/ui/public/index_patterns/_field.d.ts new file mode 100644 index 0000000000000..749cd63d0a84c --- /dev/null +++ b/src/ui/public/index_patterns/_field.d.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. + */ + +export interface Field { + name: string; + type: string; + aggregatable: boolean; + filterable: boolean; + searchable: boolean; +} diff --git a/src/ui/public/index_patterns/_index_pattern.d.ts b/src/ui/public/index_patterns/_index_pattern.d.ts index 0ff899839c42c..0465e35ff2a1f 100644 --- a/src/ui/public/index_patterns/_index_pattern.d.ts +++ b/src/ui/public/index_patterns/_index_pattern.d.ts @@ -17,11 +17,18 @@ * under the License. */ +import { Field } from 'ui/index_patterns/_field'; + /** * WARNING: these types are incomplete */ -export type IndexPattern = any; +export interface IndexPattern { + id: string; + fields: Field[]; + title: string; + timeFieldName?: string; +} export interface StaticIndexPatternField { name: string; diff --git a/src/ui/public/index_patterns/fixtures/index.ts b/src/ui/public/index_patterns/fixtures/index.ts new file mode 100644 index 0000000000000..a84ab381b52d8 --- /dev/null +++ b/src/ui/public/index_patterns/fixtures/index.ts @@ -0,0 +1,79 @@ +/* + * 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 { Field, IndexPattern } from '../index'; + +export const mockFields: Field[] = [ + { + name: 'machine.os', + type: 'string', + aggregatable: false, + searchable: false, + filterable: true, + }, + { + name: 'machine.os.raw', + type: 'string', + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'not.filterable', + type: 'string', + aggregatable: true, + searchable: false, + filterable: false, + }, + { + name: 'bytes', + type: 'number', + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: '@timestamp', + type: 'date', + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'clientip', + type: 'ip', + aggregatable: true, + searchable: true, + filterable: true, + }, + { + name: 'bool.field', + type: 'boolean', + aggregatable: true, + searchable: true, + filterable: true, + }, +]; + +export const mockIndexPattern: IndexPattern = { + id: 'logstash-*', + fields: mockFields, + title: 'logstash-*', + timeFieldName: '@timestamp', +}; diff --git a/src/ui/public/index_patterns/index.d.ts b/src/ui/public/index_patterns/index.d.ts index 92f04543c237e..e2d7ddd8c5254 100644 --- a/src/ui/public/index_patterns/index.d.ts +++ b/src/ui/public/index_patterns/index.d.ts @@ -17,4 +17,9 @@ * under the License. */ -export { IndexPattern, StaticIndexPattern } from 'ui/index_patterns/_index_pattern'; +export { + IndexPattern, + StaticIndexPattern, + StaticIndexPatternField, +} from 'ui/index_patterns/_index_pattern'; +export { Field } from 'ui/index_patterns/_field'; diff --git a/src/ui/public/index_patterns/static_utils/__tests__/index.js b/src/ui/public/index_patterns/static_utils/__tests__/index.js index 4a81b35e96555..e825df5d294ca 100644 --- a/src/ui/public/index_patterns/static_utils/__tests__/index.js +++ b/src/ui/public/index_patterns/static_utils/__tests__/index.js @@ -20,26 +20,50 @@ import expect from 'expect.js'; import { isFilterable } from '../index'; +const mockField = { + name: 'foo', + scripted: false, + searchable: true, + type: 'string', +}; + describe('static utils', () => { describe('isFilterable', () => { - it('should be filterable', () => { - ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { - expect(isFilterable({ type })).to.be(true); + describe('types', () => { + it('should return true for filterable types', () => { + ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { + expect(isFilterable({ ...mockField, type })).to.be(true); + }); }); - }); - it('should not be filterable', () => { - [ - 'geo_point', - 'geo_shape', - 'attachment', - 'murmur3', - '_source', - 'unknown', - 'conflict', - ].forEach(type => { - expect(isFilterable({ type })).to.be(false); + it('should return false for filterable types if the field is not searchable', () => { + ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { + expect(isFilterable({ ...mockField, type, searchable: false })).to.be(false); + }); }); + + it('should return false for un-filterable types', () => { + [ + 'geo_point', + 'geo_shape', + 'attachment', + 'murmur3', + '_source', + 'unknown', + 'conflict', + ].forEach(type => { + expect(isFilterable({ ...mockField, type })).to.be(false); + }); + }); + }); + + + it('should return true for scripted fields', () => { + expect(isFilterable({ ...mockField, scripted: true, searchable: false })).to.be(true); + }); + + it('should return true for the _id field', () => { + expect(isFilterable({ ...mockField, name: '_id' })).to.be(true); }); }); }); diff --git a/src/ui/public/index_patterns/static_utils/index.d.ts b/src/ui/public/index_patterns/static_utils/index.d.ts index 6d387bb95882f..c3e02f2b20d79 100644 --- a/src/ui/public/index_patterns/static_utils/index.d.ts +++ b/src/ui/public/index_patterns/static_utils/index.d.ts @@ -17,13 +17,6 @@ * under the License. */ -import { StaticIndexPattern } from 'ui/index_patterns'; +import { Field } from 'ui/index_patterns'; -interface SavedObject { - attributes: { - fields: string; - title: string; - }; -} - -export function getFromLegacyIndexPattern(indexPatterns: any[]): StaticIndexPattern[]; +export function isFilterable(field: Field): boolean; diff --git a/src/ui/public/index_patterns/static_utils/index.js b/src/ui/public/index_patterns/static_utils/index.js index 2cf43c319b10a..2285858c40ccc 100644 --- a/src/ui/public/index_patterns/static_utils/index.js +++ b/src/ui/public/index_patterns/static_utils/index.js @@ -22,7 +22,7 @@ import { KBN_FIELD_TYPES } from '../../../../utils/kbn_field_types'; const filterableTypes = KBN_FIELD_TYPES.filter(type => type.filterable).map(type => type.name); export function isFilterable(field) { - return filterableTypes.includes(field.type); + return field.name === '_id' || field.scripted || (field.searchable && filterableTypes.includes(field.type)); } export function getFromSavedObject(savedObject) { @@ -31,14 +31,8 @@ export function getFromSavedObject(savedObject) { } return { + id: savedObject.id, fields: JSON.parse(savedObject.attributes.fields), title: savedObject.attributes.title, }; } - -export function getFromLegacyIndexPattern(indexPatterns) { - return indexPatterns.map(indexPattern => ({ - fields: indexPattern.fields.raw, - title: indexPattern.title, - })); -} diff --git a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap index fb092e9f684c0..e3465e4b50c51 100644 --- a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap +++ b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap @@ -34,7 +34,6 @@ exports[`QueryBar Should disable autoFocus on EuiFieldText when disableAutoFocus role="form" >
({ }); const mockIndexPattern = { + id: '1234', title: 'logstash-*', - fields: { - raw: [ - { - name: 'response', - type: 'number', - aggregatable: true, - searchable: true, - }, - ], - }, + fields: [ + { + name: 'response', + type: 'number', + aggregatable: true, + filterable: true, + searchable: true, + }, + ], }; describe('QueryBar', () => { diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index af91fea37eb43..401950f8adf27 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -21,7 +21,6 @@ import { IndexPattern } from 'ui/index_patterns'; import { compact, debounce, isEqual } from 'lodash'; import React, { Component } from 'react'; -import { getFromLegacyIndexPattern } from 'ui/index_patterns/static_utils'; import { kfetch } from 'ui/kfetch'; import { PersistedLog } from 'ui/persisted_log'; import { Storage } from 'ui/storage'; @@ -74,6 +73,7 @@ interface Props { indexPatterns: IndexPattern[]; store: Storage; intl: InjectedIntl; + prepend?: any; } interface State { @@ -196,7 +196,7 @@ export class QueryBarUI extends Component { return recentSearchSuggestions; } - const indexPatterns = getFromLegacyIndexPattern(this.props.indexPatterns); + const indexPatterns = this.props.indexPatterns; const getAutocompleteSuggestions = autocompleteProvider({ config, indexPatterns }); const { selectionStart, selectionEnd } = this.inputRef; @@ -476,7 +476,7 @@ export class QueryBarUI extends Component { aria-controls="typeahead-items" >
-
+
{ this.state.isSuggestionsVisible ? 'suggestion-' + this.state.index : '' } role="textbox" + prepend={this.props.prepend} />
void; + onDisableAll: () => void; + onPinAll: () => void; + onUnpinAll: () => void; + onToggleAllNegated: () => void; + onToggleAllDisabled: () => void; + onRemoveAll: () => void; + intl: InjectedIntl; +} + +interface State { + isPopoverOpen: boolean; +} + +class FilterOptionsUI extends Component { + public state: State = { + isPopoverOpen: false, + }; + + public togglePopover = () => { + this.setState(prevState => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); + }; + + public closePopover = () => { + this.setState({ isPopoverOpen: false }); + }; + + public render() { + const panelTree = { + id: 0, + items: [ + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.enableAllFiltersButtonLabel', + defaultMessage: 'Enable all', + }), + icon: 'eye', + onClick: () => { + this.closePopover(); + this.props.onEnableAll(); + }, + 'data-test-subj': 'enableAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.disableAllFiltersButtonLabel', + defaultMessage: 'Disable all', + }), + icon: 'eyeClosed', + onClick: () => { + this.closePopover(); + this.props.onDisableAll(); + }, + 'data-test-subj': 'disableAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.pinAllFiltersButtonLabel', + defaultMessage: 'Pin all', + }), + icon: 'pin', + onClick: () => { + this.closePopover(); + this.props.onPinAll(); + }, + 'data-test-subj': 'pinAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.unpinAllFiltersButtonLabel', + defaultMessage: 'Unpin all', + }), + icon: 'pin', + onClick: () => { + this.closePopover(); + this.props.onUnpinAll(); + }, + 'data-test-subj': 'unpinAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.invertNegatedFiltersButtonLabel', + defaultMessage: 'Invert inclusion', + }), + icon: 'invert', + onClick: () => { + this.closePopover(); + this.props.onToggleAllNegated(); + }, + 'data-test-subj': 'invertInclusionAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.invertDisabledFiltersButtonLabel', + defaultMessage: 'Invert enabled/disabled', + }), + icon: 'eye', + onClick: () => { + this.closePopover(); + this.props.onToggleAllDisabled(); + }, + 'data-test-subj': 'invertEnableDisableAllFilters', + }, + { + name: this.props.intl.formatMessage({ + id: 'common.ui.searchBar.deleteAllFiltersButtonLabel', + defaultMessage: 'Remove all', + }), + icon: 'trash', + onClick: () => { + this.closePopover(); + this.props.onRemoveAll(); + }, + 'data-test-subj': 'removeAllFilters', + }, + ], + }; + + return ( + + } + anchorPosition="rightUp" + panelPaddingSize="none" + withTitle + > + + + + + + ); + } +} + +export const FilterOptions = injectI18n(FilterOptionsUI); diff --git a/src/ui/public/filter_editor/index.js b/src/ui/public/search_bar/components/index.tsx similarity index 95% rename from src/ui/public/filter_editor/index.js rename to src/ui/public/search_bar/components/index.tsx index dc613de885ee7..131c6059934a4 100644 --- a/src/ui/public/filter_editor/index.js +++ b/src/ui/public/search_bar/components/index.tsx @@ -17,4 +17,4 @@ * under the License. */ -import './filter_editor'; +export { SearchBar } from './search_bar'; diff --git a/src/ui/public/search_bar/components/search_bar.tsx b/src/ui/public/search_bar/components/search_bar.tsx new file mode 100644 index 0000000000000..ac7d5399e7144 --- /dev/null +++ b/src/ui/public/search_bar/components/search_bar.tsx @@ -0,0 +1,178 @@ +/* + * 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. + */ + +// @ts-ignore +import { EuiFilterButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { Filter } from '@kbn/es-query'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import classNames from 'classnames'; +import React, { Component } from 'react'; +import ResizeObserver from 'resize-observer-polyfill'; +import { FilterBar } from 'ui/filter_bar'; +import { IndexPattern } from 'ui/index_patterns'; +import { QueryBar } from 'ui/query_bar'; +import { Storage } from 'ui/storage'; + +interface Props { + query: { + query: string; + language: string; + }; + onQuerySubmit: (query: { query: string | object; language: string }) => void; + disableAutoFocus?: boolean; + appName: string; + indexPatterns: IndexPattern[]; + store: Storage; + filters: Filter[]; + onFiltersUpdated: (filters: Filter[]) => void; + showQueryBar: boolean; + showFilterBar: boolean; + intl: InjectedIntl; +} + +interface State { + isFiltersVisible: boolean; +} + +class SearchBarUI extends Component { + public static defaultProps = { + showQueryBar: true, + showFilterBar: true, + }; + + public filterBarRef: Element | null = null; + public filterBarWrapperRef: Element | null = null; + + public state = { + isFiltersVisible: true, + }; + + public setFilterBarHeight = () => { + requestAnimationFrame(() => { + const height = + this.filterBarRef && this.state.isFiltersVisible ? this.filterBarRef.clientHeight : 0; + if (this.filterBarWrapperRef) { + this.filterBarWrapperRef.setAttribute('style', `height: ${height}px`); + } + }); + }; + + // member-ordering rules conflict with use-before-declaration rules + /* tslint:disable */ + public ro = new ResizeObserver(this.setFilterBarHeight); + /* tslint:enable */ + + public toggleFiltersVisible = () => { + this.setState({ + isFiltersVisible: !this.state.isFiltersVisible, + }); + }; + + public componentDidMount() { + if (this.filterBarRef) { + this.setFilterBarHeight(); + this.ro.observe(this.filterBarRef); + } + } + + public componentDidUpdate() { + if (this.filterBarRef) { + this.setFilterBarHeight(); + this.ro.unobserve(this.filterBarRef); + } + } + + public render() { + const filtersAppliedText = this.props.intl.formatMessage({ + id: 'common.ui.searchBar.filtersButtonFiltersAppliedTitle', + defaultMessage: 'filters applied.', + }); + const clickToShowOrHideText = this.state.isFiltersVisible + ? this.props.intl.formatMessage({ + id: 'common.ui.searchBar.filtersButtonClickToShowTitle', + defaultMessage: 'Select to hide', + }) + : this.props.intl.formatMessage({ + id: 'common.ui.searchBar.filtersButtonClickToHideTitle', + defaultMessage: 'Select to show', + }); + + const filterTriggerButton = ( + 0 ? this.props.filters.length : null} + aria-controls="GlobalFilterGroup" + aria-expanded={!!this.state.isFiltersVisible} + title={`${this.props.filters.length} ${filtersAppliedText} ${clickToShowOrHideText}`} + > + Filters + + ); + + const classes = classNames('globalFilterGroup__wrapper', { + 'globalFilterGroup__wrapper-isVisible': this.state.isFiltersVisible, + }); + + return ( +
+ {this.props.showQueryBar ? ( + + ) : ( + '' + )} + + {this.props.showFilterBar ? ( +
{ + this.filterBarWrapperRef = node; + }} + className={classes} + > +
{ + this.filterBarRef = node; + }} + > + +
+
+ ) : ( + '' + )} +
+ ); + } +} + +export const SearchBar = injectI18n(SearchBarUI); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_range_editor.js b/src/ui/public/search_bar/directive/index.js similarity index 69% rename from src/ui/public/filter_editor/params_editor/filter_params_range_editor.js rename to src/ui/public/search_bar/directive/index.js index 8bab49a1bbe0a..f03624dd189a2 100644 --- a/src/ui/public/filter_editor/params_editor/filter_params_range_editor.js +++ b/src/ui/public/search_bar/directive/index.js @@ -17,20 +17,20 @@ * under the License. */ +import 'ngreact'; import { uiModules } from '../../modules'; -import template from './filter_params_range_editor.html'; -import './filter_params_input_type'; -import '../../directives/documentation_href'; -import '../../directives/focus_on'; +import { SearchBar } from '../components'; +import { injectI18nProvider } from '@kbn/i18n/react'; -const module = uiModules.get('kibana'); -module.directive('filterParamsRangeEditor', function () { - return { - restrict: 'E', - template, - scope: { - field: '=', - params: '=' +const app = uiModules.get('app/kibana', ['react']); + +app.directive('searchBar', (reactDirective, localStorage) => { + return reactDirective( + injectI18nProvider(SearchBar), + undefined, + {}, + { + store: localStorage, } - }; + ); }); diff --git a/src/ui/public/search_bar/index.tsx b/src/ui/public/search_bar/index.tsx new file mode 100644 index 0000000000000..2469f62781f97 --- /dev/null +++ b/src/ui/public/search_bar/index.tsx @@ -0,0 +1,22 @@ +/* + * 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 './directive'; + +export { SearchBar } from './components'; diff --git a/src/ui/public/styles/bootstrap_dark.less b/src/ui/public/styles/bootstrap_dark.less index 51273dcc0e83b..0e1dd7b017825 100644 --- a/src/ui/public/styles/bootstrap_dark.less +++ b/src/ui/public/styles/bootstrap_dark.less @@ -4,5 +4,4 @@ @import "~ui/styles/bootstrap/bootstrap_dark"; // Components -- waiting on EUI conversion -@import "~ui/filter_bar/filter_bar"; @import "~ui/timepicker/timepicker"; diff --git a/src/ui/public/timefilter/get_time.ts b/src/ui/public/timefilter/get_time.ts index 4baff33e7e661..8dd3545c85a24 100644 --- a/src/ui/public/timefilter/get_time.ts +++ b/src/ui/public/timefilter/get_time.ts @@ -18,8 +18,7 @@ */ import dateMath from '@elastic/datemath'; -import { find } from 'lodash'; -import { IndexPattern } from 'ui/index_patterns'; +import { Field, IndexPattern } from 'ui/index_patterns'; interface CalculateBoundsOptions { forceNow?: Date; @@ -58,8 +57,9 @@ export function getTime( } let filter: Filter; - const timefield: { name: string } | undefined = - indexPattern.timeFieldName && find(indexPattern.fields, { name: indexPattern.timeFieldName }); + const timefield: Field | undefined = indexPattern.fields.find( + field => field.name === indexPattern.timeFieldName + ); if (!timefield) { return; diff --git a/src/ui/public/value_suggestions/index.ts b/src/ui/public/value_suggestions/index.ts new file mode 100644 index 0000000000000..87ff473eaeece --- /dev/null +++ b/src/ui/public/value_suggestions/index.ts @@ -0,0 +1,24 @@ +/* + * 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 chrome from 'ui/chrome'; +import { kfetch } from 'ui/kfetch'; +import { getSuggestionsProvider } from './value_suggestions'; + +export const getSuggestions = getSuggestionsProvider(chrome.getUiSettingsClient(), kfetch); diff --git a/src/ui/public/value_suggestions/value_suggestions.test.ts b/src/ui/public/value_suggestions/value_suggestions.test.ts new file mode 100644 index 0000000000000..e918a8669bfe7 --- /dev/null +++ b/src/ui/public/value_suggestions/value_suggestions.test.ts @@ -0,0 +1,131 @@ +/* + * 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 { mockFields, mockIndexPattern } from 'ui/index_patterns/fixtures'; +import { getSuggestionsProvider } from './value_suggestions'; + +describe('getSuggestions', () => { + let getSuggestions: any; + let fetch: any; + + describe('with value suggestions disabled', () => { + beforeEach(() => { + const config = { get: () => false }; + fetch = jest.fn(); + getSuggestions = getSuggestionsProvider(config, fetch); + }); + + it('should return an empty array', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields; + const query = ''; + const suggestions = await getSuggestions(index, field, query); + expect(suggestions).toEqual([]); + expect(fetch).not.toHaveBeenCalled(); + }); + }); + + describe('with value suggestions enabled', () => { + beforeEach(() => { + const config = { get: () => true }; + fetch = jest.fn(); + getSuggestions = getSuggestionsProvider(config, fetch); + }); + + it('should return true/false for boolean fields', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter(({ type }) => type === 'boolean'); + const query = ''; + const suggestions = await getSuggestions(index, field, query); + expect(suggestions).toEqual([true, false]); + expect(fetch).not.toHaveBeenCalled(); + }); + + it('should return an empty array if the field type is not a string or boolean', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter(({ type }) => type !== 'string' && type !== 'boolean'); + const query = ''; + const suggestions = await getSuggestions(index, field, query); + expect(suggestions).toEqual([]); + expect(fetch).not.toHaveBeenCalled(); + }); + + it('should return an empty array if the field is not aggregatable', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter(({ aggregatable }) => !aggregatable); + const query = ''; + const suggestions = await getSuggestions(index, field, query); + expect(suggestions).toEqual([]); + expect(fetch).not.toHaveBeenCalled(); + }); + + it('should otherwise request suggestions', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter( + ({ type, aggregatable }) => type === 'string' && aggregatable + ); + const query = ''; + await getSuggestions(index, field, query); + expect(fetch).toHaveBeenCalled(); + }); + + it('should cache results if using the same index/field/query/filter', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter( + ({ type, aggregatable }) => type === 'string' && aggregatable + ); + const query = ''; + await getSuggestions(index, field, query); + await getSuggestions(index, field, query); + expect(fetch).toHaveBeenCalledTimes(1); + }); + + it('should cache results for only one minute', async () => { + const index = mockIndexPattern.id; + const [field] = mockFields.filter( + ({ type, aggregatable }) => type === 'string' && aggregatable + ); + const query = ''; + + const { now } = Date; + Date.now = jest.fn(() => 0); + await getSuggestions(index, field, query); + Date.now = jest.fn(() => 60 * 1000); + await getSuggestions(index, field, query); + Date.now = now; + + expect(fetch).toHaveBeenCalledTimes(2); + }); + + it('should not cache results if using a different index/field/query', async () => { + const fields = mockFields.filter( + ({ type, aggregatable }) => type === 'string' && aggregatable + ); + await getSuggestions('index', fields[0], ''); + await getSuggestions('index', fields[0], 'query'); + await getSuggestions('index', fields[1], ''); + await getSuggestions('index', fields[1], 'query'); + await getSuggestions('logstash-*', fields[0], ''); + await getSuggestions('logstash-*', fields[0], 'query'); + await getSuggestions('logstash-*', fields[1], ''); + await getSuggestions('logstash-*', fields[1], 'query'); + expect(fetch).toHaveBeenCalledTimes(8); + }); + }); +}); diff --git a/src/ui/public/value_suggestions/value_suggestions.ts b/src/ui/public/value_suggestions/value_suggestions.ts new file mode 100644 index 0000000000000..31e42e9945ede --- /dev/null +++ b/src/ui/public/value_suggestions/value_suggestions.ts @@ -0,0 +1,53 @@ +/* + * 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 { memoize } from 'lodash'; +import { Field } from 'ui/index_patterns'; + +export function getSuggestionsProvider( + config: { get: (key: string) => any }, + fetch: (...options: any[]) => any +) { + const requestSuggestions = memoize( + (index: string, field: Field, query: string, boolFilter: any = []) => { + return fetch({ + pathname: `/api/kibana/suggestions/values/${index}`, + method: 'POST', + body: JSON.stringify({ query, field: field.name, boolFilter }), + }); + }, + resolver + ); + + return async (index: string, field: Field, query: string, boolFilter?: any) => { + const shouldSuggestValues = config.get('filterEditor:suggestValues'); + if (field.type === 'boolean') { + return [true, false]; + } else if (!shouldSuggestValues || !field.aggregatable || field.type !== 'string') { + return []; + } + return await requestSuggestions(index, field, query, boolFilter); + }; +} + +function resolver(index: string, field: Field, query: string, boolFilter: any) { + // Only cache results for a minute + const ttl = Math.floor(Date.now() / 1000 / 60); + return [ttl, query, index, field.name, JSON.stringify(boolFilter)].join('|'); +} diff --git a/src/ui/public/vis/editors/config/editor_config_providers.test.ts b/src/ui/public/vis/editors/config/editor_config_providers.test.ts index 3ba4c78b0abb5..94eb453ff54ed 100644 --- a/src/ui/public/vis/editors/config/editor_config_providers.test.ts +++ b/src/ui/public/vis/editors/config/editor_config_providers.test.ts @@ -22,6 +22,19 @@ import { EditorParamConfig, FixedParam, NumericIntervalParam, TimeIntervalParam describe('EditorConfigProvider', () => { let registry: EditorConfigProviderRegistry; + const indexPattern = { + id: '1234', + title: 'logstash-*', + fields: [ + { + name: 'response', + type: 'number', + aggregatable: true, + filterable: true, + searchable: true, + }, + ], + }; beforeEach(() => { registry = new EditorConfigProviderRegistry(); @@ -32,7 +45,6 @@ describe('EditorConfigProvider', () => { registry.register(provider); expect(provider).not.toHaveBeenCalled(); const aggType = {}; - const indexPattern = {}; const aggConfig = {}; registry.getConfigForAgg(aggType, indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); @@ -46,7 +58,6 @@ describe('EditorConfigProvider', () => { expect(provider).not.toHaveBeenCalled(); expect(provider2).not.toHaveBeenCalled(); const aggType = {}; - const indexPattern = {}; const aggConfig = {}; registry.getConfigForAgg(aggType, indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); @@ -59,7 +70,7 @@ describe('EditorConfigProvider', () => { } function getOutputConfig(reg: EditorConfigProviderRegistry) { - return reg.getConfigForAgg({}, {}, {}).singleParam; + return reg.getConfigForAgg({}, indexPattern, {}).singleParam; } it('should have hidden true if at least one config was hidden true', () => { diff --git a/test/functional/apps/dashboard/_dashboard_filter_bar.js b/test/functional/apps/dashboard/_dashboard_filter_bar.js index bd074d896329d..a393a949377e1 100644 --- a/test/functional/apps/dashboard/_dashboard_filter_bar.js +++ b/test/functional/apps/dashboard/_dashboard_filter_bar.js @@ -58,7 +58,7 @@ export default function ({ getService, getPageObjects }) { it('uses default index pattern on an empty dashboard', async () => { await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']); + await dashboardExpect.fieldSuggestions(['bytes']); }); it('shows index pattern of vis when one is added', async () => { @@ -66,7 +66,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); await filterBar.ensureFieldEditorModalIsClosed(); await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']); + await dashboardExpect.fieldSuggestions(['animal']); }); it('works when a vis with no index pattern is added', async () => { @@ -74,7 +74,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); await filterBar.ensureFieldEditorModalIsClosed(); await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']); + await dashboardExpect.fieldSuggestions(['animal']); }); }); @@ -86,16 +86,16 @@ export default function ({ getService, getPageObjects }) { }); it('are not selected by default', async function () { - const filters = await PageObjects.dashboard.getFilters(1000); - expect(filters.length).to.equal(0); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.equal(0); }); it('are added when a pie chart slice is clicked', async function () { await dashboardAddPanel.addVisualization('Rendering Test: pie'); await PageObjects.dashboard.waitForRenderComplete(); await pieChart.filterOnPieSlice('4,886'); - const filters = await PageObjects.dashboard.getFilters(); - expect(filters.length).to.equal(1); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.equal(1); await pieChart.expectPieSliceCount(1); }); @@ -104,8 +104,8 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.saveDashboard('with filters'); await PageObjects.header.waitUntilLoadingHasFinished(); - const filters = await PageObjects.dashboard.getFilters(); - expect(filters.length).to.equal(1); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.equal(1); await pieChart.expectPieSliceCount(1); }); @@ -115,8 +115,8 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.loadSavedDashboard('with filters'); await PageObjects.header.waitUntilLoadingHasFinished(); - const filters = await PageObjects.dashboard.getFilters(); - expect(filters.length).to.equal(1); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.equal(1); await pieChart.expectPieSliceCount(1); }); diff --git a/test/functional/apps/dashboard/_dashboard_filtering.js b/test/functional/apps/dashboard/_dashboard_filtering.js index a127f96f8bc7c..ebabc4c691cc0 100644 --- a/test/functional/apps/dashboard/_dashboard_filtering.js +++ b/test/functional/apps/dashboard/_dashboard_filtering.js @@ -172,7 +172,7 @@ export default function ({ getService, getPageObjects }) { describe('disabling a filter unfilters the data on', async () => { before(async () => { - await testSubjects.click('disableFilter-bytes'); + await filterBar.toggleFilterEnabled('bytes'); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.dashboard.waitForRenderComplete(); }); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index 64e2a2fdc952e..f5612be7a611f 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -413,7 +413,7 @@ export default function ({ getService, getPageObjects }) { it('should show the phrases if you re-open a phrases filter', async function () { await filterBar.clickEditFilter('extension.raw', 'jpg'); - const phrases = await filterBar.getFilterEditorPhrases(); + const phrases = await filterBar.getFilterEditorSelectedPhrases(); expect(phrases.length).to.be(1); expect(phrases[0]).to.be('jpg'); }); diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index fd20b35a74666..fa12727f21434 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -38,6 +38,7 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const inspector = getService('inspector'); const testSubjects = getService('testSubjects'); + const filterBar = getService('filterBar'); const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize', 'discover']); describe('scripted fields', () => { @@ -128,7 +129,7 @@ export default function ({ getService, getPageObjects }) { ['20', '23'], ['19', '21'], ['6', '20'], ['17', '20'], ['30', '20'], ['13', '19'], ['18', '18'], ['16', '17'], ['5', '16'], ['8', '16'], ['15', '14'], ['3', '13'], ['2', '12'], ['9', '10'], ['4', '9'] ]; - await PageObjects.discover.removeAllFilters(); + await filterBar.removeAllFilters(); await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); @@ -185,7 +186,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('27'); }); - await PageObjects.discover.removeAllFilters(); + await filterBar.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { @@ -247,7 +248,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('359'); }); - await PageObjects.discover.removeAllFilters(); + await filterBar.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { @@ -309,7 +310,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('1'); }); - await PageObjects.discover.removeAllFilters(); + await filterBar.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js index 988fd99c386c4..902f016f13ee8 100644 --- a/test/functional/page_objects/dashboard_page.js +++ b/test/functional/page_objects/dashboard_page.js @@ -530,10 +530,6 @@ export function DashboardPageProvider({ getService, getPageObjects }) { } } - async getFilters(timeout = defaultFindTimeout) { - return await find.allByCssSelector('.filter-bar .filter', timeout); - } - async getFilterDescriptions(timeout = defaultFindTimeout) { const filters = await find.allByCssSelector( '.filter-bar > .filter > .filter-description', diff --git a/test/functional/page_objects/discover_page.js b/test/functional/page_objects/discover_page.js index 48fdfe47d92fe..bc2bc7cd0d7f3 100644 --- a/test/functional/page_objects/discover_page.js +++ b/test/functional/page_objects/discover_page.js @@ -264,13 +264,6 @@ export function DiscoverPageProvider({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); } - async removeAllFilters() { - await testSubjects.click('showFilterActions'); - await testSubjects.click('removeAllFilters'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.common.waitUntilUrlIncludes('filters:!()'); - } - async removeHeaderColumn(name) { await testSubjects.moveMouseTo(`docTableHeader-${name}`); await testSubjects.click(`docTableRemoveHeader-${name}`); diff --git a/test/functional/services/dashboard/expectations.js b/test/functional/services/dashboard/expectations.js index 2f5fe2d7a7958..72b3bbf7e8847 100644 --- a/test/functional/services/dashboard/expectations.js +++ b/test/functional/services/dashboard/expectations.js @@ -61,10 +61,12 @@ export function DashboardExpectProvider({ getService, getPageObjects }) { }); } - async fieldSuggestionIndexPatterns(expectedIndexPatterns) { - log.debug(`DashboardExpect.fieldSuggestionIndexPatterns(${expectedIndexPatterns})`); - const indexPatterns = await filterBar.getFilterFieldIndexPatterns(); - expect(indexPatterns).to.eql(expectedIndexPatterns); + async fieldSuggestions(expectedFields) { + log.debug(`DashboardExpect.fieldSuggestions(${expectedFields})`); + const fields = await filterBar.getFilterEditorFields(); + expectedFields.forEach(expectedField => { + expect(fields).to.contain(expectedField); + }); } async legendValuesToExist(legendValues) { diff --git a/test/functional/services/filter_bar.js b/test/functional/services/filter_bar.js index 18f0917814726..413e46becaa0c 100644 --- a/test/functional/services/filter_bar.js +++ b/test/functional/services/filter_bar.js @@ -18,19 +18,10 @@ */ export function FilterBarProvider({ getService, getPageObjects }) { - const browser = getService('browser'); const testSubjects = getService('testSubjects'); - const find = getService('find'); + const comboBox = getService('comboBox'); const PageObjects = getPageObjects(['common', 'header']); - async function typeIntoReactSelect(testSubj, value) { - const select = await testSubjects.find(testSubj); - const input = await select.findByClassName('ui-select-search'); - await input.type(value); - const activeSelection = await select.findByClassName('active'); - await activeSelection.click(); - } - class FilterBar { hasFilter(key, value, enabled = true) { const filterActivationState = enabled ? 'enabled' : 'disabled'; @@ -40,23 +31,33 @@ export function FilterBarProvider({ getService, getPageObjects }) { } async removeFilter(key) { - const filterElement = await testSubjects.find(`filter & filter-key-${key}`); - await browser.moveMouseTo(filterElement); - await testSubjects.click(`filter & filter-key-${key} removeFilter-${key}`); + await testSubjects.click(`filter & filter-key-${key}`); + await testSubjects.click(`deleteFilter`); await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); } + async removeAllFilters() { + await testSubjects.click('showFilterActions'); + await testSubjects.click('removeAllFilters'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.waitUntilUrlIncludes('filters:!()'); + } + async toggleFilterEnabled(key) { - const filterElement = await testSubjects.find(`filter & filter-key-${key}`); - await browser.moveMouseTo(filterElement); - await testSubjects.click(`filter & filter-key-${key} disableFilter-${key}`); + await testSubjects.click(`filter & filter-key-${key}`); + await testSubjects.click(`disableFilter`); await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); } async toggleFilterPinned(key) { - const filterElement = await testSubjects.find(`filter & filter-key-${key}`); - await browser.moveMouseTo(filterElement); - await testSubjects.click(`filter & filter-key-${key} pinFilter-${key}`); + await testSubjects.click(`filter & filter-key-${key}`); + await testSubjects.click(`pinFilter`); + await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); + } + + async getFilterCount() { + const filters = await testSubjects.findAll('filter'); + return filters.length; } /** @@ -79,18 +80,26 @@ export function FilterBarProvider({ getService, getPageObjects }) { */ async addFilter(field, operator, ...values) { await testSubjects.click('addFilter'); - await typeIntoReactSelect('filterfieldSuggestionList', field); - await typeIntoReactSelect('filterOperatorList', operator); + await comboBox.set('filterFieldSuggestionList', field); + await comboBox.set('filterOperatorList', operator); const params = await testSubjects.find('filterParams'); + const paramsComboBoxes = await params.findAllByCssSelector('[data-test-subj~="filterParamsComboBox"]'); const paramFields = await params.findAllByTagName('input'); for (let i = 0; i < values.length; i++) { let fieldValues = values[i]; if (!Array.isArray(fieldValues)) { fieldValues = [fieldValues]; } - for (let j = 0; j < fieldValues.length; j++) { - await paramFields[i].type(fieldValues[j]); - await paramFields[i].pressKeys(browser.keys.RETURN); + + if (paramsComboBoxes && paramsComboBoxes.length > 0) { + for (let j = 0; j < fieldValues.length; j++) { + await comboBox.setElement(paramsComboBoxes[i], fieldValues[j]); + } + } + else if (paramFields && paramFields.length > 0) { + for (let j = 0; j < fieldValues.length; j++) { + await paramFields[i].type(fieldValues[j]); + } } } await testSubjects.click('saveFilter'); @@ -98,30 +107,25 @@ export function FilterBarProvider({ getService, getPageObjects }) { } async clickEditFilter(key, value) { - const pill = await testSubjects.find(`filter & filter-key-${key} & filter-value-${value}`); - await browser.moveMouseTo(pill); - await testSubjects.click('editFilter'); + await testSubjects.click(`filter & filter-key-${key} & filter-value-${value}`); + await testSubjects.click(`editFilter`); + await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); } - async getFilterEditorPhrases() { - const spans = await testSubjects.findAll('filterEditorPhrases'); - return await Promise.all(spans.map(el => el.getVisibleText())); + async getFilterEditorSelectedPhrases() { + return await comboBox.getComboBoxSelectedOptions('filterParamsComboBox'); } - async ensureFieldEditorModalIsClosed() { - const closeFilterEditorModalButtonExists = await testSubjects.exists('filterEditorModalCloseButton'); - if (closeFilterEditorModalButtonExists) { - await testSubjects.click('filterEditorModalCloseButton'); - } + async getFilterEditorFields() { + const optionsString = await comboBox.getOptionsList('filterFieldSuggestionList'); + return optionsString.split('\n'); } - async getFilterFieldIndexPatterns() { - const indexPatterns = []; - const groups = await find.allByCssSelector('.ui-select-choices-group-label'); - for (let i = 0; i < groups.length; i++) { - indexPatterns.push(await groups[i].getVisibleText()); + async ensureFieldEditorModalIsClosed() { + const cancelSaveFilterModalButtonExists = await testSubjects.exists('cancelSaveFilter'); + if (cancelSaveFilterModalButtonExists) { + await testSubjects.click('cancelSaveFilter'); } - return indexPatterns; } } diff --git a/x-pack/plugins/beats_management/types/kibana.d.ts b/x-pack/plugins/beats_management/types/kibana.d.ts index e95dc0df93bea..07a5985f55a13 100644 --- a/x-pack/plugins/beats_management/types/kibana.d.ts +++ b/x-pack/plugins/beats_management/types/kibana.d.ts @@ -4,22 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -declare module 'ui/index_patterns' { - export type IndexPattern = any; - - export interface StaticIndexPatternField { - name: string; - type: string; - aggregatable: boolean; - searchable: boolean; - } - - export interface StaticIndexPattern { - fields: StaticIndexPatternField[]; - title: string; - } -} - declare module 'ui/autocomplete_providers' { import { StaticIndexPattern } from 'ui/index_patterns'; diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js index 04cbce3281eb3..e7120ca428acb 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js @@ -21,101 +21,78 @@ describe('Kuery value suggestions', function () { beforeEach(() => fetchMock.post(fetchUrlMatcher, mockValues)); afterEach(() => fetchMock.restore()); - describe('with config setting turned off', () => { - beforeEach(() => { - config = getConfigStub(false); - indexPatterns = [indexPatternResponse]; - getSuggestions = getSuggestionsProvider({ config, indexPatterns }); - }); - - it('should return a function', function () { - expect(typeof getSuggestions).to.be('function'); - }); - - it('should not make a request for suggestions', async () => { - const fieldName = 'machine.os.raw'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(fetchMock.called(fetchUrlMatcher)).to.be(false); - expect(suggestions).to.eql([]); - }); + beforeEach(() => { + config = getConfigStub(true); + indexPatterns = [indexPatternResponse]; + getSuggestions = getSuggestionsProvider({ config, indexPatterns }); }); - describe('with config setting turned on', () => { - beforeEach(() => { - config = getConfigStub(true); - indexPatterns = [indexPatternResponse]; - getSuggestions = getSuggestionsProvider({ config, indexPatterns }); - }); - - it('should return a function', function () { - expect(typeof getSuggestions).to.be('function'); - }); - - it('should return boolean suggestions for boolean fields', async () => { - const fieldName = 'ssl'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.map(({ text }) => text)).to.eql(['true ', 'false ']); - }); + it('should return a function', function () { + expect(typeof getSuggestions).to.be('function'); + }); - it('should filter boolean suggestions for boolean fields', async () => { - const fieldName = 'ssl'; - const prefix = 'fa'; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.map(({ text }) => text)).to.eql(['false ']); - }); + it('should return boolean suggestions for boolean fields', async () => { + const fieldName = 'ssl'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.map(({ text }) => text)).to.eql(['true ', 'false ']); + }); - it('should not make a request for non-aggregatable fields', async () => { - const fieldName = 'non-sortable'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(fetchMock.called(fetchUrlMatcher)).to.be(false); - expect(suggestions).to.eql([]); - }); + it('should filter boolean suggestions for boolean fields', async () => { + const fieldName = 'ssl'; + const prefix = 'fa'; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.map(({ text }) => text)).to.eql(['false ']); + }); - it('should not make a request for non-string fields', async () => { - const fieldName = 'bytes'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(fetchMock.called(fetchUrlMatcher)).to.be(false); - expect(suggestions).to.eql([]); - }); + it('should not make a request for non-aggregatable fields', async () => { + const fieldName = 'non-sortable'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(fetchMock.called(fetchUrlMatcher)).to.be(false); + expect(suggestions).to.eql([]); + }); - it('should make a request for string fields', async () => { - const fieldName = 'machine.os.raw'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + it('should not make a request for non-string fields', async () => { + const fieldName = 'bytes'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(fetchMock.called(fetchUrlMatcher)).to.be(false); + expect(suggestions).to.eql([]); + }); - const lastCall = fetchMock.lastCall(fetchUrlMatcher, 'POST'); - expect(lastCall[0]).to.eql('/api/kibana/suggestions/values/logstash-*'); - expect(lastCall[1]).to.eql({ - method: 'POST', - body: '{"query":"","field":"machine.os.raw"}', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - 'kbn-version': '1.2.3', - }, - }); - expect(suggestions.map(({ text }) => text)).to.eql(['"foo" ', '"bar" ']); + it('should make a request for string fields', async () => { + const fieldName = 'machine.os.raw'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + + const lastCall = fetchMock.lastCall(fetchUrlMatcher, 'POST'); + expect(lastCall[0]).to.eql('/api/kibana/suggestions/values/logstash-*'); + expect(lastCall[1]).to.eql({ + method: 'POST', + body: '{"query":"","field":"machine.os.raw","boolFilter":[]}', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + 'kbn-version': '1.2.3', + }, }); + expect(suggestions.map(({ text }) => text)).to.eql(['"foo" ', '"bar" ']); + }); - it('should not have descriptions', async () => { - const fieldName = 'ssl'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.length).to.be.greaterThan(0); - suggestions.forEach(suggestion => { - expect(suggestion.description).to.not.be.ok(); - }); + it('should not have descriptions', async () => { + const fieldName = 'ssl'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.length).to.be.greaterThan(0); + suggestions.forEach(suggestion => { + expect(suggestion.description).to.not.be.ok(); }); }); }); diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js index 762ab51324668..9ea853ab63271 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js @@ -23,11 +23,12 @@ function getDescription(fieldName) { } export function getSuggestionsProvider({ indexPatterns }) { - const allFields = flatten(indexPatterns.map(indexPattern => indexPattern.fields)); + const allFields = flatten(indexPatterns.map(indexPattern => { + return indexPattern.fields.filter(isFilterable); + })); return function getFieldSuggestions({ start, end, prefix, suffix }) { const search = `${prefix}${suffix}`.toLowerCase(); - const filterableFields = allFields.filter(isFilterable); - const fieldNames = filterableFields.map(field => field.name); + const fieldNames = allFields.map(field => field.name); const matchingFieldNames = fieldNames.filter(name => name.toLowerCase().includes(search)); const sortedFieldNames = sortPrefixFirst(matchingFieldNames.sort(keywordComparator), search); const suggestions = sortedFieldNames.map(fieldName => { diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js index 76139e4e76728..5ad41494d4216 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js @@ -96,7 +96,9 @@ function getDescription(operator) { } export function getSuggestionsProvider({ indexPatterns }) { - const allFields = flatten(indexPatterns.map(indexPattern => indexPattern.fields)); + const allFields = flatten(indexPatterns.map(indexPattern => { + return indexPattern.fields.slice(); + })); return function getOperatorSuggestions({ end, fieldName }) { const fields = allFields.filter(field => field.name === fieldName); return flatten(fields.map(field => { diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js index faea99c8f0f6a..36fb77a30acd0 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js @@ -4,21 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { flatten, memoize } from 'lodash'; +import { flatten } from 'lodash'; import { escapeQuotes } from './escape_kuery'; -import { kfetch } from 'ui/kfetch'; +import { getSuggestions } from 'ui/value_suggestions'; const type = 'value'; -const requestSuggestions = memoize((query, field, boolFilter) => { - return kfetch({ - pathname: `/api/kibana/suggestions/values/${field.indexPatternTitle}`, - method: 'POST', - body: JSON.stringify({ query, field: field.name, boolFilter }), - }); -}, resolver); - -export function getSuggestionsProvider({ config, indexPatterns, boolFilter }) { +export function getSuggestionsProvider({ indexPatterns, boolFilter }) { const allFields = flatten( indexPatterns.map(indexPattern => { return indexPattern.fields.map(field => ({ @@ -27,7 +19,6 @@ export function getSuggestionsProvider({ config, indexPatterns, boolFilter }) { })); }) ); - const shouldSuggestValues = config.get('filterEditor:suggestValues'); return function getValueSuggestions({ start, @@ -40,18 +31,8 @@ export function getSuggestionsProvider({ config, indexPatterns, boolFilter }) { const query = `${prefix}${suffix}`; const suggestionsByField = fields.map(field => { - if (field.type === 'boolean') { - return wrapAsSuggestions(start, end, query, ['true', 'false']); - } else if ( - !shouldSuggestValues || - !field.aggregatable || - field.type !== 'string' - ) { - return []; - } - - return requestSuggestions(query, field, boolFilter).then(data => { - const quotedValues = data.map(value => `"${escapeQuotes(value)}"`); + return getSuggestions(field.indexPatternTitle, field, query, boolFilter).then(data => { + const quotedValues = data.map(value => typeof value === 'string' ? `"${escapeQuotes(value)}"` : `${value}`); return wrapAsSuggestions(start, end, query, quotedValues); }); }); @@ -70,9 +51,3 @@ function wrapAsSuggestions(start, end, query, values) { return { type, text, start, end }; }); } - -function resolver(query, field, boolFilter) { - // Only cache results for a minute - const ttl = Math.floor(Date.now() / 1000 / 60); - return [ttl, query, field.indexPatternTitle, field.name, JSON.stringify(boolFilter)].join('|'); -} diff --git a/x-pack/plugins/ml/public/explorer/explorer.html b/x-pack/plugins/ml/public/explorer/explorer.html index 9fff39b76deeb..6ffd8816de30f 100644 --- a/x-pack/plugins/ml/public/explorer/explorer.html +++ b/x-pack/plugins/ml/public/explorer/explorer.html @@ -6,9 +6,11 @@ - + class-name="'globalFilterGroup__filterBar'" + filters="queryFilters" + on-filters-updated="updateFilters" + index-patterns="indexPatterns" + >
diff --git a/x-pack/plugins/ml/public/explorer/explorer_controller.js b/x-pack/plugins/ml/public/explorer/explorer_controller.js index dd3638f1727e6..32507fb10e1b1 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_controller.js +++ b/x-pack/plugins/ml/public/explorer/explorer_controller.js @@ -5,7 +5,6 @@ */ - /* * Angular controller for the Machine Learning Explorer dashboard. The controller makes * multiple queries to Elasticsearch to obtain the data to populate all the components @@ -49,13 +48,16 @@ uiRoutes CheckLicense: checkFullLicense, privileges: checkGetJobsPrivilege, indexPatterns: loadIndexPatterns, - } + }, }); import { uiModules } from 'ui/modules'; +import { getFromSavedObject } from 'ui/index_patterns/static_utils'; + const module = uiModules.get('apps/ml'); module.controller('MlExplorerController', function ( + $route, $injector, $scope, $timeout, @@ -75,6 +77,7 @@ module.controller('MlExplorerController', function ( // For the moment that's the job selector and the (hidden) filter bar. $scope.jobs = []; $scope.queryFilters = []; + $scope.indexPatterns = $route.current ? $route.current.locals.indexPatterns.map(getFromSavedObject) : []; timefilter.enableTimeRangeSelector(); timefilter.enableAutoRefreshSelector(); @@ -96,6 +99,11 @@ module.controller('MlExplorerController', function ( return job; }); + $scope.updateFilters = filters => { + // The filters will automatically be set when the queryFilter emits an update event (see below) + queryFilter.setFilters(filters); + }; + const selectedJobs = jobs.filter(job => job.selected); function fieldFormatServiceCallback() { @@ -108,7 +116,7 @@ module.controller('MlExplorerController', function ( loading: false, noJobsFound, selectedCells, - selectedJobs + selectedJobs, }); } @@ -157,7 +165,7 @@ module.controller('MlExplorerController', function ( fullJobs: resp.jobs, selectedCells, selectedJobIds, - swimlaneViewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName + swimlaneViewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName, }); } else { mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.RELOAD, { @@ -171,6 +179,7 @@ module.controller('MlExplorerController', function ( }); } } + mlExplorerDashboardService.explorer.watch(loadJobsListener); // Listen for changes to job selection. @@ -197,6 +206,7 @@ module.controller('MlExplorerController', function ( // Only redraw 100ms after last resize event. resizeTimeout = $timeout(redrawOnResize, 100); } + $(window).resize(jqueryRedrawOnResize); const navListener = $scope.$on('globalNav:update', () => { diff --git a/x-pack/plugins/ml/public/util/index_utils.js b/x-pack/plugins/ml/public/util/index_utils.js index 9e5353ab66851..582c1fae4f883 100644 --- a/x-pack/plugins/ml/public/util/index_utils.js +++ b/x-pack/plugins/ml/public/util/index_utils.js @@ -22,7 +22,7 @@ export function loadIndexPatterns(Private, indexPatterns) { const savedObjectsClient = Private(SavedObjectsClientProvider); return savedObjectsClient.find({ type: 'index-pattern', - fields: ['title', 'type'], + fields: ['id', 'title', 'type', 'fields'], perPage: 10000 }).then((response) => { indexPatternCache = response.savedObjects; diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index cb701ffb6f32b..b1739bdf4fb02 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }) { const dashboardAddPanel = getService('dashboardAddPanel'); const dashboardPanelActions = getService('dashboardPanelActions'); const appsMenu = getService('appsMenu'); + const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ 'security', 'common', @@ -140,8 +141,8 @@ export default function ({ getService, getPageObjects }) { it('can filter on a visualization', async () => { await PageObjects.dashboard.setTimepickerInHistoricalDataRange(); await pieChart.filterOnPieSlice(); - const filters = await PageObjects.dashboard.getFilters(); - expect(filters.length).to.equal(1); + const filterCount = await filterBar.getFilterCount(); + expect(filterCount).to.equal(1); }); it('does not show the edit menu item', async () => { From 1b0f595f01b3cff1d63a709d31df854c362e168d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Wed, 30 Jan 2019 15:53:03 -0500 Subject: [PATCH 13/40] Add new "references" attribute to saved objects for relationships (#28199) * Add new references attribute to saved objects * Add dual support for dashboard export API * Use new relationships API supporting legacy relationships extraction * Code cleanup * Fix style and CI error * Add missing spaces test for findRelationships * Convert collect_references_deep to typescript * Add missing trailing commas * Fix broken test by making saved object API consistently return references * Fix broken api integration tests * Add comment about the two TS types for saved object * Only return title from the attributes returned in findRelationships * Fix broken test * Add missing security tests * Drop filterTypes support * Implement references to search, dashboard, visualization, graph * Add index pattern migration to dashboards * Add references mapping to dashboard mppings.json * Remove findRelationships from repository and into it's own function / file * Apply PR feedback pt1 * Fix some failing tests * Remove error throwing in migrations * Add references to edit saved object screen * Pass types to findRelationships * [ftr] restore snapshots from master, rely on migrations to add references * [security] remove `find_relationships` action * remove data set modifications * [security/savedObjectsClient] remove _getAuthorizedTypes method * fix security & spaces tests to consider references and migrationVersion * Add space id prefixes to es_archiver/saved_objects/spaces/data.json * Rename referenced attributes to have a suffix of RefName * Fix length check in scenario references doesn't exist * Add test for inject references to not be called when references array is empty or missing * some code cleanup * Make migrations run on machine learning data files, fix rollup filterPath for savedSearchRefName * fix broken test * Fix collector.js to include references in elasticsearch response * code cleanup pt2 * add some more tests * fix broken tests * updated documentation on referencedBy option for saved object client find function * Move visualization migrations into kibana plugin * Update docs with better description on references * Apply PR feedback * Fix merge * fix tests I broke adressing PR feedback * PR feedback pt2 --- docs/api/saved-objects/bulk_create.asciidoc | 3 + docs/api/saved-objects/create.asciidoc | 2 + docs/api/saved-objects/find.asciidoc | 2 + docs/api/saved-objects/update.asciidoc | 2 + src/legacy/core_plugins/kibana/mappings.json | 2 +- src/legacy/core_plugins/kibana/migrations.js | 93 +- .../core_plugins/kibana/migrations.test.js | 883 +++++++++++++++++- .../saved_dashboard/saved_dashboard.js | 6 + .../saved_dashboard_references.js | 78 ++ .../saved_dashboard_references.test.js | 220 +++++ .../management/sections/objects/_view.js | 17 +- .../__jest__/relationships.test.js | 8 +- .../components/relationships/relationships.js | 40 +- .../objects/lib/resolve_saved_objects.js | 5 +- .../objects/lib/retrieve_and_export_docs.js | 1 + .../saved_visualizations/_saved_vis.js | 6 + .../saved_visualization_references.js | 51 + .../saved_visualization_references.test.js | 117 +++ .../server/lib/__tests__/relationships.js | 288 +++--- .../export/__tests__/collect_dashboards.js | 89 -- .../__tests__/collect_index_patterns.js | 106 --- .../lib/export/__tests__/collect_panels.js | 105 --- .../__tests__/collect_search_sources.js | 85 -- .../lib/export/__tests__/export_dashboards.js | 74 -- .../server/lib/export/collect_dashboards.js | 43 - .../lib/export/collect_index_patterns.js | 43 - .../server/lib/export/collect_panels.js | 43 - .../export/collect_references_deep.test.ts | 196 ++++ .../lib/export/collect_references_deep.ts | 55 ++ .../lib/export/collect_search_sources.js | 39 - .../server/lib/export/export_dashboards.js | 5 +- .../management/saved_objects/relationships.js | 191 +--- .../management/saved_objects/relationships.js | 22 +- .../api/management/saved_objects/scroll.js | 1 + .../build_active_mappings.test.ts.snap | 14 + .../migrations/core/build_active_mappings.ts | 14 + .../migrations/core/document_migrator.test.ts | 20 +- .../migrations/core/document_migrator.ts | 36 +- .../migrations/core/index_migrator.test.ts | 34 +- .../migrations/core/migrate_raw_docs.test.ts | 7 +- .../migrations/core/migrate_raw_docs.ts | 5 +- .../kibana_migrator.test.ts.snap | 14 + .../migrations/kibana/kibana_migrator.ts | 8 +- .../saved_objects/routes/bulk_create.js | 8 + .../saved_objects/routes/bulk_get.test.js | 3 +- src/server/saved_objects/routes/create.js | 12 +- .../saved_objects/routes/create.test.js | 7 +- src/server/saved_objects/routes/find.js | 5 + src/server/saved_objects/routes/find.test.js | 6 +- src/server/saved_objects/routes/get.test.js | 3 +- src/server/saved_objects/routes/update.js | 14 +- .../saved_objects/routes/update.test.js | 5 +- .../saved_objects/serialization/index.ts | 43 +- .../serialization/serialization.test.ts | 39 + .../saved_objects/service/lib/repository.js | 24 +- .../service/lib/repository.test.js | 188 +++- .../service/lib/search_dsl/query_params.js | 26 +- .../lib/search_dsl/query_params.test.js | 42 + .../service/lib/search_dsl/search_dsl.js | 3 +- .../service/lib/search_dsl/search_dsl.test.js | 7 +- .../service/saved_objects_client.d.ts | 11 +- .../service/saved_objects_client.js | 1 + .../saved_object/__tests__/saved_object.js | 93 ++ .../courier/saved_object/saved_object.js | 63 +- src/ui/public/saved_objects/saved_object.js | 15 +- .../saved_objects/saved_objects_client.js | 20 +- .../management/saved_objects/relationships.js | 31 +- .../apis/saved_objects/bulk_create.js | 9 +- .../apis/saved_objects/bulk_get.js | 13 +- .../apis/saved_objects/create.js | 12 +- .../apis/saved_objects/find.js | 3 +- .../api_integration/apis/saved_objects/get.js | 10 +- .../apis/saved_objects/migrations.js | 26 +- .../apis/saved_objects/update.js | 3 +- x-pack/plugins/graph/index.js | 4 +- x-pack/plugins/graph/migrations.js | 41 + x-pack/plugins/graph/migrations.test.js | 102 ++ .../graph/public/services/saved_workspace.js | 6 + .../services/saved_workspace_references.js | 53 ++ .../saved_workspace_references.test.js | 124 +++ ...ache2-Access-Remote-IP-Count-Explorer.json | 1 + .../ML-Apache2-Remote-IP-URL-Explorer.json | 1 + .../search/ML-Filebeat-Apache2-Access.json | 1 + .../visualization/ML-Apache2-Access-Map.json | 15 +- ...ML-Apache2-Access-Remote-IP-Timechart.json | 15 +- ...pache2-Access-Response-Code-Timechart.json | 15 +- ...L-Apache2-Access-Top-Remote-IPs-Table.json | 15 +- .../ML-Apache2-Access-Top-URLs-Table.json | 15 +- ...he2-Access-Unique-Count-URL-Timechart.json | 15 +- .../plugins/rollup/server/usage/collector.js | 11 +- .../spaces_saved_objects_client.ts | 1 + .../lib/space_request_interceptors.test.ts | 6 + .../saved_objects/spaces/data.json | 8 +- .../common/suites/bulk_create.ts | 2 + .../common/suites/bulk_get.ts | 9 + .../common/suites/create.ts | 2 + .../common/suites/find.ts | 2 + .../common/suites/get.ts | 8 + .../common/suites/update.ts | 2 + 99 files changed, 3122 insertions(+), 1170 deletions(-) create mode 100644 src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.js create mode 100644 src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.test.js create mode 100644 src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.js create mode 100644 src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_dashboards.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_index_patterns.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_panels.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_search_sources.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/__tests__/export_dashboards.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_dashboards.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_index_patterns.js delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_panels.js create mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts create mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.ts delete mode 100644 src/legacy/core_plugins/kibana/server/lib/export/collect_search_sources.js create mode 100644 x-pack/plugins/graph/migrations.js create mode 100644 x-pack/plugins/graph/migrations.test.js create mode 100644 x-pack/plugins/graph/public/services/saved_workspace_references.js create mode 100644 x-pack/plugins/graph/public/services/saved_workspace_references.test.js diff --git a/docs/api/saved-objects/bulk_create.asciidoc b/docs/api/saved-objects/bulk_create.asciidoc index 62b63674e6f81..1e749cb67c472 100644 --- a/docs/api/saved-objects/bulk_create.asciidoc +++ b/docs/api/saved-objects/bulk_create.asciidoc @@ -33,6 +33,9 @@ contains the following properties: `attributes` (required):: (object) The data to persist +`references` (optional):: + (array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export. + `version` (optional):: (number) Enables specifying a version diff --git a/docs/api/saved-objects/create.asciidoc b/docs/api/saved-objects/create.asciidoc index 7631dd296c2b3..c4a2cf260f7d9 100644 --- a/docs/api/saved-objects/create.asciidoc +++ b/docs/api/saved-objects/create.asciidoc @@ -33,6 +33,8 @@ Note: You cannot access this endpoint via the Console in Kibana. `attributes` (required):: (object) The data to persist +`references` (optional):: + (array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export. ==== Examples diff --git a/docs/api/saved-objects/find.asciidoc b/docs/api/saved-objects/find.asciidoc index 8a866c9de71d7..43fea5b5116c6 100644 --- a/docs/api/saved-objects/find.asciidoc +++ b/docs/api/saved-objects/find.asciidoc @@ -29,6 +29,8 @@ Note: You cannot access this endpoint via the Console in Kibana. (array|string) The fields to return in the response `sort_field` (optional):: (string) The field on which the response will be sorted +`has_reference` (optional):: + (object) Filters to objects having a relationship with the type and id combination [NOTE] ============================================== diff --git a/docs/api/saved-objects/update.asciidoc b/docs/api/saved-objects/update.asciidoc index 2c61f2e66b4b0..092128040d3eb 100644 --- a/docs/api/saved-objects/update.asciidoc +++ b/docs/api/saved-objects/update.asciidoc @@ -26,6 +26,8 @@ Note: You cannot access this endpoint via the Console in Kibana. `attributes` (required):: (object) The data to persist +`references` (optional):: + (array) An array of objects with `name`, `id`, and `type` properties that describe the other saved objects this object references. The `name` can be used in the attributes to refer to the other saved object, but never the `id`, which may be updated automatically in the future during migrations or import/export. ==== Examples diff --git a/src/legacy/core_plugins/kibana/mappings.json b/src/legacy/core_plugins/kibana/mappings.json index 155742b15c8a7..243d49c448c6d 100644 --- a/src/legacy/core_plugins/kibana/mappings.json +++ b/src/legacy/core_plugins/kibana/mappings.json @@ -42,7 +42,7 @@ } } }, - "savedSearchId": { + "savedSearchRefName": { "type": "keyword" }, "title": { diff --git a/src/legacy/core_plugins/kibana/migrations.js b/src/legacy/core_plugins/kibana/migrations.js index 8dee9566f0e8a..1d672936b389f 100644 --- a/src/legacy/core_plugins/kibana/migrations.js +++ b/src/legacy/core_plugins/kibana/migrations.js @@ -19,9 +19,53 @@ import { cloneDeep, get, omit } from 'lodash'; +function migrateIndexPattern(doc) { + const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); + if (typeof searchSourceJSON !== 'string') { + return; + } + let searchSource; + try { + searchSource = JSON.parse(searchSourceJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + return; + } + if (!searchSource.index) { + return; + } + doc.references.push({ + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: searchSource.index, + }); + searchSource.indexRefName = 'kibanaSavedObjectMeta.searchSourceJSON.index'; + delete searchSource.index; + doc.attributes.kibanaSavedObjectMeta.searchSourceJSON = JSON.stringify(searchSource); +} + export const migrations = { visualization: { '7.0.0': (doc) => { + // Set new "references" attribute + doc.references = doc.references || []; + + // Migrate index pattern + migrateIndexPattern(doc); + + // Migrate saved search + const savedSearchId = get(doc, 'attributes.savedSearchId'); + if (savedSearchId) { + doc.references.push({ + type: 'search', + name: 'search_0', + id: savedSearchId, + }); + doc.attributes.savedSearchRefName = 'search_0'; + delete doc.attributes.savedSearchId; + } + + // Migrate table splits try { const visState = JSON.parse(doc.attributes.visState); if (get(visState, 'type') !== 'table') { @@ -55,5 +99,52 @@ export const migrations = { throw new Error(`Failure attempting to migrate saved object '${doc.attributes.title}' - ${e}`); } } - } + }, + dashboard: { + '7.0.0': (doc) => { + // Set new "references" attribute + doc.references = doc.references || []; + // Migrate index pattern + migrateIndexPattern(doc); + // Migrate panels + const panelsJSON = get(doc, 'attributes.panelsJSON'); + if (typeof panelsJSON !== 'string') { + return doc; + } + let panels; + try { + panels = JSON.parse(panelsJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + return doc; + } + if (!Array.isArray(panels)) { + return doc; + } + panels.forEach((panel, i) => { + if (!panel.type || !panel.id) { + return; + } + panel.panelRefName = `panel_${i}`; + doc.references.push({ + name: `panel_${i}`, + type: panel.type, + id: panel.id, + }); + delete panel.type; + delete panel.id; + }); + doc.attributes.panelsJSON = JSON.stringify(panels); + return doc; + }, + }, + search: { + '7.0.0': (doc) => { + // Set new "references" attribute + doc.references = doc.references || []; + // Migrate index pattern + migrateIndexPattern(doc); + return doc; + }, + }, }; diff --git a/src/legacy/core_plugins/kibana/migrations.test.js b/src/legacy/core_plugins/kibana/migrations.test.js index dc8ddb594af02..cafd141fc2f19 100644 --- a/src/legacy/core_plugins/kibana/migrations.test.js +++ b/src/legacy/core_plugins/kibana/migrations.test.js @@ -19,8 +19,7 @@ import { migrations } from './migrations'; -describe('table vis migrations', () => { - +describe('visualization', () => { describe('7.0.0', () => { const migrate = doc => migrations.visualization['7.0.0'](doc); const generateDoc = ({ type, aggs }) => ({ @@ -31,9 +30,296 @@ describe('table vis migrations', () => { uiStateJSON: '{}', version: 1, kibanaSavedObjectMeta: { - searchSourceJSON: '{}' - } - } + searchSourceJSON: '{}', + }, + }, + }); + + it('does not throw error on empty object', () => { + const migratedDoc = migrate({ + attributes: { + visState: '{}', + }, + }); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "visState": "{}", + }, + "references": Array [], +} +`); + }); + + it('skips errors when searchSourceJSON is null', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: null, + }, + savedSearchId: '123', + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": null, + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('skips errors when searchSourceJSON is undefined', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: undefined, + }, + savedSearchId: '123', + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": undefined, + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('skips error when searchSourceJSON is not a string', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: 123, + }, + savedSearchId: '123', + }, + }; + expect(migrate(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": 123, + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('skips error when searchSourceJSON is invalid json', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: '{abc123}', + }, + savedSearchId: '123', + }, + }; + expect(migrate(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{abc123}", + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('skips error when "index" is missing from searchSourceJSON', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true }), + }, + savedSearchId: '123', + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true}", + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('extracts "index" attribute from doc', () => { + const doc = { + id: '1', + type: 'visualization', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true, index: 'pattern*' }), + }, + savedSearchId: '123', + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true,\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "pattern*", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern", + }, + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", +} +`); + }); + + it('skips extracting savedSearchId when missing', () => { + const doc = { + id: '1', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: '{}', + }, + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{}", + }, + "visState": "{}", + }, + "id": "1", + "references": Array [], +} +`); + }); + + it('extract savedSearchId from doc', () => { + const doc = { + id: '1', + attributes: { + visState: '{}', + kibanaSavedObjectMeta: { + searchSourceJSON: '{}', + }, + savedSearchId: '123', + }, + }; + const migratedDoc = migrate(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{}", + }, + "savedSearchRefName": "search_0", + "visState": "{}", + }, + "id": "1", + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], +} +`); }); it('should return a new object if vis is table and has multiple split aggs', () => { @@ -41,17 +327,17 @@ describe('table vis migrations', () => { { id: '1', schema: 'metric', - params: {} + params: {}, }, { id: '2', schema: 'split', - params: { foo: 'bar', row: true } + params: { foo: 'bar', row: true }, }, { id: '3', schema: 'split', - params: { hey: 'ya', row: false } + params: { hey: 'ya', row: false }, }, ]; const tableDoc = generateDoc({ type: 'table', aggs }); @@ -73,18 +359,18 @@ describe('table vis migrations', () => { { id: '1', schema: 'metric', - params: {} + params: {}, }, { id: '2', schema: 'split', - params: { foo: 'bar', row: true } + params: { foo: 'bar', row: true }, }, { id: '3', schema: 'segment', - params: { hey: 'ya' } - } + params: { hey: 'ya' }, + }, ]; const pieDoc = generateDoc({ type: 'pie', aggs }); const expected = pieDoc; @@ -97,13 +383,13 @@ describe('table vis migrations', () => { { id: '1', schema: 'metric', - params: {} + params: {}, }, { id: '2', schema: 'split', - params: { foo: 'bar', row: true } - } + params: { foo: 'bar', row: true }, + }, ]; const tableDoc = generateDoc({ type: 'table', aggs }); const expected = tableDoc; @@ -116,23 +402,23 @@ describe('table vis migrations', () => { { id: '1', schema: 'metric', - params: {} + params: {}, }, { id: '2', schema: 'split', - params: { foo: 'bar', row: true } + params: { foo: 'bar', row: true }, }, { id: '3', schema: 'split', - params: { hey: 'ya', row: false } + params: { hey: 'ya', row: false }, }, { id: '4', schema: 'bucket', - params: { heyyy: 'yaaa' } - } + params: { heyyy: 'yaaa' }, + }, ]; const expected = ['metric', 'split', 'bucket', 'bucket']; const migrated = migrate(generateDoc({ type: 'table', aggs })); @@ -145,18 +431,18 @@ describe('table vis migrations', () => { { id: '1', schema: 'metric', - params: {} + params: {}, }, { id: '2', schema: 'split', - params: { foo: 'bar', row: true } + params: { foo: 'bar', row: true }, }, { id: '3', schema: 'split', - params: { hey: 'ya', row: false } - } + params: { hey: 'ya', row: false }, + }, ]; const expected = [{}, { foo: 'bar', row: true }, { hey: 'ya' }]; const migrated = migrate(generateDoc({ type: 'table', aggs })); @@ -173,12 +459,555 @@ describe('table vis migrations', () => { uiStateJSON: '{}', version: 1, kibanaSavedObjectMeta: { - searchSourceJSON: '{}' - } - } + searchSourceJSON: '{}', + }, + }, }; expect(() => migrate(doc)).toThrowError(/My Vis/); }); }); +}); + +describe('dashboard', () => { + describe('7.0.0', () => { + const migration = migrations.dashboard['7.0.0']; + + test('skips error on empty object', () => { + expect(migration({})).toMatchInlineSnapshot(` +Object { + "references": Array [], +} +`); + }); + + test('skips errors when searchSourceJSON is null', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: null, + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": null, + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('skips errors when searchSourceJSON is undefined', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: undefined, + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": undefined, + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('skips error when searchSourceJSON is not a string', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: 123, + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": 123, + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('skips error when searchSourceJSON is invalid json', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: '{abc123}', + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{abc123}", + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('skips error when "index" is missing from searchSourceJSON', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true }), + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true}", + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('extracts "index" attribute from doc', () => { + const doc = { + id: '1', + type: 'dashboard', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true, index: 'pattern*' }), + }, + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true,\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", + }, + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "pattern*", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern", + }, + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", +} +`); + }); + + test('skips error when panelsJSON is not a string', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: 123, + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": 123, + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('skips error when panelsJSON is not valid JSON', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: '{123abc}', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": "{123abc}", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('skips panelsJSON when its not an array', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: '{}', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": "{}", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('skips error when a panel is missing "type" attribute', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: '[{"id":"123"}]', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": "[{\\"id\\":\\"123\\"}]", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('skips error when a panel is missing "id" attribute', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: '[{"type":"visualization"}]', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": "[{\\"type\\":\\"visualization\\"}]", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('extract panel references from doc', () => { + const doc = { + id: '1', + attributes: { + panelsJSON: + '[{"id":"1","type":"visualization","foo":true},{"id":"2","type":"visualization","bar":true}]', + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "panelsJSON": "[{\\"foo\\":true,\\"panelRefName\\":\\"panel_0\\"},{\\"bar\\":true,\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], +} +`); + }); + }); +}); + +describe('search', () => { + describe('7.0.0', () => { + const migration = migrations.search['7.0.0']; + test('skips errors when searchSourceJSON is null', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: null, + }, + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": null, + }, + }, + "id": "123", + "references": Array [], + "type": "search", +} +`); + }); + + test('skips errors when searchSourceJSON is undefined', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: undefined, + }, + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": undefined, + }, + }, + "id": "123", + "references": Array [], + "type": "search", +} +`); + }); + + test('skips error when searchSourceJSON is not a string', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: 123, + }, + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": 123, + }, + }, + "id": "123", + "references": Array [], + "type": "search", +} +`); + }); + + test('skips error when searchSourceJSON is invalid json', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: '{abc123}', + }, + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{abc123}", + }, + }, + "id": "123", + "references": Array [], + "type": "search", +} +`); + }); + + test('skips error when "index" is missing from searchSourceJSON', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true }), + }, + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true}", + }, + }, + "id": "123", + "references": Array [], + "type": "search", +} +`); + }); + + test('extracts "index" attribute from doc', () => { + const doc = { + id: '123', + type: 'search', + attributes: { + foo: true, + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ bar: true, index: 'pattern*' }), + }, + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"bar\\":true,\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", + }, + }, + "id": "123", + "references": Array [ + Object { + "id": "pattern*", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern", + }, + ], + "type": "search", +} +`); + }); + }); }); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js index 82cf20d9c25af..c3e4b2c668656 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.js @@ -22,6 +22,10 @@ import { uiModules } from 'ui/modules'; import { createDashboardEditUrl } from '../dashboard_constants'; import { createLegacyClass } from 'ui/utils/legacy_class'; import { SavedObjectProvider } from 'ui/courier'; +import { + extractReferences, + injectReferences, +} from './saved_dashboard_references'; const module = uiModules.get('app/dashboard'); @@ -37,6 +41,8 @@ module.factory('SavedDashboard', function (Private, config, i18n) { type: SavedDashboard.type, mapping: SavedDashboard.mapping, searchSource: SavedDashboard.searchsource, + extractReferences: extractReferences, + injectReferences: injectReferences, // if this is null/undefined then the SavedObject will be assigned the defaults id: id, diff --git a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.js b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.js new file mode 100644 index 0000000000000..724847337a26e --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.js @@ -0,0 +1,78 @@ +/* + * 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 function extractReferences({ attributes, references = [] }) { + const panelReferences = []; + const panels = JSON.parse(attributes.panelsJSON); + panels.forEach((panel, i) => { + if (!panel.type) { + throw new Error(`"type" attribute is missing from panel "${i}"`); + } + if (!panel.id) { + throw new Error(`"id" attribute is missing from panel "${i}"`); + } + panel.panelRefName = `panel_${i}`; + panelReferences.push({ + name: `panel_${i}`, + type: panel.type, + id: panel.id, + }); + delete panel.type; + delete panel.id; + }); + return { + references: [ + ...references, + ...panelReferences, + ], + attributes: { + ...attributes, + panelsJSON: JSON.stringify(panels), + }, + }; +} + +export function injectReferences(savedObject, references) { + // Skip if panelsJSON is missing otherwise this will cause saved object import to fail when + // importing objects without panelsJSON. At development time of this, there is no guarantee each saved + // object has panelsJSON in all previous versions of kibana. + if (typeof savedObject.panelsJSON !== 'string') { + return; + } + const panels = JSON.parse(savedObject.panelsJSON); + // Same here, prevent failing saved object import if ever panels aren't an array. + if (!Array.isArray(panels)) { + return; + } + panels.forEach((panel) => { + if (!panel.panelRefName) { + return; + } + const reference = references.find(reference => reference.name === panel.panelRefName); + if (!reference) { + // Throw an error since "panelRefName" means the reference exists within + // "references" and in this scenario we have bad data. + throw new Error(`Could not find reference "${panel.panelRefName}"`); + } + panel.id = reference.id; + panel.type = reference.type; + delete panel.panelRefName; + }); + savedObject.panelsJSON = JSON.stringify(panels); +} diff --git a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.test.js b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.test.js new file mode 100644 index 0000000000000..f32effd667846 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard_references.test.js @@ -0,0 +1,220 @@ +/* + * 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 { extractReferences, injectReferences } from './saved_dashboard_references'; + +describe('extractReferences', () => { + test('extracts references from panelsJSON', () => { + const doc = { + id: '1', + attributes: { + foo: true, + panelsJSON: JSON.stringify([ + { + type: 'visualization', + id: '1', + title: 'Title 1', + }, + { + type: 'visualization', + id: '2', + title: 'Title 2', + }, + ]), + }, + }; + const updatedDoc = extractReferences(doc); + /* eslint-disable max-len */ + expect(updatedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "panelsJSON": "[{\\"title\\":\\"Title 1\\",\\"panelRefName\\":\\"panel_0\\"},{\\"title\\":\\"Title 2\\",\\"panelRefName\\":\\"panel_1\\"}]", + }, + "references": Array [ + Object { + "id": "1", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "2", + "name": "panel_1", + "type": "visualization", + }, + ], +} +`); + /* eslint-enable max-len */ + }); + + test('fails when "type" attribute is missing from a panel', () => { + const doc = { + id: '1', + attributes: { + foo: true, + panelsJSON: JSON.stringify([ + { + id: '1', + title: 'Title 1', + }, + ]), + }, + }; + expect(() => extractReferences(doc)).toThrowErrorMatchingInlineSnapshot( + `"\\"type\\" attribute is missing from panel \\"0\\""` + ); + }); + + test('fails when "id" attribute is missing from a panel', () => { + const doc = { + id: '1', + attributes: { + foo: true, + panelsJSON: JSON.stringify([ + { + type: 'visualization', + title: 'Title 1', + }, + ]), + }, + }; + expect(() => extractReferences(doc)).toThrowErrorMatchingInlineSnapshot( + `"\\"id\\" attribute is missing from panel \\"0\\""` + ); + }); +}); + +describe('injectReferences', () => { + test('injects references into context', () => { + const context = { + id: '1', + foo: true, + panelsJSON: JSON.stringify([ + { + panelRefName: 'panel_0', + title: 'Title 1', + }, + { + panelRefName: 'panel_1', + title: 'Title 2', + }, + ]), + }; + const references = [ + { + name: 'panel_0', + type: 'visualization', + id: '1', + }, + { + name: 'panel_1', + type: 'visualization', + id: '2', + }, + ]; + injectReferences(context, references); + /* eslint-disable max-len */ + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", + "panelsJSON": "[{\\"title\\":\\"Title 1\\",\\"id\\":\\"1\\",\\"type\\":\\"visualization\\"},{\\"title\\":\\"Title 2\\",\\"id\\":\\"2\\",\\"type\\":\\"visualization\\"}]", +} +`); + /* eslint-enable max-len */ + }); + + test('skips when panelsJSON is missing', () => { + const context = { + id: '1', + foo: true, + }; + injectReferences(context, []); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", +} +`); + }); + + test('skips when panelsJSON is not an array', () => { + const context = { + id: '1', + foo: true, + panelsJSON: '{}', + }; + injectReferences(context, []); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", + "panelsJSON": "{}", +} +`); + }); + + test('skips a panel when panelRefName is missing', () => { + const context = { + id: '1', + foo: true, + panelsJSON: JSON.stringify([ + { + panelRefName: 'panel_0', + title: 'Title 1', + }, + { + title: 'Title 2', + }, + ]), + }; + const references = [ + { + name: 'panel_0', + type: 'visualization', + id: '1', + }, + ]; + injectReferences(context, references); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", + "panelsJSON": "[{\\"title\\":\\"Title 1\\",\\"id\\":\\"1\\",\\"type\\":\\"visualization\\"},{\\"title\\":\\"Title 2\\"}]", +} +`); + }); + + test(`fails when it can't find the reference in the array`, () => { + const context = { + id: '1', + foo: true, + panelsJSON: JSON.stringify([ + { + panelRefName: 'panel_0', + title: 'Title 1', + }, + ]), + }; + expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( + `"Could not find reference \\"panel_0\\""` + ); + }); +}); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js index 735d1f22daedf..6f513b46f18ec 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/_view.js @@ -125,6 +125,14 @@ uiModules.get('apps/management') value: '{}' }); } + + if (!fieldMap.references) { + fields.push({ + name: 'references', + type: 'array', + value: '[]', + }); + } }; $scope.notFound = $routeParams.notFound; @@ -136,7 +144,10 @@ uiModules.get('apps/management') $scope.obj = obj; $scope.link = service.urlFor(obj.id); - const fields = _.reduce(obj.attributes, createField, []); + const fields = _.reduce(obj.attributes, createField, []); + // Special handling for references which isn't within "attributes" + createField(fields, obj.references, 'references'); + if (service.Class) readObjectClass(fields, service.Class); // sorts twice since we want numerical sort to prioritize over name, @@ -234,7 +245,9 @@ uiModules.get('apps/management') _.set(source, field.name, value); }); - savedObjectsClient.update(service.type, $routeParams.id, source) + const { references, ...attributes } = source; + + savedObjectsClient.update(service.type, $routeParams.id, attributes, { references }) .then(function () { return redirectHandler('updated'); }) diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js index 9eb269ea46440..fabbfce0395e3 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/__jest__/relationships.test.js @@ -83,12 +83,12 @@ describe('Relationships', () => { it('should render searches normally', async () => { const props = { getRelationships: jest.fn().mockImplementation(() => ({ - indexPatterns: [ + 'index-pattern': [ { id: '1', } ], - visualizations: [ + visualization: [ { id: '2', } @@ -123,7 +123,7 @@ describe('Relationships', () => { it('should render visualizations normally', async () => { const props = { getRelationships: jest.fn().mockImplementation(() => ({ - dashboards: [ + dashboard: [ { id: '1', }, @@ -161,7 +161,7 @@ describe('Relationships', () => { it('should render dashboards normally', async () => { const props = { getRelationships: jest.fn().mockImplementation(() => ({ - visualizations: [ + visualization: [ { id: '1', }, diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js index c73f77d2687c9..b7491583edf61 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/components/objects_table/components/relationships/relationships.js @@ -148,7 +148,7 @@ class RelationshipsUI extends Component { />); break; case 'search': - if (type === 'visualizations') { + if (type === 'visualization') { calloutText = (); + if (type === 'index-pattern') { + calloutColor = 'success'; + calloutTitle = (); + calloutText = (); + } else if (type === 'search') { + calloutColor = 'success'; + calloutTitle = (); + calloutText = (); + } else { + calloutText = (); + } break; case 'index-pattern': - if (type === 'visualizations') { + if (type === 'visualization') { calloutText = (); - } else if (type === 'searches') { + } else if (type === 'search') { calloutText = ( reference.name === savedObject.savedSearchRefName); + if (!reference) { + throw new Error(`Could not find reference "${savedObject.savedSearchRefName}"`); + } + savedObject.savedSearchId = reference.id; + delete savedObject.savedSearchRefName; +} diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js new file mode 100644 index 0000000000000..be9375dc33e56 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/saved_visualization_references.test.js @@ -0,0 +1,117 @@ +/* + * 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 { extractReferences, injectReferences } from './saved_visualization_references'; + +describe('extractReferences', () => { + test('extracts nothing if savedSearchId is empty', () => { + const doc = { + id: '1', + attributes: { + foo: true, + }, + }; + const updatedDoc = extractReferences(doc); + expect(updatedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + }, + "references": Array [], +} +`); + }); + + test('extracts references from savedSearchId', () => { + const doc = { + id: '1', + attributes: { + foo: true, + savedSearchId: '123', + }, + }; + const updatedDoc = extractReferences(doc); + expect(updatedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "savedSearchId": undefined, + "savedSearchRefName": "search_0", + }, + "references": Array [ + Object { + "id": "123", + "name": "search_0", + "type": "search", + }, + ], +} +`); + }); +}); + +describe('injectReferences', () => { + test('injects nothing when savedSearchRefName is null', () => { + const context = { + id: '1', + foo: true, + }; + injectReferences(context, []); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", +} +`); + }); + + test('injects references into context', () => { + const context = { + id: '1', + foo: true, + savedSearchRefName: 'search_0', + }; + const references = [ + { + name: 'search_0', + type: 'search', + id: '123', + }, + ]; + injectReferences(context, references); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", + "savedSearchId": "123", +} +`); + }); + + test(`fails when it can't find the reference in the array`, () => { + const context = { + id: '1', + foo: true, + savedSearchRefName: 'search_0', + }; + expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( + `"Could not find reference \\"search_0\\""` + ); + }); +}); diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js index 1c5473fe5e311..42845b4cf0eb1 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js @@ -27,28 +27,44 @@ describe('findRelationships', () => { const size = 10; const savedObjectsClient = { - _index: '.kibana', get: () => ({ attributes: { - panelsJSON: JSON.stringify([{ id: '1' }, { id: '2' }, { id: '3' }]), + panelsJSON: JSON.stringify([{ panelRefName: 'panel_0' }, { panelRefName: 'panel_1' }, { panelRefName: 'panel_2' }]), }, + references: [{ + name: 'panel_0', + type: 'visualization', + id: '1', + }, { + name: 'panel_1', + type: 'visualization', + id: '2', + }, { + name: 'panel_2', + type: 'visualization', + id: '3', + }], }), - bulkGet: () => ({ + bulkGet: () => ({ saved_objects: [] }), + find: () => ({ saved_objects: [ { id: '1', + type: 'visualization', attributes: { title: 'Foo', }, }, { id: '2', + type: 'visualization', attributes: { title: 'Bar', }, }, { id: '3', + type: 'visualization', attributes: { title: 'FooBar', }, @@ -59,11 +75,14 @@ describe('findRelationships', () => { const result = await findRelationships( type, id, - size, - savedObjectsClient + { + size, + savedObjectsClient, + savedObjectTypes: ['dashboard', 'visualization', 'search', 'index-pattern'], + }, ); expect(result).to.eql({ - visualizations: [ + visualization: [ { id: '1', title: 'Foo' }, { id: '2', title: 'Bar' }, { id: '3', title: 'FooBar' }, @@ -77,11 +96,36 @@ describe('findRelationships', () => { const size = 10; const savedObjectsClient = { - get: () => {}, + get: () => ({ + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }), + }, + }, + references: [{ + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '1', + }], + }), + bulkGet: () => ({ + saved_objects: [ + { + id: '1', + type: 'index-pattern', + attributes: { + title: 'My Index Pattern', + }, + }, + ], + }), find: () => ({ saved_objects: [ { id: '1', + type: 'dashboard', attributes: { title: 'My Dashboard', panelsJSON: JSON.stringify([ @@ -98,6 +142,7 @@ describe('findRelationships', () => { }, { id: '2', + type: 'dashboard', attributes: { title: 'Your Dashboard', panelsJSON: JSON.stringify([ @@ -119,11 +164,17 @@ describe('findRelationships', () => { const result = await findRelationships( type, id, - size, - savedObjectsClient + { + size, + savedObjectsClient, + savedObjectTypes: ['dashboard', 'visualization', 'search', 'index-pattern'], + }, ); expect(result).to.eql({ - dashboards: [ + 'index-pattern': [ + { id: '1', title: 'My Index Pattern' }, + ], + dashboard: [ { id: '1', title: 'My Dashboard' }, { id: '2', title: 'Your Dashboard' }, ], @@ -136,43 +187,52 @@ describe('findRelationships', () => { const size = 10; const savedObjectsClient = { - get: type => { - if (type === 'search') { - return { + get: () => ({ + id: '1', + type: 'search', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }), + }, + }, + references: [{ + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '1', + }], + }), + bulkGet: () => ({ + saved_objects: [ + { id: '1', + type: 'index-pattern', attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'index-pattern:1', - }), - }, + title: 'My Index Pattern', }, - }; - } - - return { - id: 'index-pattern:1', - attributes: { - title: 'My Index Pattern', }, - }; - }, + ], + }), find: () => ({ saved_objects: [ { id: '1', + type: 'visualization', attributes: { title: 'Foo', }, }, { id: '2', + type: 'visualization', attributes: { title: 'Bar', }, }, { id: '3', + type: 'visualization', attributes: { title: 'FooBar', }, @@ -184,16 +244,19 @@ describe('findRelationships', () => { const result = await findRelationships( type, id, - size, - savedObjectsClient + { + size, + savedObjectsClient, + savedObjectTypes: ['dashboard', 'visualization', 'search', 'index-pattern'], + }, ); expect(result).to.eql({ - visualizations: [ + visualization: [ { id: '1', title: 'Foo' }, { id: '2', title: 'Bar' }, { id: '3', title: 'FooBar' }, ], - indexPatterns: [{ id: 'index-pattern:1', title: 'My Index Pattern' }], + 'index-pattern': [{ id: '1', title: 'My Index Pattern' }], }); }); @@ -203,106 +266,103 @@ describe('findRelationships', () => { const size = 10; const savedObjectsClient = { - get: () => {}, - find: options => { - if (options.type === 'visualization') { - return { - saved_objects: [ - { - id: '1', - found: true, - attributes: { - title: 'Foo', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo', - }), - }, - }, - }, - { - id: '2', - found: true, - attributes: { - title: 'Bar', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo', - }), - }, - }, - }, - { - id: '3', - found: true, - attributes: { - title: 'FooBar', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo2', - }), - }, - }, - }, - ] - }; - } - - return { - saved_objects: [ - { - id: '1', - attributes: { - title: 'Foo', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo', - }), - }, + get: () => ({ + id: '1', + type: 'index-pattern', + attributes: { + title: 'My Index Pattern' + }, + }), + find: () => ({ + saved_objects: [ + { + id: '1', + type: 'visualization', + attributes: { + title: 'Foo', + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + index: 'foo', + }), }, }, - { - id: '2', - attributes: { - title: 'Bar', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo', - }), - }, + }, + { + id: '2', + type: 'visualization', + attributes: { + title: 'Bar', + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + index: 'foo', + }), }, }, - { - id: '3', - attributes: { - title: 'FooBar', - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - index: 'foo2', - }), - }, + }, + { + id: '3', + type: 'visualization', + attributes: { + title: 'FooBar', + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + index: 'foo2', + }), }, }, - ] - }; - } + }, + { + id: '1', + type: 'search', + attributes: { + title: 'My Saved Search', + }, + }, + ], + }), }; const result = await findRelationships( type, id, - size, - savedObjectsClient + { + size, + savedObjectsClient, + savedObjectTypes: ['dashboard', 'visualization', 'search', 'index-pattern'], + }, ); expect(result).to.eql({ - visualizations: [{ id: '1', title: 'Foo' }, { id: '2', title: 'Bar' }], - searches: [{ id: '1', title: 'Foo' }, { id: '2', title: 'Bar' }], + visualization: [{ id: '1', title: 'Foo' }, { id: '2', title: 'Bar' }, { id: '3', title: 'FooBar' }], + search: [{ id: '1', title: 'My Saved Search' }], }); }); - it('should return an empty object for invalid types', async () => { + it('should return an empty object for non related objects', async () => { const type = 'invalid'; - const result = await findRelationships(type); + const id = 'foo'; + const size = 10; + + const savedObjectsClient = { + get: () => ({ + id: '1', + type: 'index-pattern', + attributes: { + title: 'My Index Pattern', + }, + references: [], + }), + find: () => ({ saved_objects: [] }), + }; + + const result = await findRelationships( + type, + id, + { + size, + savedObjectsClient, + savedObjectTypes: ['dashboard', 'visualization', 'search', 'index-pattern'], + }, + ); expect(result).to.eql({}); }); }); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_dashboards.js b/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_dashboards.js deleted file mode 100644 index fbbe0cc6e3701..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_dashboards.js +++ /dev/null @@ -1,89 +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 sinon from 'sinon'; -import * as deps from '../collect_panels'; -import { collectDashboards } from '../collect_dashboards'; -import { expect } from 'chai'; - -describe('collectDashboards(req, ids)', () => { - - let collectPanelsStub; - const savedObjectsClient = { bulkGet: sinon.stub() }; - - const ids = ['dashboard-01', 'dashboard-02']; - - beforeEach(() => { - collectPanelsStub = sinon.stub(deps, 'collectPanels'); - collectPanelsStub.onFirstCall().returns(Promise.resolve([ - { id: 'dashboard-01' }, - { id: 'panel-01' }, - { id: 'index-*' } - ])); - collectPanelsStub.onSecondCall().returns(Promise.resolve([ - { id: 'dashboard-02' }, - { id: 'panel-01' }, - { id: 'index-*' } - ])); - - savedObjectsClient.bulkGet.returns(Promise.resolve({ - saved_objects: [ - { id: 'dashboard-01' }, { id: 'dashboard-02' } - ] - })); - }); - - afterEach(() => { - collectPanelsStub.restore(); - savedObjectsClient.bulkGet.resetHistory(); - }); - - it('should request all dashboards', async () => { - await collectDashboards(savedObjectsClient, ids); - - expect(savedObjectsClient.bulkGet.calledOnce).to.equal(true); - - const args = savedObjectsClient.bulkGet.getCall(0).args; - expect(args[0]).to.eql([{ - id: 'dashboard-01', - type: 'dashboard' - }, { - id: 'dashboard-02', - type: 'dashboard' - }]); - }); - - it('should call collectPanels with dashboard docs', async () => { - await collectDashboards(savedObjectsClient, ids); - - expect(collectPanelsStub.calledTwice).to.equal(true); - expect(collectPanelsStub.args[0][1]).to.eql({ id: 'dashboard-01' }); - expect(collectPanelsStub.args[1][1]).to.eql({ id: 'dashboard-02' }); - }); - - it('should return an unique list of objects', async () => { - const results = await collectDashboards(savedObjectsClient, ids); - expect(results).to.eql([ - { id: 'dashboard-01' }, - { id: 'panel-01' }, - { id: 'index-*' }, - { id: 'dashboard-02' }, - ]); - }); -}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_index_patterns.js b/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_index_patterns.js deleted file mode 100644 index edbb8ecbf10b3..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_index_patterns.js +++ /dev/null @@ -1,106 +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 sinon from 'sinon'; -import { collectIndexPatterns } from '../collect_index_patterns'; -import { expect } from 'chai'; - -describe('collectIndexPatterns(req, panels)', () => { - const panels = [ - { - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'index-*' }) - } - } - }, { - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'logstash-*' }) - } - } - }, { - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'logstash-*' }) - } - } - }, { - attributes: { - savedSearchId: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'bad-*' }) - } - } - } - ]; - - const savedObjectsClient = { bulkGet: sinon.stub() }; - - beforeEach(() => { - savedObjectsClient.bulkGet.returns(Promise.resolve({ - saved_objects: [ - { id: 'index-*' }, { id: 'logstash-*' } - ] - })); - }); - - afterEach(() => { - savedObjectsClient.bulkGet.resetHistory(); - }); - - it('should request all index patterns', async () => { - await collectIndexPatterns(savedObjectsClient, panels); - - expect(savedObjectsClient.bulkGet.calledOnce).to.equal(true); - expect(savedObjectsClient.bulkGet.getCall(0).args[0]).to.eql([{ - id: 'index-*', - type: 'index-pattern' - }, { - id: 'logstash-*', - type: 'index-pattern' - }]); - }); - - it('should return the index pattern docs', async () => { - const results = await collectIndexPatterns(savedObjectsClient, panels); - - expect(results).to.eql([ - { id: 'index-*' }, - { id: 'logstash-*' } - ]); - }); - - it('should return an empty array if nothing is requested', async () => { - const input = [ - { - attributes: { - savedSearchId: 1, - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'bad-*' }) - } - } - } - ]; - - const results = await collectIndexPatterns(savedObjectsClient, input); - expect(results).to.eql([]); - expect(savedObjectsClient.bulkGet.calledOnce).to.eql(false); - }); -}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_panels.js b/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_panels.js deleted file mode 100644 index f15d6a088f997..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_panels.js +++ /dev/null @@ -1,105 +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 sinon from 'sinon'; -import * as collectIndexPatternsDep from '../collect_index_patterns'; -import * as collectSearchSourcesDep from '../collect_search_sources'; -import { collectPanels } from '../collect_panels'; -import { expect } from 'chai'; - -describe('collectPanels(req, dashboard)', () => { - let collectSearchSourcesStub; - let collectIndexPatternsStub; - let dashboard; - - const savedObjectsClient = { bulkGet: sinon.stub() }; - - beforeEach(() => { - dashboard = { - attributes: { - panelsJSON: JSON.stringify([ - { id: 'panel-01', type: 'search' }, - { id: 'panel-02', type: 'visualization' } - ]) - } - }; - - savedObjectsClient.bulkGet.returns(Promise.resolve({ - saved_objects: [ - { id: 'panel-01' }, { id: 'panel-02' } - ] - })); - - collectIndexPatternsStub = sinon.stub(collectIndexPatternsDep, 'collectIndexPatterns'); - collectIndexPatternsStub.returns([{ id: 'logstash-*' }]); - collectSearchSourcesStub = sinon.stub(collectSearchSourcesDep, 'collectSearchSources'); - collectSearchSourcesStub.returns([ { id: 'search-01' }]); - }); - - afterEach(() => { - collectSearchSourcesStub.restore(); - collectIndexPatternsStub.restore(); - savedObjectsClient.bulkGet.resetHistory(); - }); - - it('should request each panel in the panelJSON', async () => { - await collectPanels(savedObjectsClient, dashboard); - - expect(savedObjectsClient.bulkGet.calledOnce).to.equal(true); - expect(savedObjectsClient.bulkGet.getCall(0).args[0]).to.eql([{ - id: 'panel-01', - type: 'search' - }, { - id: 'panel-02', - type: 'visualization' - }]); - }); - - it('should call collectSearchSources()', async () => { - await collectPanels(savedObjectsClient, dashboard); - expect(collectSearchSourcesStub.calledOnce).to.equal(true); - expect(collectSearchSourcesStub.args[0][1]).to.eql([ - { id: 'panel-01' }, - { id: 'panel-02' } - ]); - }); - - it('should call collectIndexPatterns()', async () => { - await collectPanels(savedObjectsClient, dashboard); - - expect(collectIndexPatternsStub.calledOnce).to.equal(true); - expect(collectIndexPatternsStub.args[0][1]).to.eql([ - { id: 'panel-01' }, - { id: 'panel-02' } - ]); - }); - - it('should return panels, index patterns, search sources, and dashboard', async () => { - const results = await collectPanels(savedObjectsClient, dashboard); - - expect(results).to.eql([ - { id: 'panel-01' }, - { id: 'panel-02' }, - { id: 'logstash-*' }, - { id: 'search-01' }, - dashboard - ]); - }); - -}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_search_sources.js b/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_search_sources.js deleted file mode 100644 index 4f9de8a971b7c..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/collect_search_sources.js +++ /dev/null @@ -1,85 +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 sinon from 'sinon'; -import * as deps from '../collect_index_patterns'; -import { collectSearchSources } from '../collect_search_sources'; -import { expect } from 'chai'; -describe('collectSearchSources(req, panels)', () => { - const savedObjectsClient = { bulkGet: sinon.stub() }; - - let panels; - let collectIndexPatternsStub; - - beforeEach(() => { - panels = [ - { attributes: { savedSearchId: 1 } }, - { attributes: { savedSearchId: 2 } } - ]; - - collectIndexPatternsStub = sinon.stub(deps, 'collectIndexPatterns'); - collectIndexPatternsStub.returns(Promise.resolve([{ id: 'logstash-*' }])); - - savedObjectsClient.bulkGet.returns(Promise.resolve({ - saved_objects: [ - { id: 1 }, { id: 2 } - ] - })); - }); - - afterEach(() => { - collectIndexPatternsStub.restore(); - savedObjectsClient.bulkGet.resetHistory(); - }); - - it('should request all search sources', async () => { - await collectSearchSources(savedObjectsClient, panels); - - expect(savedObjectsClient.bulkGet.calledOnce).to.equal(true); - expect(savedObjectsClient.bulkGet.getCall(0).args[0]).to.eql([ - { type: 'search', id: 1 }, { type: 'search', id: 2 } - ]); - }); - - it('should return the search source and index patterns', async () => { - const results = await collectSearchSources(savedObjectsClient, panels); - - expect(results).to.eql([ - { id: 1 }, - { id: 2 }, - { id: 'logstash-*' } - ]); - }); - - it('should return an empty array if nothing is requested', async () => { - const input = [ - { - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ index: 'bad-*' }) - } - } - } - ]; - - const results = await collectSearchSources(savedObjectsClient, input); - expect(results).to.eql([]); - expect(savedObjectsClient.bulkGet.calledOnce).to.eql(false); - }); -}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/export_dashboards.js b/src/legacy/core_plugins/kibana/server/lib/export/__tests__/export_dashboards.js deleted file mode 100644 index 1fb93ec4d95c5..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/__tests__/export_dashboards.js +++ /dev/null @@ -1,74 +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 * as deps from '../collect_dashboards'; -import { exportDashboards } from '../export_dashboards'; -import sinon from 'sinon'; -import { expect } from 'chai'; - -describe('exportDashboards(req)', () => { - - let req; - let collectDashboardsStub; - - beforeEach(() => { - req = { - query: { dashboard: 'dashboard-01' }, - server: { - config: () => ({ get: () => '6.0.0' }), - plugins: { - elasticsearch: { - getCluster: () => ({ callWithRequest: sinon.stub() }) - } - }, - }, - getSavedObjectsClient() { - return null; - } - }; - - collectDashboardsStub = sinon.stub(deps, 'collectDashboards'); - collectDashboardsStub.returns(Promise.resolve([ - { id: 'dashboard-01' }, - { id: 'logstash-*' }, - { id: 'panel-01' } - ])); - }); - - afterEach(() => { - collectDashboardsStub.restore(); - }); - - it('should return a response object with version', () => { - return exportDashboards(req).then((resp) => { - expect(resp).to.have.property('version', '6.0.0'); - }); - }); - - it('should return a response object with objects', () => { - return exportDashboards(req).then((resp) => { - expect(resp).to.have.property('objects'); - expect(resp.objects).to.eql([ - { id: 'dashboard-01' }, - { id: 'logstash-*' }, - { id: 'panel-01' } - ]); - }); - }); -}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_dashboards.js b/src/legacy/core_plugins/kibana/server/lib/export/collect_dashboards.js deleted file mode 100644 index 969c2add1364d..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/collect_dashboards.js +++ /dev/null @@ -1,43 +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 { collectPanels } from './collect_panels'; - -export async function collectDashboards(savedObjectsClient, ids) { - - if (ids.length === 0) return []; - - const objects = ids.map(id => { - return { - type: 'dashboard', - id: id - }; - }); - - const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(objects); - const results = await Promise.all(savedObjects.map(d => collectPanels(savedObjectsClient, d))); - - return results - .reduce((acc, result) => acc.concat(result), []) - .reduce((acc, obj) => { - if (!acc.find(o => o.id === obj.id)) acc.push(obj); - return acc; - }, []); - -} diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_index_patterns.js b/src/legacy/core_plugins/kibana/server/lib/export/collect_index_patterns.js deleted file mode 100644 index 441871208dc08..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/collect_index_patterns.js +++ /dev/null @@ -1,43 +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. - */ - -export async function collectIndexPatterns(savedObjectsClient, panels) { - const docs = panels.reduce((acc, panel) => { - const { kibanaSavedObjectMeta, savedSearchId } = panel.attributes; - - if (kibanaSavedObjectMeta && kibanaSavedObjectMeta.searchSourceJSON && !savedSearchId) { - let searchSourceData; - try { - searchSourceData = JSON.parse(kibanaSavedObjectMeta.searchSourceJSON); - } catch (err) { - return acc; - } - - if (searchSourceData.index && !acc.find(s => s.id === searchSourceData.index)) { - acc.push({ type: 'index-pattern', id: searchSourceData.index }); - } - } - return acc; - }, []); - - if (docs.length === 0) return []; - - const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(docs); - return savedObjects; -} diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_panels.js b/src/legacy/core_plugins/kibana/server/lib/export/collect_panels.js deleted file mode 100644 index eba6e335818e3..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/collect_panels.js +++ /dev/null @@ -1,43 +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 { get } from 'lodash'; - -import { collectIndexPatterns } from './collect_index_patterns'; -import { collectSearchSources } from './collect_search_sources'; - - -export async function collectPanels(savedObjectsClient, dashboard) { - let panels; - try { - panels = JSON.parse(get(dashboard, 'attributes.panelsJSON', '[]')); - } catch(err) { - panels = []; - } - - if (panels.length === 0) return [].concat([dashboard]); - - const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(panels); - const [ indexPatterns, searchSources ] = await Promise.all([ - collectIndexPatterns(savedObjectsClient, savedObjects), - collectSearchSources(savedObjectsClient, savedObjects) - ]); - - return savedObjects.concat(indexPatterns).concat(searchSources).concat([dashboard]); -} diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts new file mode 100644 index 0000000000000..f5b9b299fd766 --- /dev/null +++ b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.test.ts @@ -0,0 +1,196 @@ +/* + * 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 '../../../../../../server/saved_objects/service/saved_objects_client'; +import { collectReferencesDeep } from './collect_references_deep'; + +const data = [ + { + id: '1', + type: 'dashboard', + attributes: { + panelsJSON: JSON.stringify([{ panelRefName: 'panel_0' }, { panelRefName: 'panel_1' }]), + }, + references: [ + { + name: 'panel_0', + type: 'visualization', + id: '2', + }, + { + name: 'panel_1', + type: 'visualization', + id: '3', + }, + ], + }, + { + id: '2', + type: 'visualization', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }), + }, + }, + references: [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '4', + }, + ], + }, + { + id: '3', + type: 'visualization', + attributes: { + savedSearchRefName: 'search_0', + }, + references: [ + { + name: 'search_0', + type: 'search', + id: '5', + }, + ], + }, + { + id: '4', + type: 'index-pattern', + attributes: { + title: 'pattern*', + }, + }, + { + id: '5', + type: 'search', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }), + }, + }, + references: [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '4', + }, + ], + }, +]; + +test('collects dashboard and all dependencies', async () => { + const savedObjectClient = { + errors: {} as any, + create: jest.fn(), + bulkCreate: jest.fn(), + delete: jest.fn(), + find: jest.fn(), + get: jest.fn(), + update: jest.fn(), + bulkGet: jest.fn(getObjects => { + return { + saved_objects: getObjects.map((obj: SavedObject) => + data.find(row => row.id === obj.id && row.type === obj.type) + ), + }; + }), + }; + const objects = await collectReferencesDeep(savedObjectClient, [{ type: 'dashboard', id: '1' }]); + expect(objects).toMatchInlineSnapshot(` +Array [ + Object { + "attributes": Object { + "panelsJSON": "[{\\"panelRefName\\":\\"panel_0\\"},{\\"panelRefName\\":\\"panel_1\\"}]", + }, + "id": "1", + "references": Array [ + Object { + "id": "2", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "3", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", + }, + Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", + }, + }, + "id": "2", + "references": Array [ + Object { + "id": "4", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern", + }, + ], + "type": "visualization", + }, + Object { + "attributes": Object { + "savedSearchRefName": "search_0", + }, + "id": "3", + "references": Array [ + Object { + "id": "5", + "name": "search_0", + "type": "search", + }, + ], + "type": "visualization", + }, + Object { + "attributes": Object { + "title": "pattern*", + }, + "id": "4", + "type": "index-pattern", + }, + Object { + "attributes": Object { + "kibanaSavedObjectMeta": Object { + "searchSourceJSON": "{\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", + }, + }, + "id": "5", + "references": Array [ + Object { + "id": "4", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern", + }, + ], + "type": "search", + }, +] +`); +}); diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.ts b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.ts new file mode 100644 index 0000000000000..f62fc3c474c08 --- /dev/null +++ b/src/legacy/core_plugins/kibana/server/lib/export/collect_references_deep.ts @@ -0,0 +1,55 @@ +/* + * 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, + SavedObjectsClient, +} from '../../../../../../server/saved_objects/service/saved_objects_client'; + +const MAX_BULK_GET_SIZE = 10000; + +interface ObjectsToCollect { + id: string; + type: string; +} + +export async function collectReferencesDeep( + savedObjectClient: SavedObjectsClient, + objects: ObjectsToCollect[] +) { + let result: SavedObject[] = []; + const queue = [...objects]; + while (queue.length !== 0) { + const itemsToGet = queue.splice(0, MAX_BULK_GET_SIZE); + const { saved_objects: savedObjects } = await savedObjectClient.bulkGet(itemsToGet); + result = result.concat(savedObjects); + for (const { references = [] } of savedObjects) { + for (const reference of references) { + const isDuplicate = queue + .concat(result) + .some(obj => obj.type === reference.type && obj.id === reference.id); + if (isDuplicate) { + continue; + } + queue.push({ type: reference.type, id: reference.id }); + } + } + } + return result; +} diff --git a/src/legacy/core_plugins/kibana/server/lib/export/collect_search_sources.js b/src/legacy/core_plugins/kibana/server/lib/export/collect_search_sources.js deleted file mode 100644 index 38471e9b6012c..0000000000000 --- a/src/legacy/core_plugins/kibana/server/lib/export/collect_search_sources.js +++ /dev/null @@ -1,39 +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 { collectIndexPatterns } from './collect_index_patterns'; - -export async function collectSearchSources(savedObjectsClient, panels) { - const docs = panels.reduce((acc, panel) => { - const { savedSearchId } = panel.attributes; - if (savedSearchId) { - if (!acc.find(s => s.id === savedSearchId) && !panels.find(p => p.id === savedSearchId)) { - acc.push({ type: 'search', id: savedSearchId }); - } - } - return acc; - }, []); - - if (docs.length === 0) return []; - - const { saved_objects: savedObjects } = await savedObjectsClient.bulkGet(docs); - const indexPatterns = await collectIndexPatterns(savedObjectsClient, savedObjects); - - return savedObjects.concat(indexPatterns); -} diff --git a/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js b/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js index ed61d2c83366a..07b1bafd61c91 100644 --- a/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js +++ b/src/legacy/core_plugins/kibana/server/lib/export/export_dashboards.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { collectDashboards } from './collect_dashboards'; +import { collectReferencesDeep } from './collect_references_deep'; export async function exportDashboards(req) { @@ -26,8 +26,9 @@ export async function exportDashboards(req) { const config = req.server.config(); const savedObjectsClient = req.getSavedObjectsClient(); + const objectsToExport = ids.map(id => ({ id, type: 'dashboard' })); - const objects = await collectDashboards(savedObjectsClient, ids); + const objects = await collectReferencesDeep(savedObjectsClient, objectsToExport); return { version: config.get('pkg.version'), objects diff --git a/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js b/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js index e98bebe4c4066..afed200476343 100644 --- a/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js +++ b/src/legacy/core_plugins/kibana/server/lib/management/saved_objects/relationships.js @@ -17,166 +17,45 @@ * under the License. */ -async function findDashboardRelationships(id, size, savedObjectsClient) { - const dashboard = await savedObjectsClient.get('dashboard', id); - const visualizations = []; - - // TODO: should we handle exceptions here or at the parent level? - const panelsJSON = JSON.parse(dashboard.attributes.panelsJSON); - if (panelsJSON) { - const visualizationIds = panelsJSON.map(panel => panel.id); - const visualizationResponse = await savedObjectsClient.bulkGet( - visualizationIds.slice(0, size).map(id => ({ - id, - type: 'visualization', - })) - ); - - visualizations.push( - ...visualizationResponse.saved_objects.reduce((accum, object) => { - if (!object.error) { - accum.push({ - id: object.id, - title: object.attributes.title, - }); - } - return accum; - }, []) - ); - } - - return { visualizations }; -} - -async function findVisualizationRelationships(id, size, savedObjectsClient) { - await savedObjectsClient.get('visualization', id); - const allDashboardsResponse = await savedObjectsClient.find({ - type: 'dashboard', - fields: ['title', 'panelsJSON'], - }); - - const dashboards = []; - for (const dashboard of allDashboardsResponse.saved_objects) { - if (dashboard.error) { - continue; - } - const panelsJSON = JSON.parse(dashboard.attributes.panelsJSON); - if (panelsJSON) { - for (const panel of panelsJSON) { - if (panel.type === 'visualization' && panel.id === id) { - dashboards.push({ - id: dashboard.id, - title: dashboard.attributes.title, - }); - } - } - } - - if (dashboards.length >= size) { - break; - } - } - return { dashboards }; -} - -async function findSavedSearchRelationships(id, size, savedObjectsClient) { - const search = await savedObjectsClient.get('search', id); - - const searchSourceJSON = JSON.parse(search.attributes.kibanaSavedObjectMeta.searchSourceJSON); - - const indexPatterns = []; - try { - const indexPattern = await savedObjectsClient.get('index-pattern', searchSourceJSON.index); - indexPatterns.push({ id: indexPattern.id, title: indexPattern.attributes.title }); - } catch (err) { - // Do nothing - } - - const allVisualizationsResponse = await savedObjectsClient.find({ - type: 'visualization', - searchFields: ['savedSearchId'], - search: id, - fields: ['title'], - }); - - const visualizations = allVisualizationsResponse.saved_objects.reduce((accum, object) => { - if (!object.error) { - accum.push({ - id: object.id, - title: object.attributes.title, - }); - } - return accum; - }, []); - - return { visualizations, indexPatterns }; -} - -async function findIndexPatternRelationships(id, size, savedObjectsClient) { - await savedObjectsClient.get('index-pattern', id); - const [allVisualizationsResponse, savedSearchResponse] = await Promise.all([ +export async function findRelationships(type, id, options = {}) { + const { + size, + savedObjectsClient, + savedObjectTypes, + } = options; + + const { references = [] } = await savedObjectsClient.get(type, id); + const bulkGetOpts = references.map(ref => ({ id: ref.id, type: ref.type })); + + const [referencedObjects, referencedResponse] = await Promise.all([ + bulkGetOpts.length > 0 + ? savedObjectsClient.bulkGet(bulkGetOpts) + : Promise.resolve({ saved_objects: [] }), savedObjectsClient.find({ - type: 'visualization', - searchFields: ['kibanaSavedObjectMeta.searchSourceJSON'], - search: '*', - fields: [`title`, `kibanaSavedObjectMeta.searchSourceJSON`], - }), - savedObjectsClient.find({ - type: 'search', - searchFields: ['kibanaSavedObjectMeta.searchSourceJSON'], - search: '*', - fields: [`title`, `kibanaSavedObjectMeta.searchSourceJSON`], + hasReference: { type, id }, + perPage: size, + fields: ['title'], + type: savedObjectTypes, }), ]); - const visualizations = []; - for (const visualization of allVisualizationsResponse.saved_objects) { - if (visualization.error) { - continue; - } - const searchSourceJSON = JSON.parse(visualization.attributes.kibanaSavedObjectMeta.searchSourceJSON); - if (searchSourceJSON && searchSourceJSON.index === id) { - visualizations.push({ - id: visualization.id, - title: visualization.attributes.title, - }); - } - - if (visualizations.length >= size) { - break; - } - } - - const searches = []; - for (const search of savedSearchResponse.saved_objects) { - if (search.error) { - continue; - } - const searchSourceJSON = JSON.parse(search.attributes.kibanaSavedObjectMeta.searchSourceJSON); - if (searchSourceJSON && searchSourceJSON.index === id) { - searches.push({ - id: search.id, - title: search.attributes.title, - }); - } - - if (searches.length >= size) { - break; - } - } - return { visualizations, searches }; + const relationshipObjects = [].concat( + referencedObjects.saved_objects.map(extractCommonProperties), + referencedResponse.saved_objects.map(extractCommonProperties), + ); + + return relationshipObjects.reduce((result, relationshipObject) => { + const objectsForType = (result[relationshipObject.type] || []); + const { type, ...relationshipObjectWithoutType } = relationshipObject; + result[type] = objectsForType.concat(relationshipObjectWithoutType); + return result; + }, {}); } -export async function findRelationships(type, id, size, savedObjectsClient) { - switch (type) { - case 'dashboard': - return await findDashboardRelationships(id, size, savedObjectsClient); - case 'visualization': - return await findVisualizationRelationships(id, size, savedObjectsClient); - case 'search': - return await findSavedSearchRelationships(id, size, savedObjectsClient); - case 'index-pattern': - return await findIndexPatternRelationships(id, size, savedObjectsClient); - } - return {}; +function extractCommonProperties(savedObject) { + return { + id: savedObject.id, + type: savedObject.type, + title: savedObject.attributes.title, + }; } diff --git a/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js b/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js index d88cc05c97f8d..268f16b4f4afa 100644 --- a/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js +++ b/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/relationships.js @@ -17,10 +17,8 @@ * under the License. */ -import Boom from 'boom'; import Joi from 'joi'; import { findRelationships } from '../../../../lib/management/saved_objects/relationships'; -import { isNotFoundError } from '../../../../../../../../server/saved_objects/service/lib/errors'; export function registerRelationships(server) { server.route({ @@ -33,7 +31,7 @@ export function registerRelationships(server) { id: Joi.string(), }), query: Joi.object().keys({ - size: Joi.number(), + size: Joi.number().default(10000), }), }, }, @@ -41,17 +39,15 @@ export function registerRelationships(server) { handler: async (req) => { const type = req.params.type; const id = req.params.id; - const size = req.query.size || 10; + const size = req.query.size; + const savedObjectsClient = req.getSavedObjectsClient(); - try { - return await findRelationships(type, id, size, req.getSavedObjectsClient()); - } catch (err) { - if (isNotFoundError(err)) { - throw Boom.boomify(new Error('Resource not found'), { statusCode: 404 }); - } - - throw Boom.boomify(err, { statusCode: 500 }); - } + return await findRelationships(type, id, { + size, + savedObjectsClient, + // Pass in all types except space, spaces wrapper will throw error + savedObjectTypes: server.savedObjects.types.filter(type => type !== 'space'), + }); }, }); } diff --git a/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js b/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js index 76cc66c05385c..a2cc63b4b8679 100644 --- a/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js +++ b/src/legacy/core_plugins/kibana/server/routes/api/management/saved_objects/scroll.js @@ -62,6 +62,7 @@ export function registerScrollForExportRoute(server) { savedObjectVersion: 2 }, _migrationVersion: hit.migrationVersion, + _references: hit.references || [], }; }); } diff --git a/src/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap b/src/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap index 156c5fa6887f4..7e6b8bf5e9e58 100644 --- a/src/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap +++ b/src/server/saved_objects/migrations/core/__snapshots__/build_active_mappings.test.ts.snap @@ -25,6 +25,20 @@ Object { "namespace": Object { "type": "keyword", }, + "references": Object { + "properties": Object { + "id": Object { + "type": "keyword", + }, + "name": Object { + "type": "keyword", + }, + "type": Object { + "type": "keyword", + }, + }, + "type": "nested", + }, "type": Object { "type": "keyword", }, diff --git a/src/server/saved_objects/migrations/core/build_active_mappings.ts b/src/server/saved_objects/migrations/core/build_active_mappings.ts index 156f47faecd56..eae75b418ed54 100644 --- a/src/server/saved_objects/migrations/core/build_active_mappings.ts +++ b/src/server/saved_objects/migrations/core/build_active_mappings.ts @@ -74,6 +74,20 @@ function defaultMapping(): IndexMapping { updated_at: { type: 'date', }, + references: { + type: 'nested', + properties: { + name: { + type: 'keyword', + }, + type: { + type: 'keyword', + }, + id: { + type: 'keyword', + }, + }, + }, }, }; } diff --git a/src/server/saved_objects/migrations/core/document_migrator.test.ts b/src/server/saved_objects/migrations/core/document_migrator.test.ts index cdd895594e4dd..293d96c8e62f4 100644 --- a/src/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/server/saved_objects/migrations/core/document_migrator.test.ts @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import { SavedObjectDoc } from '../../serialization'; +import { RawSavedObjectDoc } from '../../serialization'; import { DocumentMigrator } from './document_migrator'; describe('DocumentMigrator', () => { @@ -486,13 +486,13 @@ describe('DocumentMigrator', () => { ...testOpts(), migrations: { aaa: { - '1.2.3': (doc: SavedObjectDoc) => doc, - '10.4.0': (doc: SavedObjectDoc) => doc, - '2.2.1': (doc: SavedObjectDoc) => doc, + '1.2.3': (doc: RawSavedObjectDoc) => doc, + '10.4.0': (doc: RawSavedObjectDoc) => doc, + '2.2.1': (doc: RawSavedObjectDoc) => doc, }, bbb: { - '3.2.3': (doc: SavedObjectDoc) => doc, - '2.0.0': (doc: SavedObjectDoc) => doc, + '3.2.3': (doc: RawSavedObjectDoc) => doc, + '2.0.0': (doc: RawSavedObjectDoc) => doc, }, }, }); @@ -525,11 +525,11 @@ describe('DocumentMigrator', () => { }); function renameAttr(path: string, newPath: string) { - return (doc: SavedObjectDoc) => - _.omit(_.set(doc, newPath, _.get(doc, path)), path) as SavedObjectDoc; + return (doc: RawSavedObjectDoc) => + _.omit(_.set(doc, newPath, _.get(doc, path)), path) as RawSavedObjectDoc; } function setAttr(path: string, value: any) { - return (doc: SavedObjectDoc) => - _.set(doc, path, _.isFunction(value) ? value(_.get(doc, path)) : value) as SavedObjectDoc; + return (doc: RawSavedObjectDoc) => + _.set(doc, path, _.isFunction(value) ? value(_.get(doc, path)) : value) as RawSavedObjectDoc; } diff --git a/src/server/saved_objects/migrations/core/document_migrator.ts b/src/server/saved_objects/migrations/core/document_migrator.ts index 0e0631aa8fce2..4a2a5aedc250d 100644 --- a/src/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/server/saved_objects/migrations/core/document_migrator.ts @@ -63,12 +63,12 @@ import Boom from 'boom'; import _ from 'lodash'; import Semver from 'semver'; -import { MigrationVersion, SavedObjectDoc } from '../../serialization'; +import { MigrationVersion, RawSavedObjectDoc } from '../../serialization'; import { LogFn, Logger, MigrationLogger } from './migration_logger'; -export type TransformFn = (doc: SavedObjectDoc) => SavedObjectDoc; +export type TransformFn = (doc: RawSavedObjectDoc) => RawSavedObjectDoc; -type ValidateDoc = (doc: SavedObjectDoc) => void; +type ValidateDoc = (doc: RawSavedObjectDoc) => void; interface MigrationDefinition { [type: string]: { [version: string]: TransformFn }; @@ -142,11 +142,11 @@ export class DocumentMigrator implements VersionedTransformer { /** * Migrates a document to the latest version. * - * @param {SavedObjectDoc} doc - * @returns {SavedObjectDoc} + * @param {RawSavedObjectDoc} doc + * @returns {RawSavedObjectDoc} * @memberof DocumentMigrator */ - public migrate = (doc: SavedObjectDoc): SavedObjectDoc => { + public migrate = (doc: RawSavedObjectDoc): RawSavedObjectDoc => { return this.transformDoc(doc); }; } @@ -225,7 +225,7 @@ function buildDocumentTransform({ migrations: ActiveMigrations; validateDoc: ValidateDoc; }): TransformFn { - return function transformAndValidate(doc: SavedObjectDoc) { + return function transformAndValidate(doc: RawSavedObjectDoc) { const result = doc.migrationVersion ? applyMigrations(doc, migrations) : markAsUpToDate(doc, migrations); @@ -243,7 +243,7 @@ function buildDocumentTransform({ }; } -function applyMigrations(doc: SavedObjectDoc, migrations: ActiveMigrations) { +function applyMigrations(doc: RawSavedObjectDoc, migrations: ActiveMigrations) { while (true) { const prop = nextUnmigratedProp(doc, migrations); if (!prop) { @@ -256,14 +256,14 @@ function applyMigrations(doc: SavedObjectDoc, migrations: ActiveMigrations) { /** * Gets the doc's props, handling the special case of "type". */ -function props(doc: SavedObjectDoc) { +function props(doc: RawSavedObjectDoc) { return Object.keys(doc).concat(doc.type); } /** * Looks up the prop version in a saved object document or in our latest migrations. */ -function propVersion(doc: SavedObjectDoc | ActiveMigrations, prop: string) { +function propVersion(doc: RawSavedObjectDoc | ActiveMigrations, prop: string) { return ( (doc[prop] && doc[prop].latestVersion) || (doc.migrationVersion && (doc as any).migrationVersion[prop]) @@ -273,7 +273,7 @@ function propVersion(doc: SavedObjectDoc | ActiveMigrations, prop: string) { /** * Sets the doc's migrationVersion to be the most recent version */ -function markAsUpToDate(doc: SavedObjectDoc, migrations: ActiveMigrations) { +function markAsUpToDate(doc: RawSavedObjectDoc, migrations: ActiveMigrations) { return { ...doc, migrationVersion: props(doc).reduce((acc, prop) => { @@ -288,7 +288,7 @@ function markAsUpToDate(doc: SavedObjectDoc, migrations: ActiveMigrations) { * about the document and transform that caused the failure. */ function wrapWithTry(version: string, prop: string, transform: TransformFn, log: Logger) { - return function tryTransformDoc(doc: SavedObjectDoc) { + return function tryTransformDoc(doc: RawSavedObjectDoc) { try { const result = transform(doc); @@ -313,7 +313,7 @@ function wrapWithTry(version: string, prop: string, transform: TransformFn, log: /** * Finds the first unmigrated property in the specified document. */ -function nextUnmigratedProp(doc: SavedObjectDoc, migrations: ActiveMigrations) { +function nextUnmigratedProp(doc: RawSavedObjectDoc, migrations: ActiveMigrations) { return props(doc).find(p => { const latestVersion = propVersion(migrations, p); const docVersion = propVersion(doc, p); @@ -343,10 +343,10 @@ function nextUnmigratedProp(doc: SavedObjectDoc, migrations: ActiveMigrations) { * Applies any relevent migrations to the document for the specified property. */ function migrateProp( - doc: SavedObjectDoc, + doc: RawSavedObjectDoc, prop: string, migrations: ActiveMigrations -): SavedObjectDoc { +): RawSavedObjectDoc { const originalType = doc.type; let migrationVersion = _.clone(doc.migrationVersion) || {}; const typeChanged = () => !doc.hasOwnProperty(prop) || doc.type !== originalType; @@ -367,7 +367,7 @@ function migrateProp( /** * Retrieves any prop transforms that have not been applied to doc. */ -function applicableTransforms(migrations: ActiveMigrations, doc: SavedObjectDoc, prop: string) { +function applicableTransforms(migrations: ActiveMigrations, doc: RawSavedObjectDoc, prop: string) { const minVersion = propVersion(doc, prop); const { transforms } = migrations[prop]; return minVersion @@ -380,7 +380,7 @@ function applicableTransforms(migrations: ActiveMigrations, doc: SavedObjectDoc, * has not mutated migrationVersion in an unsupported way. */ function updateMigrationVersion( - doc: SavedObjectDoc, + doc: RawSavedObjectDoc, migrationVersion: MigrationVersion, prop: string, version: string @@ -396,7 +396,7 @@ function updateMigrationVersion( * as this could get us into an infinite loop. So, we explicitly check for that here. */ function assertNoDowngrades( - doc: SavedObjectDoc, + doc: RawSavedObjectDoc, migrationVersion: MigrationVersion, prop: string, version: string diff --git a/src/server/saved_objects/migrations/core/index_migrator.test.ts b/src/server/saved_objects/migrations/core/index_migrator.test.ts index a5be8e5216773..68e13bfbb53e2 100644 --- a/src/server/saved_objects/migrations/core/index_migrator.test.ts +++ b/src/server/saved_objects/migrations/core/index_migrator.test.ts @@ -20,7 +20,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import { SavedObjectsSchema } from '../../schema'; -import { SavedObjectDoc, SavedObjectsSerializer } from '../../serialization'; +import { RawSavedObjectDoc, SavedObjectsSerializer } from '../../serialization'; import { CallCluster } from './call_cluster'; import { IndexMigrator } from './index_migrator'; @@ -50,6 +50,14 @@ describe('IndexMigrator', () => { namespace: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, + references: { + type: 'nested', + properties: { + name: { type: 'keyword' }, + type: { type: 'keyword' }, + id: { type: 'keyword' }, + }, + }, }, }, include_type_name: true, @@ -83,6 +91,14 @@ describe('IndexMigrator', () => { namespace: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, + references: { + type: 'nested', + properties: { + name: { type: 'keyword' }, + type: { type: 'keyword' }, + id: { type: 'keyword' }, + }, + }, }, }, settings: { number_of_shards: 1, auto_expand_replicas: '0-1' }, @@ -191,6 +207,14 @@ describe('IndexMigrator', () => { namespace: { type: 'keyword' }, type: { type: 'keyword' }, updated_at: { type: 'date' }, + references: { + type: 'nested', + properties: { + name: { type: 'keyword' }, + type: { type: 'keyword' }, + id: { type: 'keyword' }, + }, + }, }, }, settings: { number_of_shards: 1, auto_expand_replicas: '0-1' }, @@ -240,7 +264,7 @@ describe('IndexMigrator', () => { let count = 0; const opts = defaultOpts(); const callCluster = clusterStub(opts); - const migrateDoc = sinon.spy((doc: SavedObjectDoc) => ({ + const migrateDoc = sinon.spy((doc: RawSavedObjectDoc) => ({ ...doc, attributes: { name: ++count }, })); @@ -266,24 +290,26 @@ describe('IndexMigrator', () => { type: 'foo', attributes: { name: 'Bar' }, migrationVersion: {}, + references: [], }); sinon.assert.calledWith(migrateDoc, { id: '2', type: 'foo', attributes: { name: 'Baz' }, migrationVersion: {}, + references: [], }); expect(callCluster.args.filter(([action]) => action === 'bulk').length).toEqual(2); sinon.assert.calledWith(callCluster, 'bulk', { body: [ { index: { _id: 'foo:1', _index: '.kibana_2' } }, - { foo: { name: 1 }, type: 'foo', migrationVersion: {} }, + { foo: { name: 1 }, type: 'foo', migrationVersion: {}, references: [] }, ], }); sinon.assert.calledWith(callCluster, 'bulk', { body: [ { index: { _id: 'foo:2', _index: '.kibana_2' } }, - { foo: { name: 2 }, type: 'foo', migrationVersion: {} }, + { foo: { name: 2 }, type: 'foo', migrationVersion: {}, references: [] }, ], }); }); diff --git a/src/server/saved_objects/migrations/core/migrate_raw_docs.test.ts b/src/server/saved_objects/migrations/core/migrate_raw_docs.test.ts index 01bd409da8b69..26ccb4085e2a9 100644 --- a/src/server/saved_objects/migrations/core/migrate_raw_docs.test.ts +++ b/src/server/saved_objects/migrations/core/migrate_raw_docs.test.ts @@ -34,11 +34,11 @@ describe('migrateRawDocs', () => { expect(result).toEqual([ { _id: 'a:b', - _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {} }, + _source: { type: 'a', a: { name: 'HOI!' }, migrationVersion: {}, references: [] }, }, { _id: 'c:d', - _source: { type: 'c', c: { name: 'HOI!' }, migrationVersion: {} }, + _source: { type: 'c', c: { name: 'HOI!' }, migrationVersion: {}, references: [] }, }, ]); @@ -56,7 +56,7 @@ describe('migrateRawDocs', () => { { _id: 'foo:b', _source: { type: 'a', a: { name: 'AAA' } } }, { _id: 'c:d', - _source: { type: 'c', c: { name: 'TADA' }, migrationVersion: {} }, + _source: { type: 'c', c: { name: 'TADA' }, migrationVersion: {}, references: [] }, }, ]); @@ -69,6 +69,7 @@ describe('migrateRawDocs', () => { name: 'DDD', }, migrationVersion: {}, + references: [], }, ], ]); diff --git a/src/server/saved_objects/migrations/core/migrate_raw_docs.ts b/src/server/saved_objects/migrations/core/migrate_raw_docs.ts index ffafa9908d23e..c008b18619629 100644 --- a/src/server/saved_objects/migrations/core/migrate_raw_docs.ts +++ b/src/server/saved_objects/migrations/core/migrate_raw_docs.ts @@ -41,7 +41,10 @@ export function migrateRawDocs( if (serializer.isRawSavedObject(raw)) { const savedObject = serializer.rawToSavedObject(raw); savedObject.migrationVersion = savedObject.migrationVersion || {}; - return serializer.savedObjectToRaw(migrateDoc(savedObject)); + return serializer.savedObjectToRaw({ + references: [], + ...migrateDoc(savedObject), + }); } return raw; diff --git a/src/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap b/src/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap index 1733f94ded552..9627a351f55d4 100644 --- a/src/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap +++ b/src/server/saved_objects/migrations/kibana/__snapshots__/kibana_migrator.test.ts.snap @@ -25,6 +25,20 @@ Object { "namespace": Object { "type": "keyword", }, + "references": Object { + "properties": Object { + "id": Object { + "type": "keyword", + }, + "name": Object { + "type": "keyword", + }, + "type": Object { + "type": "keyword", + }, + }, + "type": "nested", + }, "type": Object { "type": "keyword", }, diff --git a/src/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/server/saved_objects/migrations/kibana/kibana_migrator.ts index 06ff383133d35..3eddd46586d6b 100644 --- a/src/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -24,7 +24,7 @@ import { once } from 'lodash'; import { SavedObjectsSchema, SavedObjectsSchemaDefinition } from '../../schema'; -import { SavedObjectDoc, SavedObjectsSerializer } from '../../serialization'; +import { RawSavedObjectDoc, SavedObjectsSerializer } from '../../serialization'; import { docValidator } from '../../validation'; import { buildActiveMappings, CallCluster, IndexMigrator, LogFn, MappingProperties } from '../core'; import { DocumentMigrator, VersionedTransformer } from '../core/document_migrator'; @@ -146,11 +146,11 @@ export class KibanaMigrator { /** * Migrates an individual doc to the latest version, as defined by the plugin migrations. * - * @param {SavedObjectDoc} doc - * @returns {SavedObjectDoc} + * @param {RawSavedObjectDoc} doc + * @returns {RawSavedObjectDoc} * @memberof KibanaMigrator */ - public migrateDocument(doc: SavedObjectDoc): SavedObjectDoc { + public migrateDocument(doc: RawSavedObjectDoc): RawSavedObjectDoc { return this.documentMigrator.migrate(doc); } } diff --git a/src/server/saved_objects/routes/bulk_create.js b/src/server/saved_objects/routes/bulk_create.js index 943b2520a331d..d2dc14e3f6f7b 100644 --- a/src/server/saved_objects/routes/bulk_create.js +++ b/src/server/saved_objects/routes/bulk_create.js @@ -37,6 +37,14 @@ export const createBulkCreateRoute = prereqs => ({ attributes: Joi.object().required(), version: Joi.number(), migrationVersion: Joi.object().optional(), + references: Joi.array().items( + Joi.object() + .keys({ + name: Joi.string().required(), + type: Joi.string().required(), + id: Joi.string().required(), + }), + ).default([]), }).required() ), }, diff --git a/src/server/saved_objects/routes/bulk_get.test.js b/src/server/saved_objects/routes/bulk_get.test.js index e646629970fd4..62c155a57a165 100644 --- a/src/server/saved_objects/routes/bulk_get.test.js +++ b/src/server/saved_objects/routes/bulk_get.test.js @@ -59,7 +59,8 @@ describe('POST /api/saved_objects/_bulk_get', () => { id: 'abc123', type: 'index-pattern', title: 'logstash-*', - version: 2 + version: 2, + references: [], }] }; diff --git a/src/server/saved_objects/routes/create.js b/src/server/saved_objects/routes/create.js index 46d47d0f33891..a93e23a57550b 100644 --- a/src/server/saved_objects/routes/create.js +++ b/src/server/saved_objects/routes/create.js @@ -40,14 +40,22 @@ export const createCreateRoute = prereqs => { payload: Joi.object({ attributes: Joi.object().required(), migrationVersion: Joi.object().optional(), + references: Joi.array().items( + Joi.object() + .keys({ + name: Joi.string().required(), + type: Joi.string().required(), + id: Joi.string().required(), + }), + ).default([]), }).required(), }, handler(request) { const { savedObjectsClient } = request.pre; const { type, id } = request.params; const { overwrite } = request.query; - const { migrationVersion } = request.payload; - const options = { id, overwrite, migrationVersion }; + const { migrationVersion, references } = request.payload; + const options = { id, overwrite, migrationVersion, references }; return savedObjectsClient.create(type, request.payload.attributes, options); }, diff --git a/src/server/saved_objects/routes/create.test.js b/src/server/saved_objects/routes/create.test.js index 48b6cb970e56b..4e35e2e3b38d4 100644 --- a/src/server/saved_objects/routes/create.test.js +++ b/src/server/saved_objects/routes/create.test.js @@ -57,7 +57,8 @@ describe('POST /api/saved_objects/{type}', () => { const clientResponse = { type: 'index-pattern', id: 'logstash-*', - title: 'Testing' + title: 'Testing', + references: [], }; savedObjectsClient.create.returns(Promise.resolve(clientResponse)); @@ -100,7 +101,7 @@ describe('POST /api/saved_objects/{type}', () => { expect(savedObjectsClient.create.calledOnce).toBe(true); const args = savedObjectsClient.create.getCall(0).args; - const options = { overwrite: false, id: undefined, migrationVersion: undefined }; + const options = { overwrite: false, id: undefined, migrationVersion: undefined, references: [] }; const attributes = { title: 'Testing' }; expect(args).toEqual(['index-pattern', attributes, options]); @@ -121,7 +122,7 @@ describe('POST /api/saved_objects/{type}', () => { expect(savedObjectsClient.create.calledOnce).toBe(true); const args = savedObjectsClient.create.getCall(0).args; - const options = { overwrite: false, id: 'logstash-*' }; + const options = { overwrite: false, id: 'logstash-*', references: [] }; const attributes = { title: 'Testing' }; expect(args).toEqual(['index-pattern', attributes, options]); diff --git a/src/server/saved_objects/routes/find.js b/src/server/saved_objects/routes/find.js index 27a30f0aa6427..2dd92c01e9867 100644 --- a/src/server/saved_objects/routes/find.js +++ b/src/server/saved_objects/routes/find.js @@ -34,6 +34,11 @@ export const createFindRoute = (prereqs) => ({ default_search_operator: Joi.string().valid('OR', 'AND').default('OR'), search_fields: Joi.array().items(Joi.string()).single(), sort_field: Joi.array().items(Joi.string()).single(), + has_reference: Joi.object() + .keys({ + type: Joi.string().required(), + id: Joi.string().required(), + }).optional(), fields: Joi.array().items(Joi.string()).single() }).default() }, diff --git a/src/server/saved_objects/routes/find.test.js b/src/server/saved_objects/routes/find.test.js index 5c865c22f426b..d11ac8f00cb54 100644 --- a/src/server/saved_objects/routes/find.test.js +++ b/src/server/saved_objects/routes/find.test.js @@ -74,13 +74,15 @@ describe('GET /api/saved_objects/_find', () => { id: 'logstash-*', title: 'logstash-*', timeFieldName: '@timestamp', - notExpandable: true + notExpandable: true, + references: [], }, { type: 'index-pattern', id: 'stocks-*', title: 'stocks-*', timeFieldName: '@timestamp', - notExpandable: true + notExpandable: true, + references: [], } ] }; diff --git a/src/server/saved_objects/routes/get.test.js b/src/server/saved_objects/routes/get.test.js index 63246bcf3a329..52ccb38601fb7 100644 --- a/src/server/saved_objects/routes/get.test.js +++ b/src/server/saved_objects/routes/get.test.js @@ -53,7 +53,8 @@ describe('GET /api/saved_objects/{type}/{id}', () => { id: 'logstash-*', title: 'logstash-*', timeFieldName: '@timestamp', - notExpandable: true + notExpandable: true, + references: [], }; savedObjectsClient.get.returns(Promise.resolve(clientResponse)); diff --git a/src/server/saved_objects/routes/update.js b/src/server/saved_objects/routes/update.js index cc7e2c0a4b4d1..163fb77d5b62f 100644 --- a/src/server/saved_objects/routes/update.js +++ b/src/server/saved_objects/routes/update.js @@ -32,14 +32,22 @@ export const createUpdateRoute = (prereqs) => { }).required(), payload: Joi.object({ attributes: Joi.object().required(), - version: Joi.number().min(1) + version: Joi.number().min(1), + references: Joi.array().items( + Joi.object() + .keys({ + name: Joi.string().required(), + type: Joi.string().required(), + id: Joi.string().required(), + }), + ).default([]), }).required() }, handler(request) { const { savedObjectsClient } = request.pre; const { type, id } = request.params; - const { attributes, version } = request.payload; - const options = { version }; + const { attributes, version, references } = request.payload; + const options = { version, references }; return savedObjectsClient.update(type, id, attributes, options); } diff --git a/src/server/saved_objects/routes/update.test.js b/src/server/saved_objects/routes/update.test.js index ac4d938794fda..72a540979c2de 100644 --- a/src/server/saved_objects/routes/update.test.js +++ b/src/server/saved_objects/routes/update.test.js @@ -51,7 +51,8 @@ describe('PUT /api/saved_objects/{type}/{id?}', () => { payload: { attributes: { title: 'Testing' - } + }, + references: [], } }; @@ -66,7 +67,7 @@ describe('PUT /api/saved_objects/{type}/{id?}', () => { it('calls upon savedObjectClient.update', async () => { const attributes = { title: 'Testing' }; - const options = { version: 2 }; + const options = { version: 2, references: [] }; const request = { method: 'PUT', url: '/api/saved_objects/index-pattern/logstash-*', diff --git a/src/server/saved_objects/serialization/index.ts b/src/server/saved_objects/serialization/index.ts index 09b8ddd94325a..94807ddeb7668 100644 --- a/src/server/saved_objects/serialization/index.ts +++ b/src/server/saved_objects/serialization/index.ts @@ -43,13 +43,22 @@ export interface MigrationVersion { [type: string]: string; } +/** + * A reference object to anohter saved object. + */ +export interface SavedObjectReference { + name: string; + type: string; + id: string; +} + /** * A saved object type definition that allows for miscellaneous, unknown * properties, as current discussions around security, ACLs, etc indicate * that future props are likely to be added. Migrations support this * scenario out of the box. */ -export interface SavedObjectDoc { +interface SavedObjectDoc { attributes: object; id: string; type: string; @@ -61,6 +70,19 @@ export interface SavedObjectDoc { [rootProp: string]: any; } +interface Referencable { + references: SavedObjectReference[]; +} + +/** + * We want to have two types, one that guarantees a "references" attribute + * will exist and one that allows it to be null. Since we're not migrating + * all the saved objects to have a "references" array, we need to support + * the scenarios where it may be missing (ex migrations). + */ +export type RawSavedObjectDoc = SavedObjectDoc & Partial; +export type SanitizedSavedObjectDoc = SavedObjectDoc & Referencable; + function assertNonEmptyString(value: string, name: string) { if (!value || typeof value !== 'string') { throw new TypeError(`Expected "${value}" to be a ${name}`); @@ -94,13 +116,14 @@ export class SavedObjectsSerializer { * * @param {RawDoc} rawDoc - The raw ES document to be converted to saved object format. */ - public rawToSavedObject({ _id, _source, _version }: RawDoc): SavedObjectDoc { + public rawToSavedObject({ _id, _source, _version }: RawDoc): SanitizedSavedObjectDoc { const { type, namespace } = _source; return { type, id: this.trimIdPrefix(namespace, type, _id), ...(namespace && !this.schema.isNamespaceAgnostic(type) && { namespace }), attributes: _source[type], + references: _source.references || [], ...(_source.migrationVersion && { migrationVersion: _source.migrationVersion }), ...(_source.updated_at && { updated_at: _source.updated_at }), ...(_version != null && { version: _version }), @@ -110,13 +133,23 @@ export class SavedObjectsSerializer { /** * Converts a document from the saved object client format to the format that is stored in elasticsearch. * - * @param {SavedObjectDoc} savedObj - The saved object to be converted to raw ES format. + * @param {SanitizedSavedObjectDoc} savedObj - The saved object to be converted to raw ES format. */ - public savedObjectToRaw(savedObj: SavedObjectDoc): RawDoc { - const { id, type, namespace, attributes, migrationVersion, updated_at, version } = savedObj; + public savedObjectToRaw(savedObj: SanitizedSavedObjectDoc): RawDoc { + const { + id, + type, + namespace, + attributes, + migrationVersion, + updated_at, + version, + references, + } = savedObj; const source = { [type]: attributes, type, + references, ...(namespace && !this.schema.isNamespaceAgnostic(type) && { namespace }), ...(migrationVersion && { migrationVersion }), ...(updated_at && { updated_at }), diff --git a/src/server/saved_objects/serialization/serialization.test.ts b/src/server/saved_objects/serialization/serialization.test.ts index 43ff4a2df7252..2178105fc289e 100644 --- a/src/server/saved_objects/serialization/serialization.test.ts +++ b/src/server/saved_objects/serialization/serialization.test.ts @@ -34,6 +34,24 @@ describe('saved object conversion', () => { expect(actual).toHaveProperty('type', 'foo'); }); + test('it copies the _source.references property to references', () => { + const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); + const actual = serializer.rawToSavedObject({ + _id: 'foo:bar', + _source: { + type: 'foo', + references: [{ name: 'ref_0', type: 'index-pattern', id: 'pattern*' }], + }, + }); + expect(actual).toHaveProperty('references', [ + { + name: 'ref_0', + type: 'index-pattern', + id: 'pattern*', + }, + ]); + }); + test('if specified it copies the _source.migrationVersion property to migrationVersion', () => { const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); const actual = serializer.rawToSavedObject({ @@ -95,6 +113,7 @@ describe('saved object conversion', () => { acl: '33.3.5', }, updated_at: now, + references: [], }; expect(expected).toEqual(actual); }); @@ -166,6 +185,7 @@ describe('saved object conversion', () => { attributes: { world: 'earth', }, + references: [], }); }); @@ -180,6 +200,7 @@ describe('saved object conversion', () => { expect(actual).toEqual({ id: 'universe', type: 'hello', + references: [], }); }); @@ -214,6 +235,7 @@ describe('saved object conversion', () => { }, namespace: 'foo-namespace', updated_at: new Date(), + references: [], }, }; @@ -385,6 +407,23 @@ describe('saved object conversion', () => { expect(actual._source).toHaveProperty('type', 'foo'); }); + test('it copies the references property to _source.references', () => { + const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); + const actual = serializer.savedObjectToRaw({ + id: '1', + type: 'foo', + attributes: {}, + references: [{ name: 'ref_0', type: 'index-pattern', id: 'pattern*' }], + }); + expect(actual._source).toHaveProperty('references', [ + { + name: 'ref_0', + type: 'index-pattern', + id: 'pattern*', + }, + ]); + }); + test('if specified it copies the updated_at property to _source.updated_at', () => { const serializer = new SavedObjectsSerializer(new SavedObjectsSchema()); const now = new Date(); diff --git a/src/server/saved_objects/service/lib/repository.js b/src/server/saved_objects/service/lib/repository.js index c047b6d72edc1..01b79b4050a55 100644 --- a/src/server/saved_objects/service/lib/repository.js +++ b/src/server/saved_objects/service/lib/repository.js @@ -72,6 +72,7 @@ export class SavedObjectsRepository { * @property {boolean} [options.overwrite=false] * @property {object} [options.migrationVersion=undefined] * @property {string} [options.namespace] + * @property {array} [options.references] - [{ name, type, id }] * @returns {promise} - { id, type, version, attributes } */ async create(type, attributes = {}, options = {}) { @@ -80,6 +81,7 @@ export class SavedObjectsRepository { migrationVersion, overwrite = false, namespace, + references = [], } = options; const method = id && !overwrite ? 'create' : 'index'; @@ -93,6 +95,7 @@ export class SavedObjectsRepository { attributes, migrationVersion, updated_at: time, + references, }); const raw = this._serializer.savedObjectToRaw(migrated); @@ -122,11 +125,11 @@ export class SavedObjectsRepository { /** * Creates multiple documents at once * - * @param {array} objects - [{ type, id, attributes, migrationVersion }] + * @param {array} objects - [{ type, id, attributes, references, migrationVersion }] * @param {object} [options={}] * @property {boolean} [options.overwrite=false] - overwrites existing documents * @property {string} [options.namespace] - * @returns {promise} - {saved_objects: [[{ id, type, version, attributes, error: { message } }]} + * @returns {promise} - {saved_objects: [[{ id, type, version, references, attributes, error: { message } }]} */ async bulkCreate(objects, options = {}) { const { @@ -143,6 +146,7 @@ export class SavedObjectsRepository { migrationVersion: object.migrationVersion, namespace, updated_at: time, + references: object.references || [], }); const raw = this._serializer.savedObjectToRaw(migrated); @@ -178,6 +182,7 @@ export class SavedObjectsRepository { id = responseId, type, attributes, + references = [], } = objects[i]; if (error) { @@ -202,7 +207,8 @@ export class SavedObjectsRepository { type, updated_at: time, version, - attributes + attributes, + references, }; }) }; @@ -292,6 +298,7 @@ export class SavedObjectsRepository { * @property {string} [options.sortOrder] * @property {Array} [options.fields] * @property {string} [options.namespace] + * @property {object} [options.hasReference] - { type, id } * @returns {promise} - { saved_objects: [{ id, type, version, attributes }], total, per_page, page } */ async find(options = {}) { @@ -300,6 +307,7 @@ export class SavedObjectsRepository { search, defaultSearchOperator = 'OR', searchFields, + hasReference, page = 1, perPage = 20, sortField, @@ -337,6 +345,7 @@ export class SavedObjectsRepository { sortField, sortOrder, namespace, + hasReference, }) } }; @@ -414,6 +423,7 @@ export class SavedObjectsRepository { ...time && { updated_at: time }, version: doc._version, attributes: doc._source[type], + references: doc._source.references || [], migrationVersion: doc._source.migrationVersion, }; }) @@ -456,6 +466,7 @@ export class SavedObjectsRepository { ...updatedAt && { updated_at: updatedAt }, version: response._version, attributes: response._source[type], + references: response._source.references || [], migrationVersion: response._source.migrationVersion, }; } @@ -468,12 +479,14 @@ export class SavedObjectsRepository { * @param {object} [options={}] * @property {integer} options.version - ensures version matches that of persisted object * @property {string} [options.namespace] + * @property {array} [options.references] - [{ name, type, id }] * @returns {promise} */ async update(type, id, attributes, options = {}) { const { version, - namespace + namespace, + references = [], } = options; const time = this._getCurrentTime(); @@ -488,6 +501,7 @@ export class SavedObjectsRepository { doc: { [type]: attributes, updated_at: time, + references, } }, }); @@ -502,6 +516,7 @@ export class SavedObjectsRepository { type, updated_at: time, version: response._version, + references, attributes }; } @@ -575,6 +590,7 @@ export class SavedObjectsRepository { id, type, updated_at: time, + references: response.get._source.references, version: response._version, attributes: response.get._source[type], }; diff --git a/src/server/saved_objects/service/lib/repository.test.js b/src/server/saved_objects/service/lib/repository.test.js index 2862785694211..c5e1d609d2d58 100644 --- a/src/server/saved_objects/service/lib/repository.test.js +++ b/src/server/saved_objects/service/lib/repository.test.js @@ -259,6 +259,11 @@ describe('SavedObjectsRepository', () => { }, { id: 'logstash-*', namespace: 'foo-namespace', + references: [{ + name: 'ref_0', + type: 'test', + id: '123', + }], }); expect(response).toEqual({ @@ -268,7 +273,12 @@ describe('SavedObjectsRepository', () => { version: 2, attributes: { title: 'Logstash', - } + }, + references: [{ + name: 'ref_0', + type: 'test', + id: '123', + }], }); }); @@ -428,8 +438,8 @@ describe('SavedObjectsRepository', () => { callAdminCluster.returns({ items: [] }); await savedObjectsRepository.bulkCreate([ - { type: 'config', id: 'one', attributes: { title: 'Test One' } }, - { type: 'index-pattern', id: 'two', attributes: { title: 'Test Two' } } + { type: 'config', id: 'one', attributes: { title: 'Test One' }, references: [{ name: 'ref_0', type: 'test', id: '1' }] }, + { type: 'index-pattern', id: 'two', attributes: { title: 'Test Two' }, references: [{ name: 'ref_0', type: 'test', id: '2' }] }, ]); sinon.assert.calledOnce(callAdminCluster); @@ -439,9 +449,14 @@ describe('SavedObjectsRepository', () => { expect(bulkCalls[0][1].body).toEqual([ { create: { _type: '_doc', _id: 'config:one' } }, - { type: 'config', ...mockTimestampFields, config: { title: 'Test One' } }, + { type: 'config', ...mockTimestampFields, config: { title: 'Test One' }, references: [{ name: 'ref_0', type: 'test', id: '1' }] }, { create: { _type: '_doc', _id: 'index-pattern:two' } }, - { type: 'index-pattern', ...mockTimestampFields, 'index-pattern': { title: 'Test Two' } } + { + type: 'index-pattern', + ...mockTimestampFields, + 'index-pattern': { title: 'Test Two' }, + references: [{ name: 'ref_0', type: 'test', id: '2' }], + }, ]); sinon.assert.calledOnce(onBeforeWrite); @@ -463,9 +478,21 @@ describe('SavedObjectsRepository', () => { sinon.assert.calledWithExactly(callAdminCluster, 'bulk', sinon.match({ body: [ { create: { _type: '_doc', _id: 'config:one' } }, - { type: 'config', ...mockTimestampFields, config: { title: 'Test One!!' }, migrationVersion: { foo: '2.3.4' } }, + { + type: 'config', + ...mockTimestampFields, + config: { title: 'Test One!!' }, + migrationVersion: { foo: '2.3.4' }, + references: [], + }, { create: { _type: '_doc', _id: 'index-pattern:two' } }, - { type: 'index-pattern', ...mockTimestampFields, 'index-pattern': { title: 'Test Two!!' }, migrationVersion: { foo: '2.3.4' } } + { + type: 'index-pattern', + ...mockTimestampFields, + 'index-pattern': { title: 'Test Two!!' }, + migrationVersion: { foo: '2.3.4' }, + references: [], + }, ] })); }); @@ -479,7 +506,7 @@ describe('SavedObjectsRepository', () => { body: [ // uses create because overwriting is not allowed { create: { _type: '_doc', _id: 'foo:bar' } }, - { type: 'foo', ...mockTimestampFields, 'foo': {} }, + { type: 'foo', ...mockTimestampFields, 'foo': {}, references: [] }, ] })); @@ -494,7 +521,7 @@ describe('SavedObjectsRepository', () => { body: [ // uses index because overwriting is allowed { index: { _type: '_doc', _id: 'foo:bar' } }, - { type: 'foo', ...mockTimestampFields, 'foo': {} }, + { type: 'foo', ...mockTimestampFields, 'foo': {}, references: [] }, ] })); @@ -538,6 +565,7 @@ describe('SavedObjectsRepository', () => { version: 2, ...mockTimestampFields, attributes: { title: 'Test Two' }, + references: [], } ] }); @@ -576,12 +604,14 @@ describe('SavedObjectsRepository', () => { version: 2, ...mockTimestampFields, attributes: { title: 'Test One' }, + references: [], }, { id: 'two', type: 'index-pattern', version: 2, ...mockTimestampFields, attributes: { title: 'Test Two' }, + references: [], } ] }); @@ -602,9 +632,21 @@ describe('SavedObjectsRepository', () => { sinon.assert.calledWithExactly(callAdminCluster, 'bulk', sinon.match({ body: [ { create: { _type: '_doc', _id: 'foo-namespace:config:one' } }, - { namespace: 'foo-namespace', type: 'config', ...mockTimestampFields, config: { title: 'Test One' } }, + { + namespace: 'foo-namespace', + type: 'config', + ...mockTimestampFields, + config: { title: 'Test One' }, + references: [], + }, { create: { _type: '_doc', _id: 'foo-namespace:index-pattern:two' } }, - { namespace: 'foo-namespace', type: 'index-pattern', ...mockTimestampFields, 'index-pattern': { title: 'Test Two' } } + { + namespace: 'foo-namespace', + type: 'index-pattern', + ...mockTimestampFields, + 'index-pattern': { title: 'Test Two' }, + references: [], + }, ] })); sinon.assert.calledOnce(onBeforeWrite); @@ -620,9 +662,9 @@ describe('SavedObjectsRepository', () => { sinon.assert.calledWithExactly(callAdminCluster, 'bulk', sinon.match({ body: [ { create: { _type: '_doc', _id: 'config:one' } }, - { type: 'config', ...mockTimestampFields, config: { title: 'Test One' } }, + { type: 'config', ...mockTimestampFields, config: { title: 'Test One' }, references: [] }, { create: { _type: '_doc', _id: 'index-pattern:two' } }, - { type: 'index-pattern', ...mockTimestampFields, 'index-pattern': { title: 'Test Two' } } + { type: 'index-pattern', ...mockTimestampFields, 'index-pattern': { title: 'Test Two' }, references: [] } ] })); sinon.assert.calledOnce(onBeforeWrite); @@ -642,7 +684,7 @@ describe('SavedObjectsRepository', () => { sinon.assert.calledWithExactly(callAdminCluster, 'bulk', sinon.match({ body: [ { create: { _type: '_doc', _id: 'globaltype:one' } }, - { type: 'globaltype', ...mockTimestampFields, 'globaltype': { title: 'Test One' } }, + { type: 'globaltype', ...mockTimestampFields, 'globaltype': { title: 'Test One' }, references: [] }, ] })); sinon.assert.calledOnce(onBeforeWrite); @@ -812,22 +854,29 @@ describe('SavedObjectsRepository', () => { } }); - it('passes mappings, schema, search, defaultSearchOperator, searchFields, type, sortField, and sortOrder to getSearchDsl', async () => { - callAdminCluster.returns(namespacedSearchResults); - const relevantOpts = { - namespace: 'foo-namespace', - search: 'foo*', - searchFields: ['foo'], - type: 'bar', - sortField: 'name', - sortOrder: 'desc', - defaultSearchOperator: 'AND', - }; + it( + 'passes mappings, schema, search, defaultSearchOperator, searchFields, type, sortField, sortOrder and hasReference to getSearchDsl', + async () => { + callAdminCluster.returns(namespacedSearchResults); + const relevantOpts = { + namespace: 'foo-namespace', + search: 'foo*', + searchFields: ['foo'], + type: 'bar', + sortField: 'name', + sortOrder: 'desc', + defaultSearchOperator: 'AND', + hasReference: { + type: 'foo', + id: '1', + }, + }; - await savedObjectsRepository.find(relevantOpts); - sinon.assert.calledOnce(getSearchDsl); - sinon.assert.calledWithExactly(getSearchDsl, mappings, schema, relevantOpts); - }); + await savedObjectsRepository.find(relevantOpts); + sinon.assert.calledOnce(getSearchDsl); + sinon.assert.calledWithExactly(getSearchDsl, mappings, schema, relevantOpts); + } + ); it('merges output of getSearchDsl into es request body', async () => { callAdminCluster.returns(noNamespaceSearchResults); @@ -858,7 +907,8 @@ describe('SavedObjectsRepository', () => { type: doc._source.type, ...mockTimestampFields, version: doc._version, - attributes: doc._source[doc._source.type] + attributes: doc._source[doc._source.type], + references: [], }); }); }); @@ -881,7 +931,8 @@ describe('SavedObjectsRepository', () => { type: doc._source.type, ...mockTimestampFields, version: doc._version, - attributes: doc._source[doc._source.type] + attributes: doc._source[doc._source.type], + references: [], }); }); }); @@ -970,7 +1021,8 @@ describe('SavedObjectsRepository', () => { version: 2, attributes: { title: 'Testing' - } + }, + references: [], }); }); @@ -985,7 +1037,8 @@ describe('SavedObjectsRepository', () => { version: 2, attributes: { title: 'Testing' - } + }, + references: [], }); }); @@ -1132,7 +1185,8 @@ describe('SavedObjectsRepository', () => { type: 'config', ...mockTimestampFields, version: 2, - attributes: { title: 'Test' } + attributes: { title: 'Test' }, + references: [], }); expect(savedObjects[1]).toEqual({ id: 'bad', @@ -1168,13 +1222,25 @@ describe('SavedObjectsRepository', () => { }); it('returns current ES document version', async () => { - const response = await savedObjectsRepository.update('index-pattern', 'logstash-*', attributes, { namespace: 'foo-namespace' }); + const response = await savedObjectsRepository.update('index-pattern', 'logstash-*', attributes, { + namespace: 'foo-namespace', + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], + }); expect(response).toEqual({ id, type, ...mockTimestampFields, version: newVersion, - attributes + attributes, + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], }); }); @@ -1197,6 +1263,11 @@ describe('SavedObjectsRepository', () => { title: 'Testing', }, { namespace: 'foo-namespace', + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], }); sinon.assert.calledOnce(callAdminCluster); @@ -1205,7 +1276,15 @@ describe('SavedObjectsRepository', () => { id: 'foo-namespace:index-pattern:logstash-*', version: undefined, body: { - doc: { updated_at: mockTimestamp, 'index-pattern': { title: 'Testing' } } + doc: { + updated_at: mockTimestamp, + 'index-pattern': { title: 'Testing' }, + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], + }, }, ignore: [404], refresh: 'wait_for', @@ -1216,7 +1295,15 @@ describe('SavedObjectsRepository', () => { }); it(`doesn't prepend namespace to the id or add namespace property when providing no namespace for namespaced type`, async () => { - await savedObjectsRepository.update('index-pattern', 'logstash-*', { title: 'Testing' }); + await savedObjectsRepository.update('index-pattern', 'logstash-*', { + title: 'Testing', + }, { + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], + }); sinon.assert.calledOnce(callAdminCluster); sinon.assert.calledWithExactly(callAdminCluster, 'update', { @@ -1224,7 +1311,15 @@ describe('SavedObjectsRepository', () => { id: 'index-pattern:logstash-*', version: undefined, body: { - doc: { updated_at: mockTimestamp, 'index-pattern': { title: 'Testing' } } + doc: { + updated_at: mockTimestamp, + 'index-pattern': { title: 'Testing' }, + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], + }, }, ignore: [404], refresh: 'wait_for', @@ -1239,6 +1334,11 @@ describe('SavedObjectsRepository', () => { name: 'bar', }, { namespace: 'foo-namespace', + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], }); sinon.assert.calledOnce(callAdminCluster); @@ -1247,7 +1347,15 @@ describe('SavedObjectsRepository', () => { id: 'globaltype:foo', version: undefined, body: { - doc: { updated_at: mockTimestamp, 'globaltype': { name: 'bar' } } + doc: { + updated_at: mockTimestamp, + 'globaltype': { name: 'bar' }, + references: [{ + name: 'ref_0', + type: 'test', + id: '1', + }], + }, }, ignore: [404], refresh: 'wait_for', diff --git a/src/server/saved_objects/service/lib/search_dsl/query_params.js b/src/server/saved_objects/service/lib/search_dsl/query_params.js index 47e5812e5eb2e..cd316593dde9e 100644 --- a/src/server/saved_objects/service/lib/search_dsl/query_params.js +++ b/src/server/saved_objects/service/lib/search_dsl/query_params.js @@ -99,13 +99,37 @@ function getClauseForType(schema, namespace, type) { * @param {String} search * @param {Array} searchFields * @param {String} defaultSearchOperator + * @param {Object} hasReference * @return {Object} */ -export function getQueryParams(mappings, schema, namespace, type, search, searchFields, defaultSearchOperator) { +export function getQueryParams(mappings, schema, namespace, type, search, searchFields, defaultSearchOperator, hasReference) { const types = getTypes(mappings, type); const bool = { filter: [{ bool: { + must: hasReference + ? [{ + nested: { + path: 'references', + query: { + bool: { + must: [ + { + term: { + 'references.id': hasReference.id, + }, + }, + { + term: { + 'references.type': hasReference.type, + }, + }, + ], + }, + }, + }, + }] + : undefined, should: types.map(type => getClauseForType(schema, namespace, type)), minimum_should_match: 1 } diff --git a/src/server/saved_objects/service/lib/search_dsl/query_params.test.js b/src/server/saved_objects/service/lib/search_dsl/query_params.test.js index 8e98fe3a023cb..1d0a8063be992 100644 --- a/src/server/saved_objects/service/lib/search_dsl/query_params.test.js +++ b/src/server/saved_objects/service/lib/search_dsl/query_params.test.js @@ -778,4 +778,46 @@ describe('searchDsl/queryParams', () => { }); }); }); + + describe('type (plural, namespaced and global), hasReference', () => { + it('supports hasReference', () => { + expect(getQueryParams(MAPPINGS, SCHEMA, 'foo-namespace', ['saved', 'global'], null, null, 'OR', { type: 'bar', id: '1' })) + .toEqual({ + query: { + bool: { + filter: [{ + bool: { + must: [{ + nested: { + path: 'references', + query: { + bool: { + must: [ + { + term: { + 'references.id': '1', + }, + }, + { + term: { + 'references.type': 'bar', + }, + }, + ], + }, + }, + }, + }], + should: [ + createTypeClause('saved', 'foo-namespace'), + createTypeClause('global'), + ], + minimum_should_match: 1, + } + }] + } + } + }); + }); + }); }); diff --git a/src/server/saved_objects/service/lib/search_dsl/search_dsl.js b/src/server/saved_objects/service/lib/search_dsl/search_dsl.js index d6a224f4c3857..3a11cd0c8e91d 100644 --- a/src/server/saved_objects/service/lib/search_dsl/search_dsl.js +++ b/src/server/saved_objects/service/lib/search_dsl/search_dsl.js @@ -31,6 +31,7 @@ export function getSearchDsl(mappings, schema, options = {}) { sortField, sortOrder, namespace, + hasReference, } = options; if (!type) { @@ -42,7 +43,7 @@ export function getSearchDsl(mappings, schema, options = {}) { } return { - ...getQueryParams(mappings, schema, namespace, type, search, searchFields, defaultSearchOperator), + ...getQueryParams(mappings, schema, namespace, type, search, searchFields, defaultSearchOperator, hasReference), ...getSortingParams(mappings, type, sortField, sortOrder), }; } diff --git a/src/server/saved_objects/service/lib/search_dsl/search_dsl.test.js b/src/server/saved_objects/service/lib/search_dsl/search_dsl.test.js index 1ba780fc79ed0..0600c01848346 100644 --- a/src/server/saved_objects/service/lib/search_dsl/search_dsl.test.js +++ b/src/server/saved_objects/service/lib/search_dsl/search_dsl.test.js @@ -46,7 +46,7 @@ describe('getSearchDsl', () => { }); describe('passes control', () => { - it('passes (mappings, schema, namespace, type, search, searchFields) to getQueryParams', () => { + it('passes (mappings, schema, namespace, type, search, searchFields, hasReference) to getQueryParams', () => { const spy = sandbox.spy(queryParamsNS, 'getQueryParams'); const mappings = { type: { properties: {} } }; const schema = { isNamespaceAgnostic: () => {} }; @@ -56,6 +56,10 @@ describe('getSearchDsl', () => { search: 'bar', searchFields: ['baz'], defaultSearchOperator: 'AND', + hasReference: { + type: 'bar', + id: '1', + }, }; getSearchDsl(mappings, schema, opts); @@ -69,6 +73,7 @@ describe('getSearchDsl', () => { opts.search, opts.searchFields, opts.defaultSearchOperator, + opts.hasReference, ); }); diff --git a/src/server/saved_objects/service/saved_objects_client.d.ts b/src/server/saved_objects/service/saved_objects_client.d.ts index a6e10aa1b85b1..a58cec023b335 100644 --- a/src/server/saved_objects/service/saved_objects_client.d.ts +++ b/src/server/saved_objects/service/saved_objects_client.d.ts @@ -36,7 +36,7 @@ export interface BulkCreateObject { } export interface BulkCreateResponse { - savedObjects: Array>; + saved_objects: Array>; } export interface FindOptions extends BaseOptions { @@ -68,7 +68,7 @@ export interface BulkGetObject { export type BulkGetObjects = BulkGetObject[]; export interface BulkGetResponse { - savedObjects: Array>; + saved_objects: Array>; } export interface SavedObjectAttributes { @@ -84,6 +84,13 @@ export interface SavedObject { message: string; }; attributes: T; + references: SavedObjectReference[]; +} + +export interface SavedObjectReference { + name: string; + type: string; + id: string; } export declare class SavedObjectsClient { diff --git a/src/server/saved_objects/service/saved_objects_client.js b/src/server/saved_objects/service/saved_objects_client.js index a354067e6f702..a18881ad09d41 100644 --- a/src/server/saved_objects/service/saved_objects_client.js +++ b/src/server/saved_objects/service/saved_objects_client.js @@ -148,6 +148,7 @@ export class SavedObjectsClient { * @property {string} [options.sortOrder] * @property {Array} [options.fields] * @property {string} [options.namespace] + * @property {object} [options.hasReference] - { type, id } * @returns {promise} - { saved_objects: [{ id, type, version, attributes }], total, per_page, page } */ async find(options = {}) { diff --git a/src/ui/public/courier/saved_object/__tests__/saved_object.js b/src/ui/public/courier/saved_object/__tests__/saved_object.js index 4d89ae5c19a66..9c0d092557b76 100644 --- a/src/ui/public/courier/saved_object/__tests__/saved_object.js +++ b/src/ui/public/courier/saved_object/__tests__/saved_object.js @@ -285,6 +285,32 @@ describe('Saved Object', function () { }); }); }); + + describe('with extractReferences', () => { + it('calls the function', async () => { + const id = '123'; + stubESResponse(getMockedDocResponse('id')); + let extractReferencesCallCount = 0; + const extractReferences = ({ attributes, references }) => { + extractReferencesCallCount++; + return { attributes, references }; + }; + return createInitializedSavedObject({ type: 'dashboard', extractReferences }) + .then((savedObject) => { + sinon.stub(savedObjectsClientStub, 'create').callsFake(() => { + return BluebirdPromise.resolve({ + id, + version: 2, + type: 'dashboard', + }); + }); + return savedObject.save(); + }) + .then(() => { + expect(extractReferencesCallCount).to.be(1); + }); + }); + }); }); describe('applyESResp', function () { @@ -405,6 +431,73 @@ describe('Saved Object', function () { }); }); + it('does not inject references when references array is missing', async () => { + const injectReferences = sinon.stub(); + const config = { + type: 'dashboard', + injectReferences, + }; + const savedObject = new SavedObject(config); + return savedObject.init() + .then(() => { + const response = { + found: true, + _source: { + dinosaurs: { tRex: 'has big teeth' }, + }, + }; + return savedObject.applyESResp(response); + }) + .then(() => { + expect(injectReferences).to.have.property('notCalled', true); + }); + }); + + it('does not inject references when references array is empty', async () => { + const injectReferences = sinon.stub(); + const config = { + type: 'dashboard', + injectReferences, + }; + const savedObject = new SavedObject(config); + return savedObject.init() + .then(() => { + const response = { + found: true, + _source: { + dinosaurs: { tRex: 'has big teeth' }, + }, + references: [], + }; + return savedObject.applyESResp(response); + }) + .then(() => { + expect(injectReferences).to.have.property('notCalled', true); + }); + }); + + it('injects references when function is provided and references exist', async () => { + const injectReferences = sinon.stub(); + const config = { + type: 'dashboard', + injectReferences, + }; + const savedObject = new SavedObject(config); + return savedObject.init() + .then(() => { + const response = { + found: true, + _source: { + dinosaurs: { tRex: 'has big teeth' }, + }, + references: [{}], + }; + return savedObject.applyESResp(response); + }) + .then(() => { + expect(injectReferences).to.have.property('calledOnce', true); + }); + }); }); describe ('config', function () { diff --git a/src/ui/public/courier/saved_object/saved_object.js b/src/ui/public/courier/saved_object/saved_object.js index edbfa6b898f5c..c3cf9be9491bb 100644 --- a/src/ui/public/courier/saved_object/saved_object.js +++ b/src/ui/public/courier/saved_object/saved_object.js @@ -103,6 +103,8 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm const afterESResp = config.afterESResp || _.noop; const customInit = config.init || _.noop; + const extractReferences = config.extractReferences; + const injectReferences = config.injectReferences; // optional search source which this object configures this.searchSource = config.searchSource ? new SearchSource() : undefined; @@ -117,7 +119,7 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm // in favor of a better rename/save flow. this.copyOnSave = false; - const parseSearchSource = (searchSourceJson) => { + const parseSearchSource = (searchSourceJson, references) => { if (!this.searchSource) return; // if we have a searchSource, set its values based on the searchSourceJson field @@ -136,6 +138,16 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm throw new InvalidJSONProperty(`Invalid searchSourceJSON in ${esType} "${this.id}".`); } + // Inject index id if a reference is saved + if (searchSourceValues.indexRefName) { + const reference = references.find(reference => reference.name === searchSourceValues.indexRefName); + if (!reference) { + throw new Error(`Could not find reference for ${searchSourceValues.indexRefName} on ${this.getEsType()} ${this.id}`); + } + searchSourceValues.index = reference.id; + delete searchSourceValues.indexRefName; + } + const searchSourceFields = this.searchSource.getFields(); const fnProps = _.transform(searchSourceFields, function (dynamic, val, name) { if (_.isFunction(val)) dynamic[name] = val; @@ -213,6 +225,7 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm _id: resp.id, _type: resp.type, _source: _.cloneDeep(resp.attributes), + references: resp.references, found: resp._version ? true : false }; }) @@ -254,8 +267,13 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm this.lastSavedTitle = this.title; return Promise.try(() => { - parseSearchSource(meta.searchSourceJSON); + parseSearchSource(meta.searchSourceJSON, resp.references); return this.hydrateIndexPattern(); + }).then(() => { + if (injectReferences && resp.references && resp.references.length > 0) { + injectReferences(this, resp.references); + } + return this; }).then(() => { return Promise.cast(afterESResp.call(this, resp)); }); @@ -266,12 +284,13 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm * * @return {Object} */ - this.serialize = () => { - const body = {}; + this._serialize = () => { + const attributes = {}; + const references = []; _.forOwn(mapping, (fieldMapping, fieldName) => { if (this[fieldName] != null) { - body[fieldName] = (fieldMapping._serialize) + attributes[fieldName] = (fieldMapping._serialize) ? fieldMapping._serialize(this[fieldName]) : this[fieldName]; } @@ -279,12 +298,22 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm if (this.searchSource) { const searchSourceFields = _.omit(this.searchSource.getFields(), ['sort', 'size']); - body.kibanaSavedObjectMeta = { + if (searchSourceFields.index) { + const indexId = searchSourceFields.index; + searchSourceFields.indexRefName = 'kibanaSavedObjectMeta.searchSourceJSON.index'; + references.push({ + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: indexId, + }); + delete searchSourceFields.index; + } + attributes.kibanaSavedObjectMeta = { searchSourceJSON: angular.toJson(searchSourceFields) }; } - return body; + return { attributes, references }; }; /** @@ -304,16 +333,17 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm /** * Attempts to create the current object using the serialized source. If an object already * exists, a warning message requests an overwrite confirmation. - * @param source - serialized version of this object (return value from this.serialize()) + * @param source - serialized version of this object (return value from this._serialize()) * What will be indexed into elasticsearch. + * @param options - options to pass to the saved object create method * @returns {Promise} - A promise that is resolved with the objects id if the object is * successfully indexed. If the overwrite confirmation was rejected, an error is thrown with * a confirmRejected = true parameter so that case can be handled differently than * a create or index error. * @resolved {SavedObject} */ - const createSource = (source) => { - return savedObjectsClient.create(esType, source, this.creationOpts()) + const createSource = (source, options = {}) => { + return savedObjectsClient.create(esType, source, options) .catch(err => { // record exists, confirm overwriting if (_.get(err, 'res.status') === 409) { @@ -331,7 +361,7 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm values: { name: this.getDisplayName() } }), }) - .then(() => savedObjectsClient.create(esType, source, this.creationOpts({ overwrite: true }))) + .then(() => savedObjectsClient.create(esType, source, this.creationOpts({ overwrite: true, ...options }))) .catch(() => Promise.reject(new Error(OVERWRITE_REJECTED))); } return Promise.reject(err); @@ -406,16 +436,21 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm this.id = null; } - const source = this.serialize(); + // Here we want to extract references and set them within "references" attribute + let { attributes, references } = this._serialize(); + if (extractReferences) { + ({ attributes, references } = extractReferences({ attributes, references })); + } + if (!references) throw new Error('References not returned from extractReferences'); this.isSaving = true; return checkForDuplicateTitle(isTitleDuplicateConfirmed, onTitleDuplicate) .then(() => { if (confirmOverwrite) { - return createSource(source); + return createSource(attributes, this.creationOpts({ references })); } else { - return savedObjectsClient.create(esType, source, this.creationOpts({ overwrite: true })); + return savedObjectsClient.create(esType, attributes, this.creationOpts({ references, overwrite: true })); } }) .then((resp) => { diff --git a/src/ui/public/saved_objects/saved_object.js b/src/ui/public/saved_objects/saved_object.js index 9287b9e313d8f..ed3bbfe9b0fb1 100644 --- a/src/ui/public/saved_objects/saved_object.js +++ b/src/ui/public/saved_objects/saved_object.js @@ -20,11 +20,12 @@ import _ from 'lodash'; export class SavedObject { - constructor(client, { id, type, version, attributes, error, migrationVersion } = {}) { + constructor(client, { id, type, version, attributes, error, migrationVersion, references } = {}) { this._client = client; this.id = id; this.type = type; this.attributes = attributes || {}; + this.references = references || []; this._version = version; this.migrationVersion = migrationVersion; if (error) { @@ -46,9 +47,17 @@ export class SavedObject { save() { if (this.id) { - return this._client.update(this.type, this.id, this.attributes, { migrationVersion: this.migrationVersion }); + return this._client.update( + this.type, + this.id, + this.attributes, + { + migrationVersion: this.migrationVersion, + references: this.references, + }, + ); } else { - return this._client.create(this.type, this.attributes, { migrationVersion: this.migrationVersion }); + return this._client.create(this.type, this.attributes, { migrationVersion: this.migrationVersion, references: this.references }); } } diff --git a/src/ui/public/saved_objects/saved_objects_client.js b/src/ui/public/saved_objects/saved_objects_client.js index eba1acebabe4b..0ee4c2ff47ad3 100644 --- a/src/ui/public/saved_objects/saved_objects_client.js +++ b/src/ui/public/saved_objects/saved_objects_client.js @@ -51,6 +51,7 @@ export class SavedObjectsClient { * @property {string} [options.id] - force id on creation, not recommended * @property {boolean} [options.overwrite=false] * @property {object} [options.migrationVersion] + * @property {array} [options.references] [{ name, type, id }] * @returns {promise} - SavedObject({ id, type, version, attributes }) */ create = (type, attributes = {}, options = {}) => { @@ -61,7 +62,17 @@ export class SavedObjectsClient { const path = this._getPath([type, options.id]); const query = _.pick(options, ['overwrite']); - return this._request({ method: 'POST', path, query, body: { attributes, migrationVersion: options.migrationVersion } }) + return this + ._request({ + method: 'POST', + path, + query, + body: { + attributes, + migrationVersion: options.migrationVersion, + references: options.references, + }, + }) .catch(error => { if (isAutoCreateIndexError(error)) { return showAutoCreateIndexErrorPage(); @@ -75,7 +86,7 @@ export class SavedObjectsClient { /** * Creates multiple documents at once * - * @param {array} objects - [{ type, id, attributes, migrationVersion }] + * @param {array} objects - [{ type, id, attributes, references, migrationVersion }] * @param {object} [options={}] * @property {boolean} [options.overwrite=false] * @returns {promise} - { savedObjects: [{ id, type, version, attributes, error: { message } }]} @@ -117,6 +128,7 @@ export class SavedObjectsClient { * @property {integer} [options.page=1] * @property {integer} [options.perPage=20] * @property {array} options.fields + * @property {object} [options.hasReference] - { type, id } * @returns {promise} - { savedObjects: [ SavedObject({ id, type, version, attributes }) ]} */ find = (options = {}) => { @@ -178,9 +190,10 @@ export class SavedObjectsClient { * @param {object} options * @prop {integer} options.version - ensures version matches that of persisted object * @prop {object} options.migrationVersion - The optional migrationVersion of this document + * @prop {array} option.references - the references of the saved object * @returns {promise} */ - update(type, id, attributes, { version, migrationVersion } = {}) { + update(type, id, attributes, { version, migrationVersion, references } = {}) { if (!type || !id || !attributes) { return Promise.reject(new Error('requires type, id and attributes')); } @@ -189,6 +202,7 @@ export class SavedObjectsClient { const body = { attributes, migrationVersion, + references, version }; diff --git a/test/api_integration/apis/management/saved_objects/relationships.js b/test/api_integration/apis/management/saved_objects/relationships.js index 45b0a8b82e4a2..e31a5fe3aaa7e 100644 --- a/test/api_integration/apis/management/saved_objects/relationships.js +++ b/test/api_integration/apis/management/saved_objects/relationships.js @@ -40,8 +40,8 @@ export default function ({ getService }) { after(() => esArchiver.unload('management/saved_objects')); const SEARCH_RESPONSE_SCHEMA = Joi.object().keys({ - visualizations: GENERIC_RESPONSE_SCHEMA, - indexPatterns: GENERIC_RESPONSE_SCHEMA, + visualization: GENERIC_RESPONSE_SCHEMA, + 'index-pattern': GENERIC_RESPONSE_SCHEMA, }); describe('searches', async () => { @@ -61,13 +61,13 @@ export default function ({ getService }) { .expect(200) .then(resp => { expect(resp.body).to.eql({ - visualizations: [ + visualization: [ { id: 'a42c0580-3224-11e8-a572-ffca06da1357', title: 'VisualizationFromSavedSearch', }, ], - indexPatterns: [ + 'index-pattern': [ { id: '8963ca30-3224-11e8-a572-ffca06da1357', title: 'saved_objects*', @@ -85,7 +85,7 @@ export default function ({ getService }) { describe('dashboards', async () => { const DASHBOARD_RESPONSE_SCHEMA = Joi.object().keys({ - visualizations: GENERIC_RESPONSE_SCHEMA, + visualization: GENERIC_RESPONSE_SCHEMA, }); it('should validate dashboard response schema', async () => { @@ -104,7 +104,7 @@ export default function ({ getService }) { .expect(200) .then(resp => { expect(resp.body).to.eql({ - visualizations: [ + visualization: [ { id: 'add810b0-3224-11e8-a572-ffca06da1357', title: 'Visualization', @@ -128,7 +128,8 @@ export default function ({ getService }) { describe('visualizations', async () => { const VISUALIZATIONS_RESPONSE_SCHEMA = Joi.object().keys({ - dashboards: GENERIC_RESPONSE_SCHEMA, + dashboard: GENERIC_RESPONSE_SCHEMA, + search: GENERIC_RESPONSE_SCHEMA, }); it('should validate visualization response schema', async () => { @@ -147,7 +148,13 @@ export default function ({ getService }) { .expect(200) .then(resp => { expect(resp.body).to.eql({ - dashboards: [ + search: [ + { + id: '960372e0-3224-11e8-a572-ffca06da1357', + title: 'OneRecord' + }, + ], + dashboard: [ { id: 'b70c7ae0-3224-11e8-a572-ffca06da1357', title: 'Dashboard', @@ -166,8 +173,8 @@ export default function ({ getService }) { describe('index patterns', async () => { const INDEX_PATTERN_RESPONSE_SCHEMA = Joi.object().keys({ - searches: GENERIC_RESPONSE_SCHEMA, - visualizations: GENERIC_RESPONSE_SCHEMA, + search: GENERIC_RESPONSE_SCHEMA, + visualization: GENERIC_RESPONSE_SCHEMA, }); it('should validate visualization response schema', async () => { @@ -186,13 +193,13 @@ export default function ({ getService }) { .expect(200) .then(resp => { expect(resp.body).to.eql({ - searches: [ + search: [ { id: '960372e0-3224-11e8-a572-ffca06da1357', title: 'OneRecord', }, ], - visualizations: [ + visualization: [ { id: 'add810b0-3224-11e8-a572-ffca06da1357', title: 'Visualization', diff --git a/test/api_integration/apis/saved_objects/bulk_create.js b/test/api_integration/apis/saved_objects/bulk_create.js index 153dda4691fa6..074af9f775dde 100644 --- a/test/api_integration/apis/saved_objects/bulk_create.js +++ b/test/api_integration/apis/saved_objects/bulk_create.js @@ -69,7 +69,8 @@ export default function ({ getService }) { version: 1, attributes: { title: 'A great new dashboard' - } + }, + references: [], }, ] }); @@ -101,7 +102,8 @@ export default function ({ getService }) { version: 1, attributes: { title: 'An existing visualization' - } + }, + references: [], }, { type: 'dashboard', @@ -110,7 +112,8 @@ export default function ({ getService }) { version: 1, attributes: { title: 'A great new dashboard' - } + }, + references: [], }, ] }); diff --git a/test/api_integration/apis/saved_objects/bulk_get.js b/test/api_integration/apis/saved_objects/bulk_get.js index 68773e5124039..da208a5cbe70a 100644 --- a/test/api_integration/apis/saved_objects/bulk_get.js +++ b/test/api_integration/apis/saved_objects/bulk_get.js @@ -68,7 +68,15 @@ export default function ({ getService }) { visState: resp.body.saved_objects[0].attributes.visState, uiStateJSON: resp.body.saved_objects[0].attributes.uiStateJSON, kibanaSavedObjectMeta: resp.body.saved_objects[0].attributes.kibanaSavedObjectMeta - } + }, + migrationVersion: { + visualization: '7.0.0', + }, + references: [{ + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '91200a00-9efd-11e7-acb3-3dab96693fab', + }], }, { id: 'does not exist', @@ -86,7 +94,8 @@ export default function ({ getService }) { attributes: { buildNum: 8467, defaultIndex: '91200a00-9efd-11e7-acb3-3dab96693fab' - } + }, + references: [], } ] }); diff --git a/test/api_integration/apis/saved_objects/create.js b/test/api_integration/apis/saved_objects/create.js index 379539928ebaf..a4e66318fb01e 100644 --- a/test/api_integration/apis/saved_objects/create.js +++ b/test/api_integration/apis/saved_objects/create.js @@ -54,7 +54,11 @@ export default function ({ getService }) { version: 1, attributes: { title: 'My favorite vis' - } + }, + migrationVersion: { + visualization: '7.0.0', + }, + references: [], }); }); }); @@ -95,7 +99,11 @@ export default function ({ getService }) { version: 1, attributes: { title: 'My favorite vis' - } + }, + migrationVersion: { + visualization: '7.0.0', + }, + references: [], }); }); diff --git a/test/api_integration/apis/saved_objects/find.js b/test/api_integration/apis/saved_objects/find.js index c9b1e9fc73f4a..515f4501517bc 100644 --- a/test/api_integration/apis/saved_objects/find.js +++ b/test/api_integration/apis/saved_objects/find.js @@ -45,7 +45,8 @@ export default function ({ getService }) { version: 1, attributes: { 'title': 'Count of requests' - } + }, + references: [], } ] }); diff --git a/test/api_integration/apis/saved_objects/get.js b/test/api_integration/apis/saved_objects/get.js index 22ea4798f4324..0734918f5f3e4 100644 --- a/test/api_integration/apis/saved_objects/get.js +++ b/test/api_integration/apis/saved_objects/get.js @@ -42,6 +42,9 @@ export default function ({ getService }) { type: 'visualization', updated_at: '2017-09-21T18:51:23.794Z', version: resp.body.version, + migrationVersion: { + visualization: '7.0.0', + }, attributes: { title: 'Count of requests', description: '', @@ -50,7 +53,12 @@ export default function ({ getService }) { visState: resp.body.attributes.visState, uiStateJSON: resp.body.attributes.uiStateJSON, kibanaSavedObjectMeta: resp.body.attributes.kibanaSavedObjectMeta - } + }, + references: [{ + type: 'index-pattern', + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + id: '91200a00-9efd-11e7-acb3-3dab96693fab', + }], }); }) )); diff --git a/test/api_integration/apis/saved_objects/migrations.js b/test/api_integration/apis/saved_objects/migrations.js index 260609d3b881e..a4993658837f2 100644 --- a/test/api_integration/apis/saved_objects/migrations.js +++ b/test/api_integration/apis/saved_objects/migrations.js @@ -85,11 +85,11 @@ export default ({ getService }) => { // The docs in the alias have been migrated assert.deepEqual(await fetchDocs({ callCluster, index }), [ - { id: 'bar:i', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 68 } }, - { id: 'bar:o', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 6 } }, - { id: 'baz:u', type: 'baz', baz: { title: 'Terrific!' } }, - { id: 'foo:a', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOO A' } }, - { id: 'foo:e', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOOEY' } }, + { id: 'bar:i', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 68 }, references: [] }, + { id: 'bar:o', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 6 }, references: [] }, + { id: 'baz:u', type: 'baz', baz: { title: 'Terrific!' }, references: [] }, + { id: 'foo:a', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOO A' }, references: [] }, + { id: 'foo:e', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOOEY' }, references: [] }, ]); }); @@ -131,10 +131,10 @@ export default ({ getService }) => { // The index for the initial migration has not been destroyed... assert.deepEqual(await fetchDocs({ callCluster, index: `${index}_2` }), [ - { id: 'bar:i', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 68 } }, - { id: 'bar:o', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 6 } }, - { id: 'foo:a', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOO A' } }, - { id: 'foo:e', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOOEY' } }, + { id: 'bar:i', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 68 }, references: [] }, + { id: 'bar:o', type: 'bar', migrationVersion: { bar: '1.9.0' }, bar: { mynum: 6 }, references: [] }, + { id: 'foo:a', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOO A' }, references: [] }, + { id: 'foo:e', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'FOOEY' }, references: [] }, ]); // The docs were migrated again... @@ -144,15 +144,17 @@ export default ({ getService }) => { type: 'bar', migrationVersion: { bar: '2.3.4' }, bar: { mynum: 68, name: 'NAME i' }, + references: [], }, { id: 'bar:o', type: 'bar', migrationVersion: { bar: '2.3.4' }, bar: { mynum: 6, name: 'NAME o' }, + references: [], }, - { id: 'foo:a', type: 'foo', migrationVersion: { foo: '2.0.1' }, foo: { name: 'FOO Av2' } }, - { id: 'foo:e', type: 'foo', migrationVersion: { foo: '2.0.1' }, foo: { name: 'FOOEYv2' } }, + { id: 'foo:a', type: 'foo', migrationVersion: { foo: '2.0.1' }, foo: { name: 'FOO Av2' }, references: [] }, + { id: 'foo:e', type: 'foo', migrationVersion: { foo: '2.0.1' }, foo: { name: 'FOOEYv2' }, references: [] }, ]); }); @@ -203,7 +205,7 @@ export default ({ getService }) => { // The docs in the alias have been migrated assert.deepEqual(await fetchDocs({ callCluster, index }), [ - { id: 'foo:lotr', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'LOTR' } }, + { id: 'foo:lotr', type: 'foo', migrationVersion: { foo: '1.0.0' }, foo: { name: 'LOTR' }, references: [] }, ]); }); }); diff --git a/test/api_integration/apis/saved_objects/update.js b/test/api_integration/apis/saved_objects/update.js index e6ca3d0317bf3..a00ab69783cb0 100644 --- a/test/api_integration/apis/saved_objects/update.js +++ b/test/api_integration/apis/saved_objects/update.js @@ -51,7 +51,8 @@ export default function ({ getService }) { version: 2, attributes: { title: 'My second favorite vis' - } + }, + references: [], }); }); }); diff --git a/x-pack/plugins/graph/index.js b/x-pack/plugins/graph/index.js index 83134f20d4f82..39dbc148772ec 100644 --- a/x-pack/plugins/graph/index.js +++ b/x-pack/plugins/graph/index.js @@ -7,6 +7,7 @@ import { resolve } from 'path'; import Boom from 'boom'; +import migrations from './migrations'; import { initServer } from './server'; import mappings from './mappings.json'; @@ -28,7 +29,8 @@ export function graph(kibana) { styleSheetPaths: resolve(__dirname, 'public/index.scss'), hacks: ['plugins/graph/hacks/toggle_app_link_in_nav'], home: ['plugins/graph/register_feature'], - mappings + mappings, + migrations, }, config(Joi) { diff --git a/x-pack/plugins/graph/migrations.js b/x-pack/plugins/graph/migrations.js new file mode 100644 index 0000000000000..d454de49f2b00 --- /dev/null +++ b/x-pack/plugins/graph/migrations.js @@ -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 { get } from 'lodash'; + +export default { + 'graph-workspace': { + '7.0.0': (doc) => { + // Set new "references" attribute + doc.references = doc.references || []; + // Migrate index pattern + const wsState = get(doc, 'attributes.wsState'); + if (typeof wsState !== 'string') { + return doc; + } + let state; + try { + state = JSON.parse(JSON.parse(wsState)); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + return doc; + } + const { indexPattern } = state; + if (!indexPattern) { + return doc; + } + state.indexPatternRefName = 'indexPattern_0'; + delete state.indexPattern; + doc.attributes.wsState = JSON.stringify(JSON.stringify(state)); + doc.references.push({ + name: 'indexPattern_0', + type: 'index-pattern', + id: indexPattern, + }); + return doc; + } + } +}; diff --git a/x-pack/plugins/graph/migrations.test.js b/x-pack/plugins/graph/migrations.test.js new file mode 100644 index 0000000000000..93162d94857ce --- /dev/null +++ b/x-pack/plugins/graph/migrations.test.js @@ -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 migrations from './migrations'; + +describe('graph-workspace', () => { + describe('7.0.0', () => { + const migration = migrations['graph-workspace']['7.0.0']; + + test('returns doc on empty object', () => { + expect(migration({})).toMatchInlineSnapshot(` +Object { + "references": Array [], +} +`); + }); + + test('returns doc when wsState is not a string', () => { + const doc = { + id: '1', + attributes: { + wsState: true, + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "wsState": true, + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('returns doc when wsState is not valid JSON', () => { + const doc = { + id: '1', + attributes: { + wsState: '123abc', + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "wsState": "123abc", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('returns doc when "indexPattern" is missing from wsState', () => { + const doc = { + id: '1', + attributes: { + wsState: JSON.stringify(JSON.stringify({ foo: true })), + }, + }; + expect(migration(doc)).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "wsState": "\\"{\\\\\\"foo\\\\\\":true}\\"", + }, + "id": "1", + "references": Array [], +} +`); + }); + + test('extract "indexPattern" attribute from doc', () => { + const doc = { + id: '1', + attributes: { + wsState: JSON.stringify(JSON.stringify({ foo: true, indexPattern: 'pattern*' })), + bar: true, + }, + }; + const migratedDoc = migration(doc); + expect(migratedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "bar": true, + "wsState": "\\"{\\\\\\"foo\\\\\\":true,\\\\\\"indexPatternRefName\\\\\\":\\\\\\"indexPattern_0\\\\\\"}\\"", + }, + "id": "1", + "references": Array [ + Object { + "id": "pattern*", + "name": "indexPattern_0", + "type": "index-pattern", + }, + ], +} +`); + }); + }); +}); diff --git a/x-pack/plugins/graph/public/services/saved_workspace.js b/x-pack/plugins/graph/public/services/saved_workspace.js index eb0c0e1dd936a..f25743900dab8 100644 --- a/x-pack/plugins/graph/public/services/saved_workspace.js +++ b/x-pack/plugins/graph/public/services/saved_workspace.js @@ -7,6 +7,10 @@ import { uiModules } from 'ui/modules'; import { SavedObjectProvider } from 'ui/courier'; import { i18n } from '@kbn/i18n'; +import { + extractReferences, + injectReferences, +} from './saved_workspace_references'; const module = uiModules.get('app/dashboard'); @@ -21,6 +25,8 @@ export function SavedWorkspaceProvider(Private) { type: SavedWorkspace.type, mapping: SavedWorkspace.mapping, searchSource: SavedWorkspace.searchsource, + extractReferences: extractReferences, + injectReferences: injectReferences, // if this is null/undefined then the SavedObject will be assigned the defaults id: id, diff --git a/x-pack/plugins/graph/public/services/saved_workspace_references.js b/x-pack/plugins/graph/public/services/saved_workspace_references.js new file mode 100644 index 0000000000000..a1b4254685c40 --- /dev/null +++ b/x-pack/plugins/graph/public/services/saved_workspace_references.js @@ -0,0 +1,53 @@ +/* + * 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 function extractReferences({ attributes, references = [] }) { + // For some reason, wsState comes in stringified 2x + const state = JSON.parse(JSON.parse(attributes.wsState)); + const { indexPattern } = state; + if (!indexPattern) { + throw new Error('indexPattern attribute is missing in "wsState"'); + } + state.indexPatternRefName = 'indexPattern_0'; + delete state.indexPattern; + return { + references: [ + ...references, + { + name: 'indexPattern_0', + type: 'index-pattern', + id: indexPattern, + } + ], + attributes: { + ...attributes, + wsState: JSON.stringify(JSON.stringify(state)), + }, + }; +} + +export function injectReferences(savedObject, references) { + // Skip if wsState is missing, at the time of development of this, there is no guarantee each + // saved object has wsState. + if (typeof savedObject.wsState !== 'string') { + return; + } + // Only need to parse / stringify once here compared to extractReferences + const state = JSON.parse(savedObject.wsState); + // Like the migration, skip injectReferences if "indexPatternRefName" is missing + if (!state.indexPatternRefName) { + return; + } + const indexPatternReference = references.find(reference => reference.name === state.indexPatternRefName); + if (!indexPatternReference) { + // Throw an error as "indexPatternRefName" means the reference exists within + // "references" and in this scenario we have bad data. + throw new Error(`Could not find reference "${state.indexPatternRefName}"`); + } + state.indexPattern = indexPatternReference.id; + delete state.indexPatternRefName; + savedObject.wsState = JSON.stringify(state); +} diff --git a/x-pack/plugins/graph/public/services/saved_workspace_references.test.js b/x-pack/plugins/graph/public/services/saved_workspace_references.test.js new file mode 100644 index 0000000000000..01eb7f9ead1f0 --- /dev/null +++ b/x-pack/plugins/graph/public/services/saved_workspace_references.test.js @@ -0,0 +1,124 @@ +/* + * 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 { extractReferences, injectReferences } from './saved_workspace_references'; + +describe('extractReferences', () => { + test('extracts references from wsState', () => { + const doc = { + id: '1', + attributes: { + foo: true, + wsState: JSON.stringify( + JSON.stringify({ + indexPattern: 'pattern*', + bar: true, + }) + ), + }, + }; + const updatedDoc = extractReferences(doc); + expect(updatedDoc).toMatchInlineSnapshot(` +Object { + "attributes": Object { + "foo": true, + "wsState": "\\"{\\\\\\"bar\\\\\\":true,\\\\\\"indexPatternRefName\\\\\\":\\\\\\"indexPattern_0\\\\\\"}\\"", + }, + "references": Array [ + Object { + "id": "pattern*", + "name": "indexPattern_0", + "type": "index-pattern", + }, + ], +} +`); + }); + + test('fails when indexPattern is missing from workspace', () => { + const doc = { + id: '1', + attributes: { + wsState: JSON.stringify( + JSON.stringify({ + bar: true, + }) + ), + }, + }; + expect(() => extractReferences(doc)).toThrowErrorMatchingInlineSnapshot( + `"indexPattern attribute is missing in \\"wsState\\""` + ); + }); +}); + +describe('injectReferences', () => { + test('injects references into context', () => { + const context = { + id: '1', + foo: true, + wsState: JSON.stringify({ + indexPatternRefName: 'indexPattern_0', + bar: true, + }), + }; + const references = [ + { + name: 'indexPattern_0', + type: 'index-pattern', + id: 'pattern*', + }, + ]; + injectReferences(context, references); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", + "wsState": "{\\"bar\\":true,\\"indexPattern\\":\\"pattern*\\"}", +} +`); + }); + + test('skips when wsState is not a string', () => { + const context = { + id: '1', + foo: true, + }; + injectReferences(context, []); + expect(context).toMatchInlineSnapshot(` +Object { + "foo": true, + "id": "1", +} +`); + }); + + test('skips when indexPatternRefName is missing wsState', () => { + const context = { + id: '1', + wsState: JSON.stringify({ bar: true }), + }; + injectReferences(context, []); + expect(context).toMatchInlineSnapshot(` +Object { + "id": "1", + "wsState": "{\\"bar\\":true}", +} +`); + }); + + test(`fails when it can't find the reference in the array`, () => { + const context = { + id: '1', + wsState: JSON.stringify({ + indexPatternRefName: 'indexPattern_0', + }), + }; + expect(() => injectReferences(context, [])).toThrowErrorMatchingInlineSnapshot( + `"Could not find reference \\"indexPattern_0\\""` + ); + }); +}); diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json index 5fc696c6c702d..24b87e39b35db 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Access-Remote-IP-Count-Explorer.json @@ -7,6 +7,7 @@ "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Remote-IP-Timechart\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Map\",\"col\":7,\"row\":4},{\"size_x\":12,\"size_y\":9,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]", "optionsJSON": "{}", "version": 1, + "migrationVersion": {}, "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}" } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json index b04050ceb6e19..d4ef153201bf2 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/dashboard/ML-Apache2-Remote-IP-URL-Explorer.json @@ -7,6 +7,7 @@ "panelsJSON": "[{\"col\":1,\"id\":\"ML-Apache2-Access-Unique-Count-URL-Timechart\",\"panelIndex\":1,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Response-Code-Timechart\",\"panelIndex\":2,\"row\":1,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ML-Apache2-Access-Top-Remote-IPs-Table\",\"panelIndex\":3,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"ML-Apache2-Access-Map\",\"panelIndex\":4,\"row\":4,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"size_x\":12,\"size_y\":8,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ML-Apache2-Access-Top-URLs-Table\",\"col\":1,\"row\":7}]", "optionsJSON": "{}", "version": 1, + "migrationVersion": {}, "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}],\"highlightAll\":true,\"version\":true}" } diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/search/ML-Filebeat-Apache2-Access.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/search/ML-Filebeat-Apache2-Access.json index edb54752c2ffe..7c6124295aae3 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/search/ML-Filebeat-Apache2-Access.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/search/ML-Filebeat-Apache2-Access.json @@ -7,6 +7,7 @@ "description": "Filebeat Apache2 Access Data", "title": "ML Apache2 Access Data", "version": 1, + "migrationVersion": {}, "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"index\":\"INDEX_PATTERN_ID\",\"query\":{\"query_string\":{\"query\":\"_exists_:apache2.access\",\"analyze_wildcard\":true}},\"filter\":[],\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@/kibana-highlighted-field@\"],\"fields\":{\"*\":{}},\"require_field_match\":false,\"fragment_size\":2147483647}}" }, diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Map.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Map.json index f782f329c037b..c2df807f18985 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Map.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Map.json @@ -1,11 +1,12 @@ { - "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"autoPrecision\":true,\"field\":\"apache2.access.geoip.location\"},\"schema\":\"segment\",\"type\":\"geohash_grid\"}],\"listeners\":{},\"params\":{\"addTooltip\":true,\"heatBlur\":15,\"heatMaxZoom\":16,\"heatMinOpacity\":0.1,\"heatNormalizeData\":true,\"heatRadius\":25,\"isDesaturated\":true,\"legendPosition\":\"bottomright\",\"mapCenter\":[15,5],\"mapType\":\"Scaled Circle Markers\",\"mapZoom\":2,\"wms\":{\"enabled\":false,\"options\":{\"attribution\":\"Maps provided by USGS\",\"format\":\"image/png\",\"layers\":\"0\",\"styles\":\"\",\"transparent\":true,\"version\":\"1.3.0\"},\"url\":\"https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer\"}},\"title\":\"ML Apache2 Access Map\",\"type\":\"tile_map\"}", - "description": "", - "title": "ML Apache2 Access Map", - "uiStateJSON": "{\n \"mapCenter\": [\n 12.039320557540572,\n -0.17578125\n ]\n}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"autoPrecision\":true,\"field\":\"apache2.access.geoip.location\"},\"schema\":\"segment\",\"type\":\"geohash_grid\"}],\"listeners\":{},\"params\":{\"addTooltip\":true,\"heatBlur\":15,\"heatMaxZoom\":16,\"heatMinOpacity\":0.1,\"heatNormalizeData\":true,\"heatRadius\":25,\"isDesaturated\":true,\"legendPosition\":\"bottomright\",\"mapCenter\":[15,5],\"mapType\":\"Scaled Circle Markers\",\"mapZoom\":2,\"wms\":{\"enabled\":false,\"options\":{\"attribution\":\"Maps provided by USGS\",\"format\":\"image/png\",\"layers\":\"0\",\"styles\":\"\",\"transparent\":true,\"version\":\"1.3.0\"},\"url\":\"https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer\"}},\"title\":\"ML Apache2 Access Map\",\"type\":\"tile_map\"}", + "description": "", + "title": "ML Apache2 Access Map", + "uiStateJSON": "{\n \"mapCenter\": [\n 12.039320557540572,\n -0.17578125\n ]\n}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"filter\":[]}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Remote-IP-Timechart.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Remote-IP-Timechart.json index dcceff40a2c0f..0789ee1e03f6f 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Remote-IP-Timechart.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Remote-IP-Timechart.json @@ -1,11 +1,12 @@ { - "visState": "{\"title\":\"ML Apache2 Access Remote IP Timechart\",\"type\":\"area\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"@timestamp per 5 minutes\"},\"type\":\"category\"}],\"defaultYExtents\":false,\"drawLinesBetweenPoints\":true,\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"interpolate\":\"linear\",\"legendPosition\":\"right\",\"radiusRatio\":9,\"scale\":\"linear\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"interpolate\":\"linear\",\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"area\",\"valueAxis\":\"ValueAxis-1\"}],\"setYExtents\":false,\"showCircles\":true,\"times\":[],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"apache2.access.remote_ip\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", - "description": "", - "title": "ML Apache2 Access Remote IP Timechart", - "uiStateJSON": "{\"vis\":{\"legendOpen\":false}}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"title\":\"ML Apache2 Access Remote IP Timechart\",\"type\":\"area\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"@timestamp per 5 minutes\"},\"type\":\"category\"}],\"defaultYExtents\":false,\"drawLinesBetweenPoints\":true,\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"interpolate\":\"linear\",\"legendPosition\":\"right\",\"radiusRatio\":9,\"scale\":\"linear\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"interpolate\":\"linear\",\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"area\",\"valueAxis\":\"ValueAxis-1\"}],\"setYExtents\":false,\"showCircles\":true,\"times\":[],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"apache2.access.remote_ip\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML Apache2 Access Remote IP Timechart", + "uiStateJSON": "{\"vis\":{\"legendOpen\":false}}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Response-Code-Timechart.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Response-Code-Timechart.json index f52019014b138..bc0a22685d5cf 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Response-Code-Timechart.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Response-Code-Timechart.json @@ -1,11 +1,12 @@ { - "visState": "{\"title\":\"ML Apache2 Access Response Code Timechart\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"apache2.access.response_code\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", - "description": "", - "title": "ML Apache2 Access Response Code Timechart", - "uiStateJSON": "{\n \"vis\": {\n \"colors\": {\n \"200\": \"#7EB26D\",\n \"404\": \"#614D93\"\n }\n }\n}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"title\":\"ML Apache2 Access Response Code Timechart\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"apache2.access.response_code\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML Apache2 Access Response Code Timechart", + "uiStateJSON": "{\n \"vis\": {\n \"colors\": {\n \"200\": \"#7EB26D\",\n \"404\": \"#614D93\"\n }\n }\n}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{\"filter\":[]}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-Remote-IPs-Table.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-Remote-IPs-Table.json index 0c49d9de46001..38943fd9ee6ac 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-Remote-IPs-Table.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-Remote-IPs-Table.json @@ -1,11 +1,12 @@ { - "visState": "{\"title\":\"ML Apache2 Access Top Remote IPs Table\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"apache2.access.remote_ip\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", - "description": "", - "title": "ML Apache2 Access Top Remote IPs Table", - "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"title\":\"ML Apache2 Access Top Remote IPs Table\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"apache2.access.remote_ip\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML Apache2 Access Top Remote IPs Table", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-URLs-Table.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-URLs-Table.json index ab7760feff999..406c314787c72 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-URLs-Table.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Top-URLs-Table.json @@ -1,11 +1,12 @@ { - "visState": "{\"title\":\"ML Apache2 Access Top URLs Table\",\"type\":\"table\",\"params\":{\"perPage\":100,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"apache2.access.url\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", - "description": "", - "title": "ML Apache2 Access Top URLs Table", - "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"title\":\"ML Apache2 Access Top URLs Table\",\"type\":\"table\",\"params\":{\"perPage\":100,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"apache2.access.url\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML Apache2 Access Top URLs Table", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Unique-Count-URL-Timechart.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Unique-Count-URL-Timechart.json index c6ce4fcf741eb..54d324434925c 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Unique-Count-URL-Timechart.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache2/kibana/visualization/ML-Apache2-Access-Unique-Count-URL-Timechart.json @@ -1,11 +1,12 @@ { - "visState": "{\"title\":\"ML Apache2 Access Unique Count URL Timechart\",\"type\":\"line\",\"params\":{\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{\"text\":\"@timestamp per day\"}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Unique count of apache2.access.url\"}}],\"seriesParams\":[{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"lineWidth\":2,\"data\":{\"id\":\"1\",\"label\":\"Unique count of apache2.access.url\"},\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"showCircles\":true,\"interpolate\":\"linear\",\"scale\":\"linear\",\"drawLinesBetweenPoints\":true,\"radiusRatio\":9,\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"apache2.access.url\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}", - "description": "", - "title": "ML Apache2 Access Unique Count URL Timechart", - "uiStateJSON": "{}", - "version": 1, - "savedSearchId": "ML-Filebeat-Apache2-Access", + "visState": "{\"title\":\"ML Apache2 Access Unique Count URL Timechart\",\"type\":\"line\",\"params\":{\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{\"text\":\"@timestamp per day\"}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Unique count of apache2.access.url\"}}],\"seriesParams\":[{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"lineWidth\":2,\"data\":{\"id\":\"1\",\"label\":\"Unique count of apache2.access.url\"},\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"showCircles\":true,\"interpolate\":\"linear\",\"scale\":\"linear\",\"drawLinesBetweenPoints\":true,\"radiusRatio\":9,\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"apache2.access.url\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}", + "description": "", + "title": "ML Apache2 Access Unique Count URL Timechart", + "uiStateJSON": "{}", + "version": 1, + "migrationVersion": {}, + "savedSearchId": "ML-Filebeat-Apache2-Access", "kibanaSavedObjectMeta": { "searchSourceJSON": "{}" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/rollup/server/usage/collector.js b/x-pack/plugins/rollup/server/usage/collector.js index 4cb9fba66ca67..d017740def9e3 100644 --- a/x-pack/plugins/rollup/server/usage/collector.js +++ b/x-pack/plugins/rollup/server/usage/collector.js @@ -102,8 +102,9 @@ async function fetchRollupVisualizations(kibanaIndex, callCluster, rollupIndexPa index: kibanaIndex, ignoreUnavailable: true, filterPath: [ - 'hits.hits._source.visualization.savedSearchId', + 'hits.hits._source.visualization.savedSearchRefName', 'hits.hits._source.visualization.kibanaSavedObjectMeta', + 'hits.hits._source.references', ], body: { query: { @@ -128,19 +129,21 @@ async function fetchRollupVisualizations(kibanaIndex, callCluster, rollupIndexPa const { _source: { visualization: { - savedSearchId, + savedSearchRefName, kibanaSavedObjectMeta: { searchSourceJSON, }, }, + references = [], }, } = visualization; const searchSource = JSON.parse(searchSourceJSON); - if (savedSearchId) { + if (savedSearchRefName) { // This visualization depends upon a saved search. - if (rollupSavedSearchesToFlagMap[savedSearchId]) { + const savedSearch = references.find(ref => ref.name === savedSearchRefName); + if (rollupSavedSearchesToFlagMap[savedSearch.id]) { rollupVisualizations++; rollupVisualizationsFromSavedSearches++; } diff --git a/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.ts b/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.ts index 5e86cd4f08c5e..9a3203305b59d 100644 --- a/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.ts +++ b/x-pack/plugins/spaces/server/lib/saved_objects_client/spaces_saved_objects_client.ts @@ -149,6 +149,7 @@ export class SpacesSavedObjectsClient implements SavedObjectsClient { * @property {string} [options.sortOrder] * @property {Array} [options.fields] * @property {string} [options.namespace] + * @property {object} [options.hasReference] - { type, id } * @returns {promise} - { saved_objects: [{ id, type, version, attributes }], total, per_page, page } */ public async find(options: FindOptions = {}) { diff --git a/x-pack/plugins/spaces/server/lib/space_request_interceptors.test.ts b/x-pack/plugins/spaces/server/lib/space_request_interceptors.test.ts index 9d9ad1417a3e9..7604cbc06f712 100644 --- a/x-pack/plugins/spaces/server/lib/space_request_interceptors.test.ts +++ b/x-pack/plugins/spaces/server/lib/space_request_interceptors.test.ts @@ -229,6 +229,7 @@ describe('interceptors', () => { attributes: { name: 'a space', }, + references: [], }, ]; @@ -265,6 +266,7 @@ describe('interceptors', () => { attributes: { name: 'a space', }, + references: [], }, ]; @@ -302,6 +304,7 @@ describe('interceptors', () => { attributes: { name: 'a space', }, + references: [], }, ]; @@ -348,6 +351,7 @@ describe('interceptors', () => { attributes: { name: 'Default Space', }, + references: [], }, ]; @@ -379,6 +383,7 @@ describe('interceptors', () => { attributes: { name: 'a space', }, + references: [], }, { id: 'b-space', @@ -386,6 +391,7 @@ describe('interceptors', () => { attributes: { name: 'b space', }, + references: [], }, ]; diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json index 6bf3413f3797d..368384479bc30 100644 --- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json +++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json @@ -195,7 +195,7 @@ "description": "", "version": 1, "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"91200a00-9efd-11e7-acb3-3dab96693fab\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" + "searchSourceJSON": "{\"index\":\"space_1-91200a00-9efd-11e7-acb3-3dab96693fab\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" } } } @@ -216,7 +216,7 @@ "title": "Requests", "hits": 0, "description": "", - "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]", + "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"space_1-dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]", "optionsJSON": "{}", "uiStateJSON": "{}", "version": 1, @@ -291,7 +291,7 @@ "description": "", "version": 1, "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"91200a00-9efd-11e7-acb3-3dab96693fab\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" + "searchSourceJSON": "{\"index\":\"space_2-91200a00-9efd-11e7-acb3-3dab96693fab\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}" } } } @@ -312,7 +312,7 @@ "title": "Requests", "hits": 0, "description": "", - "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]", + "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"space_2-dd7caf20-9efd-11e7-acb3-3dab96693fab\",\"col\":1,\"row\":1}]", "optionsJSON": "{}", "uiStateJSON": "{}", "version": 1, diff --git a/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts b/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts index 0d9e800c64003..6dcaae760a58d 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts @@ -88,6 +88,7 @@ export function bulkCreateTestSuiteFactory(es: any, esArchiver: any, supertest: attributes: { title: 'A great new dashboard', }, + references: [], }, { type: 'globaltype', @@ -97,6 +98,7 @@ export function bulkCreateTestSuiteFactory(es: any, esArchiver: any, supertest: attributes: { name: 'A new globaltype object', }, + references: [], }, { type: 'globaltype', diff --git a/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts b/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts index fdffe545f3416..e82ea7b856a8c 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts @@ -69,6 +69,7 @@ export function bulkGetTestSuiteFactory(esArchiver: any, supertest: SuperTest) attributes: { name: 'My favorite global object', }, + references: [], }, ], }); @@ -99,6 +100,7 @@ export function findTestSuiteFactory(esArchiver: any, supertest: SuperTest) attributes: { title: 'Count of requests', }, + references: [], }, ], }); diff --git a/x-pack/test/saved_object_api_integration/common/suites/get.ts b/x-pack/test/saved_object_api_integration/common/suites/get.ts index 5bf2385544a7d..1cc36b411c61a 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/get.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/get.ts @@ -69,6 +69,7 @@ export function getTestSuiteFactory(esArchiver: any, supertest: SuperTest) attributes: { name: 'My favorite global object', }, + references: [], }); }; @@ -108,6 +109,13 @@ export function getTestSuiteFactory(esArchiver: any, supertest: SuperTest) uiStateJSON: resp.body.attributes.uiStateJSON, kibanaSavedObjectMeta: resp.body.attributes.kibanaSavedObjectMeta, }, + references: [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: `${getIdPrefix(spaceId)}91200a00-9efd-11e7-acb3-3dab96693fab`, + }, + ], }); }; diff --git a/x-pack/test/saved_object_api_integration/common/suites/update.ts b/x-pack/test/saved_object_api_integration/common/suites/update.ts index f936567200f54..5d496ba58bbba 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/update.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/update.ts @@ -78,6 +78,7 @@ export function updateTestSuiteFactory(esArchiver: any, supertest: SuperTest Date: Wed, 30 Jan 2019 16:07:28 -0500 Subject: [PATCH 14/40] Make Canvas expressions use socket.io polling only (#29647) This gets Canvas expressions to behave consistently across environments, and is the first step in migrating expressions to a different transport layer. --- packages/kbn-interpreter/src/public/socket.js | 2 +- src/legacy/core_plugins/interpreter/server/routes/socket.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/kbn-interpreter/src/public/socket.js b/packages/kbn-interpreter/src/public/socket.js index 7d209e09c6887..04f8a91ed01b8 100644 --- a/packages/kbn-interpreter/src/public/socket.js +++ b/packages/kbn-interpreter/src/public/socket.js @@ -26,7 +26,7 @@ export async function createSocket(basePath, functionsRegistry) { return new Promise((resolve, reject) => { const socket = io({ path: `${basePath}/socket.io`, - transports: ['polling', 'websocket'], + transports: ['polling'], transportOptions: { polling: { extraHeaders: { diff --git a/src/legacy/core_plugins/interpreter/server/routes/socket.js b/src/legacy/core_plugins/interpreter/server/routes/socket.js index 6201eaf70ca8a..66e0fa782b449 100644 --- a/src/legacy/core_plugins/interpreter/server/routes/socket.js +++ b/src/legacy/core_plugins/interpreter/server/routes/socket.js @@ -46,7 +46,10 @@ export function socketApi(server) { handler: () => 'pong', }); - const io = socket(server.listener, { path: '/socket.io' }); + const io = socket(server.listener, { + path: '/socket.io', + transports: ['polling'], + }); io.on('connection', async socket => { // 'request' is the modified hapi request object From 45b24afe831c8db941a04e29bd4d82ac400da7e3 Mon Sep 17 00:00:00 2001 From: Matt Bargar Date: Wed, 30 Jan 2019 17:00:42 -0500 Subject: [PATCH 15/40] Revert "Migrate filter bar to React, EUI, and Typescript (#25563)" (#29662) This reverts commit 410c094547e235d5805a94f066117a05381ab5a4. --- packages/kbn-es-query/README.md | 94 ---- packages/kbn-es-query/package.json | 5 +- packages/kbn-es-query/src/filters/exists.js | 1 - packages/kbn-es-query/src/filters/index.d.ts | 47 -- packages/kbn-es-query/src/filters/index.js | 1 - .../src/filters/lib/custom_filter.ts | 24 - .../kbn-es-query/src/filters/lib/index.ts | 50 -- .../src/filters/lib/meta_filter.ts | 100 ---- .../src/filters/lib/phrases_filter.ts | 28 -- .../src/filters/lib/query_string_filter.ts | 26 - packages/kbn-es-query/src/filters/phrase.js | 1 - packages/kbn-es-query/src/filters/phrases.js | 2 - packages/kbn-es-query/src/filters/query.js | 1 - packages/kbn-es-query/src/filters/range.js | 2 - packages/kbn-es-query/src/index.d.ts | 1 - packages/kbn-es-query/tsconfig.json | 8 +- .../fixtures/filters/exists_filter.js | 26 +- .../fixtures/filters/index.js | 16 +- .../filters/phrase_filter.js} | 22 +- .../filters/phrases_filter.js} | 33 +- .../filters/range_filter.js} | 29 +- .../filters/scripted_phrase_filter.js} | 37 +- .../kibana/public/context/app.html | 7 +- .../core_plugins/kibana/public/context/app.js | 1 - .../context/query_parameters/actions.js | 7 - .../public/dashboard/dashboard_app.html | 21 +- .../kibana/public/dashboard/dashboard_app.js | 53 +- .../public/discover/controllers/discover.js | 21 +- .../kibana/public/discover/index.html | 25 +- .../public/visualize/editor/editor.html | 32 +- .../kibana/public/visualize/editor/editor.js | 26 +- src/ui/public/_index.scss | 1 - .../agg_types/filter/agg_type_filters.test.ts | 2 +- .../apply_filters/apply_filters_popover.tsx | 128 ----- src/ui/public/apply_filters/directive.html | 7 - src/ui/public/apply_filters/directive.js | 59 --- .../public/doc_table/components/table_row.js | 2 +- .../public/filter_bar/__tests__/filter_bar.js | 228 +++++++++ .../__tests__/filter_bar_click_handler.js | 80 +++ .../filter_bar/_global_filter_group.scss | 22 - .../filter_bar/_global_filter_item.scss | 37 -- src/ui/public/filter_bar/_index.scss | 2 - src/ui/public/filter_bar/filter_bar.html | 149 ++++++ src/ui/public/filter_bar/filter_bar.js | 213 ++++++++ src/ui/public/filter_bar/filter_bar.less | 226 +++++++++ src/ui/public/filter_bar/filter_bar.tsx | 217 -------- .../filter_bar/filter_bar_click_handler.js | 89 ++++ .../filter_editor/generic_combo_box.tsx | 61 --- .../public/filter_bar/filter_editor/index.tsx | 471 ------------------ .../lib/filter_editor_utils.test.ts | 314 ------------ .../filter_editor/lib/filter_editor_utils.ts | 178 ------- .../filter_editor/lib/filter_operators.ts | 106 ---- .../filter_editor/phrase_suggestor.tsx | 73 --- .../filter_editor/phrase_value_input.tsx | 88 ---- .../filter_editor/phrases_values_input.tsx | 67 --- .../filter_editor/range_value_input.tsx | 121 ----- .../filter_editor/value_input_type.tsx | 120 ----- src/ui/public/filter_bar/filter_item.tsx | 226 --------- .../filter_bar/filter_pill/filter_pill.html | 97 ++++ .../filter_bar/filter_pill/filter_pill.js | 57 +++ .../filter_pill/index.js} | 2 +- .../public/filter_bar/filter_view/index.tsx | 103 ---- .../index.tsx => filter_bar/index.js} | 4 +- src/ui/public/filter_bar/index.ts | 22 - .../lib/__tests__/disable_filter.js | 140 ++++++ .../__tests__/filter_applied_and_unwrap.js | 22 +- .../__tests__/filter_out_time_based_filter.js | 57 +++ .../public/filter_bar/lib/disable_filter.js | 44 ++ .../lib/filter_applied_and_unwrap.js} | 7 +- .../lib/filter_out_time_based_filter.js | 26 +- src/ui/public/filter_bar/lib/map_phrase.js | 8 +- src/ui/public/filter_bar/query_filter.js | 29 +- .../public/filter_editor/filter_editor.html | 148 ++++++ src/ui/public/filter_editor/filter_editor.js | 161 ++++++ .../public/filter_editor/filter_editor.less | 36 ++ .../filter_editor/filter_field_select.html | 27 + .../filter_editor/filter_field_select.js | 52 ++ .../filter_editor/filter_operator_select.html | 12 + .../filter_operator_select.js} | 27 +- .../filter_query_dsl_editor.html | 13 + .../filter_editor/filter_query_dsl_editor.js | 59 +++ .../index.d.ts => filter_editor/index.js} | 2 +- .../lib/__tests__/filter_editor_utils.js | 396 +++++++++++++++ .../filter_editor/lib/filter_editor_utils.js | 111 +++++ .../filter_editor/lib/filter_operators.js | 72 +++ .../params_editor/filter_params_editor.html | 19 + .../params_editor/filter_params_editor.js | 25 +- .../filter_params_input_type.html | 50 ++ .../params_editor/filter_params_input_type.js | 49 ++ .../filter_params_phrase_controller.js | 57 +++ .../filter_params_phrase_editor.html | 45 ++ .../filter_params_phrase_editor.js | 42 ++ .../filter_params_phrases_editor.html | 28 ++ .../filter_params_phrases_editor.js | 39 ++ .../filter_params_range_editor.html | 30 ++ .../filter_params_range_editor.js} | 26 +- src/ui/public/index_patterns/_field.d.ts | 26 - .../public/index_patterns/_index_pattern.d.ts | 9 +- .../public/index_patterns/fixtures/index.ts | 79 --- src/ui/public/index_patterns/index.d.ts | 7 +- .../static_utils/__tests__/index.js | 54 +- .../index_patterns/static_utils/index.d.ts | 11 +- .../index_patterns/static_utils/index.js | 10 +- .../__snapshots__/query_bar.test.tsx.snap | 3 + .../query_bar/components/query_bar.test.tsx | 20 +- .../public/query_bar/components/query_bar.tsx | 7 +- .../components/typeahead/_suggestion.scss | 5 +- .../search_bar/components/filter_options.tsx | 184 ------- .../search_bar/components/search_bar.tsx | 178 ------- src/ui/public/styles/bootstrap_dark.less | 1 + src/ui/public/timefilter/get_time.ts | 8 +- src/ui/public/value_suggestions/index.ts | 24 - .../value_suggestions.test.ts | 131 ----- .../value_suggestions/value_suggestions.ts | 53 -- .../config/editor_config_providers.test.ts | 17 +- .../apps/dashboard/_dashboard_filter_bar.js | 22 +- .../apps/dashboard/_dashboard_filtering.js | 2 +- test/functional/apps/discover/_discover.js | 2 +- .../apps/management/_scripted_fields.js | 9 +- .../functional/page_objects/dashboard_page.js | 4 + test/functional/page_objects/discover_page.js | 7 + .../services/dashboard/expectations.js | 10 +- test/functional/services/filter_bar.js | 86 ++-- .../beats_management/types/kibana.d.ts | 16 + .../autocomplete_providers/__tests__/value.js | 149 +++--- .../public/autocomplete_providers/field.js | 7 +- .../public/autocomplete_providers/operator.js | 4 +- .../public/autocomplete_providers/value.js | 35 +- .../plugins/ml/public/explorer/explorer.html | 8 +- .../ml/public/explorer/explorer_controller.js | 18 +- x-pack/plugins/ml/public/util/index_utils.js | 2 +- .../dashboard_mode/dashboard_view_mode.js | 5 +- 132 files changed, 3344 insertions(+), 4047 deletions(-) delete mode 100644 packages/kbn-es-query/README.md delete mode 100644 packages/kbn-es-query/src/filters/index.d.ts delete mode 100644 packages/kbn-es-query/src/filters/lib/custom_filter.ts delete mode 100644 packages/kbn-es-query/src/filters/lib/index.ts delete mode 100644 packages/kbn-es-query/src/filters/lib/meta_filter.ts delete mode 100644 packages/kbn-es-query/src/filters/lib/phrases_filter.ts delete mode 100644 packages/kbn-es-query/src/filters/lib/query_string_filter.ts rename packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts => src/fixtures/filters/exists_filter.js (74%) rename packages/kbn-es-query/src/filters/lib/phrase_filter.ts => src/fixtures/filters/index.js (75%) rename src/{ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts => fixtures/filters/phrase_filter.js} (80%) rename src/{ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts => fixtures/filters/phrases_filter.js} (70%) rename src/{ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts => fixtures/filters/range_filter.js} (72%) rename src/{ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts => fixtures/filters/scripted_phrase_filter.js} (60%) delete mode 100644 src/ui/public/apply_filters/apply_filters_popover.tsx delete mode 100644 src/ui/public/apply_filters/directive.html delete mode 100644 src/ui/public/apply_filters/directive.js create mode 100644 src/ui/public/filter_bar/__tests__/filter_bar.js create mode 100644 src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js delete mode 100644 src/ui/public/filter_bar/_global_filter_group.scss delete mode 100644 src/ui/public/filter_bar/_global_filter_item.scss delete mode 100644 src/ui/public/filter_bar/_index.scss create mode 100644 src/ui/public/filter_bar/filter_bar.html create mode 100644 src/ui/public/filter_bar/filter_bar.js delete mode 100644 src/ui/public/filter_bar/filter_bar.tsx create mode 100644 src/ui/public/filter_bar/filter_bar_click_handler.js delete mode 100644 src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/index.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts delete mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts delete mode 100644 src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts delete mode 100644 src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/range_value_input.tsx delete mode 100644 src/ui/public/filter_bar/filter_editor/value_input_type.tsx delete mode 100644 src/ui/public/filter_bar/filter_item.tsx create mode 100644 src/ui/public/filter_bar/filter_pill/filter_pill.html create mode 100644 src/ui/public/filter_bar/filter_pill/filter_pill.js rename src/ui/public/{search_bar/components/index.tsx => filter_bar/filter_pill/index.js} (95%) delete mode 100644 src/ui/public/filter_bar/filter_view/index.tsx rename src/ui/public/{search_bar/index.tsx => filter_bar/index.js} (86%) delete mode 100644 src/ui/public/filter_bar/index.ts create mode 100644 src/ui/public/filter_bar/lib/__tests__/disable_filter.js rename packages/kbn-es-query/src/filters/lib/exists_filter.ts => src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js (56%) create mode 100644 src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js create mode 100644 src/ui/public/filter_bar/lib/disable_filter.js rename src/ui/public/{apply_filters/index.ts => filter_bar/lib/filter_applied_and_unwrap.js} (87%) rename packages/kbn-es-query/src/filters/lib/range_filter.ts => src/ui/public/filter_bar/lib/filter_out_time_based_filter.js (64%) create mode 100644 src/ui/public/filter_editor/filter_editor.html create mode 100644 src/ui/public/filter_editor/filter_editor.js create mode 100644 src/ui/public/filter_editor/filter_editor.less create mode 100644 src/ui/public/filter_editor/filter_field_select.html create mode 100644 src/ui/public/filter_editor/filter_field_select.js create mode 100644 src/ui/public/filter_editor/filter_operator_select.html rename src/ui/public/{filter_bar/directive.js => filter_editor/filter_operator_select.js} (60%) create mode 100644 src/ui/public/filter_editor/filter_query_dsl_editor.html create mode 100644 src/ui/public/filter_editor/filter_query_dsl_editor.js rename src/ui/public/{documentation_links/index.d.ts => filter_editor/index.js} (94%) create mode 100644 src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js create mode 100644 src/ui/public/filter_editor/lib/filter_editor_utils.js create mode 100644 src/ui/public/filter_editor/lib/filter_operators.js create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_editor.html rename packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts => src/ui/public/filter_editor/params_editor/filter_params_editor.js (65%) create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_input_type.html create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_input_type.js create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js create mode 100644 src/ui/public/filter_editor/params_editor/filter_params_range_editor.html rename src/ui/public/{search_bar/directive/index.js => filter_editor/params_editor/filter_params_range_editor.js} (69%) delete mode 100644 src/ui/public/index_patterns/_field.d.ts delete mode 100644 src/ui/public/index_patterns/fixtures/index.ts delete mode 100644 src/ui/public/search_bar/components/filter_options.tsx delete mode 100644 src/ui/public/search_bar/components/search_bar.tsx delete mode 100644 src/ui/public/value_suggestions/index.ts delete mode 100644 src/ui/public/value_suggestions/value_suggestions.test.ts delete mode 100644 src/ui/public/value_suggestions/value_suggestions.ts diff --git a/packages/kbn-es-query/README.md b/packages/kbn-es-query/README.md deleted file mode 100644 index 53f082b864d73..0000000000000 --- a/packages/kbn-es-query/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# kbn-es-query - -This module is responsible for generating Elasticsearch queries for Kibana. See explanations below for each of the subdirectories. - -## es_query - -This folder contains the code that combines Lucene/KQL queries and filters into an Elasticsearch query. - -```javascript -buildEsQuery(indexPattern, queries, filters, config) -``` - -Generates the Elasticsearch query DSL from combining the queries and filters provided. - -```javascript -buildQueryFromFilters(filters, indexPattern) -``` - -Generates the Elasticsearch query DSL from the given filters. - -```javascript -luceneStringToDsl(query) -``` - -Generates the Elasticsearch query DSL from the given Lucene query. - -```javascript -migrateFilter(filter, indexPattern) -``` - -Migrates a filter from a previous version of Elasticsearch to the current version. - -```javascript -decorateQuery(query, queryStringOptions) -``` - -Decorates an Elasticsearch query_string query with the given options. - -## filters - -This folder contains the code related to Kibana Filter objects, including their definitions, and helper functions to create them. Filters in Kibana always contain a `meta` property which describes which `index` the filter corresponds to, as well as additional data about the specific filter. - -The object that is created by each of the following functions corresponds to a Filter object in the `lib` directory (e.g. `PhraseFilter`, `RangeFilter`, etc.) - -```javascript -buildExistsFilter(field, indexPattern) -``` - -Creates a filter (`ExistsFilter`) where the given field exists. - -```javascript -buildPhraseFilter(field, value, indexPattern) -``` - -Creates an filter (`PhraseFilter`) where the given field matches the given value. - -```javascript -buildPhrasesFilter(field, params, indexPattern) -``` - -Creates a filter (`PhrasesFilter`) where the given field matches one or more of the given values. `params` should be an array of values. - -```javascript -buildQueryFilter(query, index) -``` - -Creates a filter (`CustomFilter`) corresponding to a raw Elasticsearch query DSL object. - -```javascript -buildRangeFilter(field, params, indexPattern) -``` - -Creates a filter (`RangeFilter`) where the value for the given field is in the given range. `params` should contain `lt`, `lte`, `gt`, and/or `gte`. - -## kuery - -This folder contains the code corresponding to generating Elasticsearch queries using the Kibana query language. - -It also contains code corresponding to the original implementation of Kuery (released in 6.0) which should be removed at some point (see legacy_kuery.js, legacy_kuery.peg). - -In general, you will only need to worry about the following functions from the `ast` folder: - -```javascript -fromExpression(expression) -``` - -Generates an abstract syntax tree corresponding to the raw Kibana query `expression`. - -```javascript -toElasticsearchQuery(node, indexPattern) -``` - -Takes an abstract syntax tree (generated from the previous method) and generates the Elasticsearch query DSL using the given `indexPattern`. Note that if no `indexPattern` is provided, then an Elasticsearch query DSL will still be generated, ignoring things like the index pattern scripted fields, field types, etc. - diff --git a/packages/kbn-es-query/package.json b/packages/kbn-es-query/package.json index ec4226f6b1e75..ce3e96cc8219c 100644 --- a/packages/kbn-es-query/package.json +++ b/packages/kbn-es-query/package.json @@ -5,15 +5,14 @@ "license": "Apache-2.0", "private": true, "scripts": { - "build": "tsc && babel src --out-dir target", + "build": "babel src --out-dir target", "kbn:bootstrap": "yarn build --quiet", "kbn:watch": "yarn build --watch" -}, + }, "dependencies": { "lodash": "npm:@elastic/lodash@3.10.1-kibana1" }, "devDependencies": { - "typescript": "^3.0.3", "@kbn/babel-preset": "1.0.0", "babel-cli": "^6.26.0", "expect.js": "0.3.1" diff --git a/packages/kbn-es-query/src/filters/exists.js b/packages/kbn-es-query/src/filters/exists.js index 0c82279fb4417..dd0d62f36c146 100644 --- a/packages/kbn-es-query/src/filters/exists.js +++ b/packages/kbn-es-query/src/filters/exists.js @@ -17,7 +17,6 @@ * under the License. */ -// Creates a filter where the given field exists export function buildExistsFilter(field, indexPattern) { return { meta: { diff --git a/packages/kbn-es-query/src/filters/index.d.ts b/packages/kbn-es-query/src/filters/index.d.ts deleted file mode 100644 index c46a767e38ea4..0000000000000 --- a/packages/kbn-es-query/src/filters/index.d.ts +++ /dev/null @@ -1,47 +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 { Field, IndexPattern } from 'ui/index_patterns'; -import { CustomFilter, ExistsFilter, PhraseFilter, PhrasesFilter, RangeFilter } from './lib'; -import { RangeFilterParams } from './lib/range_filter'; - -export * from './lib'; - -export function buildExistsFilter(field: Field, indexPattern: IndexPattern): ExistsFilter; - -export function buildPhraseFilter( - field: Field, - value: string, - indexPattern: IndexPattern -): PhraseFilter; - -export function buildPhrasesFilter( - field: Field, - values: string[], - indexPattern: IndexPattern -): PhrasesFilter; - -export function buildQueryFilter(query: any, index: string): CustomFilter; - -export function buildRangeFilter( - field: Field, - params: RangeFilterParams, - indexPattern: IndexPattern, - formattedValue?: string -): RangeFilter; diff --git a/packages/kbn-es-query/src/filters/index.js b/packages/kbn-es-query/src/filters/index.js index d7d092eabd8a2..dfd8924736862 100644 --- a/packages/kbn-es-query/src/filters/index.js +++ b/packages/kbn-es-query/src/filters/index.js @@ -22,4 +22,3 @@ export * from './phrase'; export * from './phrases'; export * from './query'; export * from './range'; -export * from './lib'; diff --git a/packages/kbn-es-query/src/filters/lib/custom_filter.ts b/packages/kbn-es-query/src/filters/lib/custom_filter.ts deleted file mode 100644 index 1003cc984a90f..0000000000000 --- a/packages/kbn-es-query/src/filters/lib/custom_filter.ts +++ /dev/null @@ -1,24 +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 { Filter } from './meta_filter'; - -export type CustomFilter = Filter & { - query: any; -}; diff --git a/packages/kbn-es-query/src/filters/lib/index.ts b/packages/kbn-es-query/src/filters/lib/index.ts deleted file mode 100644 index fdf87c84eb5ca..0000000000000 --- a/packages/kbn-es-query/src/filters/lib/index.ts +++ /dev/null @@ -1,50 +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. - */ - -// The interface the other filters extend -export * from './meta_filter'; - -// The actual filter types -import { CustomFilter } from './custom_filter'; -import { ExistsFilter } from './exists_filter'; -import { GeoBoundingBoxFilter } from './geo_bounding_box_filter'; -import { GeoPolygonFilter } from './geo_polygon_filter'; -import { PhraseFilter } from './phrase_filter'; -import { PhrasesFilter } from './phrases_filter'; -import { QueryStringFilter } from './query_string_filter'; -import { RangeFilter } from './range_filter'; -export { - CustomFilter, - ExistsFilter, - GeoBoundingBoxFilter, - GeoPolygonFilter, - PhraseFilter, - PhrasesFilter, - QueryStringFilter, - RangeFilter, -}; - -// Any filter associated with a field (used in the filter bar/editor) -export type FieldFilter = - | ExistsFilter - | GeoBoundingBoxFilter - | GeoPolygonFilter - | PhraseFilter - | PhrasesFilter - | RangeFilter; diff --git a/packages/kbn-es-query/src/filters/lib/meta_filter.ts b/packages/kbn-es-query/src/filters/lib/meta_filter.ts deleted file mode 100644 index db5b308a01da3..0000000000000 --- a/packages/kbn-es-query/src/filters/lib/meta_filter.ts +++ /dev/null @@ -1,100 +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. - */ - -export enum FilterStateStore { - APP_STATE = 'appState', - GLOBAL_STATE = 'globalState', -} - -export interface FilterState { - store: FilterStateStore; -} - -export interface FilterMeta { - // index and type are optional only because when you create a new filter, there are no defaults - index?: string; - type?: string; - disabled: boolean; - negate: boolean; - alias: string | null; - key?: string; - value?: string; -} - -export interface Filter { - $state: FilterState; - meta: FilterMeta; - query?: any; -} - -export interface LatLon { - lat: number; - lon: number; -} - -export function buildEmptyFilter(isPinned: boolean, index?: string): Filter { - const meta: FilterMeta = { - disabled: false, - negate: false, - alias: null, - index, - }; - const $state: FilterState = { - store: isPinned ? FilterStateStore.GLOBAL_STATE : FilterStateStore.APP_STATE, - }; - return { meta, $state }; -} - -export function isFilterPinned(filter: Filter) { - return filter.$state.store === FilterStateStore.GLOBAL_STATE; -} - -export function toggleFilterDisabled(filter: Filter) { - const disabled = !filter.meta.disabled; - const meta = { ...filter.meta, disabled }; - return { ...filter, meta }; -} - -export function toggleFilterNegated(filter: Filter) { - const negate = !filter.meta.negate; - const meta = { ...filter.meta, negate }; - return { ...filter, meta }; -} - -export function toggleFilterPinned(filter: Filter) { - const store = isFilterPinned(filter) ? FilterStateStore.APP_STATE : FilterStateStore.GLOBAL_STATE; - const $state = { ...filter.$state, store }; - return { ...filter, $state }; -} - -export function enableFilter(filter: Filter) { - return !filter.meta.disabled ? filter : toggleFilterDisabled(filter); -} - -export function disableFilter(filter: Filter) { - return filter.meta.disabled ? filter : toggleFilterDisabled(filter); -} - -export function pinFilter(filter: Filter) { - return isFilterPinned(filter) ? filter : toggleFilterPinned(filter); -} - -export function unpinFilter(filter: Filter) { - return !isFilterPinned(filter) ? filter : toggleFilterPinned(filter); -} diff --git a/packages/kbn-es-query/src/filters/lib/phrases_filter.ts b/packages/kbn-es-query/src/filters/lib/phrases_filter.ts deleted file mode 100644 index cc36ad54c8dc4..0000000000000 --- a/packages/kbn-es-query/src/filters/lib/phrases_filter.ts +++ /dev/null @@ -1,28 +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 { Filter, FilterMeta } from './meta_filter'; - -export type PhrasesFilterMeta = FilterMeta & { - params: string[]; // The unformatted values -}; - -export type PhrasesFilter = Filter & { - meta: PhrasesFilterMeta; -}; diff --git a/packages/kbn-es-query/src/filters/lib/query_string_filter.ts b/packages/kbn-es-query/src/filters/lib/query_string_filter.ts deleted file mode 100644 index 1f6a95844437a..0000000000000 --- a/packages/kbn-es-query/src/filters/lib/query_string_filter.ts +++ /dev/null @@ -1,26 +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 { Filter, FilterMeta } from './meta_filter'; - -export type QueryStringFilterMeta = FilterMeta; - -export type QueryStringFilter = Filter & { - meta: QueryStringFilterMeta; -}; diff --git a/packages/kbn-es-query/src/filters/phrase.js b/packages/kbn-es-query/src/filters/phrase.js index b71724ab60d76..8677fde87ceda 100644 --- a/packages/kbn-es-query/src/filters/phrase.js +++ b/packages/kbn-es-query/src/filters/phrase.js @@ -17,7 +17,6 @@ * under the License. */ -// Creates an filter where the given field matches the given value export function buildPhraseFilter(field, value, indexPattern) { const filter = { meta: { index: indexPattern.id } }; const convertedValue = getConvertedValueForField(field, value); diff --git a/packages/kbn-es-query/src/filters/phrases.js b/packages/kbn-es-query/src/filters/phrases.js index f02b3763f37bb..0d85669e65fcd 100644 --- a/packages/kbn-es-query/src/filters/phrases.js +++ b/packages/kbn-es-query/src/filters/phrases.js @@ -19,8 +19,6 @@ import { getPhraseScript } from './phrase'; -// Creates a filter where the given field matches one or more of the given values -// params should be an array of values export function buildPhrasesFilter(field, params, indexPattern) { const index = indexPattern.id; const type = 'phrases'; diff --git a/packages/kbn-es-query/src/filters/query.js b/packages/kbn-es-query/src/filters/query.js index cfb1a6d36d9e2..428d656364987 100644 --- a/packages/kbn-es-query/src/filters/query.js +++ b/packages/kbn-es-query/src/filters/query.js @@ -17,7 +17,6 @@ * under the License. */ -// Creates a filter corresponding to a raw Elasticsearch query DSL object export function buildQueryFilter(query, index) { return { query: query, diff --git a/packages/kbn-es-query/src/filters/range.js b/packages/kbn-es-query/src/filters/range.js index 88be09c997154..ec3fc167f75d4 100644 --- a/packages/kbn-es-query/src/filters/range.js +++ b/packages/kbn-es-query/src/filters/range.js @@ -36,8 +36,6 @@ function formatValue(field, params) { return _.map(params, (val, key) => operators[key] + format(field, val)).join(' '); } -// Creates a filter where the value for the given field is in the given range -// params should be an object containing `lt`, `lte`, `gt`, and/or `gte` export function buildRangeFilter(field, params, indexPattern, formattedValue) { const filter = { meta: { index: indexPattern.id } }; if (formattedValue) filter.meta.formattedValue = formattedValue; diff --git a/packages/kbn-es-query/src/index.d.ts b/packages/kbn-es-query/src/index.d.ts index 873636a28889f..79e6903b18644 100644 --- a/packages/kbn-es-query/src/index.d.ts +++ b/packages/kbn-es-query/src/index.d.ts @@ -18,4 +18,3 @@ */ export * from './kuery'; -export * from './filters'; diff --git a/packages/kbn-es-query/tsconfig.json b/packages/kbn-es-query/tsconfig.json index c2b6e3075dc67..9a22ea4fc44aa 100644 --- a/packages/kbn-es-query/tsconfig.json +++ b/packages/kbn-es-query/tsconfig.json @@ -1,11 +1,7 @@ { - "extends": "../../tsconfig.browser.json", - "compilerOptions": { - "rootDir": "./src", - "outDir": "./target" - }, + "extends": "../../tsconfig.json", "include": [ "index.d.ts", - "src/**/*.ts" + "src/**/*.d.ts" ] } diff --git a/packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts b/src/fixtures/filters/exists_filter.js similarity index 74% rename from packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts rename to src/fixtures/filters/exists_filter.js index c83e146b093a3..0c4d6138a99b7 100644 --- a/packages/kbn-es-query/src/filters/lib/geo_bounding_box_filter.ts +++ b/src/fixtures/filters/exists_filter.js @@ -17,15 +17,19 @@ * under the License. */ -import { Filter, FilterMeta, LatLon } from './meta_filter'; - -export type GeoBoundingBoxFilterMeta = FilterMeta & { - params: { - bottom_right: LatLon; - top_left: LatLon; - }; -}; - -export type GeoBoundingBoxFilter = Filter & { - meta: GeoBoundingBoxFilterMeta; +export const existsFilter = { + 'meta': { + 'index': 'logstash-*', + 'negate': false, + 'disabled': false, + 'type': 'exists', + 'key': 'machine.os', + 'value': 'exists' + }, + 'exists': { + 'field': 'machine.os' + }, + '$state': { + 'store': 'appState' + } }; diff --git a/packages/kbn-es-query/src/filters/lib/phrase_filter.ts b/src/fixtures/filters/index.js similarity index 75% rename from packages/kbn-es-query/src/filters/lib/phrase_filter.ts rename to src/fixtures/filters/index.js index a8613190ce786..e8f823c4e8cbe 100644 --- a/packages/kbn-es-query/src/filters/lib/phrase_filter.ts +++ b/src/fixtures/filters/index.js @@ -17,14 +17,8 @@ * under the License. */ -import { Filter, FilterMeta } from './meta_filter'; - -export type PhraseFilterMeta = FilterMeta & { - params: { - query: string; // The unformatted value - }; -}; - -export type PhraseFilter = Filter & { - meta: PhraseFilterMeta; -}; +export { phraseFilter } from './phrase_filter'; +export { scriptedPhraseFilter } from './scripted_phrase_filter'; +export { phrasesFilter } from './phrases_filter'; +export { rangeFilter } from './range_filter'; +export { existsFilter } from './exists_filter'; diff --git a/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts b/src/fixtures/filters/phrase_filter.js similarity index 80% rename from src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts rename to src/fixtures/filters/phrase_filter.js index 77bb8e06c801a..22f02347d94aa 100644 --- a/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrase_filter.ts +++ b/src/fixtures/filters/phrase_filter.js @@ -17,22 +17,24 @@ * under the License. */ -import { FilterStateStore, PhraseFilter } from '@kbn/es-query'; - -export const phraseFilter: PhraseFilter = { +export const phraseFilter = { meta: { negate: false, index: 'logstash-*', type: 'phrase', key: 'machine.os', value: 'ios', - disabled: false, - alias: null, - params: { - query: 'ios', - }, + disabled: false }, - $state: { - store: FilterStateStore.APP_STATE, + query: { + match: { + 'machine.os': { + query: 'ios', + type: 'phrase' + } + } }, + $state: { + store: 'appState' + } }; diff --git a/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts b/src/fixtures/filters/phrases_filter.js similarity index 70% rename from src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts rename to src/fixtures/filters/phrases_filter.js index e86c3ee1318e3..184f1268c9da0 100644 --- a/src/ui/public/filter_bar/filter_editor/lib/fixtures/phrases_filter.ts +++ b/src/fixtures/filters/phrases_filter.js @@ -17,20 +17,37 @@ * under the License. */ -import { FilterStateStore, PhrasesFilter } from '@kbn/es-query'; - -export const phrasesFilter: PhrasesFilter = { +export const phrasesFilter = { meta: { index: 'logstash-*', type: 'phrases', key: 'machine.os.raw', value: 'win xp, osx', - params: ['win xp', 'osx'], + params: [ + 'win xp', + 'osx' + ], negate: false, - disabled: false, - alias: null, + disabled: false }, - $state: { - store: FilterStateStore.APP_STATE, + query: { + bool: { + should: [ + { + match_phrase: { + 'machine.os.raw': 'win xp' + } + }, + { + match_phrase: { + 'machine.os.raw': 'osx' + } + } + ], + minimum_should_match: 1 + } }, + $state: { + store: 'appState' + } }; diff --git a/src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts b/src/fixtures/filters/range_filter.js similarity index 72% rename from src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts rename to src/fixtures/filters/range_filter.js index a17f767006f3e..c18b6c98a5639 100644 --- a/src/ui/public/filter_bar/filter_editor/lib/fixtures/exists_filter.ts +++ b/src/fixtures/filters/range_filter.js @@ -17,18 +17,23 @@ * under the License. */ -import { ExistsFilter, FilterStateStore } from '@kbn/es-query'; - -export const existsFilter: ExistsFilter = { - meta: { - index: 'logstash-*', - negate: false, - disabled: false, - type: 'exists', - key: 'machine.os', - alias: null, +export const rangeFilter = { + 'meta': { + 'index': 'logstash-*', + 'negate': false, + 'disabled': false, + 'alias': null, + 'type': 'range', + 'key': 'bytes', + 'value': '0 to 10' }, - $state: { - store: FilterStateStore.APP_STATE, + 'range': { + 'bytes': { + 'gte': 0, + 'lt': 10 + } }, + '$state': { + 'store': 'appState' + } }; diff --git a/src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts b/src/fixtures/filters/scripted_phrase_filter.js similarity index 60% rename from src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts rename to src/fixtures/filters/scripted_phrase_filter.js index f6daf9cb36f11..f21a6356de19f 100644 --- a/src/ui/public/filter_bar/filter_editor/lib/fixtures/range_filter.ts +++ b/src/fixtures/filters/scripted_phrase_filter.js @@ -17,23 +17,26 @@ * under the License. */ -import { FilterStateStore, RangeFilter } from '@kbn/es-query'; - -export const rangeFilter: RangeFilter = { - meta: { - index: 'logstash-*', - negate: false, - disabled: false, - alias: null, - type: 'range', - key: 'bytes', - value: '0 to 10', - params: { - gte: 0, - lt: 10, - }, +export const scriptedPhraseFilter = { + 'meta': { + 'negate': false, + 'index': 'logstash-*', + 'field': 'script string', + 'type': 'phrase', + 'key': 'script string', + 'value': 'i am a string', + 'disabled': false }, - $state: { - store: FilterStateStore.APP_STATE, + 'script': { + 'script': { + 'inline': 'boolean compare(Supplier s, def v) {return s.get() == v;}compare(() -> { \'i am a string\' }, params.value);', + 'lang': 'painless', + 'params': { + 'value': 'i am a string' + } + } }, + '$state': { + 'store': 'appState' + } }; diff --git a/src/legacy/core_plugins/kibana/public/context/app.html b/src/legacy/core_plugins/kibana/public/context/app.html index ea9b66ac29e56..9bdd538b850bb 100644 --- a/src/legacy/core_plugins/kibana/public/context/app.html +++ b/src/legacy/core_plugins/kibana/public/context/app.html @@ -19,12 +19,7 @@
- +
(predecessorCount) => ( @@ -67,10 +65,6 @@ export function QueryParameterActionsProvider(indexPatterns, Private) { ) ); - const updateFilters = () => filters => { - queryFilter.setFilters(filters); - }; - const addFilter = (state) => async (field, values, operation) => { const indexPatternId = state.queryParameters.indexPatternId; filterManager.add(field, values, operation, indexPatternId); @@ -80,7 +74,6 @@ export function QueryParameterActionsProvider(indexPatterns, Private) { return { addFilter, - updateFilters, increasePredecessorCount, increaseSuccessorCount, setPredecessorCount, diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html index 67774b3400816..0aa3c6eb930cc 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.html @@ -30,25 +30,22 @@
- + >
- + +
0) { - $scope.indexPatterns = panelIndexPatterns; - } - else { - indexPatterns.getDefault().then((defaultIndexPattern) => { - $scope.$evalAsync(() => { - $scope.indexPatterns = [defaultIndexPattern]; - }); - }); - } + $scope.indexPatterns = dashboardStateManager.getPanelIndexPatterns(); }; // Part of the exposed plugin API - do not remove without careful consideration. @@ -167,7 +153,7 @@ app.directive('dashboardApp', function ($injector) { query: '', language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage') }, - queryFilter.getFilters() + filterBar.getFilters() ); timefilter.enableAutoRefreshSelector(); @@ -238,31 +224,11 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.requestReload(); } else { $scope.model.query = migrateLegacyQuery(query); - dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters); + dashboardStateManager.applyFilters($scope.model.query, filterBar.getFilters()); } $scope.refresh(); }; - $scope.onFiltersUpdated = filters => { - // The filters will automatically be set when the queryFilter emits an update event (see below) - queryFilter.setFilters(filters); - }; - - $scope.onCancelApplyFilters = () => { - $scope.appState.$newFilters = []; - }; - - $scope.onApplyFilters = filters => { - queryFilter.addFiltersAndChangeTimeFilter(filters); - $scope.appState.$newFilters = []; - }; - - $scope.$watch('appState.$newFilters', (filters = []) => { - if (filters.length === 1) { - $scope.onApplyFilters(filters); - } - }); - $scope.indexPatterns = []; $scope.onPanelRemoved = (panelIndex) => { @@ -381,7 +347,7 @@ app.directive('dashboardApp', function ($injector) { }); } - $scope.showFilterBar = () => $scope.model.filters.length > 0 || !dashboardStateManager.getFullScreenMode(); + $scope.showFilterBar = () => filterBar.getFilters().length > 0 || !dashboardStateManager.getFullScreenMode(); $scope.showAddPanel = () => { dashboardStateManager.setFullScreenMode(false); @@ -492,13 +458,12 @@ app.directive('dashboardApp', function ($injector) { updateViewMode(dashboardStateManager.getViewMode()); // update root source when filters update - $scope.$listen(queryFilter, 'update', function () { - $scope.model.filters = queryFilter.getFilters(); - dashboardStateManager.applyFilters($scope.model.query, $scope.model.filters); + $scope.$listen(filterBar, 'update', function () { + dashboardStateManager.applyFilters($scope.model.query, filterBar.getFilters()); }); // update data when filters fire fetch event - $scope.$listen(queryFilter, 'fetch', $scope.refresh); + $scope.$listen(filterBar, 'fetch', $scope.refresh); $scope.$on('$destroy', () => { dashboardStateManager.destroy(); diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index 5845625163cd3..cedaa5fbb232a 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -33,7 +33,7 @@ import 'ui/filters/moment'; import 'ui/index_patterns'; import 'ui/state_management/app_state'; import { timefilter } from 'ui/timefilter'; -import 'ui/search_bar'; +import 'ui/query_bar'; import { hasSearchStategyForIndexPattern, isDefaultTypeIndexPattern } from 'ui/courier'; import { toastNotifications } from 'ui/notify'; import { VisProvider } from 'ui/vis'; @@ -351,24 +351,6 @@ function discoverController( const $state = $scope.state = new AppState(getStateDefaults()); - $scope.filters = queryFilter.getFilters(); - - $scope.onFiltersUpdated = filters => { - // The filters will automatically be set when the queryFilter emits an update event (see below) - queryFilter.setFilters(filters); - }; - - $scope.applyFilters = filters => { - queryFilter.addFiltersAndChangeTimeFilter(filters); - $scope.state.$newFilters = []; - }; - - $scope.$watch('state.$newFilters', (filters = []) => { - if (filters.length === 1) { - $scope.applyFilters(filters); - } - }); - const getFieldCounts = async () => { // the field counts aren't set until we have the data back, // so we wait for the fetch to be done before proceeding @@ -506,7 +488,6 @@ function discoverController( // update data source when filters update $scope.$listen(queryFilter, 'update', function () { - $scope.filters = queryFilter.getFilters(); return $scope.updateDataSource().then(function () { $state.save(); }); diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index b11097a07ce02..f9fae245a6469 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -30,20 +30,23 @@

- + >

+
+ +
- + - -
{ - // The filters will automatically be set when the queryFilter emits an update event (see below) - queryFilter.setFilters(filters); - }; - - $scope.onCancelApplyFilters = () => { - $scope.state.$newFilters = []; - }; - - $scope.onApplyFilters = filters => { - queryFilter.addFiltersAndChangeTimeFilter(filters); - $scope.state.$newFilters = []; - }; - - $scope.$watch('state.$newFilters', (filters = []) => { - if (filters.length === 1) { - $scope.onApplyFilters(filters); - } - }); - function init() { // export some objects $scope.savedVis = savedVis; @@ -376,7 +353,6 @@ function VisEditor( // update the searchSource when filters update $scope.$listen(queryFilter, 'update', function () { - $scope.filters = queryFilter.getFilters(); $scope.fetch(); }); diff --git a/src/ui/public/_index.scss b/src/ui/public/_index.scss index 88726b1a69e5e..fc8e02aadc8da 100644 --- a/src/ui/public/_index.scss +++ b/src/ui/public/_index.scss @@ -26,7 +26,6 @@ @import './notify/index'; @import './partials/index'; @import './query_bar/index'; -@import './filter_bar/index'; @import './style_compile/index'; // The following are prefixed with "vis" diff --git a/src/ui/public/agg_types/filter/agg_type_filters.test.ts b/src/ui/public/agg_types/filter/agg_type_filters.test.ts index 416e9c1b45fd2..47e7bebf9f365 100644 --- a/src/ui/public/agg_types/filter/agg_type_filters.test.ts +++ b/src/ui/public/agg_types/filter/agg_type_filters.test.ts @@ -21,7 +21,7 @@ import { AggTypeFilters } from './agg_type_filters'; describe('AggTypeFilters', () => { let registry: AggTypeFilters; - const indexPattern = { id: '1234', fields: [], title: 'foo' }; + const indexPattern = {}; const aggConfig = {}; beforeEach(() => { diff --git a/src/ui/public/apply_filters/apply_filters_popover.tsx b/src/ui/public/apply_filters/apply_filters_popover.tsx deleted file mode 100644 index 67f78b0951f19..0000000000000 --- a/src/ui/public/apply_filters/apply_filters_popover.tsx +++ /dev/null @@ -1,128 +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 { - EuiButton, - EuiButtonEmpty, - EuiForm, - EuiFormRow, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiOverlayMask, - EuiSwitch, -} from '@elastic/eui'; -import { Filter } from '@kbn/es-query'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { Component } from 'react'; -import { getFilterDisplayText } from '../filter_bar/filter_view'; - -interface Props { - filters: Filter[]; - onCancel: () => void; - onSubmit: (filters: Filter[]) => void; -} - -interface State { - isFilterSelected: boolean[]; -} - -export class ApplyFiltersPopover extends Component { - public static defaultProps = { - filters: [], - }; - - public constructor(props: Props) { - super(props); - this.state = { - isFilterSelected: props.filters.map(() => true), - }; - } - - public render() { - if (this.props.filters.length === 0) { - return ''; - } - - const form = ( - - {this.props.filters.map((filter, i) => ( - - this.toggleFilterSelected(i)} - /> - - ))} - - ); - - return ( - - - - - - - - - {form} - - - - - - - - - - - - ); - } - - private isFilterSelected = (i: number) => { - return this.state.isFilterSelected[i]; - }; - - private toggleFilterSelected = (i: number) => { - const isFilterSelected = [...this.state.isFilterSelected]; - isFilterSelected[i] = !isFilterSelected[i]; - this.setState({ isFilterSelected }); - }; - - private onSubmit = () => { - const selectedFilters = this.props.filters.filter( - (filter, i) => this.state.isFilterSelected[i] - ); - this.props.onSubmit(selectedFilters); - }; -} diff --git a/src/ui/public/apply_filters/directive.html b/src/ui/public/apply_filters/directive.html deleted file mode 100644 index ed7a5d70a2b80..0000000000000 --- a/src/ui/public/apply_filters/directive.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/ui/public/apply_filters/directive.js b/src/ui/public/apply_filters/directive.js deleted file mode 100644 index d364a1843494a..0000000000000 --- a/src/ui/public/apply_filters/directive.js +++ /dev/null @@ -1,59 +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 'ngreact'; -import { uiModules } from '../modules'; -import template from './directive.html'; -import { ApplyFiltersPopover } from './apply_filters_popover'; -import { FilterBarLibMapAndFlattenFiltersProvider } from '../filter_bar/lib/map_and_flatten_filters'; - -const app = uiModules.get('app/kibana', ['react']); - -app.directive('applyFiltersPopoverComponent', (reactDirective) => { - return reactDirective(ApplyFiltersPopover); -}); - -app.directive('applyFiltersPopover', (reactDirective, Private) => { - const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); - - return { - template, - restrict: 'E', - scope: { - filters: '=', - onCancel: '=', - onSubmit: '=', - }, - link: function ($scope) { - $scope.state = {}; - - // Each time the new filters change we want to rebuild (not just re-render) the "apply filters" - // popover, because it has to reset its state whenever the new filters change. Setting a `key` - // property on the component accomplishes this due to how React handles the `key` property. - $scope.$watch('filters', filters => { - mapAndFlattenFilters(filters).then(mappedFilters => { - $scope.state = { - filters: mappedFilters, - key: Date.now(), - }; - }); - }); - } - }; -}); diff --git a/src/ui/public/doc_table/components/table_row.js b/src/ui/public/doc_table/components/table_row.js index f16be56778355..b7c5768bbaa9a 100644 --- a/src/ui/public/doc_table/components/table_row.js +++ b/src/ui/public/doc_table/components/table_row.js @@ -27,7 +27,7 @@ import { noWhiteSpace } from '../../../../legacy/core_plugins/kibana/common/util import openRowHtml from './table_row/open.html'; import detailsHtml from './table_row/details.html'; import { uiModules } from '../../modules'; -import { disableFilter } from '@kbn/es-query'; +import { disableFilter } from '../../filter_bar'; import { dispatchRenderComplete } from '../../render_complete'; const module = uiModules.get('app/discover'); diff --git a/src/ui/public/filter_bar/__tests__/filter_bar.js b/src/ui/public/filter_bar/__tests__/filter_bar.js new file mode 100644 index 0000000000000..a17875a3d8837 --- /dev/null +++ b/src/ui/public/filter_bar/__tests__/filter_bar.js @@ -0,0 +1,228 @@ +/* + * 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 ngMock from 'ng_mock'; +import expect from 'expect.js'; +import sinon from 'sinon'; + +import MockState from 'fixtures/mock_state'; +import $ from 'jquery'; +import '..'; +import { FilterBarLibMapFilterProvider } from '../lib/map_filter'; +import { FilterBarQueryFilterProvider } from '../query_filter'; + +describe('Filter Bar Directive', function () { + let $rootScope; + let $compile; + let Promise; + let appState; + let mapFilter; + let $el; + let $scope; + + beforeEach(ngMock.module('kibana/global_state', function ($provide) { + $provide.service('getAppState', _.constant(_.constant( + appState = new MockState({ filters: [] }) + ))); + })); + + beforeEach(function () { + // load the application + ngMock.module('kibana'); + + ngMock.module('kibana/courier', function ($provide) { + $provide.service('indexPatterns', require('fixtures/mock_index_patterns')); + }); + + ngMock.inject(function (Private, $injector, _$rootScope_, _$compile_) { + $rootScope = _$rootScope_; + $compile = _$compile_; + Promise = $injector.get('Promise'); + mapFilter = Private(FilterBarLibMapFilterProvider); + + const queryFilter = Private(FilterBarQueryFilterProvider); + queryFilter.getFilters = function () { + return appState.filters; + }; + }); + }); + + describe('Element rendering', function () { + beforeEach(function (done) { + const filters = [ + { meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'apache' } } } }, + { meta: { index: 'logstash-*' }, query: { match: { '_type': { query: 'nginx' } } } }, + { meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } }, + { meta: { index: 'logstash-*' }, missing: { field: 'host' }, disabled: true }, + { meta: { index: 'logstash-*', alias: 'foo' }, query: { match: { '_type': { query: 'nginx' } } } }, + ]; + + Promise.map(filters, mapFilter).then(function (filters) { + appState.filters = filters; + $el = $compile('')($rootScope); + $scope = $el.isolateScope(); + }); + + const off = $rootScope.$on('filterbar:updated', function () { + off(); + // force a nextTick so it continues *after* the $digest loop completes + setTimeout(done, 0); + }); + + // kick off the digest loop + $rootScope.$digest(); + }); + + it('should render all the filters in state', function () { + const filters = $el.find('.filter'); + expect(filters).to.have.length(5); + expect($(filters[0]).find('span')[0].innerHTML).to.equal('_type:'); + expect($(filters[0]).find('span')[1].innerHTML).to.equal('"apache"'); + expect($(filters[1]).find('span')[0].innerHTML).to.equal('_type:'); + expect($(filters[1]).find('span')[1].innerHTML).to.equal('"nginx"'); + expect($(filters[2]).find('span')[0].innerHTML).to.equal('@timestamp:'); + expect($(filters[2]).find('span')[1].innerHTML).to.equal('"exists"'); + expect($(filters[3]).find('span')[0].innerHTML).to.equal('host:'); + expect($(filters[3]).find('span')[1].innerHTML).to.equal('"missing"'); + }); + + it('should be able to set an alias', function () { + const filter = $el.find('.filter')[4]; + expect($(filter).find('span')[0].innerHTML).to.equal('foo'); + }); + + describe('editing filters', function () { + beforeEach(function () { + $scope.editFilter(appState.filters[3]); + $scope.$digest(); + }); + + it('should be able to edit a filter', function () { + expect($el.find('.filter-edit-container').length).to.be(1); + }); + + it('should be able to stop editing a filter', function () { + $scope.cancelEdit(); + $scope.$digest(); + expect($el.find('.filter-edit-container').length).to.be(0); + }); + + it('should remove old filter and add new filter when saving', function () { + sinon.spy($scope, 'removeFilter'); + sinon.spy($scope, 'addFilters'); + + $scope.saveEdit(appState.filters[3], appState.filters[3], false); + expect($scope.removeFilter.called).to.be(true); + expect($scope.addFilters.called).to.be(true); + }); + }); + + describe('show and hide filters', function () { + let scope; + + beforeEach(() => { + scope = $rootScope.$new(); + }); + + function create(attrs) { + const template = ` +
+ + +
`; + + const element = $compile(template)(scope); + + scope.$apply(() => { + Object.assign(scope, attrs); + }); + + return element; + } + + + describe('collapse filters', function () { + let element; + + beforeEach(function () { + element = create({ + filterNavToggle: { + isOpen: false + } + }); + }); + + it('should be able to collapse filters', function () { + expect(element.hasClass('filter-panel-close')).to.be(true); + }); + + it('should be able to see `actions`', function () { + expect(element.find('.filter-link.pull-right').hasClass('action-show')).to.be(true); + }); + + it('should be able to view the same button for `expand`', function () { + expect(element.find('.filter-nav-link__icon').hasClass('filter-nav-link--close')).to.be(true); + }); + }); + + describe('expand filters', function () { + let element; + + beforeEach(function () { + element = create({ + filterNavToggle: { + isOpen: true + } + }); + }); + + it('should be able to expand filters', function () { + expect(element.hasClass('filter-panel-close')).to.be(false); + }); + + it('should be able to view the `actions` at the bottom of the filter-bar', function () { + expect(element.find('.filter-link.pull-right').hasClass('action-show')).to.be(false); + }); + + it('should be able to view the same button for `collapse`', function () { + expect(element.find('.filter-nav-link__icon').hasClass('filter-nav-link--close')).to.be(false); + }); + }); + + }); + + }); +}); diff --git a/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js b/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js new file mode 100644 index 0000000000000..612956327c18f --- /dev/null +++ b/src/ui/public/filter_bar/__tests__/filter_bar_click_handler.js @@ -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 ngMock from 'ng_mock'; +import expect from 'expect.js'; + +import MockState from 'fixtures/mock_state'; +import { toastNotifications } from '../../notify'; +import AggConfigResult from '../../vis/agg_config_result'; + +import { VisProvider } from '../../vis'; +import StubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; +import { FilterBarClickHandlerProvider } from '../filter_bar_click_handler'; + +describe('filterBarClickHandler', function () { + let setup = null; + + beforeEach(ngMock.module('kibana')); + beforeEach(ngMock.inject(function (Private) { + setup = function () { + const Vis = Private(VisProvider); + const createClickHandler = Private(FilterBarClickHandlerProvider); + const indexPattern = Private(StubbedLogstashIndexPatternProvider); + + const vis = new Vis(indexPattern, { + type: 'histogram', + aggs: [ + { type: 'count', schema: 'metric' }, + { + type: 'terms', + schema: 'segment', + params: { field: 'non-filterable' } + } + ] + }); + const aggConfigResult = new AggConfigResult(vis.aggs[1], void 0, 'apache', 'apache'); + + const $state = new MockState({ filters: [] }); + const clickHandler = createClickHandler($state); + + return { clickHandler, $state, aggConfigResult }; + }; + })); + + beforeEach(function () { + toastNotifications.list.splice(0); + }); + + describe('on non-filterable fields', function () { + it('warns about trying to filter on a non-filterable field', function () { + const { clickHandler, aggConfigResult } = setup(); + expect(toastNotifications.list).to.have.length(0); + clickHandler({ point: { aggConfigResult } }); + expect(toastNotifications.list).to.have.length(1); + }); + + it('does not warn if the event is click is being simulated', function () { + const { clickHandler, aggConfigResult } = setup(); + expect(toastNotifications.list).to.have.length(0); + clickHandler({ point: { aggConfigResult } }, true); + expect(toastNotifications.list).to.have.length(0); + }); + }); +}); diff --git a/src/ui/public/filter_bar/_global_filter_group.scss b/src/ui/public/filter_bar/_global_filter_group.scss deleted file mode 100644 index 9ed40964a95b4..0000000000000 --- a/src/ui/public/filter_bar/_global_filter_group.scss +++ /dev/null @@ -1,22 +0,0 @@ -// SASSTODO: Probably not the right file for this selector, but temporary until the files get re-organized -.globalQueryBar { - padding-bottom: $euiSizeS; -} - -.globalFilterGroup__filterBar { - margin-top: $euiSizeM; -} - -// sass-lint:disable quotes -.globalFilterGroup__branch { - padding: $euiSize $euiSize $euiSizeS $euiSizeS; - background-repeat: no-repeat; - background-position: right top; - background-image: url("data:image/svg+xml,%0A%3Csvg width='28px' height='28px' viewBox='0 0 28 28' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='#{hexToRGB($euiColorLightShade)}'%3E%3Crect x='14' y='27' width='14' height='1'%3E%3C/rect%3E%3Crect x='0' y='0' width='1' height='14'%3E%3C/rect%3E%3C/g%3E%3C/svg%3E"); -} - -.globalFilterGroup__wrapper { - line-height: 1; // Override kuiLocalNav & kuiLocalNavRow - overflow: hidden; - transition: height $euiAnimSpeedNormal $euiAnimSlightResistance; -} diff --git a/src/ui/public/filter_bar/_global_filter_item.scss b/src/ui/public/filter_bar/_global_filter_item.scss deleted file mode 100644 index b3bc510be0c74..0000000000000 --- a/src/ui/public/filter_bar/_global_filter_item.scss +++ /dev/null @@ -1,37 +0,0 @@ -@import '@elastic/eui/src/components/form/mixins'; -@import '@elastic/eui/src/components/form/variables'; - -.globalFilterItem { - line-height: $euiSizeL + $euiSizeXS; - border: none; - color: $euiTextColor; - - &:not(.globalFilterItem-isDisabled) { - @include euiFormControlDefaultShadow; - } -} - -.globalFilterItem-isDisabled { - background-color: transparentize($euiColorLightShade, .4); - text-decoration: line-through; - font-weight: $euiFontWeightRegular; - font-style: italic; -} - -.globalFilterItem-isPinned { - position: relative; - - &::before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: $euiSizeXS; - background-color: $euiColorVis0; - } -} - -.globalFilterItem__editorForm { - padding: $euiSizeM; -} diff --git a/src/ui/public/filter_bar/_index.scss b/src/ui/public/filter_bar/_index.scss deleted file mode 100644 index 3c57b7fe2ca3a..0000000000000 --- a/src/ui/public/filter_bar/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import 'global_filter_group'; -@import 'global_filter_item'; diff --git a/src/ui/public/filter_bar/filter_bar.html b/src/ui/public/filter_bar/filter_bar.html new file mode 100644 index 0000000000000..5cd239781d192 --- /dev/null +++ b/src/ui/public/filter_bar/filter_bar.html @@ -0,0 +1,149 @@ +
+
+ +
    +
  • Apply these filters?
  • +
  • + NOT {{ filter.meta.key }}: {{ filter.meta.value }} +
  • +
  • Change time to: {{changeTimeFilter.meta.value}}
  • +
  • +
    + + + +
    +
  • +
+ +
+ +
+
+ +
+ + + + + + + +
+ +
+
+ +
+
+ + + + + + + + +
+
+
diff --git a/src/ui/public/filter_bar/filter_bar.js b/src/ui/public/filter_bar/filter_bar.js new file mode 100644 index 0000000000000..0a1648ac75d4a --- /dev/null +++ b/src/ui/public/filter_bar/filter_bar.js @@ -0,0 +1,213 @@ +/* + * 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 template from './filter_bar.html'; +import '../directives/json_input'; +import '../filter_editor'; +import './filter_pill/filter_pill'; +import { filterAppliedAndUnwrap } from './lib/filter_applied_and_unwrap'; +import { FilterBarLibMapAndFlattenFiltersProvider } from './lib/map_and_flatten_filters'; +import { FilterBarLibMapFlattenAndWrapFiltersProvider } from './lib/map_flatten_and_wrap_filters'; +import { FilterBarLibExtractTimeFilterProvider } from './lib/extract_time_filter'; +import { FilterBarLibFilterOutTimeBasedFilterProvider } from './lib/filter_out_time_based_filter'; +import { changeTimeFilter } from './lib/change_time_filter'; +import { FilterBarQueryFilterProvider } from './query_filter'; +import { compareFilters } from './lib/compare_filters'; +import { uiModules } from '../modules'; + +export { disableFilter, enableFilter, toggleFilterDisabled } from './lib/disable_filter'; + + +const module = uiModules.get('kibana'); + +module.directive('filterBar', function (Private, Promise, getAppState) { + const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); + const mapFlattenAndWrapFilters = Private(FilterBarLibMapFlattenAndWrapFiltersProvider); + const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider); + const filterOutTimeBasedFilter = Private(FilterBarLibFilterOutTimeBasedFilterProvider); + const queryFilter = Private(FilterBarQueryFilterProvider); + + return { + template, + restrict: 'E', + scope: { + indexPatterns: '=', + tooltipContent: '=', + }, + link: function ($scope, $elem) { + // bind query filter actions to the scope + [ + 'addFilters', + 'toggleFilter', + 'toggleAll', + 'pinFilter', + 'pinAll', + 'invertFilter', + 'invertAll', + 'removeFilter', + 'removeAll' + ].forEach(function (method) { + $scope[method] = queryFilter[method]; + }); + + $scope.state = getAppState(); + + $scope.showCollapseLink = () => { + const pill = $elem.find('filter-pill'); + return pill[pill.length - 1].offsetTop > 10; + }; + + $scope.filterNavToggle = { + isOpen: true, + tooltipContent: 'Collapse filter bar \n to show less' + }; + + $scope.toggleFilterShown = () => { + const collapser = $elem.find('.filter-nav-link__collapser'); + const filterPanelPill = $elem.find('.filter-panel__pill'); + if ($scope.filterNavToggle.isOpen) { + $scope.filterNavToggle.tooltipContent = 'Expand filter bar \n to show more'; + collapser.attr('aria-expanded', 'false'); + filterPanelPill.attr('style', 'width: calc(100% - 80px)'); + } else { + $scope.filterNavToggle.tooltipContent = 'Collapse filter bar \n to show less'; + collapser.attr('aria-expanded', 'true'); + filterPanelPill.attr('style', 'width: auto'); + } + + $scope.filterNavToggle.isOpen = !$scope.filterNavToggle.isOpen; + }; + + $scope.applyFilters = function (filters) { + addAndInvertFilters(filterAppliedAndUnwrap(filters)); + $scope.newFilters = []; + + // change time filter + if ($scope.changeTimeFilter && $scope.changeTimeFilter.meta && $scope.changeTimeFilter.meta.apply) { + changeTimeFilter($scope.changeTimeFilter); + } + }; + + $scope.addFilter = () => { + $scope.editingFilter = { + meta: { isNew: true } + }; + }; + + $scope.deleteFilter = (filter) => { + $scope.removeFilter(filter); + if (filter === $scope.editingFilter) $scope.cancelEdit(); + }; + + $scope.editFilter = (filter) => { + $scope.editingFilter = filter; + }; + + $scope.cancelEdit = () => { + delete $scope.editingFilter; + }; + + $scope.saveEdit = (filter, newFilter, isPinned) => { + if (!filter.meta.isNew) $scope.removeFilter(filter); + delete $scope.editingFilter; + $scope.addFilters([newFilter], isPinned); + }; + + $scope.clearFilterBar = function () { + $scope.newFilters = []; + $scope.changeTimeFilter = null; + }; + + // update the scope filter list on filter changes + $scope.$listen(queryFilter, 'update', function () { + updateFilters(); + }); + + // when appState changes, update scope's state + $scope.$watch(getAppState, function (appState) { + $scope.state = appState; + }); + + $scope.$watch('state.$newFilters', function (filters) { + if (!filters) return; + + // If filters is not undefined and the length is greater than + // one we need to set the newFilters attribute and allow the + // users to decide what they want to apply. + if (filters.length > 1) { + return mapFlattenAndWrapFilters(filters) + .then(function (results) { + extractTimeFilter(results).then(function (filter) { + $scope.changeTimeFilter = filter; + }); + return results; + }) + .then(filterOutTimeBasedFilter) + .then(function (results) { + $scope.newFilters = results; + }); + } + + // Just add single filters to the state. + if (filters.length === 1) { + Promise.resolve(filters).then(function (filters) { + extractTimeFilter(filters) + .then(function (timeFilter) { + if (timeFilter) changeTimeFilter(timeFilter); + }); + return filters; + }) + .then(filterOutTimeBasedFilter) + .then(addAndInvertFilters); + } + }); + + function addAndInvertFilters(filters) { + const existingFilters = queryFilter.getFilters(); + const inversionFilters = _.filter(existingFilters, (existingFilter) => { + const newMatchingFilter = _.find(filters, _.partial(compareFilters, existingFilter)); + return newMatchingFilter + && newMatchingFilter.meta + && existingFilter.meta + && existingFilter.meta.negate !== newMatchingFilter.meta.negate; + }); + const newFilters = _.reject(filters, (filter) => { + return _.find(inversionFilters, _.partial(compareFilters, filter)); + }); + + _.forEach(inversionFilters, $scope.invertFilter); + $scope.addFilters(newFilters); + } + + function updateFilters() { + const filters = queryFilter.getFilters(); + mapAndFlattenFilters(filters).then(function (results) { + // used to display the current filters in the state + $scope.filters = _.sortBy(results, function (filter) { + return !filter.meta.pinned; + }); + $scope.$emit('filterbar:updated'); + }); + } + + updateFilters(); + } + }; +}); diff --git a/src/ui/public/filter_bar/filter_bar.less b/src/ui/public/filter_bar/filter_bar.less index e69de29bb2d1d..979ca42ea5dc1 100644 --- a/src/ui/public/filter_bar/filter_bar.less +++ b/src/ui/public/filter_bar/filter_bar.less @@ -0,0 +1,226 @@ +// Variables ================================================================== +@filter-bar-confirm-bg: @gray-lighter; +@filter-bar-confirm-filter-color: @gray-darker; +@filter-bar-confirm-border: @gray-light; +@filter-bar-confirm-filter-bg: @gray-light; + +@filter-bar-bar-bg: @gray-lightest; +@filter-bar-bar-border: @gray-lighter; +@filter-bar-bar-condensed-bg: tint(@blue, 90%); + +@filter-bar-bar-filter-bg: @blue; +@filter-bar-bar-filter-color: @white; +@filter-bar-bar-filter-negate-bg: @brand-danger; +@filterBarDepth: 4; + +filter-bar { + z-index: @filterBarDepth !important; +} + +.filter-bar-confirm { + padding: 8px 10px 4px; + background: @filter-bar-confirm-bg; + border-bottom: 1px solid; + border-bottom-color: @filter-bar-confirm-border; + + ul { + margin-bottom: 0px; + } + + li { + display: inline-block; + } + + li:first-child { + font-weight: bold; + font-size: 1.2em; + } + + li button { + font-size: 0.9em; + padding: 2px 8px; + } + + .filter { + position: relative; + display: inline-block; + text-align: center; + // Number of filter icons multiplied by icon width + // Escaped to prevent less math + min-width: ~"calc(5*(1.414em + 13px))"; + vertical-align: middle; + font-size: @font-size-small; + background-color: @filter-bar-confirm-filter-bg; + color: @filter-bar-confirm-filter-color; + margin-right: 4px; + margin-bottom: 4px; + max-width: 100%; + + // Replace padding with border so absolute controls position correctly + padding: 4px 8px; + border-radius: 12px; + } +} + +.filter-panel { + position: relative; + + .filter-panel__pill { + display: inline; + } + +} + +.filter-panel--close { + max-height: 36px; + overflow-y: hidden; + min-width: 250px; + + .filter-panel__pill { + display: inline-block; + } +} + +.filter-bar { + padding: 6px 10px 1px 10px; + background: @filter-bar-bar-bg; + border-bottom: solid 1px @gray-lighter; + + .ace_editor { + height: 175px; + } + + .filter-edit-alias { + margin-top: 15px; + } + + .filter-link { + position: relative; + display: inline-block; + border: 4px solid transparent; + margin-bottom: 4px; + } + + .filter-description { + white-space: nowrap; + text-overflow: ellipsis; + vertical-align: middle; + line-height: 1.5; + } + + .action-show { + position: absolute; + right: 30px; + bottom: 0; + } + + .filter-nav-link__icon { + display: inline; + position: absolute; + top: 10px; + right: 10px; + opacity: 0.75; + font-size: 16px; + + &:hover { + opacity: 1; + } + + .filter-nav-link__collapser { + border: none; + line-height: 1; + } + } + + .filter { + position: relative; + display: inline-block; + text-align: center; + // Number of filter icons multiplied by icon width + // Escaped to prevent less math + min-width: ~"calc(5*(1.414em + 13px))"; + font-size: @font-size-small; + background-color: @filter-bar-bar-filter-bg; + color: @filter-bar-bar-filter-color; + margin-right: 4px; + margin-bottom: 4px; + max-width: 100%; + vertical-align: middle; + + // Replace padding with border so absolute controls position correctly + padding: 4px 8px; + border-radius: 12px; + + .filter-actions { + font-size: 1.1em; + line-height: 1.4em; + position: absolute; + padding: 4px 8px; + top: 0; + left: 0; + width: 100%; + opacity: 0; + text-align: center; + white-space: nowrap; + display: flex; + + .action { + border: none; + border-right: 1px solid rgba(255, 255, 255, 0.4); + padding: 0; + background-color: transparent; + flex: 1 1 auto; + + &:last-child { + border-right: 0; + padding-right: 0; + margin-right: 0; + } + + .unpinned { + .opacity(.7); + } + + .fa-disabled { + opacity: 0.7; + cursor: not-allowed; + } + } + } + + .filter-actions-activated { + opacity: 1; + } + + .filter-description-deactivated { + opacity: 0.15; + background: transparent; + overflow: hidden; + } + + &.negate { + background-color: @filter-bar-bar-filter-negate-bg; + } + + a { + color: @filter-bar-bar-filter-color; + } + + &.disabled { + opacity: 0.6; + background-image: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,255,255,.3) 10px, rgba(255,255,255,.3) 20px); + } + + &.disabled:hover { + span { + text-decoration: none; + } + } + } +} + + .filter-bar-condensed { + padding: 6px 6px 2px 6px !important; + font-size: 0.9em; + background: @filter-bar-bar-condensed-bg; + } diff --git a/src/ui/public/filter_bar/filter_bar.tsx b/src/ui/public/filter_bar/filter_bar.tsx deleted file mode 100644 index 551114e0bf33a..0000000000000 --- a/src/ui/public/filter_bar/filter_bar.tsx +++ /dev/null @@ -1,217 +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 { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPopover } from '@elastic/eui'; -import { - buildEmptyFilter, - disableFilter, - enableFilter, - Filter, - pinFilter, - toggleFilterDisabled, - toggleFilterNegated, - unpinFilter, -} from '@kbn/es-query'; -import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import classNames from 'classnames'; -import React, { Component } from 'react'; -import chrome from 'ui/chrome'; -import { IndexPattern } from 'ui/index_patterns'; -import { FilterOptions } from 'ui/search_bar/components/filter_options'; -import { FilterEditor } from './filter_editor'; -import { FilterItem } from './filter_item'; - -const config = chrome.getUiSettingsClient(); - -interface Props { - filters: Filter[]; - onFiltersUpdated: (filters: Filter[]) => void; - className: string; - indexPatterns: IndexPattern[]; - intl: InjectedIntl; -} - -interface State { - isAddFilterPopoverOpen: boolean; -} - -class FilterBarUI extends Component { - public state = { - isAddFilterPopoverOpen: false, - }; - - public render() { - const classes = classNames('globalFilterBar', this.props.className); - - return ( - - - - - - - - {this.renderItems()} - {this.renderAddFilter()} - - - - ); - } - - private renderItems() { - return this.props.filters.map((filter, i) => ( - - this.onUpdate(i, newFilter)} - onRemove={() => this.onRemove(i)} - indexPatterns={this.props.indexPatterns} - /> - - )); - } - - private renderAddFilter() { - const isPinned = config.get('filters:pinnedByDefault'); - const [indexPattern] = this.props.indexPatterns; - const index = indexPattern && indexPattern.id; - const newFilter = buildEmptyFilter(isPinned, index); - - const button = ( - - +{' '} - - - ); - - return ( - - -
- -
-
-
- ); - } - - private onAdd = (filter: Filter) => { - this.onCloseAddFilterPopover(); - const filters = [...this.props.filters, filter]; - this.props.onFiltersUpdated(filters); - }; - - private onRemove = (i: number) => { - const filters = [...this.props.filters]; - filters.splice(i, 1); - this.props.onFiltersUpdated(filters); - }; - - private onUpdate = (i: number, filter: Filter) => { - const filters = [...this.props.filters]; - filters[i] = filter; - this.props.onFiltersUpdated(filters); - }; - - private onEnableAll = () => { - const filters = this.props.filters.map(enableFilter); - this.props.onFiltersUpdated(filters); - }; - - private onDisableAll = () => { - const filters = this.props.filters.map(disableFilter); - this.props.onFiltersUpdated(filters); - }; - - private onPinAll = () => { - const filters = this.props.filters.map(pinFilter); - this.props.onFiltersUpdated(filters); - }; - - private onUnpinAll = () => { - const filters = this.props.filters.map(unpinFilter); - this.props.onFiltersUpdated(filters); - }; - - private onToggleAllNegated = () => { - const filters = this.props.filters.map(toggleFilterNegated); - this.props.onFiltersUpdated(filters); - }; - - private onToggleAllDisabled = () => { - const filters = this.props.filters.map(toggleFilterDisabled); - this.props.onFiltersUpdated(filters); - }; - - private onRemoveAll = () => { - this.props.onFiltersUpdated([]); - }; - - private onOpenAddFilterPopover = () => { - this.setState({ - isAddFilterPopoverOpen: true, - }); - }; - - private onCloseAddFilterPopover = () => { - this.setState({ - isAddFilterPopoverOpen: false, - }); - }; -} - -export const FilterBar = injectI18n(FilterBarUI); diff --git a/src/ui/public/filter_bar/filter_bar_click_handler.js b/src/ui/public/filter_bar/filter_bar_click_handler.js new file mode 100644 index 0000000000000..060be79644d38 --- /dev/null +++ b/src/ui/public/filter_bar/filter_bar_click_handler.js @@ -0,0 +1,89 @@ +/* + * 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 { dedupFilters } from './lib/dedup_filters'; +import { uniqFilters } from './lib/uniq_filters'; +import { findByParam } from '../utils/find_by_param'; +import { toastNotifications } from '../notify'; + +export function FilterBarClickHandlerProvider() { + + return function ($state) { + return function (event, simulate) { + if (!$state) return; + + let aggConfigResult; + + // Hierarchical and tabular data set their aggConfigResult parameter + // differently because of how the point is rewritten between the two. So + // we need to check if the point.orig is set, if not use try the point.aggConfigResult + if (event.point.orig) { + aggConfigResult = event.point.orig.aggConfigResult; + } else if (event.point.values) { + aggConfigResult = findByParam(event.point.values, 'aggConfigResult'); + } else { + aggConfigResult = event.point.aggConfigResult; + } + + if (aggConfigResult) { + const isLegendLabel = !!event.point.values; + let aggBuckets = _.filter(aggConfigResult.getPath(), { type: 'bucket' }); + + // For legend clicks, use the last bucket in the path + if (isLegendLabel) { + // series data has multiple values, use aggConfig on the first + // hierarchical data values is an object with the addConfig + const aggConfig = findByParam(event.point.values, 'aggConfig'); + aggBuckets = aggBuckets.filter((result) => result.aggConfig && result.aggConfig === aggConfig); + } + + let filters = _(aggBuckets) + .map(function (result) { + try { + return result.createFilter(); + } catch (e) { + if (!simulate) { + toastNotifications.addSuccess(e.message); + } + } + }) + .flatten() + .filter(Boolean) + .value(); + + if (!filters.length) return; + + if (event.negate) { + _.each(filters, function (filter) { + filter.meta = filter.meta || {}; + filter.meta.negate = true; + }); + } + + filters = dedupFilters($state.filters, uniqFilters(filters), { negate: true }); + + if (!simulate) { + $state.$newFilters = filters; + } + return filters; + } + }; + }; +} diff --git a/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx b/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx deleted file mode 100644 index 81b129d214e37..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/generic_combo_box.tsx +++ /dev/null @@ -1,61 +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 { EuiComboBox, EuiComboBoxOptionProps } from '@elastic/eui'; -import React from 'react'; - -export interface GenericComboBoxProps { - options: T[]; - selectedOptions: T[]; - getLabel: (value: T) => string; - onChange: (values: T[]) => void; - [propName: string]: any; -} - -/** - * A generic combo box. Instead of accepting a set of options that contain a `label`, it accepts - * any type of object. It also accepts a `getLabel` function that each object will be sent through - * to get the label to be passed to the combo box. The `onChange` will trigger with the actual - * selected objects, rather than an option object. - */ -export function GenericComboBox(props: GenericComboBoxProps) { - const { options, selectedOptions, getLabel, onChange, ...otherProps } = props; - - const labels = options.map(getLabel); - const euiOptions: EuiComboBoxOptionProps[] = labels.map(label => ({ label })); - const selectedEuiOptions = selectedOptions.map(option => { - return euiOptions[options.indexOf(option)]; - }); - - const onComboBoxChange = (newOptions: EuiComboBoxOptionProps[]) => { - const newValues = newOptions.map(({ label }) => { - return options[labels.indexOf(label)]; - }); - onChange(newValues); - }; - - return ( - - ); -} diff --git a/src/ui/public/filter_bar/filter_editor/index.tsx b/src/ui/public/filter_bar/filter_editor/index.tsx deleted file mode 100644 index de301432b1b67..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/index.tsx +++ /dev/null @@ -1,471 +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 { - EuiButton, - EuiButtonEmpty, - // @ts-ignore - EuiCodeEditor, - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiForm, - EuiFormRow, - EuiPopoverTitle, - EuiSpacer, - EuiSwitch, -} from '@elastic/eui'; -import { FieldFilter, Filter } from '@kbn/es-query'; -import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { get } from 'lodash'; -import React, { Component } from 'react'; -import { Field, IndexPattern } from 'ui/index_patterns'; -import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; -import { - buildCustomFilter, - buildFilter, - getFieldFromFilter, - getFilterableFields, - getFilterParams, - getIndexPatternFromFilter, - getOperatorFromFilter, - getOperatorOptions, - getQueryDslFromFilter, - isFilterValid, -} from './lib/filter_editor_utils'; -import { Operator } from './lib/filter_operators'; -import { PhraseValueInput } from './phrase_value_input'; -import { PhrasesValuesInput } from './phrases_values_input'; -import { RangeValueInput } from './range_value_input'; - -interface Props { - filter: Filter; - indexPatterns: IndexPattern[]; - onSubmit: (filter: Filter) => void; - onCancel: () => void; - intl: InjectedIntl; -} - -interface State { - selectedIndexPattern?: IndexPattern; - selectedField?: Field; - selectedOperator?: Operator; - params: any; - useCustomLabel: boolean; - customLabel: string | null; - queryDsl: string; - isCustomEditorOpen: boolean; -} - -class FilterEditorUI extends Component { - public constructor(props: Props) { - super(props); - this.state = { - selectedIndexPattern: this.getIndexPatternFromFilter(), - selectedField: this.getFieldFromFilter(), - selectedOperator: this.getSelectedOperator(), - params: getFilterParams(props.filter), - useCustomLabel: props.filter.meta.alias !== null, - customLabel: props.filter.meta.alias, - queryDsl: JSON.stringify(getQueryDslFromFilter(props.filter), null, 2), - isCustomEditorOpen: this.isUnknownFilterType(), - }; - } - - public render() { - return ( -
- - - - - - - - {this.state.isCustomEditorOpen ? ( - - ) : ( - - )} - - - - - -
- - {this.renderIndexPatternInput()} - - {this.state.isCustomEditorOpen ? this.renderCustomEditor() : this.renderRegularEditor()} - - - - - - {this.state.useCustomLabel && ( -
- - - - -
- )} - - - - - - - - - - - - - - - - -
-
-
- ); - } - - private renderIndexPatternInput() { - if (this.props.indexPatterns.length <= 1) { - return ''; - } - const { selectedIndexPattern } = this.state; - return ( - - - - indexPattern.title} - onChange={this.onIndexPatternChange} - singleSelection={{ asPlainText: true }} - isClearable={false} - /> - - - - ); - } - - private renderRegularEditor() { - return ( -
- - {this.renderFieldInput()} - {this.renderOperatorInput()} - - -
{this.renderParamsEditor()}
-
- ); - } - - private renderFieldInput() { - const { selectedIndexPattern, selectedField } = this.state; - const fields = selectedIndexPattern ? getFilterableFields(selectedIndexPattern) : []; - return ( - - field.name} - onChange={this.onFieldChange} - singleSelection={{ asPlainText: true }} - isClearable={false} - data-test-subj="filterFieldSuggestionList" - /> - - ); - } - - private renderOperatorInput() { - const { selectedField, selectedOperator } = this.state; - const operators = selectedField ? getOperatorOptions(selectedField) : []; - return ( - - message} - onChange={this.onOperatorChange} - singleSelection={{ asPlainText: true }} - isClearable={false} - data-test-subj="filterOperatorList" - /> - - ); - } - - private renderCustomEditor() { - return ( - - - - ); - } - - private renderParamsEditor() { - const indexPattern = this.state.selectedIndexPattern; - if (!indexPattern || !this.state.selectedOperator) { - return ''; - } - - switch (this.state.selectedOperator.type) { - case 'exists': - return ''; - case 'phrase': - return ( - - ); - case 'phrases': - return ( - - ); - case 'range': - return ( - - ); - } - } - - private toggleCustomEditor = () => { - const isCustomEditorOpen = !this.state.isCustomEditorOpen; - this.setState({ isCustomEditorOpen }); - }; - - private isUnknownFilterType() { - const { type } = this.props.filter.meta; - return !!type && !['phrase', 'phrases', 'range', 'exists'].includes(type); - } - - private getIndexPatternFromFilter() { - return getIndexPatternFromFilter(this.props.filter, this.props.indexPatterns); - } - - private getFieldFromFilter() { - const indexPattern = this.getIndexPatternFromFilter(); - return indexPattern && getFieldFromFilter(this.props.filter as FieldFilter, indexPattern); - } - - private getSelectedOperator() { - return getOperatorFromFilter(this.props.filter); - } - - private isFilterValid() { - const { - isCustomEditorOpen, - queryDsl, - selectedIndexPattern: indexPattern, - selectedField: field, - selectedOperator: operator, - params, - } = this.state; - - if (isCustomEditorOpen) { - try { - return Boolean(JSON.parse(queryDsl)); - } catch (e) { - return false; - } - } - - return isFilterValid(indexPattern, field, operator, params); - } - - private onIndexPatternChange = ([selectedIndexPattern]: IndexPattern[]) => { - const selectedField = undefined; - const selectedOperator = undefined; - const params = undefined; - this.setState({ selectedIndexPattern, selectedField, selectedOperator, params }); - }; - - private onFieldChange = ([selectedField]: Field[]) => { - const selectedOperator = undefined; - const params = undefined; - this.setState({ selectedField, selectedOperator, params }); - }; - - private onOperatorChange = ([selectedOperator]: Operator[]) => { - // Only reset params when the operator type changes - const params = - get(this.state.selectedOperator, 'type') === get(selectedOperator, 'type') - ? this.state.params - : undefined; - this.setState({ selectedOperator, params }); - }; - - private onCustomLabelSwitchChange = (event: React.ChangeEvent) => { - const useCustomLabel = event.target.checked; - const customLabel = event.target.checked ? '' : null; - this.setState({ useCustomLabel, customLabel }); - }; - - private onCustomLabelChange = (event: React.ChangeEvent) => { - const customLabel = event.target.value; - this.setState({ customLabel }); - }; - - private onParamsChange = (params: any) => { - this.setState({ params }); - }; - - private onQueryDslChange = (queryDsl: string) => { - this.setState({ queryDsl }); - }; - - private onSubmit = () => { - const { - selectedIndexPattern: indexPattern, - selectedField: field, - selectedOperator: operator, - params, - useCustomLabel, - customLabel, - isCustomEditorOpen, - queryDsl, - } = this.state; - - const { store } = this.props.filter.$state; - const alias = useCustomLabel ? customLabel : null; - - if (isCustomEditorOpen) { - const { index, disabled, negate } = this.props.filter.meta; - const newIndex = index || this.props.indexPatterns[0].id; - const body = JSON.parse(queryDsl); - const filter = buildCustomFilter(newIndex, body, disabled, negate, alias, store); - this.props.onSubmit(filter); - } else if (indexPattern && field && operator) { - const filter = buildFilter(indexPattern, field, operator, params, alias, store); - this.props.onSubmit(filter); - } - }; -} - -function IndexPatternComboBox(props: GenericComboBoxProps) { - return GenericComboBox(props); -} - -function FieldComboBox(props: GenericComboBoxProps) { - return GenericComboBox(props); -} - -function OperatorComboBox(props: GenericComboBoxProps) { - return GenericComboBox(props); -} - -export const FilterEditor = injectI18n(FilterEditorUI); diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts deleted file mode 100644 index 859f2fcc1535a..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.test.ts +++ /dev/null @@ -1,314 +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 { FilterStateStore, toggleFilterNegated } from '@kbn/es-query'; -import { mockFields, mockIndexPattern } from 'ui/index_patterns/fixtures'; -import { - buildFilter, - getFieldFromFilter, - getFilterableFields, - getFilterParams, - getIndexPatternFromFilter, - getOperatorFromFilter, - getOperatorOptions, - getQueryDslFromFilter, - isFilterValid, -} from './filter_editor_utils'; -import { - doesNotExistOperator, - existsOperator, - isBetweenOperator, - isOneOfOperator, - isOperator, -} from './filter_operators'; -import { existsFilter } from './fixtures/exists_filter'; -import { phraseFilter } from './fixtures/phrase_filter'; -import { phrasesFilter } from './fixtures/phrases_filter'; -import { rangeFilter } from './fixtures/range_filter'; - -describe('Filter editor utils', () => { - describe('getQueryDslFromFilter', () => { - it('should return query DSL without meta and $state', () => { - const queryDsl = getQueryDslFromFilter(phraseFilter); - expect(queryDsl).not.toHaveProperty('meta'); - expect(queryDsl).not.toHaveProperty('$state'); - }); - }); - - describe('getIndexPatternFromFilter', () => { - it('should return the index pattern from the filter', () => { - const indexPattern = getIndexPatternFromFilter(phraseFilter, [mockIndexPattern]); - expect(indexPattern).toBe(mockIndexPattern); - }); - }); - - describe('getFieldFromFilter', () => { - it('should return the field from the filter', () => { - const field = getFieldFromFilter(phraseFilter, mockIndexPattern); - expect(field).not.toBeUndefined(); - expect(field && field.name).toBe(phraseFilter.meta.key); - }); - }); - - describe('getOperatorFromFilter', () => { - it('should return "is" for phrase filter', () => { - const operator = getOperatorFromFilter(phraseFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('phrase'); - expect(operator && operator.negate).toBe(false); - }); - - it('should return "is not" for phrase filter', () => { - const negatedPhraseFilter = toggleFilterNegated(phraseFilter); - const operator = getOperatorFromFilter(negatedPhraseFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('phrase'); - expect(operator && operator.negate).toBe(true); - }); - - it('should return "is one of" for phrases filter', () => { - const operator = getOperatorFromFilter(phrasesFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('phrases'); - expect(operator && operator.negate).toBe(false); - }); - - it('should return "is not one of" for negated phrases filter', () => { - const negatedPhrasesFilter = toggleFilterNegated(phrasesFilter); - const operator = getOperatorFromFilter(negatedPhrasesFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('phrases'); - expect(operator && operator.negate).toBe(true); - }); - - it('should return "is between" for range filter', () => { - const operator = getOperatorFromFilter(rangeFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('range'); - expect(operator && operator.negate).toBe(false); - }); - - it('should return "is not between" for negated range filter', () => { - const negatedRangeFilter = toggleFilterNegated(rangeFilter); - const operator = getOperatorFromFilter(negatedRangeFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('range'); - expect(operator && operator.negate).toBe(true); - }); - - it('should return "exists" for exists filter', () => { - const operator = getOperatorFromFilter(existsFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('exists'); - expect(operator && operator.negate).toBe(false); - }); - - it('should return "does not exists" for negated exists filter', () => { - const negatedExistsFilter = toggleFilterNegated(existsFilter); - const operator = getOperatorFromFilter(negatedExistsFilter); - expect(operator).not.toBeUndefined(); - expect(operator && operator.type).toBe('exists'); - expect(operator && operator.negate).toBe(true); - }); - }); - - describe('getFilterParams', () => { - it('should retrieve params from phrase filter', () => { - const params = getFilterParams(phraseFilter); - expect(params).toBe('ios'); - }); - - it('should retrieve params from phrases filter', () => { - const params = getFilterParams(phrasesFilter); - expect(params).toEqual(['win xp', 'osx']); - }); - - it('should retrieve params from range filter', () => { - const params = getFilterParams(rangeFilter); - expect(params).toEqual({ from: 0, to: 10 }); - }); - - it('should return undefined for exists filter', () => { - const params = getFilterParams(existsFilter); - expect(params).toBeUndefined(); - }); - }); - - describe('getFilterableFields', () => { - it('returns the list of fields from the given index pattern', () => { - const fieldOptions = getFilterableFields(mockIndexPattern); - expect(fieldOptions.length).toBeGreaterThan(0); - }); - - it('limits the fields to the filterable fields', () => { - const fieldOptions = getFilterableFields(mockIndexPattern); - const nonFilterableFields = fieldOptions.filter(field => !field.filterable); - expect(nonFilterableFields.length).toBe(0); - }); - }); - - describe('getOperatorOptions', () => { - it('returns range for number fields', () => { - const [field] = mockFields.filter(({ type }) => type === 'number'); - const operatorOptions = getOperatorOptions(field); - const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); - expect(rangeOperator).not.toBeUndefined(); - }); - - it('does not return range for string fields', () => { - const [field] = mockFields.filter(({ type }) => type === 'string'); - const operatorOptions = getOperatorOptions(field); - const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); - expect(rangeOperator).toBeUndefined(); - }); - }); - - describe('isFilterValid', () => { - it('should return false if index pattern is not provided', () => { - const isValid = isFilterValid(undefined, mockFields[0], isOperator, 'foo'); - expect(isValid).toBe(false); - }); - - it('should return false if field is not provided', () => { - const isValid = isFilterValid(mockIndexPattern, undefined, isOperator, 'foo'); - expect(isValid).toBe(false); - }); - - it('should return false if operator is not provided', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], undefined, 'foo'); - expect(isValid).toBe(false); - }); - - it('should return false for phrases filter without phrases', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], isOneOfOperator, []); - expect(isValid).toBe(false); - }); - - it('should return true for phrases filter with phrases', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], isOneOfOperator, ['foo']); - expect(isValid).toBe(true); - }); - - it('should return false for range filter without range', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, undefined); - expect(isValid).toBe(false); - }); - - it('should return true for range filter with from', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, { - from: 'foo', - }); - expect(isValid).toBe(true); - }); - - it('should return true for range filter with from/to', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], isBetweenOperator, { - from: 'foo', - too: 'goo', - }); - expect(isValid).toBe(true); - }); - - it('should return true for exists filter without params', () => { - const isValid = isFilterValid(mockIndexPattern, mockFields[0], existsOperator); - expect(isValid).toBe(true); - }); - }); - - describe('buildFilter', () => { - it('should build phrase filters', () => { - const params = 'foo'; - const alias = 'bar'; - const state = FilterStateStore.APP_STATE; - const filter = buildFilter(mockIndexPattern, mockFields[0], isOperator, params, alias, state); - expect(filter.meta.negate).toBe(isOperator.negate); - expect(filter.meta.alias).toBe(alias); - expect(filter.$state.store).toBe(state); - }); - - it('should build phrases filters', () => { - const params = ['foo', 'bar']; - const alias = 'bar'; - const state = FilterStateStore.APP_STATE; - const filter = buildFilter( - mockIndexPattern, - mockFields[0], - isOneOfOperator, - params, - alias, - state - ); - expect(filter.meta.type).toBe(isOneOfOperator.type); - expect(filter.meta.negate).toBe(isOneOfOperator.negate); - expect(filter.meta.alias).toBe(alias); - expect(filter.$state.store).toBe(state); - }); - - it('should build range filters', () => { - const params = { from: 'foo', to: 'qux' }; - const alias = 'bar'; - const state = FilterStateStore.APP_STATE; - const filter = buildFilter( - mockIndexPattern, - mockFields[0], - isBetweenOperator, - params, - alias, - state - ); - expect(filter.meta.negate).toBe(isBetweenOperator.negate); - expect(filter.meta.alias).toBe(alias); - expect(filter.$state.store).toBe(state); - }); - - it('should build exists filters', () => { - const params = undefined; - const alias = 'bar'; - const state = FilterStateStore.APP_STATE; - const filter = buildFilter( - mockIndexPattern, - mockFields[0], - existsOperator, - params, - alias, - state - ); - expect(filter.meta.negate).toBe(existsOperator.negate); - expect(filter.meta.alias).toBe(alias); - expect(filter.$state.store).toBe(state); - }); - - it('should negate based on operator', () => { - const params = undefined; - const alias = 'bar'; - const state = FilterStateStore.APP_STATE; - const filter = buildFilter( - mockIndexPattern, - mockFields[0], - doesNotExistOperator, - params, - alias, - state - ); - expect(filter.meta.negate).toBe(doesNotExistOperator.negate); - expect(filter.meta.alias).toBe(alias); - expect(filter.$state.store).toBe(state); - }); - }); -}); diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts deleted file mode 100644 index b1b456e482ac9..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/lib/filter_editor_utils.ts +++ /dev/null @@ -1,178 +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 dateMath from '@elastic/datemath'; -import { - buildExistsFilter, - buildPhraseFilter, - buildPhrasesFilter, - buildRangeFilter, - FieldFilter, - Filter, - FilterMeta, - FilterStateStore, - PhraseFilter, - PhrasesFilter, - RangeFilter, -} from '@kbn/es-query'; -import { omit } from 'lodash'; -import { Field, IndexPattern } from 'ui/index_patterns'; -import { isFilterable } from 'ui/index_patterns/static_utils'; -import Ipv4Address from 'ui/utils/ipv4_address'; -import { FILTER_OPERATORS, Operator } from './filter_operators'; - -export function getIndexPatternFromFilter( - filter: Filter, - indexPatterns: IndexPattern[] -): IndexPattern | undefined { - return indexPatterns.find(indexPattern => indexPattern.id === filter.meta.index); -} - -export function getFieldFromFilter(filter: FieldFilter, indexPattern: IndexPattern) { - return indexPattern.fields.find(field => field.name === filter.meta.key); -} - -export function getOperatorFromFilter(filter: Filter) { - return FILTER_OPERATORS.find(operator => { - return filter.meta.type === operator.type && filter.meta.negate === operator.negate; - }); -} - -export function getQueryDslFromFilter(filter: Filter) { - return omit(filter, ['$state', 'meta']); -} - -export function getFilterableFields(indexPattern: IndexPattern) { - return indexPattern.fields.filter(isFilterable); -} - -export function getOperatorOptions(field: Field) { - return FILTER_OPERATORS.filter(operator => { - return !operator.fieldTypes || operator.fieldTypes.includes(field.type); - }); -} - -export function getFilterParams(filter: Filter) { - switch (filter.meta.type) { - case 'phrase': - return (filter as PhraseFilter).meta.params.query; - case 'phrases': - return (filter as PhrasesFilter).meta.params; - case 'range': - return { - from: (filter as RangeFilter).meta.params.gte, - to: (filter as RangeFilter).meta.params.lt, - }; - } -} - -export function validateParams(params: any, type: string) { - switch (type) { - case 'date': - const moment = typeof params === 'string' ? dateMath.parse(params) : null; - return Boolean(typeof params === 'string' && moment && moment.isValid()); - case 'ip': - try { - return Boolean(new Ipv4Address(params)); - } catch (e) { - return false; - } - default: - return true; - } -} - -export function isFilterValid( - indexPattern?: IndexPattern, - field?: Field, - operator?: Operator, - params?: any -) { - if (!indexPattern || !field || !operator) { - return false; - } - switch (operator.type) { - case 'phrase': - return validateParams(params, field.type); - case 'phrases': - if (!Array.isArray(params) || !params.length) { - return false; - } - return params.every(phrase => validateParams(phrase, field.type)); - case 'range': - if (typeof params !== 'object') { - return false; - } - return validateParams(params.from, field.type) || validateParams(params.to, field.type); - case 'exists': - return true; - default: - throw new Error(`Unknown operator type: ${operator.type}`); - } -} - -export function buildFilter( - indexPattern: IndexPattern, - field: Field, - operator: Operator, - params: any, - alias: string | null, - store: FilterStateStore -): Filter { - const filter = buildBaseFilter(indexPattern, field, operator, params); - filter.meta.alias = alias; - filter.meta.negate = operator.negate; - filter.$state = { store }; - return filter; -} - -function buildBaseFilter( - indexPattern: IndexPattern, - field: Field, - operator: Operator, - params: any -): Filter { - switch (operator.type) { - case 'phrase': - return buildPhraseFilter(field, params, indexPattern); - case 'phrases': - return buildPhrasesFilter(field, params, indexPattern); - case 'range': - const newParams = { gte: params.from, lt: params.to }; - return buildRangeFilter(field, newParams, indexPattern); - case 'exists': - return buildExistsFilter(field, indexPattern); - default: - throw new Error(`Unknown operator type: ${operator.type}`); - } -} - -export function buildCustomFilter( - index: string, - queryDsl: any, - disabled: boolean, - negate: boolean, - alias: string | null, - store: FilterStateStore -): Filter { - const meta: FilterMeta = { index, type: 'custom', disabled, negate, alias }; - const filter: Filter = { ...queryDsl, meta }; - filter.$state = { store }; - return filter; -} diff --git a/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts b/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts deleted file mode 100644 index b97f4a73901b6..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/lib/filter_operators.ts +++ /dev/null @@ -1,106 +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'; - -export interface Operator { - message: string; - type: string; - negate: boolean; - fieldTypes?: string[]; -} - -export const isOperator = { - message: i18n.translate('common.ui.filterEditor.isOperatorOptionLabel', { - defaultMessage: 'is', - }), - type: 'phrase', - negate: false, -}; - -export const isNotOperator = { - message: i18n.translate('common.ui.filterEditor.isNotOperatorOptionLabel', { - defaultMessage: 'is not', - }), - type: 'phrase', - negate: true, -}; - -export const isOneOfOperator = { - message: i18n.translate('common.ui.filterEditor.isOneOfOperatorOptionLabel', { - defaultMessage: 'is one of', - }), - type: 'phrases', - negate: false, - fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], -}; - -export const isNotOneOfOperator = { - message: i18n.translate('common.ui.filterEditor.isNotOneOfOperatorOptionLabel', { - defaultMessage: 'is not one of', - }), - type: 'phrases', - negate: true, - fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'], -}; - -export const isBetweenOperator = { - message: i18n.translate('common.ui.filterEditor.isBetweenOperatorOptionLabel', { - defaultMessage: 'is between', - }), - type: 'range', - negate: false, - fieldTypes: ['number', 'date', 'ip'], -}; - -export const isNotBetweenOperator = { - message: i18n.translate('common.ui.filterEditor.isNotBetweenOperatorOptionLabel', { - defaultMessage: 'is not between', - }), - type: 'range', - negate: true, - fieldTypes: ['number', 'date', 'ip'], -}; - -export const existsOperator = { - message: i18n.translate('common.ui.filterEditor.existsOperatorOptionLabel', { - defaultMessage: 'exists', - }), - type: 'exists', - negate: false, -}; - -export const doesNotExistOperator = { - message: i18n.translate('common.ui.filterEditor.doesNotExistOperatorOptionLabel', { - defaultMessage: 'does not exist', - }), - type: 'exists', - negate: true, -}; - -export const FILTER_OPERATORS: Operator[] = [ - isOperator, - isNotOperator, - isOneOfOperator, - isNotOneOfOperator, - isBetweenOperator, - isNotBetweenOperator, - existsOperator, - doesNotExistOperator, -]; diff --git a/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx b/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx deleted file mode 100644 index 75073def34281..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/phrase_suggestor.tsx +++ /dev/null @@ -1,73 +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 { Component } from 'react'; -import chrome from 'ui/chrome'; -import { Field, IndexPattern } from 'ui/index_patterns'; -import { getSuggestions } from 'ui/value_suggestions'; -const config = chrome.getUiSettingsClient(); - -export interface PhraseSuggestorProps { - indexPattern: IndexPattern; - field?: Field; -} - -export interface PhraseSuggestorState { - suggestions: string[]; - isLoading: boolean; -} - -/** - * Since both "phrase" and "phrases" filter inputs suggest values (if enabled and the field is - * aggregatable), we pull out the common logic for requesting suggestions into this component - * which both of them extend. - */ -export class PhraseSuggestor extends Component< - T, - PhraseSuggestorState -> { - public state: PhraseSuggestorState = { - suggestions: [], - isLoading: false, - }; - - public componentDidMount() { - this.updateSuggestions(); - } - - protected isSuggestingValues() { - const shouldSuggestValues = config.get('filterEditor:suggestValues'); - const { field } = this.props; - return shouldSuggestValues && field && field.aggregatable && field.type === 'string'; - } - - protected onSearchChange = (value: string | number | boolean) => { - this.updateSuggestions(`${value}`); - }; - - protected async updateSuggestions(value: string = '') { - const { indexPattern, field } = this.props as PhraseSuggestorProps; - if (!field || !this.isSuggestingValues()) { - return; - } - this.setState({ isLoading: true }); - const suggestions = await getSuggestions(indexPattern.title, field, value); - this.setState({ suggestions, isLoading: false }); - } -} diff --git a/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx b/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx deleted file mode 100644 index 06b826d681d0c..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/phrase_value_input.tsx +++ /dev/null @@ -1,88 +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 { EuiFormRow } from '@elastic/eui'; -import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { uniq } from 'lodash'; -import React from 'react'; -import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; -import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor'; -import { ValueInputType } from './value_input_type'; - -interface Props extends PhraseSuggestorProps { - value?: string; - onChange: (value: string | number | boolean) => void; - intl: InjectedIntl; -} - -class PhraseValueInputUI extends PhraseSuggestor { - public render() { - return ( - - {this.isSuggestingValues() ? ( - this.renderWithSuggestions() - ) : ( - - )} - - ); - } - - private renderWithSuggestions() { - const { suggestions } = this.state; - const { value, intl, onChange } = this.props; - const options = value ? uniq([value, ...suggestions]) : suggestions; - return ( - option} - selectedOptions={value ? [value] : []} - onChange={([newValue = '']) => onChange(newValue)} - onSearchChange={this.onSearchChange} - singleSelection={{ asPlainText: true }} - onCreateOption={onChange} - isClearable={false} - data-test-subj="filterParamsComboBox phraseParamsComboxBox" - /> - ); - } -} - -function StringComboBox(props: GenericComboBoxProps) { - return GenericComboBox(props); -} - -export const PhraseValueInput = injectI18n(PhraseValueInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx b/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx deleted file mode 100644 index bef1433223e74..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/phrases_values_input.tsx +++ /dev/null @@ -1,67 +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 { EuiFormRow } from '@elastic/eui'; -import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { uniq } from 'lodash'; -import React from 'react'; -import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box'; -import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor'; - -interface Props extends PhraseSuggestorProps { - values?: string[]; - onChange: (values: string[]) => void; - intl: InjectedIntl; -} - -class PhrasesValuesInputUI extends PhraseSuggestor { - public render() { - const { suggestions } = this.state; - const { values, intl, onChange } = this.props; - const options = values ? uniq([...values, ...suggestions]) : suggestions; - return ( - - option} - selectedOptions={values || []} - onCreateOption={(option: string) => onChange([...(values || []), option])} - onChange={onChange} - isClearable={false} - data-test-subj="filterParamsComboBox phrasesParamsComboxBox" - /> - - ); - } -} - -function StringComboBox(props: GenericComboBoxProps) { - return GenericComboBox(props); -} - -export const PhrasesValuesInput = injectI18n(PhrasesValuesInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/range_value_input.tsx b/src/ui/public/filter_bar/filter_editor/range_value_input.tsx deleted file mode 100644 index 7343c5722f226..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/range_value_input.tsx +++ /dev/null @@ -1,121 +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 { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIcon, EuiLink } from '@elastic/eui'; -import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { get } from 'lodash'; -import { Component } from 'react'; -import React from 'react'; -import { getDocLink } from 'ui/documentation_links'; -import { Field } from 'ui/index_patterns'; -import { ValueInputType } from './value_input_type'; - -interface RangeParams { - from: number | string; - to: number | string; -} - -type RangeParamsPartial = Partial; - -interface Props { - field?: Field; - value?: RangeParams; - onChange: (params: RangeParamsPartial) => void; - intl: InjectedIntl; -} - -class RangeValueInputUI extends Component { - public constructor(props: Props) { - super(props); - } - - public render() { - const type = this.props.field ? this.props.field.type : 'string'; - - return ( -
- - - - - - - - - - - - - {type === 'date' ? ( - - {' '} - - - ) : ( - '' - )} -
- ); - } - - private onFromChange = (value: string | number | boolean) => { - if (typeof value !== 'string' && typeof value !== 'number') { - throw new Error('Range params must be a string or number'); - } - this.props.onChange({ from: value, to: get(this, 'props.value.to') }); - }; - - private onToChange = (value: string | number | boolean) => { - if (typeof value !== 'string' && typeof value !== 'number') { - throw new Error('Range params must be a string or number'); - } - this.props.onChange({ from: get(this, 'props.value.from'), to: value }); - }; -} - -export const RangeValueInput = injectI18n(RangeValueInputUI); diff --git a/src/ui/public/filter_bar/filter_editor/value_input_type.tsx b/src/ui/public/filter_bar/filter_editor/value_input_type.tsx deleted file mode 100644 index 0a573c88eae70..0000000000000 --- a/src/ui/public/filter_bar/filter_editor/value_input_type.tsx +++ /dev/null @@ -1,120 +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 { EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui'; -import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import { isEmpty } from 'lodash'; -import React, { Component } from 'react'; -import { validateParams } from './lib/filter_editor_utils'; - -interface Props { - value?: string | number; - type: string; - onChange: (value: string | number | boolean) => void; - placeholder: string; - intl: InjectedIntl; -} - -class ValueInputTypeUI extends Component { - public render() { - const value = this.props.value; - let inputElement: React.ReactNode; - switch (this.props.type) { - case 'string': - inputElement = ( - - ); - break; - case 'number': - inputElement = ( - - ); - break; - case 'date': - inputElement = ( - - ); - break; - case 'ip': - inputElement = ( - - ); - break; - case 'boolean': - inputElement = ( - - ); - break; - default: - break; - } - - return inputElement; - } - - private onBoolChange = (event: React.ChangeEvent) => { - const boolValue = event.target.value === 'true'; - this.props.onChange(boolValue); - }; - - private onChange = (event: React.ChangeEvent) => { - const params = event.target.value; - this.props.onChange(params); - }; -} - -export const ValueInputType = injectI18n(ValueInputTypeUI); diff --git a/src/ui/public/filter_bar/filter_item.tsx b/src/ui/public/filter_bar/filter_item.tsx deleted file mode 100644 index 82ed8c692d549..0000000000000 --- a/src/ui/public/filter_bar/filter_item.tsx +++ /dev/null @@ -1,226 +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 { EuiContextMenu, EuiPopover } from '@elastic/eui'; -import { - Filter, - isFilterPinned, - toggleFilterDisabled, - toggleFilterNegated, - toggleFilterPinned, -} from '@kbn/es-query'; -import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import classNames from 'classnames'; -import React, { Component } from 'react'; -import { IndexPattern } from 'ui/index_patterns'; -import { FilterEditor } from './filter_editor'; -import { FilterView } from './filter_view'; - -interface Props { - id: string; - filter: Filter; - indexPatterns: IndexPattern[]; - className?: string; - onUpdate: (filter: Filter) => void; - onRemove: () => void; - intl: InjectedIntl; -} - -interface State { - isPopoverOpen: boolean; -} - -class FilterItemUI extends Component { - public state = { - isPopoverOpen: false, - }; - - public render() { - const { filter, id } = this.props; - const { negate, disabled } = filter.meta; - - const classes = classNames( - 'globalFilterItem', - { - 'globalFilterItem-isDisabled': disabled, - 'globalFilterItem-isPinned': isFilterPinned(filter), - 'globalFilterItem-isExcluded': negate, - }, - this.props.className - ); - - const dataTestSubjKey = filter.meta.key ? `filter-key-${filter.meta.key}` : ''; - const dataTestSubjValue = filter.meta.value ? `filter-value-${filter.meta.value}` : ''; - const dataTestSubjDisabled = `filter-${ - this.props.filter.meta.disabled ? 'disabled' : 'enabled' - }`; - - const badge = ( - this.props.onRemove()} - onClick={this.togglePopover} - data-test-subj={`filter ${dataTestSubjDisabled} ${dataTestSubjKey} ${dataTestSubjValue}`} - /> - ); - - const panelTree = [ - { - id: 0, - items: [ - { - name: isFilterPinned(filter) - ? this.props.intl.formatMessage({ - id: 'common.ui.filterBar.unpinFilterButtonLabel', - defaultMessage: 'Unpin', - }) - : this.props.intl.formatMessage({ - id: 'common.ui.filterBar.pinFilterButtonLabel', - defaultMessage: 'Pin across all apps', - }), - icon: 'pin', - onClick: () => { - this.closePopover(); - this.onTogglePinned(); - }, - 'data-test-subj': 'pinFilter', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.filterBar.editFilterButtonLabel', - defaultMessage: 'Edit filter', - }), - icon: 'pencil', - panel: 1, - 'data-test-subj': 'editFilter', - }, - { - name: negate - ? this.props.intl.formatMessage({ - id: 'common.ui.filterBar.includeFilterButtonLabel', - defaultMessage: 'Include results', - }) - : this.props.intl.formatMessage({ - id: 'common.ui.filterBar.excludeFilterButtonLabel', - defaultMessage: 'Exclude results', - }), - icon: negate ? 'plusInCircle' : 'minusInCircle', - onClick: () => { - this.closePopover(); - this.onToggleNegated(); - }, - 'data-test-subj': 'negateFilter', - }, - { - name: disabled - ? this.props.intl.formatMessage({ - id: 'common.ui.filterBar.enableFilterButtonLabel', - defaultMessage: 'Re-enable', - }) - : this.props.intl.formatMessage({ - id: 'common.ui.filterBar.disableFilterButtonLabel', - defaultMessage: 'Temporarily disable', - }), - icon: `${disabled ? 'eye' : 'eyeClosed'}`, - onClick: () => { - this.closePopover(); - this.onToggleDisabled(); - }, - 'data-test-subj': 'disableFilter', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.filterBar.deleteFilterButtonLabel', - defaultMessage: 'Delete', - }), - icon: 'trash', - onClick: () => { - this.closePopover(); - this.props.onRemove(); - }, - 'data-test-subj': 'deleteFilter', - }, - ], - }, - { - id: 1, - width: 400, - content: ( -
- -
- ), - }, - ]; - - return ( - - - - ); - } - - private closePopover = () => { - this.setState({ - isPopoverOpen: false, - }); - }; - - private togglePopover = () => { - this.setState({ - isPopoverOpen: !this.state.isPopoverOpen, - }); - }; - - private onSubmit = (filter: Filter) => { - this.closePopover(); - this.props.onUpdate(filter); - }; - - private onTogglePinned = () => { - const filter = toggleFilterPinned(this.props.filter); - this.props.onUpdate(filter); - }; - - private onToggleNegated = () => { - const filter = toggleFilterNegated(this.props.filter); - this.props.onUpdate(filter); - }; - - private onToggleDisabled = () => { - const filter = toggleFilterDisabled(this.props.filter); - this.props.onUpdate(filter); - }; -} - -export const FilterItem = injectI18n(FilterItemUI); diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.html b/src/ui/public/filter_bar/filter_pill/filter_pill.html new file mode 100644 index 0000000000000..f79d42665e8fc --- /dev/null +++ b/src/ui/public/filter_bar/filter_pill/filter_pill.html @@ -0,0 +1,97 @@ +
+ +
+ + NOT + {{ pill.filter.meta.alias }} + {{ pill.filter.meta.key }}: + "{{ pill.filter.meta.value }}" +
+ +
+ + + + + + + + + + +
+
diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.js b/src/ui/public/filter_bar/filter_pill/filter_pill.js new file mode 100644 index 0000000000000..03b19427af930 --- /dev/null +++ b/src/ui/public/filter_bar/filter_pill/filter_pill.js @@ -0,0 +1,57 @@ +/* + * 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 template from './filter_pill.html'; +import { uiModules } from '../../modules'; + +const module = uiModules.get('kibana'); + +module.directive('filterPill', function () { + return { + template, + restrict: 'E', + scope: { + filter: '=', + onToggleFilter: '=', + onPinFilter: '=', + onInvertFilter: '=', + onDeleteFilter: '=', + onEditFilter: '=', + }, + bindToController: true, + controllerAs: 'pill', + controller: function filterPillController() { + + this.activateActions = () => { + this.areActionsActivated = true; + }; + + this.deactivateActions = () => { + this.areActionsActivated = false; + }; + + this.isControlledByPanel = () => { + return _.has(this.filter, 'meta.controlledBy'); + }; + + } + }; +}); + diff --git a/src/ui/public/search_bar/components/index.tsx b/src/ui/public/filter_bar/filter_pill/index.js similarity index 95% rename from src/ui/public/search_bar/components/index.tsx rename to src/ui/public/filter_bar/filter_pill/index.js index 131c6059934a4..3db610588eb75 100644 --- a/src/ui/public/search_bar/components/index.tsx +++ b/src/ui/public/filter_bar/filter_pill/index.js @@ -17,4 +17,4 @@ * under the License. */ -export { SearchBar } from './search_bar'; +import './filter_pill'; diff --git a/src/ui/public/filter_bar/filter_view/index.tsx b/src/ui/public/filter_bar/filter_view/index.tsx deleted file mode 100644 index 2421e7dcfab97..0000000000000 --- a/src/ui/public/filter_bar/filter_view/index.tsx +++ /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 { EuiBadge } from '@elastic/eui'; -import { Filter, isFilterPinned } from '@kbn/es-query'; -import { i18n } from '@kbn/i18n'; -import React, { SFC } from 'react'; -import { existsOperator, isOneOfOperator } from 'ui/filter_bar/filter_editor/lib/filter_operators'; - -interface Props { - filter: Filter; - [propName: string]: any; -} - -export const FilterView: SFC = ({ filter, ...rest }: Props) => { - let title = `Filter: ${getFilterDisplayText(filter)}. ${i18n.translate( - 'common.ui.filterBar.moreFilterActionsMessage', - { - defaultMessage: 'Select for more filter actions.', - } - )}`; - - if (isFilterPinned(filter)) { - title = `${i18n.translate('common.ui.filterBar.pinnedFilterPrefix', { - defaultMessage: 'Pinned', - })} ${title}`; - } - if (filter.meta.disabled) { - title = `${i18n.translate('common.ui.filterBar.disabledFilterPrefix', { - defaultMessage: 'Disabled', - })} ${title}`; - } - - return ( - - {getFilterDisplayText(filter)} - - ); -}; - -export function getFilterDisplayText(filter: Filter) { - if (filter.meta.alias !== null) { - return filter.meta.alias; - } - - const prefix = filter.meta.negate - ? ` ${i18n.translate('common.ui.filterBar.negatedFilterPrefix', { - defaultMessage: 'NOT ', - })}` - : ''; - - switch (filter.meta.type) { - case 'exists': - return `${prefix}${filter.meta.key} ${existsOperator.message}`; - case 'geo_bounding_box': - return `${prefix}${filter.meta.key}: ${filter.meta.value}`; - case 'geo_polygon': - return `${prefix}${filter.meta.key}: ${filter.meta.value}`; - case 'phrase': - return `${prefix}${filter.meta.key}: ${filter.meta.value}`; - case 'phrases': - return `${prefix}${filter.meta.key} ${isOneOfOperator.message} ${filter.meta.value}`; - case 'query_string': - return `${prefix}${filter.meta.value}`; - case 'range': - return `${prefix}${filter.meta.key}: ${filter.meta.value}`; - default: - return `${prefix}${JSON.stringify(filter.query)}`; - } -} diff --git a/src/ui/public/search_bar/index.tsx b/src/ui/public/filter_bar/index.js similarity index 86% rename from src/ui/public/search_bar/index.tsx rename to src/ui/public/filter_bar/index.js index 2469f62781f97..082a17b501ed9 100644 --- a/src/ui/public/search_bar/index.tsx +++ b/src/ui/public/filter_bar/index.js @@ -17,6 +17,6 @@ * under the License. */ -import './directive'; +import './filter_bar'; // directive -export { SearchBar } from './components'; +export { disableFilter, enableFilter, toggleFilterDisabled } from './lib/disable_filter'; diff --git a/src/ui/public/filter_bar/index.ts b/src/ui/public/filter_bar/index.ts deleted file mode 100644 index cdf49a72e9554..0000000000000 --- a/src/ui/public/filter_bar/index.ts +++ /dev/null @@ -1,22 +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 './directive'; - -export { FilterBar } from './filter_bar'; diff --git a/src/ui/public/filter_bar/lib/__tests__/disable_filter.js b/src/ui/public/filter_bar/lib/__tests__/disable_filter.js new file mode 100644 index 0000000000000..2541ec6cacae0 --- /dev/null +++ b/src/ui/public/filter_bar/lib/__tests__/disable_filter.js @@ -0,0 +1,140 @@ +/* + * 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 expect from 'expect.js'; + +import { + disableFilter, + enableFilter, + toggleFilterDisabled, +} from '../disable_filter'; + + +describe('function disableFilter', function () { + it('should disable a filter that is explicitly enabled', function () { + const enabledFilter = { + meta: { + disabled: false, + }, + match_all: {}, + }; + + expect(disableFilter(enabledFilter).meta).to.have.property('disabled', true); + }); + + it('should disable a filter that is implicitly enabled', function () { + const enabledFilter = { + match_all: {}, + }; + + expect(disableFilter(enabledFilter).meta).to.have.property('disabled', true); + }); + + it('should preserve other properties', function () { + const enabledFilterWithProperties = { + meta: { + meta_property: 'META_PROPERTY', + }, + match_all: {}, + }; + + const disabledFilter = disableFilter(enabledFilterWithProperties); + expect(disabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); + expect(disabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); + }); +}); + +describe('function enableFilter', function () { + it('should enable a filter that is disabled', function () { + const disabledFilter = { + meta: { + disabled: true, + }, + match_all: {}, + }; + + expect(enableFilter(disabledFilter).meta).to.have.property('disabled', false); + }); + + it('should explicitly enable a filter that is implicitly enabled', function () { + const enabledFilter = { + match_all: {}, + }; + + expect(enableFilter(enabledFilter).meta).to.have.property('disabled', false); + }); + + it('should preserve other properties', function () { + const enabledFilterWithProperties = { + meta: { + meta_property: 'META_PROPERTY', + }, + match_all: {}, + }; + + const enabledFilter = enableFilter(enabledFilterWithProperties); + expect(enabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); + expect(enabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); + }); +}); + +describe('function toggleFilterDisabled', function () { + it('should enable a filter that is disabled', function () { + const disabledFilter = { + meta: { + disabled: true, + }, + match_all: {}, + }; + + expect(toggleFilterDisabled(disabledFilter).meta).to.have.property('disabled', false); + }); + + it('should disable a filter that is explicitly enabled', function () { + const enabledFilter = { + meta: { + disabled: false, + }, + match_all: {}, + }; + + expect(toggleFilterDisabled(enabledFilter).meta).to.have.property('disabled', true); + }); + + it('should disable a filter that is implicitly enabled', function () { + const enabledFilter = { + match_all: {}, + }; + + expect(toggleFilterDisabled(enabledFilter).meta).to.have.property('disabled', true); + }); + + it('should preserve other properties', function () { + const enabledFilterWithProperties = { + meta: { + meta_property: 'META_PROPERTY', + }, + match_all: {}, + }; + + const disabledFilter = toggleFilterDisabled(enabledFilterWithProperties); + expect(disabledFilter).to.have.property('match_all', enabledFilterWithProperties.match_all); + expect(disabledFilter.meta).to.have.property('meta_property', enabledFilterWithProperties.meta_property); + }); +}); diff --git a/packages/kbn-es-query/src/filters/lib/exists_filter.ts b/src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js similarity index 56% rename from packages/kbn-es-query/src/filters/lib/exists_filter.ts rename to src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js index 356d039f4d19b..819035452837e 100644 --- a/packages/kbn-es-query/src/filters/lib/exists_filter.ts +++ b/src/ui/public/filter_bar/lib/__tests__/filter_applied_and_unwrap.js @@ -17,10 +17,22 @@ * under the License. */ -import { Filter, FilterMeta } from './meta_filter'; +import expect from 'expect.js'; +import { filterAppliedAndUnwrap } from '../filter_applied_and_unwrap'; -export type ExistsFilterMeta = FilterMeta; +describe('Filter Bar Directive', function () { + describe('filterAppliedAndUnwrap()', function () { -export type ExistsFilter = Filter & { - meta: ExistsFilterMeta; -}; + const filters = [ + { meta: { apply: true }, exists: { field: '_type' } }, + { meta: { apply: false }, query: { query_string: { query: 'foo:bar' } } } + ]; + + it('should filter the applied and unwrap the filter', function () { + const results = filterAppliedAndUnwrap(filters); + expect(results).to.have.length(1); + expect(results[0]).to.eql(filters[0]); + }); + + }); +}); diff --git a/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js b/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js new file mode 100644 index 0000000000000..009683e3c07f4 --- /dev/null +++ b/src/ui/public/filter_bar/lib/__tests__/filter_out_time_based_filter.js @@ -0,0 +1,57 @@ +/* + * 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 expect from 'expect.js'; +import ngMock from 'ng_mock'; +import { FilterBarLibFilterOutTimeBasedFilterProvider } from '../filter_out_time_based_filter'; + +describe('Filter Bar Directive', function () { + describe('filterOutTimeBasedFilter()', function () { + + let filterOutTimeBasedFilter; + let $rootScope; + + beforeEach(ngMock.module( + 'kibana', + 'kibana/courier', + function ($provide) { + $provide.service('indexPatterns', require('fixtures/mock_index_patterns')); + } + )); + + beforeEach(ngMock.inject(function (Private, _$rootScope_) { + filterOutTimeBasedFilter = Private(FilterBarLibFilterOutTimeBasedFilterProvider); + $rootScope = _$rootScope_; + })); + + it('should return the matching filter for the default time field', function (done) { + const filters = [ + { meta: { index: 'logstash-*' }, query: { match: { _type: { query: 'apache', type: 'phrase' } } } }, + { meta: { index: 'logstash-*' }, range: { 'time': { gt: 1388559600000, lt: 1388646000000 } } } + ]; + filterOutTimeBasedFilter(filters).then(function (results) { + expect(results).to.have.length(1); + expect(results).to.not.contain(filters[1]); + done(); + }); + $rootScope.$apply(); + }); + + }); +}); diff --git a/src/ui/public/filter_bar/lib/disable_filter.js b/src/ui/public/filter_bar/lib/disable_filter.js new file mode 100644 index 0000000000000..815bc4eb2a83a --- /dev/null +++ b/src/ui/public/filter_bar/lib/disable_filter.js @@ -0,0 +1,44 @@ +/* + * 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 function disableFilter(filter) { + return setFilterDisabled(filter, true); +} + +export function enableFilter(filter) { + return setFilterDisabled(filter, false); +} + +export function toggleFilterDisabled(filter) { + const { meta: { disabled = false } = {} } = filter; + + return setFilterDisabled(filter, !disabled); +} + +function setFilterDisabled(filter, disabled) { + const { meta = {} } = filter; + + return { + ...filter, + meta: { + ...meta, + disabled, + } + }; +} diff --git a/src/ui/public/apply_filters/index.ts b/src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js similarity index 87% rename from src/ui/public/apply_filters/index.ts rename to src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js index 4346316e62374..843ff6daf1049 100644 --- a/src/ui/public/apply_filters/index.ts +++ b/src/ui/public/filter_bar/lib/filter_applied_and_unwrap.js @@ -17,6 +17,9 @@ * under the License. */ -import './directive'; +import _ from 'lodash'; + +export function filterAppliedAndUnwrap(filters) { + return _.filter(filters, 'meta.apply'); +} -export { ApplyFiltersPopover } from './apply_filters_popover'; diff --git a/packages/kbn-es-query/src/filters/lib/range_filter.ts b/src/ui/public/filter_bar/lib/filter_out_time_based_filter.js similarity index 64% rename from packages/kbn-es-query/src/filters/lib/range_filter.ts rename to src/ui/public/filter_bar/lib/filter_out_time_based_filter.js index 214652fb3f332..0aa628e6ad069 100644 --- a/packages/kbn-es-query/src/filters/lib/range_filter.ts +++ b/src/ui/public/filter_bar/lib/filter_out_time_based_filter.js @@ -17,19 +17,17 @@ * under the License. */ -import { Filter, FilterMeta } from './meta_filter'; +import _ from 'lodash'; -export interface RangeFilterParams { - gt?: number | string; - gte?: number | string; - lte?: number | string; - lt?: number | string; -} - -export type RangeFilterMeta = FilterMeta & { - params: RangeFilterParams; -}; +export function FilterBarLibFilterOutTimeBasedFilterProvider(indexPatterns, Promise) { + return Promise.method(function (filters) { + const id = _.get(filters, '[0].meta.index'); + if (id == null) return; -export type RangeFilter = Filter & { - meta: RangeFilterMeta; -}; + return indexPatterns.get(id).then(function (indexPattern) { + return _.filter(filters, function (filter) { + return !(filter.range && filter.range[indexPattern.timeFieldName]); + }); + }); + }); +} diff --git a/src/ui/public/filter_bar/lib/map_phrase.js b/src/ui/public/filter_bar/lib/map_phrase.js index 687c844f7eec7..25018d4746e2b 100644 --- a/src/ui/public/filter_bar/lib/map_phrase.js +++ b/src/ui/public/filter_bar/lib/map_phrase.js @@ -30,8 +30,8 @@ export function FilterBarLibMapPhraseProvider(Promise, indexPatterns) { function getParams(indexPattern) { const type = 'phrase'; const key = isScriptedPhraseFilter ? filter.meta.field : Object.keys(filter.query.match)[0]; - const query = isScriptedPhraseFilter ? filter.script.script.params.value : filter.query.match[key].query; - const params = { query }; + const params = isScriptedPhraseFilter ? filter.script.script.params : filter.query.match[key]; + const query = isScriptedPhraseFilter ? params.value : params.query; // Sometimes a filter will end up with an invalid index or field param. This could happen for a lot of reasons, // for example a user might manually edit the url or the index pattern's ID might change due to @@ -54,6 +54,6 @@ export function FilterBarLibMapPhraseProvider(Promise, indexPatterns) { } function isScriptedPhrase(filter) { - const value = _.get(filter, ['script', 'script', 'params', 'value']); - return typeof value !== 'undefined'; + const params = _.get(filter, ['script', 'script', 'params']); + return params && params.value; } diff --git a/src/ui/public/filter_bar/query_filter.js b/src/ui/public/filter_bar/query_filter.js index 5b73013973fb8..0c1e68c084535 100644 --- a/src/ui/public/filter_bar/query_filter.js +++ b/src/ui/public/filter_bar/query_filter.js @@ -24,13 +24,10 @@ import { uniqFilters } from './lib/uniq_filters'; import { compareFilters } from './lib/compare_filters'; import { EventsProvider } from '../events'; import { FilterBarLibMapAndFlattenFiltersProvider } from './lib/map_and_flatten_filters'; -import { FilterBarLibExtractTimeFilterProvider } from './lib/extract_time_filter'; -import { changeTimeFilter } from './lib/change_time_filter'; export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, globalState, config) { const EventEmitter = Private(EventsProvider); const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); - const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider); const queryFilter = new EventEmitter(); @@ -219,24 +216,6 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g executeOnFilters(pin); }; - queryFilter.setFilters = filters => { - return mapAndFlattenFilters(filters) - .then(mappedFilters => { - const appState = getAppState(); - const [globalFilters, appFilters] = _.partition(mappedFilters, filter => { - return filter.$state.store === 'globalState'; - }); - globalState.filters = globalFilters; - if (appState) appState.filters = appFilters; - }); - }; - - queryFilter.addFiltersAndChangeTimeFilter = async filters => { - const timeFilter = await extractTimeFilter(filters); - if (timeFilter) changeTimeFilter(timeFilter); - queryFilter.addFilters(filters.filter(filter => filter !== timeFilter)); - }; - initWatchers(); return queryFilter; @@ -289,6 +268,7 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g // ensure we don't mutate the filters passed in const globalFilters = gFilters ? _.cloneDeep(gFilters) : []; const appFilters = aFilters ? _.cloneDeep(aFilters) : []; + compareOptions = _.defaults(compareOptions || {}, { disabled: true }); // existing globalFilters should be mutated by appFilters _.each(appFilters, function (filter, i) { @@ -313,8 +293,8 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g return [ // Reverse filters after uniq again, so they are still in the order, they // were before updating them - uniqFilters(globalFilters).reverse(), - uniqFilters(appFilters).reverse() + uniqFilters(globalFilters, { disabled: true }).reverse(), + uniqFilters(appFilters, { disabled: true }).reverse() ]; } @@ -352,7 +332,8 @@ export function FilterBarQueryFilterProvider(Private, $rootScope, getAppState, g // reconcile filter in global and app states const filters = mergeStateFilters(next[0], next[1]); - const [globalFilters, appFilters] = filters; + const globalFilters = filters[0]; + const appFilters = filters[1]; const appState = getAppState(); // save the state, as it may have updated diff --git a/src/ui/public/filter_editor/filter_editor.html b/src/ui/public/filter_editor/filter_editor.html new file mode 100644 index 0000000000000..0b69a1d5661d8 --- /dev/null +++ b/src/ui/public/filter_editor/filter_editor.html @@ -0,0 +1,148 @@ +
+
+
+ Add + Edit + filter +
+ + +
+ +
+ +
+ + + +
+
+ +
+ +
+ +
+ +
+ +
+
+ + +
+ + +

+ Filters are built using the Elasticsearch Query DSL. +

+
+
+ + +
+
+ +
+ + +
+
+ + +
+
+ +
+ +
+ + +
+
+
diff --git a/src/ui/public/filter_editor/filter_editor.js b/src/ui/public/filter_editor/filter_editor.js new file mode 100644 index 0000000000000..ac55a253b594f --- /dev/null +++ b/src/ui/public/filter_editor/filter_editor.js @@ -0,0 +1,161 @@ +/* + * 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 { uiModules } from '../modules'; +import { callAfterBindingsWorkaround } from '../compat'; +import { FILTER_OPERATOR_TYPES } from './lib/filter_operators'; +import template from './filter_editor.html'; +import '../directives/documentation_href'; +import './filter_query_dsl_editor'; +import './filter_field_select'; +import './filter_operator_select'; +import './params_editor/filter_params_editor'; +import './filter_editor.less'; +import { + getQueryDslFromFilter, + getFieldFromFilter, + getOperatorFromFilter, + getParamsFromFilter, + isFilterValid, + buildFilter, + areIndexPatternsProvided, + isFilterPinned +} from './lib/filter_editor_utils'; +import * as filterBuilder from '@kbn/es-query'; +import { keyMap } from '../utils/key_map'; + +const module = uiModules.get('kibana'); +module.directive('filterEditor', function ($timeout, indexPatterns) { + return { + restrict: 'E', + template, + scope: { + indexPatterns: '=', + filter: '=', + onDelete: '&', + onCancel: '&', + onSave: '&' + }, + controllerAs: 'filterEditor', + bindToController: true, + controller: callAfterBindingsWorkaround(function ($scope, $element, config) { + const pinnedByDefault = config.get('filters:pinnedByDefault'); + + this.init = async () => { + if (!areIndexPatternsProvided(this.indexPatterns)) { + const defaultIndexPattern = await indexPatterns.getDefault(); + if (defaultIndexPattern) { + this.indexPatterns = [defaultIndexPattern]; + } + } + const { filter } = this; + this.alias = filter.meta.alias; + this.isEditingQueryDsl = false; + this.queryDsl = getQueryDslFromFilter(filter); + if (filter.meta.isNew) { + this.setFocus('field'); + } else { + getFieldFromFilter(filter, indexPatterns) + .then((field) => { + this.setField(field); + this.setOperator(getOperatorFromFilter(filter)); + this.params = getParamsFromFilter(filter); + }); + } + }; + + $scope.$watch(() => this.filter, this.init); + $scope.$watchCollection(() => this.filter.meta, this.init); + + this.setQueryDsl = (queryDsl) => { + this.queryDsl = queryDsl; + }; + + this.setField = (field) => { + this.field = field; + this.operator = null; + this.params = {}; + }; + + this.onFieldSelect = (field) => { + this.setField(field); + this.setFocus('operator'); + }; + + this.setOperator = (operator) => { + this.operator = operator; + }; + + this.onOperatorSelect = (operator) => { + this.setOperator(operator); + this.setFocus('params'); + }; + + this.setParams = (params) => { + this.params = params; + }; + + this.setFocus = (name) => { + $timeout(() => $scope.$broadcast(`focus-${name}`)); + }; + + this.toggleEditingQueryDsl = () => { + this.isEditingQueryDsl = !this.isEditingQueryDsl; + }; + + this.isQueryDslEditorVisible = () => { + const { type, isNew } = this.filter.meta; + return this.isEditingQueryDsl || (!isNew && !FILTER_OPERATOR_TYPES.includes(type)); + }; + + this.isValid = () => { + if (this.isQueryDslEditorVisible()) { + return _.isObject(this.queryDsl); + } + const { field, operator, params } = this; + return isFilterValid({ field, operator, params }); + }; + + this.save = () => { + const { filter, field, operator, params, alias } = this; + + let newFilter; + if (this.isQueryDslEditorVisible()) { + const meta = _.pick(filter.meta, ['negate', 'index']); + meta.index = meta.index || this.indexPatterns[0].id; + newFilter = Object.assign(this.queryDsl, { meta }); + } else { + const indexPattern = field.indexPattern; + newFilter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + } + newFilter.meta.disabled = filter.meta.disabled; + newFilter.meta.alias = alias; + const isPinned = isFilterPinned(filter, pinnedByDefault); + return this.onSave({ filter, newFilter, isPinned }); + }; + + $element.on('keydown', (event) => { + if (keyMap[event.keyCode] === 'escape') { + $timeout(() => this.onCancel()); + } + }); + }) + }; +}); diff --git a/src/ui/public/filter_editor/filter_editor.less b/src/ui/public/filter_editor/filter_editor.less new file mode 100644 index 0000000000000..b45c0030b37d3 --- /dev/null +++ b/src/ui/public/filter_editor/filter_editor.less @@ -0,0 +1,36 @@ +.filterEditor { + position: absolute; + width: 600px; + z-index: 101; +} + +.filterEditor__labelBar { + display: flex; + align-items: center; + justify-content: space-between; +} + +.filterEditor__wideField { + min-width: 0; +} + +.filterEditorParamsInput { + min-width: 100px; +} + +.uiSelectChoices--autoWidth { + width: auto !important; + min-width: 100% !important; +} + +.uiSelectMatch--restrictToParent .ui-select-match-item { + max-width: 100%; +} + + .uiSelectMatch--pillWithTooltip { + display: block; + margin-right: 16px; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } diff --git a/src/ui/public/filter_editor/filter_field_select.html b/src/ui/public/filter_editor/filter_field_select.html new file mode 100644 index 0000000000000..65c45b1bae7b0 --- /dev/null +++ b/src/ui/public/filter_editor/filter_field_select.html @@ -0,0 +1,27 @@ + + + + {{$select.selected.name}} + + + +
+
+
diff --git a/src/ui/public/filter_editor/filter_field_select.js b/src/ui/public/filter_editor/filter_field_select.js new file mode 100644 index 0000000000000..f1aeb276d58d1 --- /dev/null +++ b/src/ui/public/filter_editor/filter_field_select.js @@ -0,0 +1,52 @@ +/* + * 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 'angular-ui-select'; +import { uiModules } from '../modules'; +import { getFilterableFields } from './lib/filter_editor_utils'; +import template from './filter_field_select.html'; +import '../directives/ui_select_focus_on'; +import '../directives/scroll_bottom'; +import '../filters/sort_prefix_first'; + +const module = uiModules.get('kibana'); +module.directive('filterFieldSelect', function () { + return { + restrict: 'E', + template, + scope: { + indexPatterns: '=', + field: '=', + onSelect: '&' + }, + link: function ($scope) { + $scope.$watch('indexPatterns', (indexPatterns) => { + $scope.fieldOptions = getFilterableFields(indexPatterns); + }); + + $scope.getFieldIndexPattern = (field) => { + return field.indexPattern.title; + }; + + $scope.increaseLimit = () => $scope.limit += 50; + $scope.resetLimit = () => $scope.limit = 50; + $scope.resetLimit(); + } + }; +}); diff --git a/src/ui/public/filter_editor/filter_operator_select.html b/src/ui/public/filter_editor/filter_operator_select.html new file mode 100644 index 0000000000000..78b730b93b58a --- /dev/null +++ b/src/ui/public/filter_editor/filter_operator_select.html @@ -0,0 +1,12 @@ + + + {{$select.selected.name}} + + +
+
+
diff --git a/src/ui/public/filter_bar/directive.js b/src/ui/public/filter_editor/filter_operator_select.js similarity index 60% rename from src/ui/public/filter_bar/directive.js rename to src/ui/public/filter_editor/filter_operator_select.js index afb598de5a7b1..3d877aee869b7 100644 --- a/src/ui/public/filter_bar/directive.js +++ b/src/ui/public/filter_editor/filter_operator_select.js @@ -17,13 +17,26 @@ * under the License. */ -import 'ngreact'; +import 'angular-ui-select'; import { uiModules } from '../modules'; -import { FilterBar } from './filter_bar'; -import { injectI18nProvider } from '@kbn/i18n/react'; +import { getOperatorOptions } from './lib/filter_editor_utils'; +import template from './filter_operator_select.html'; +import '../directives/ui_select_focus_on'; -const app = uiModules.get('app/kibana', ['react']); - -app.directive('filterBar', reactDirective => { - return reactDirective(injectI18nProvider(FilterBar)); +const module = uiModules.get('kibana'); +module.directive('filterOperatorSelect', function () { + return { + restrict: 'E', + template, + scope: { + field: '=', + operator: '=', + onSelect: '&' + }, + link: function ($scope) { + $scope.$watch('field', (field) => { + $scope.operatorOptions = getOperatorOptions(field); + }); + } + }; }); diff --git a/src/ui/public/filter_editor/filter_query_dsl_editor.html b/src/ui/public/filter_editor/filter_query_dsl_editor.html new file mode 100644 index 0000000000000..999dae7c1df0c --- /dev/null +++ b/src/ui/public/filter_editor/filter_query_dsl_editor.html @@ -0,0 +1,13 @@ +
diff --git a/src/ui/public/filter_editor/filter_query_dsl_editor.js b/src/ui/public/filter_editor/filter_query_dsl_editor.js new file mode 100644 index 0000000000000..16f763378ae05 --- /dev/null +++ b/src/ui/public/filter_editor/filter_query_dsl_editor.js @@ -0,0 +1,59 @@ +/* + * 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 'ace'; +import _ from 'lodash'; +import { uiModules } from '../modules'; +import template from './filter_query_dsl_editor.html'; +import '../accessibility/kbn_ui_ace_keyboard_mode'; + +const module = uiModules.get('kibana'); +module.directive('filterQueryDslEditor', function () { + return { + restrict: 'E', + template, + scope: { + isVisible: '=', + filter: '=', + onChange: '&' + }, + link: { + pre: function ($scope) { + let aceEditor; + + $scope.queryDsl = _.omit($scope.filter, ['meta', '$state']); + $scope.aceLoaded = function (editor) { + aceEditor = editor; + editor.$blockScrolling = Infinity; + const session = editor.getSession(); + session.setTabSize(2); + session.setUseSoftTabs(true); + }; + + $scope.$watch('isVisible', isVisible => { + // Tell the editor to re-render itself now that it's visible, otherwise it won't + // show up in the UI. + if (isVisible && aceEditor) { + aceEditor.renderer.updateFull(); + } + }); + } + } + }; +}); diff --git a/src/ui/public/documentation_links/index.d.ts b/src/ui/public/filter_editor/index.js similarity index 94% rename from src/ui/public/documentation_links/index.d.ts rename to src/ui/public/filter_editor/index.js index b37021b497de3..dc613de885ee7 100644 --- a/src/ui/public/documentation_links/index.d.ts +++ b/src/ui/public/filter_editor/index.js @@ -17,4 +17,4 @@ * under the License. */ -export function getDocLink(id: string): string; +import './filter_editor'; diff --git a/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js b/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js new file mode 100644 index 0000000000000..61aadc4c07487 --- /dev/null +++ b/src/ui/public/filter_editor/lib/__tests__/filter_editor_utils.js @@ -0,0 +1,396 @@ +/* + * 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 expect from 'expect.js'; +import ngMock from 'ng_mock'; +import sinon from 'sinon'; +import Promise from 'bluebird'; +import { + phraseFilter, + scriptedPhraseFilter, + phrasesFilter, + rangeFilter, + existsFilter +} from 'fixtures/filters'; +import stubbedLogstashIndexPattern from 'fixtures/stubbed_logstash_index_pattern'; +import stubbedLogstashFields from 'fixtures/logstash_fields'; +import { FILTER_OPERATORS } from '../filter_operators'; +import { + getQueryDslFromFilter, + getFieldFromFilter, + getOperatorFromFilter, + getParamsFromFilter, + getFilterableFields, + getOperatorOptions, + isFilterValid, + buildFilter, + areIndexPatternsProvided, + isFilterPinned +} from '../filter_editor_utils'; + +describe('FilterEditorUtils', function () { + beforeEach(ngMock.module('kibana')); + + let indexPattern; + let fields; + beforeEach(function () { + ngMock.inject(function (Private) { + indexPattern = Private(stubbedLogstashIndexPattern); + fields = stubbedLogstashFields(); + }); + }); + + describe('getQueryDslFromFilter', function () { + it('should return query DSL without meta and $state', function () { + const queryDsl = getQueryDslFromFilter(phraseFilter); + expect(queryDsl).to.not.have.key('meta'); + expect(queryDsl).to.not.have.key('$state'); + expect(queryDsl).to.have.key('query'); + }); + }); + + describe('getFieldFromFilter', function () { + let indexPatterns; + beforeEach(function () { + indexPatterns = { + get: sinon.stub().returns(Promise.resolve(indexPattern)) + }; + }); + + it('should return the field from the filter', function (done) { + getFieldFromFilter(phraseFilter, indexPatterns) + .then((field) => { + expect(field).to.be.ok(); + done(); + }); + }); + }); + + describe('getOperatorFromFilter', function () { + it('should return "is" for phrase filter', function () { + const operator = getOperatorFromFilter(phraseFilter); + expect(operator.name).to.be('is'); + expect(operator.negate).to.be(false); + }); + + it('should return "is not" for negated phrase filter', function () { + const negate = phraseFilter.meta.negate; + phraseFilter.meta.negate = true; + const operator = getOperatorFromFilter(phraseFilter); + expect(operator.name).to.be('is not'); + expect(operator.negate).to.be(true); + phraseFilter.meta.negate = negate; + }); + + it('should return "is one of" for phrases filter', function () { + const operator = getOperatorFromFilter(phrasesFilter); + expect(operator.name).to.be('is one of'); + expect(operator.negate).to.be(false); + }); + + it('should return "is not one of" for negated phrases filter', function () { + const negate = phrasesFilter.meta.negate; + phrasesFilter.meta.negate = true; + const operator = getOperatorFromFilter(phrasesFilter); + expect(operator.name).to.be('is not one of'); + expect(operator.negate).to.be(true); + phrasesFilter.meta.negate = negate; + }); + + it('should return "is between" for range filter', function () { + const operator = getOperatorFromFilter(rangeFilter); + expect(operator.name).to.be('is between'); + expect(operator.negate).to.be(false); + }); + + it('should return "is not between" for negated range filter', function () { + const negate = rangeFilter.meta.negate; + rangeFilter.meta.negate = true; + const operator = getOperatorFromFilter(rangeFilter); + expect(operator.name).to.be('is not between'); + expect(operator.negate).to.be(true); + rangeFilter.meta.negate = negate; + }); + + it('should return "exists" for exists filter', function () { + const operator = getOperatorFromFilter(existsFilter); + expect(operator.name).to.be('exists'); + expect(operator.negate).to.be(false); + }); + + it('should return "does not exists" for negated exists filter', function () { + const negate = existsFilter.meta.negate; + existsFilter.meta.negate = true; + const operator = getOperatorFromFilter(existsFilter); + expect(operator.name).to.be('does not exist'); + expect(operator.negate).to.be(true); + existsFilter.meta.negate = negate; + }); + }); + + describe('getParamsFromFilter', function () { + it('should retrieve params from phrase filter', function () { + const params = getParamsFromFilter(phraseFilter); + expect(params.phrase).to.be('ios'); + }); + + it('should retrieve params from scripted phrase filter', function () { + const params = getParamsFromFilter(scriptedPhraseFilter); + expect(params.phrase).to.be('i am a string'); + }); + + it('should retrieve params from phrases filter', function () { + const params = getParamsFromFilter(phrasesFilter); + expect(params.phrases).to.eql(['win xp', 'osx']); + }); + + it('should retrieve params from range filter', function () { + const params = getParamsFromFilter(rangeFilter); + expect(params.range).to.eql({ from: 0, to: 10 }); + }); + + it('should return undefined for exists filter', function () { + const params = getParamsFromFilter(existsFilter); + expect(params.exists).to.not.be.ok(); + }); + }); + + describe('getFilterableFields', function () { + it('returns an empty array when no index patterns are provided', function () { + const fieldOptions = getFilterableFields(); + expect(fieldOptions).to.eql([]); + }); + + it('returns the list of fields from the given index patterns', function () { + const fieldOptions = getFilterableFields([indexPattern]); + expect(fieldOptions).to.be.an('array'); + expect(fieldOptions.length).to.be.greaterThan(0); + }); + + it('limits the fields to the filterable fields', function () { + const fieldOptions = getFilterableFields([indexPattern]); + const nonFilterableFields = fieldOptions.filter(field => !field.filterable); + expect(nonFilterableFields.length).to.be(0); + }); + }); + + describe('getOperatorOptions', function () { + it('returns range for number fields', function () { + const field = fields.find(field => field.type === 'number'); + const operatorOptions = getOperatorOptions(field); + const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); + expect(rangeOperator).to.be.ok(); + }); + + it('does not return range for string fields', function () { + const field = fields.find(field => field.type === 'string'); + const operatorOptions = getOperatorOptions(field); + const rangeOperator = operatorOptions.find(operator => operator.type === 'range'); + expect(rangeOperator).to.not.be.ok(); + }); + + it('returns operators without field type restrictions', function () { + const operatorOptions = getOperatorOptions(); + const operatorsWithoutFieldTypes = FILTER_OPERATORS.filter(operator => !operator.fieldTypes); + expect(operatorOptions.length).to.be(operatorsWithoutFieldTypes.length); + }); + }); + + describe('isFilterValid', function () { + it('should return false if field is not provided', function () { + const field = null; + const operator = FILTER_OPERATORS[0]; + const params = { phrase: 'foo' }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.not.be.ok(); + }); + + it('should return false if operator is not provided', function () { + const field = fields[0]; + const operator = null; + const params = { phrase: 'foo' }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.not.be.ok(); + }); + + it('should return false for phrase filter without phrase', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); + const params = {}; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.not.be.ok(); + }); + + it('should return true for phrase filter with phrase', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); + const params = { phrase: 'foo' }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.be.ok(); + }); + + it('should return false for phrases filter without phrases', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); + const params = {}; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.not.be.ok(); + }); + + it('should return true for phrases filter with phrases', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); + const params = { phrases: ['foo', 'bar'] }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.be.ok(); + }); + + it('should return false for range filter without range', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); + const params = {}; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.not.be.ok(); + }); + + it('should return true for range filter with from', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); + const params = { range: { from: 0 } }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.be.ok(); + }); + + it('should return true for range filter with from/to', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); + const params = { range: { from: 0, to: 10 } }; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.be.ok(); + }); + + it('should return true for exists filter without params', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists'); + const params = {}; + const isValid = isFilterValid({ field, operator, params }); + expect(isValid).to.be.ok(); + }); + }); + + describe('buildFilter', function () { + let filterBuilder; + beforeEach(function () { + filterBuilder = { + buildExistsFilter: sinon.stub().returns(existsFilter), + buildPhraseFilter: sinon.stub().returns(phraseFilter), + buildPhrasesFilter: sinon.stub().returns(phrasesFilter), + buildRangeFilter: sinon.stub().returns(rangeFilter) + }; + }); + + it('should build phrase filters', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrase'); + const params = { phrase: 'foo' }; + const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + expect(filter).to.be.ok(); + expect(filter.meta.negate).to.be(operator.negate); + expect(filterBuilder.buildPhraseFilter.called).to.be.ok(); + expect(filterBuilder.buildPhraseFilter.getCall(0).args[1]).to.be(params.phrase); + }); + + it('should build phrases filters', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'phrases'); + const params = { phrases: ['foo', 'bar'] }; + const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + expect(filter).to.be.ok(); + expect(filter.meta.negate).to.be(operator.negate); + expect(filterBuilder.buildPhrasesFilter.called).to.be.ok(); + expect(filterBuilder.buildPhrasesFilter.getCall(0).args[1]).to.eql(params.phrases); + }); + + it('should build range filters', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'range'); + const params = { range: { from: 0, to: 10 } }; + const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + expect(filter).to.be.ok(); + expect(filter.meta.negate).to.be(operator.negate); + expect(filterBuilder.buildRangeFilter.called).to.be.ok(); + const range = filterBuilder.buildRangeFilter.getCall(0).args[1]; + expect(range).to.have.property('gte'); + expect(range).to.have.property('lt'); + }); + + it('should build exists filters', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists'); + const params = {}; + const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + expect(filter).to.be.ok(); + expect(filter.meta.negate).to.be(operator.negate); + expect(filterBuilder.buildExistsFilter.called).to.be.ok(); + }); + + it('should negate based on operator', function () { + const field = fields[0]; + const operator = FILTER_OPERATORS.find(operator => operator.type === 'exists' && operator.negate); + const params = {}; + const filter = buildFilter({ indexPattern, field, operator, params, filterBuilder }); + expect(filter).to.be.ok(); + expect(filter.meta.negate).to.be(operator.negate); + expect(filterBuilder.buildExistsFilter.called).to.be.ok(); + }); + }); + + describe('areIndexPatternsProvided', function () { + it('should return false when index patterns are not provided', function () { + expect(areIndexPatternsProvided(undefined)).to.be(false); + expect(areIndexPatternsProvided([])).to.be(false); + expect(areIndexPatternsProvided([undefined])).to.be(false); + }); + + it('should return true when index patterns are provided', function () { + const indexPatternMock = {}; + expect(areIndexPatternsProvided([indexPatternMock])).to.be(true); + }); + }); + + describe('isFilterPinned', function () { + it('should return false when the store is appState', function () { + const filter = { $state: { store: 'appState' } }; + expect(isFilterPinned(filter, false)).to.be(false); + expect(isFilterPinned(filter, true)).to.be(false); + }); + + it('should return true when the store is globalState', function () { + const filter = { $state: { store: 'globalState' } }; + expect(isFilterPinned(filter, false)).to.be(true); + expect(isFilterPinned(filter, true)).to.be(true); + }); + + it('should return the default when the store does not exist', function () { + const filter = {}; + expect(isFilterPinned(filter, false)).to.be(false); + expect(isFilterPinned(filter, true)).to.be(true); + }); + }); +}); diff --git a/src/ui/public/filter_editor/lib/filter_editor_utils.js b/src/ui/public/filter_editor/lib/filter_editor_utils.js new file mode 100644 index 0000000000000..4c0067b62193d --- /dev/null +++ b/src/ui/public/filter_editor/lib/filter_editor_utils.js @@ -0,0 +1,111 @@ +/* + * 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 { FILTER_OPERATORS } from './filter_operators'; + +export function getQueryDslFromFilter(filter) { + return _(filter) + .omit(['meta', '$state']) + .cloneDeep(); +} + +export function getFieldFromFilter(filter, indexPatterns) { + const { index, key } = filter.meta; + return indexPatterns.get(index) + .then(indexPattern => indexPattern.id && indexPattern.fields.byName[key]); +} + +export function getOperatorFromFilter(filter) { + const { type, negate } = filter.meta; + return FILTER_OPERATORS.find((operator) => { + return operator.type === type && operator.negate === negate; + }); +} + +export function getParamsFromFilter(filter) { + const { type, key } = filter.meta; + let params; + if (type === 'phrase') { + params = filter.query ? filter.query.match[key].query : filter.script.script.params.value; + } else if (type === 'phrases') { + params = filter.meta.params; + } else if (type === 'range') { + const range = filter.range ? filter.range[key] : filter.script.script.params; + const from = _.has(range, 'gte') ? range.gte : range.gt; + const to = _.has(range, 'lte') ? range.lte : range.lt; + params = { from, to }; + } + return { + [type]: params + }; +} + +export function getFilterableFields(indexPatterns) { + return (indexPatterns || []).reduce((fields, indexPattern) => { + const filterableFields = indexPattern.fields.filter(field => field.filterable); + return [...fields, ...filterableFields]; + }, []); +} + +export function getOperatorOptions(field) { + const type = _.get(field, 'type'); + return FILTER_OPERATORS.filter((operator) => { + return !operator.fieldTypes || operator.fieldTypes.includes(type); + }); +} + +export function isFilterValid({ field, operator, params }) { + if (!field || !operator) { + return false; + } else if (operator.type === 'phrase') { + return _.has(params, 'phrase') && params.phrase !== ''; + } else if (operator.type === 'phrases') { + return _.has(params, 'phrases') && params.phrases.length > 0; + } else if (operator.type === 'range') { + const hasFrom = _.has(params, ['range', 'from']) && params.range.from !== ''; + const hasTo = _.has(params, ['range', 'to']) && params.range.to !== ''; + return hasFrom || hasTo; + } + return true; +} + +export function buildFilter({ indexPattern, field, operator, params, filterBuilder }) { + let filter; + if (operator.type === 'phrase') { + filter = filterBuilder.buildPhraseFilter(field, params.phrase, indexPattern); + } else if (operator.type === 'phrases') { + filter = filterBuilder.buildPhrasesFilter(field, params.phrases, indexPattern); + } else if (operator.type === 'range') { + filter = filterBuilder.buildRangeFilter(field, { gte: params.range.from, lt: params.range.to }, indexPattern); + } else if (operator.type === 'exists') { + filter = filterBuilder.buildExistsFilter(field, indexPattern); + } + filter.meta.negate = operator.negate; + return filter; +} + +export function areIndexPatternsProvided(indexPatterns) { + return _.compact(indexPatterns).length !== 0; +} + +export function isFilterPinned(filter, pinnedByDefault) { + if (!filter.hasOwnProperty('$state')) return pinnedByDefault; + return filter.$state.store === 'globalState'; +} diff --git a/src/ui/public/filter_editor/lib/filter_operators.js b/src/ui/public/filter_editor/lib/filter_operators.js new file mode 100644 index 0000000000000..140928eb1912d --- /dev/null +++ b/src/ui/public/filter_editor/lib/filter_operators.js @@ -0,0 +1,72 @@ +/* + * 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'; + +export const FILTER_OPERATORS = [ + { + name: 'is', + type: 'phrase', + negate: false, + }, + { + name: 'is not', + type: 'phrase', + negate: true, + }, + { + name: 'is one of', + type: 'phrases', + negate: false, + fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] + }, + { + name: 'is not one of', + type: 'phrases', + negate: true, + fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] + }, + { + name: 'is between', + type: 'range', + negate: false, + fieldTypes: ['number', 'date', 'ip'], + }, + { + name: 'is not between', + type: 'range', + negate: true, + fieldTypes: ['number', 'date', 'ip'], + }, + { + name: 'exists', + type: 'exists', + negate: false, + }, + { + name: 'does not exist', + type: 'exists', + negate: true, + }, +]; + +export const FILTER_OPERATOR_TYPES = _(FILTER_OPERATORS) + .map('type') + .uniq() + .value(); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_editor.html new file mode 100644 index 0000000000000..f242ce2af5a2f --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_editor.html @@ -0,0 +1,19 @@ + + + + + + + diff --git a/packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts b/src/ui/public/filter_editor/params_editor/filter_params_editor.js similarity index 65% rename from packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts rename to src/ui/public/filter_editor/params_editor/filter_params_editor.js index 80b606e13bb3d..d0397d4f7508e 100644 --- a/packages/kbn-es-query/src/filters/lib/geo_polygon_filter.ts +++ b/src/ui/public/filter_editor/params_editor/filter_params_editor.js @@ -17,14 +17,21 @@ * under the License. */ -import { Filter, FilterMeta, LatLon } from './meta_filter'; +import { uiModules } from '../../modules'; +import template from './filter_params_editor.html'; +import './filter_params_phrase_editor'; +import './filter_params_phrases_editor'; +import './filter_params_range_editor'; -export type GeoPolygonFilterMeta = FilterMeta & { - params: { - points: LatLon[]; +const module = uiModules.get('kibana'); +module.directive('filterParamsEditor', function () { + return { + restrict: 'E', + template, + scope: { + field: '=', + operator: '=', + params: '=' + } }; -}; - -export type GeoPolygonFilter = Filter & { - meta: GeoPolygonFilterMeta; -}; +}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_input_type.html b/src/ui/public/filter_editor/params_editor/filter_params_input_type.html new file mode 100644 index 0000000000000..1d1a89bbb0df9 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_input_type.html @@ -0,0 +1,50 @@ +
+ + + + +
+ +
+
diff --git a/src/ui/public/filter_editor/params_editor/filter_params_input_type.js b/src/ui/public/filter_editor/params_editor/filter_params_input_type.js new file mode 100644 index 0000000000000..1278e8b508be3 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_input_type.js @@ -0,0 +1,49 @@ +/* + * 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 { uiModules } from '../../modules'; +import template from './filter_params_input_type.html'; +import '../../directives/validate_date_math'; +import '../../directives/validate_ip'; +import '../../directives/string_to_number'; + +const module = uiModules.get('kibana'); +module.directive('filterParamsInputType', function () { + return { + restrict: 'E', + template, + scope: { + type: '=', + placeholder: '@', + value: '=', + onChange: '&' + }, + link: function (scope) { + scope.boolOptions = [true, false]; + scope.setDefaultBool = () => { + if (scope.value == null) { + scope.value = scope.boolOptions[0]; + scope.onChange({ + value: scope.value + }); + } + }; + } + }; +}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js b/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js new file mode 100644 index 0000000000000..cbcd2d8ab5223 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrase_controller.js @@ -0,0 +1,57 @@ +/* + * 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 chrome from '../../chrome'; + +const baseUrl = chrome.addBasePath('/api/kibana/suggestions/values'); + +export function filterParamsPhraseController($http, $scope, config) { + const shouldSuggestValues = this.shouldSuggestValues = config.get('filterEditor:suggestValues'); + + this.compactUnion = _.flow(_.union, _.compact); + + this.getValueSuggestions = _.memoize(getValueSuggestions, getFieldQueryHash); + + this.refreshValueSuggestions = (query) => { + return this.getValueSuggestions($scope.field, query) + .then(suggestions => $scope.valueSuggestions = suggestions); + }; + + this.refreshValueSuggestions(); + + function getValueSuggestions(field, query) { + if (!shouldSuggestValues || !_.get(field, 'aggregatable') || field.type !== 'string') { + return Promise.resolve([]); + } + + const params = { + query, + field: field.name + }; + + return $http.post(`${baseUrl}/${field.indexPattern.title}`, params) + .then(response => response.data) + .catch(() => []); + } + + function getFieldQueryHash(field, query = '') { + return `${field.indexPattern.id}/${field.name}/${query}`; + } +} diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html new file mode 100644 index 0000000000000..36d509f28dece --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html @@ -0,0 +1,45 @@ + + + + {{$select.selected}} + + + +
+
+
+ + + + + + Accepted date formats + + diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js new file mode 100644 index 0000000000000..d7b166e7990f7 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.js @@ -0,0 +1,42 @@ +/* + * 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 'angular-ui-select'; +import { uiModules } from '../../modules'; +import template from './filter_params_phrase_editor.html'; +import { filterParamsPhraseController } from './filter_params_phrase_controller'; +import './filter_params_input_type'; +import '../../directives/documentation_href'; +import '../../directives/ui_select_focus_on'; +import '../../directives/focus_on'; +import '../../filters/sort_prefix_first'; + +const module = uiModules.get('kibana'); +module.directive('filterParamsPhraseEditor', function () { + return { + restrict: 'E', + template, + scope: { + field: '=', + params: '=' + }, + controllerAs: 'filterParamsPhraseEditor', + controller: filterParamsPhraseController + }; +}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html new file mode 100644 index 0000000000000..4a2935c4ba0b7 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html @@ -0,0 +1,28 @@ + + + + {{$item}} + + + +
+
+
diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js new file mode 100644 index 0000000000000..ca4f67b28caf5 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.js @@ -0,0 +1,39 @@ +/* + * 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 'angular-ui-select'; +import { uiModules } from '../../modules'; +import template from './filter_params_phrases_editor.html'; +import { filterParamsPhraseController } from './filter_params_phrase_controller'; +import '../../directives/ui_select_focus_on'; +import '../../filters/sort_prefix_first'; + +const module = uiModules.get('kibana'); +module.directive('filterParamsPhrasesEditor', function () { + return { + restrict: 'E', + template, + scope: { + field: '=', + params: '=' + }, + controllerAs: 'filterParamsPhrasesEditor', + controller: filterParamsPhraseController + }; +}); diff --git a/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html new file mode 100644 index 0000000000000..483d6c7408bd8 --- /dev/null +++ b/src/ui/public/filter_editor/params_editor/filter_params_range_editor.html @@ -0,0 +1,30 @@ +
+ +
+ +
+ +
+ + + + Accepted date formats + + diff --git a/src/ui/public/search_bar/directive/index.js b/src/ui/public/filter_editor/params_editor/filter_params_range_editor.js similarity index 69% rename from src/ui/public/search_bar/directive/index.js rename to src/ui/public/filter_editor/params_editor/filter_params_range_editor.js index f03624dd189a2..8bab49a1bbe0a 100644 --- a/src/ui/public/search_bar/directive/index.js +++ b/src/ui/public/filter_editor/params_editor/filter_params_range_editor.js @@ -17,20 +17,20 @@ * under the License. */ -import 'ngreact'; import { uiModules } from '../../modules'; -import { SearchBar } from '../components'; -import { injectI18nProvider } from '@kbn/i18n/react'; +import template from './filter_params_range_editor.html'; +import './filter_params_input_type'; +import '../../directives/documentation_href'; +import '../../directives/focus_on'; -const app = uiModules.get('app/kibana', ['react']); - -app.directive('searchBar', (reactDirective, localStorage) => { - return reactDirective( - injectI18nProvider(SearchBar), - undefined, - {}, - { - store: localStorage, +const module = uiModules.get('kibana'); +module.directive('filterParamsRangeEditor', function () { + return { + restrict: 'E', + template, + scope: { + field: '=', + params: '=' } - ); + }; }); diff --git a/src/ui/public/index_patterns/_field.d.ts b/src/ui/public/index_patterns/_field.d.ts deleted file mode 100644 index 749cd63d0a84c..0000000000000 --- a/src/ui/public/index_patterns/_field.d.ts +++ /dev/null @@ -1,26 +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. - */ - -export interface Field { - name: string; - type: string; - aggregatable: boolean; - filterable: boolean; - searchable: boolean; -} diff --git a/src/ui/public/index_patterns/_index_pattern.d.ts b/src/ui/public/index_patterns/_index_pattern.d.ts index 0465e35ff2a1f..0ff899839c42c 100644 --- a/src/ui/public/index_patterns/_index_pattern.d.ts +++ b/src/ui/public/index_patterns/_index_pattern.d.ts @@ -17,18 +17,11 @@ * under the License. */ -import { Field } from 'ui/index_patterns/_field'; - /** * WARNING: these types are incomplete */ -export interface IndexPattern { - id: string; - fields: Field[]; - title: string; - timeFieldName?: string; -} +export type IndexPattern = any; export interface StaticIndexPatternField { name: string; diff --git a/src/ui/public/index_patterns/fixtures/index.ts b/src/ui/public/index_patterns/fixtures/index.ts deleted file mode 100644 index a84ab381b52d8..0000000000000 --- a/src/ui/public/index_patterns/fixtures/index.ts +++ /dev/null @@ -1,79 +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 { Field, IndexPattern } from '../index'; - -export const mockFields: Field[] = [ - { - name: 'machine.os', - type: 'string', - aggregatable: false, - searchable: false, - filterable: true, - }, - { - name: 'machine.os.raw', - type: 'string', - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'not.filterable', - type: 'string', - aggregatable: true, - searchable: false, - filterable: false, - }, - { - name: 'bytes', - type: 'number', - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: '@timestamp', - type: 'date', - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'clientip', - type: 'ip', - aggregatable: true, - searchable: true, - filterable: true, - }, - { - name: 'bool.field', - type: 'boolean', - aggregatable: true, - searchable: true, - filterable: true, - }, -]; - -export const mockIndexPattern: IndexPattern = { - id: 'logstash-*', - fields: mockFields, - title: 'logstash-*', - timeFieldName: '@timestamp', -}; diff --git a/src/ui/public/index_patterns/index.d.ts b/src/ui/public/index_patterns/index.d.ts index e2d7ddd8c5254..92f04543c237e 100644 --- a/src/ui/public/index_patterns/index.d.ts +++ b/src/ui/public/index_patterns/index.d.ts @@ -17,9 +17,4 @@ * under the License. */ -export { - IndexPattern, - StaticIndexPattern, - StaticIndexPatternField, -} from 'ui/index_patterns/_index_pattern'; -export { Field } from 'ui/index_patterns/_field'; +export { IndexPattern, StaticIndexPattern } from 'ui/index_patterns/_index_pattern'; diff --git a/src/ui/public/index_patterns/static_utils/__tests__/index.js b/src/ui/public/index_patterns/static_utils/__tests__/index.js index e825df5d294ca..4a81b35e96555 100644 --- a/src/ui/public/index_patterns/static_utils/__tests__/index.js +++ b/src/ui/public/index_patterns/static_utils/__tests__/index.js @@ -20,50 +20,26 @@ import expect from 'expect.js'; import { isFilterable } from '../index'; -const mockField = { - name: 'foo', - scripted: false, - searchable: true, - type: 'string', -}; - describe('static utils', () => { describe('isFilterable', () => { - describe('types', () => { - it('should return true for filterable types', () => { - ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { - expect(isFilterable({ ...mockField, type })).to.be(true); - }); - }); - - it('should return false for filterable types if the field is not searchable', () => { - ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { - expect(isFilterable({ ...mockField, type, searchable: false })).to.be(false); - }); - }); - - it('should return false for un-filterable types', () => { - [ - 'geo_point', - 'geo_shape', - 'attachment', - 'murmur3', - '_source', - 'unknown', - 'conflict', - ].forEach(type => { - expect(isFilterable({ ...mockField, type })).to.be(false); - }); + it('should be filterable', () => { + ['string', 'number', 'date', 'ip', 'boolean'].forEach(type => { + expect(isFilterable({ type })).to.be(true); }); }); - - it('should return true for scripted fields', () => { - expect(isFilterable({ ...mockField, scripted: true, searchable: false })).to.be(true); - }); - - it('should return true for the _id field', () => { - expect(isFilterable({ ...mockField, name: '_id' })).to.be(true); + it('should not be filterable', () => { + [ + 'geo_point', + 'geo_shape', + 'attachment', + 'murmur3', + '_source', + 'unknown', + 'conflict', + ].forEach(type => { + expect(isFilterable({ type })).to.be(false); + }); }); }); }); diff --git a/src/ui/public/index_patterns/static_utils/index.d.ts b/src/ui/public/index_patterns/static_utils/index.d.ts index c3e02f2b20d79..6d387bb95882f 100644 --- a/src/ui/public/index_patterns/static_utils/index.d.ts +++ b/src/ui/public/index_patterns/static_utils/index.d.ts @@ -17,6 +17,13 @@ * under the License. */ -import { Field } from 'ui/index_patterns'; +import { StaticIndexPattern } from 'ui/index_patterns'; -export function isFilterable(field: Field): boolean; +interface SavedObject { + attributes: { + fields: string; + title: string; + }; +} + +export function getFromLegacyIndexPattern(indexPatterns: any[]): StaticIndexPattern[]; diff --git a/src/ui/public/index_patterns/static_utils/index.js b/src/ui/public/index_patterns/static_utils/index.js index 2285858c40ccc..2cf43c319b10a 100644 --- a/src/ui/public/index_patterns/static_utils/index.js +++ b/src/ui/public/index_patterns/static_utils/index.js @@ -22,7 +22,7 @@ import { KBN_FIELD_TYPES } from '../../../../utils/kbn_field_types'; const filterableTypes = KBN_FIELD_TYPES.filter(type => type.filterable).map(type => type.name); export function isFilterable(field) { - return field.name === '_id' || field.scripted || (field.searchable && filterableTypes.includes(field.type)); + return filterableTypes.includes(field.type); } export function getFromSavedObject(savedObject) { @@ -31,8 +31,14 @@ export function getFromSavedObject(savedObject) { } return { - id: savedObject.id, fields: JSON.parse(savedObject.attributes.fields), title: savedObject.attributes.title, }; } + +export function getFromLegacyIndexPattern(indexPatterns) { + return indexPatterns.map(indexPattern => ({ + fields: indexPattern.fields.raw, + title: indexPattern.title, + })); +} diff --git a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap index e3465e4b50c51..fb092e9f684c0 100644 --- a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap +++ b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap @@ -34,6 +34,7 @@ exports[`QueryBar Should disable autoFocus on EuiFieldText when disableAutoFocus role="form" >
({ }); const mockIndexPattern = { - id: '1234', title: 'logstash-*', - fields: [ - { - name: 'response', - type: 'number', - aggregatable: true, - filterable: true, - searchable: true, - }, - ], + fields: { + raw: [ + { + name: 'response', + type: 'number', + aggregatable: true, + searchable: true, + }, + ], + }, }; describe('QueryBar', () => { diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index 401950f8adf27..af91fea37eb43 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -21,6 +21,7 @@ import { IndexPattern } from 'ui/index_patterns'; import { compact, debounce, isEqual } from 'lodash'; import React, { Component } from 'react'; +import { getFromLegacyIndexPattern } from 'ui/index_patterns/static_utils'; import { kfetch } from 'ui/kfetch'; import { PersistedLog } from 'ui/persisted_log'; import { Storage } from 'ui/storage'; @@ -73,7 +74,6 @@ interface Props { indexPatterns: IndexPattern[]; store: Storage; intl: InjectedIntl; - prepend?: any; } interface State { @@ -196,7 +196,7 @@ export class QueryBarUI extends Component { return recentSearchSuggestions; } - const indexPatterns = this.props.indexPatterns; + const indexPatterns = getFromLegacyIndexPattern(this.props.indexPatterns); const getAutocompleteSuggestions = autocompleteProvider({ config, indexPatterns }); const { selectionStart, selectionEnd } = this.inputRef; @@ -476,7 +476,7 @@ export class QueryBarUI extends Component { aria-controls="typeahead-items" >
-
+
{ this.state.isSuggestionsVisible ? 'suggestion-' + this.state.index : '' } role="textbox" - prepend={this.props.prepend} />
void; - onDisableAll: () => void; - onPinAll: () => void; - onUnpinAll: () => void; - onToggleAllNegated: () => void; - onToggleAllDisabled: () => void; - onRemoveAll: () => void; - intl: InjectedIntl; -} - -interface State { - isPopoverOpen: boolean; -} - -class FilterOptionsUI extends Component { - public state: State = { - isPopoverOpen: false, - }; - - public togglePopover = () => { - this.setState(prevState => ({ - isPopoverOpen: !prevState.isPopoverOpen, - })); - }; - - public closePopover = () => { - this.setState({ isPopoverOpen: false }); - }; - - public render() { - const panelTree = { - id: 0, - items: [ - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.enableAllFiltersButtonLabel', - defaultMessage: 'Enable all', - }), - icon: 'eye', - onClick: () => { - this.closePopover(); - this.props.onEnableAll(); - }, - 'data-test-subj': 'enableAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.disableAllFiltersButtonLabel', - defaultMessage: 'Disable all', - }), - icon: 'eyeClosed', - onClick: () => { - this.closePopover(); - this.props.onDisableAll(); - }, - 'data-test-subj': 'disableAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.pinAllFiltersButtonLabel', - defaultMessage: 'Pin all', - }), - icon: 'pin', - onClick: () => { - this.closePopover(); - this.props.onPinAll(); - }, - 'data-test-subj': 'pinAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.unpinAllFiltersButtonLabel', - defaultMessage: 'Unpin all', - }), - icon: 'pin', - onClick: () => { - this.closePopover(); - this.props.onUnpinAll(); - }, - 'data-test-subj': 'unpinAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.invertNegatedFiltersButtonLabel', - defaultMessage: 'Invert inclusion', - }), - icon: 'invert', - onClick: () => { - this.closePopover(); - this.props.onToggleAllNegated(); - }, - 'data-test-subj': 'invertInclusionAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.invertDisabledFiltersButtonLabel', - defaultMessage: 'Invert enabled/disabled', - }), - icon: 'eye', - onClick: () => { - this.closePopover(); - this.props.onToggleAllDisabled(); - }, - 'data-test-subj': 'invertEnableDisableAllFilters', - }, - { - name: this.props.intl.formatMessage({ - id: 'common.ui.searchBar.deleteAllFiltersButtonLabel', - defaultMessage: 'Remove all', - }), - icon: 'trash', - onClick: () => { - this.closePopover(); - this.props.onRemoveAll(); - }, - 'data-test-subj': 'removeAllFilters', - }, - ], - }; - - return ( - - } - anchorPosition="rightUp" - panelPaddingSize="none" - withTitle - > - - - - - - ); - } -} - -export const FilterOptions = injectI18n(FilterOptionsUI); diff --git a/src/ui/public/search_bar/components/search_bar.tsx b/src/ui/public/search_bar/components/search_bar.tsx deleted file mode 100644 index ac7d5399e7144..0000000000000 --- a/src/ui/public/search_bar/components/search_bar.tsx +++ /dev/null @@ -1,178 +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. - */ - -// @ts-ignore -import { EuiFilterButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Filter } from '@kbn/es-query'; -import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; -import classNames from 'classnames'; -import React, { Component } from 'react'; -import ResizeObserver from 'resize-observer-polyfill'; -import { FilterBar } from 'ui/filter_bar'; -import { IndexPattern } from 'ui/index_patterns'; -import { QueryBar } from 'ui/query_bar'; -import { Storage } from 'ui/storage'; - -interface Props { - query: { - query: string; - language: string; - }; - onQuerySubmit: (query: { query: string | object; language: string }) => void; - disableAutoFocus?: boolean; - appName: string; - indexPatterns: IndexPattern[]; - store: Storage; - filters: Filter[]; - onFiltersUpdated: (filters: Filter[]) => void; - showQueryBar: boolean; - showFilterBar: boolean; - intl: InjectedIntl; -} - -interface State { - isFiltersVisible: boolean; -} - -class SearchBarUI extends Component { - public static defaultProps = { - showQueryBar: true, - showFilterBar: true, - }; - - public filterBarRef: Element | null = null; - public filterBarWrapperRef: Element | null = null; - - public state = { - isFiltersVisible: true, - }; - - public setFilterBarHeight = () => { - requestAnimationFrame(() => { - const height = - this.filterBarRef && this.state.isFiltersVisible ? this.filterBarRef.clientHeight : 0; - if (this.filterBarWrapperRef) { - this.filterBarWrapperRef.setAttribute('style', `height: ${height}px`); - } - }); - }; - - // member-ordering rules conflict with use-before-declaration rules - /* tslint:disable */ - public ro = new ResizeObserver(this.setFilterBarHeight); - /* tslint:enable */ - - public toggleFiltersVisible = () => { - this.setState({ - isFiltersVisible: !this.state.isFiltersVisible, - }); - }; - - public componentDidMount() { - if (this.filterBarRef) { - this.setFilterBarHeight(); - this.ro.observe(this.filterBarRef); - } - } - - public componentDidUpdate() { - if (this.filterBarRef) { - this.setFilterBarHeight(); - this.ro.unobserve(this.filterBarRef); - } - } - - public render() { - const filtersAppliedText = this.props.intl.formatMessage({ - id: 'common.ui.searchBar.filtersButtonFiltersAppliedTitle', - defaultMessage: 'filters applied.', - }); - const clickToShowOrHideText = this.state.isFiltersVisible - ? this.props.intl.formatMessage({ - id: 'common.ui.searchBar.filtersButtonClickToShowTitle', - defaultMessage: 'Select to hide', - }) - : this.props.intl.formatMessage({ - id: 'common.ui.searchBar.filtersButtonClickToHideTitle', - defaultMessage: 'Select to show', - }); - - const filterTriggerButton = ( - 0 ? this.props.filters.length : null} - aria-controls="GlobalFilterGroup" - aria-expanded={!!this.state.isFiltersVisible} - title={`${this.props.filters.length} ${filtersAppliedText} ${clickToShowOrHideText}`} - > - Filters - - ); - - const classes = classNames('globalFilterGroup__wrapper', { - 'globalFilterGroup__wrapper-isVisible': this.state.isFiltersVisible, - }); - - return ( -
- {this.props.showQueryBar ? ( - - ) : ( - '' - )} - - {this.props.showFilterBar ? ( -
{ - this.filterBarWrapperRef = node; - }} - className={classes} - > -
{ - this.filterBarRef = node; - }} - > - -
-
- ) : ( - '' - )} -
- ); - } -} - -export const SearchBar = injectI18n(SearchBarUI); diff --git a/src/ui/public/styles/bootstrap_dark.less b/src/ui/public/styles/bootstrap_dark.less index 0e1dd7b017825..51273dcc0e83b 100644 --- a/src/ui/public/styles/bootstrap_dark.less +++ b/src/ui/public/styles/bootstrap_dark.less @@ -4,4 +4,5 @@ @import "~ui/styles/bootstrap/bootstrap_dark"; // Components -- waiting on EUI conversion +@import "~ui/filter_bar/filter_bar"; @import "~ui/timepicker/timepicker"; diff --git a/src/ui/public/timefilter/get_time.ts b/src/ui/public/timefilter/get_time.ts index 8dd3545c85a24..4baff33e7e661 100644 --- a/src/ui/public/timefilter/get_time.ts +++ b/src/ui/public/timefilter/get_time.ts @@ -18,7 +18,8 @@ */ import dateMath from '@elastic/datemath'; -import { Field, IndexPattern } from 'ui/index_patterns'; +import { find } from 'lodash'; +import { IndexPattern } from 'ui/index_patterns'; interface CalculateBoundsOptions { forceNow?: Date; @@ -57,9 +58,8 @@ export function getTime( } let filter: Filter; - const timefield: Field | undefined = indexPattern.fields.find( - field => field.name === indexPattern.timeFieldName - ); + const timefield: { name: string } | undefined = + indexPattern.timeFieldName && find(indexPattern.fields, { name: indexPattern.timeFieldName }); if (!timefield) { return; diff --git a/src/ui/public/value_suggestions/index.ts b/src/ui/public/value_suggestions/index.ts deleted file mode 100644 index 87ff473eaeece..0000000000000 --- a/src/ui/public/value_suggestions/index.ts +++ /dev/null @@ -1,24 +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 chrome from 'ui/chrome'; -import { kfetch } from 'ui/kfetch'; -import { getSuggestionsProvider } from './value_suggestions'; - -export const getSuggestions = getSuggestionsProvider(chrome.getUiSettingsClient(), kfetch); diff --git a/src/ui/public/value_suggestions/value_suggestions.test.ts b/src/ui/public/value_suggestions/value_suggestions.test.ts deleted file mode 100644 index e918a8669bfe7..0000000000000 --- a/src/ui/public/value_suggestions/value_suggestions.test.ts +++ /dev/null @@ -1,131 +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 { mockFields, mockIndexPattern } from 'ui/index_patterns/fixtures'; -import { getSuggestionsProvider } from './value_suggestions'; - -describe('getSuggestions', () => { - let getSuggestions: any; - let fetch: any; - - describe('with value suggestions disabled', () => { - beforeEach(() => { - const config = { get: () => false }; - fetch = jest.fn(); - getSuggestions = getSuggestionsProvider(config, fetch); - }); - - it('should return an empty array', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields; - const query = ''; - const suggestions = await getSuggestions(index, field, query); - expect(suggestions).toEqual([]); - expect(fetch).not.toHaveBeenCalled(); - }); - }); - - describe('with value suggestions enabled', () => { - beforeEach(() => { - const config = { get: () => true }; - fetch = jest.fn(); - getSuggestions = getSuggestionsProvider(config, fetch); - }); - - it('should return true/false for boolean fields', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ type }) => type === 'boolean'); - const query = ''; - const suggestions = await getSuggestions(index, field, query); - expect(suggestions).toEqual([true, false]); - expect(fetch).not.toHaveBeenCalled(); - }); - - it('should return an empty array if the field type is not a string or boolean', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ type }) => type !== 'string' && type !== 'boolean'); - const query = ''; - const suggestions = await getSuggestions(index, field, query); - expect(suggestions).toEqual([]); - expect(fetch).not.toHaveBeenCalled(); - }); - - it('should return an empty array if the field is not aggregatable', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter(({ aggregatable }) => !aggregatable); - const query = ''; - const suggestions = await getSuggestions(index, field, query); - expect(suggestions).toEqual([]); - expect(fetch).not.toHaveBeenCalled(); - }); - - it('should otherwise request suggestions', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( - ({ type, aggregatable }) => type === 'string' && aggregatable - ); - const query = ''; - await getSuggestions(index, field, query); - expect(fetch).toHaveBeenCalled(); - }); - - it('should cache results if using the same index/field/query/filter', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( - ({ type, aggregatable }) => type === 'string' && aggregatable - ); - const query = ''; - await getSuggestions(index, field, query); - await getSuggestions(index, field, query); - expect(fetch).toHaveBeenCalledTimes(1); - }); - - it('should cache results for only one minute', async () => { - const index = mockIndexPattern.id; - const [field] = mockFields.filter( - ({ type, aggregatable }) => type === 'string' && aggregatable - ); - const query = ''; - - const { now } = Date; - Date.now = jest.fn(() => 0); - await getSuggestions(index, field, query); - Date.now = jest.fn(() => 60 * 1000); - await getSuggestions(index, field, query); - Date.now = now; - - expect(fetch).toHaveBeenCalledTimes(2); - }); - - it('should not cache results if using a different index/field/query', async () => { - const fields = mockFields.filter( - ({ type, aggregatable }) => type === 'string' && aggregatable - ); - await getSuggestions('index', fields[0], ''); - await getSuggestions('index', fields[0], 'query'); - await getSuggestions('index', fields[1], ''); - await getSuggestions('index', fields[1], 'query'); - await getSuggestions('logstash-*', fields[0], ''); - await getSuggestions('logstash-*', fields[0], 'query'); - await getSuggestions('logstash-*', fields[1], ''); - await getSuggestions('logstash-*', fields[1], 'query'); - expect(fetch).toHaveBeenCalledTimes(8); - }); - }); -}); diff --git a/src/ui/public/value_suggestions/value_suggestions.ts b/src/ui/public/value_suggestions/value_suggestions.ts deleted file mode 100644 index 31e42e9945ede..0000000000000 --- a/src/ui/public/value_suggestions/value_suggestions.ts +++ /dev/null @@ -1,53 +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 { memoize } from 'lodash'; -import { Field } from 'ui/index_patterns'; - -export function getSuggestionsProvider( - config: { get: (key: string) => any }, - fetch: (...options: any[]) => any -) { - const requestSuggestions = memoize( - (index: string, field: Field, query: string, boolFilter: any = []) => { - return fetch({ - pathname: `/api/kibana/suggestions/values/${index}`, - method: 'POST', - body: JSON.stringify({ query, field: field.name, boolFilter }), - }); - }, - resolver - ); - - return async (index: string, field: Field, query: string, boolFilter?: any) => { - const shouldSuggestValues = config.get('filterEditor:suggestValues'); - if (field.type === 'boolean') { - return [true, false]; - } else if (!shouldSuggestValues || !field.aggregatable || field.type !== 'string') { - return []; - } - return await requestSuggestions(index, field, query, boolFilter); - }; -} - -function resolver(index: string, field: Field, query: string, boolFilter: any) { - // Only cache results for a minute - const ttl = Math.floor(Date.now() / 1000 / 60); - return [ttl, query, index, field.name, JSON.stringify(boolFilter)].join('|'); -} diff --git a/src/ui/public/vis/editors/config/editor_config_providers.test.ts b/src/ui/public/vis/editors/config/editor_config_providers.test.ts index 94eb453ff54ed..3ba4c78b0abb5 100644 --- a/src/ui/public/vis/editors/config/editor_config_providers.test.ts +++ b/src/ui/public/vis/editors/config/editor_config_providers.test.ts @@ -22,19 +22,6 @@ import { EditorParamConfig, FixedParam, NumericIntervalParam, TimeIntervalParam describe('EditorConfigProvider', () => { let registry: EditorConfigProviderRegistry; - const indexPattern = { - id: '1234', - title: 'logstash-*', - fields: [ - { - name: 'response', - type: 'number', - aggregatable: true, - filterable: true, - searchable: true, - }, - ], - }; beforeEach(() => { registry = new EditorConfigProviderRegistry(); @@ -45,6 +32,7 @@ describe('EditorConfigProvider', () => { registry.register(provider); expect(provider).not.toHaveBeenCalled(); const aggType = {}; + const indexPattern = {}; const aggConfig = {}; registry.getConfigForAgg(aggType, indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); @@ -58,6 +46,7 @@ describe('EditorConfigProvider', () => { expect(provider).not.toHaveBeenCalled(); expect(provider2).not.toHaveBeenCalled(); const aggType = {}; + const indexPattern = {}; const aggConfig = {}; registry.getConfigForAgg(aggType, indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); @@ -70,7 +59,7 @@ describe('EditorConfigProvider', () => { } function getOutputConfig(reg: EditorConfigProviderRegistry) { - return reg.getConfigForAgg({}, indexPattern, {}).singleParam; + return reg.getConfigForAgg({}, {}, {}).singleParam; } it('should have hidden true if at least one config was hidden true', () => { diff --git a/test/functional/apps/dashboard/_dashboard_filter_bar.js b/test/functional/apps/dashboard/_dashboard_filter_bar.js index a393a949377e1..bd074d896329d 100644 --- a/test/functional/apps/dashboard/_dashboard_filter_bar.js +++ b/test/functional/apps/dashboard/_dashboard_filter_bar.js @@ -58,7 +58,7 @@ export default function ({ getService, getPageObjects }) { it('uses default index pattern on an empty dashboard', async () => { await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestions(['bytes']); + await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']); }); it('shows index pattern of vis when one is added', async () => { @@ -66,7 +66,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); await filterBar.ensureFieldEditorModalIsClosed(); await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestions(['animal']); + await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']); }); it('works when a vis with no index pattern is added', async () => { @@ -74,7 +74,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); await filterBar.ensureFieldEditorModalIsClosed(); await testSubjects.click('addFilter'); - await dashboardExpect.fieldSuggestions(['animal']); + await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']); }); }); @@ -86,16 +86,16 @@ export default function ({ getService, getPageObjects }) { }); it('are not selected by default', async function () { - const filterCount = await filterBar.getFilterCount(); - expect(filterCount).to.equal(0); + const filters = await PageObjects.dashboard.getFilters(1000); + expect(filters.length).to.equal(0); }); it('are added when a pie chart slice is clicked', async function () { await dashboardAddPanel.addVisualization('Rendering Test: pie'); await PageObjects.dashboard.waitForRenderComplete(); await pieChart.filterOnPieSlice('4,886'); - const filterCount = await filterBar.getFilterCount(); - expect(filterCount).to.equal(1); + const filters = await PageObjects.dashboard.getFilters(); + expect(filters.length).to.equal(1); await pieChart.expectPieSliceCount(1); }); @@ -104,8 +104,8 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.saveDashboard('with filters'); await PageObjects.header.waitUntilLoadingHasFinished(); - const filterCount = await filterBar.getFilterCount(); - expect(filterCount).to.equal(1); + const filters = await PageObjects.dashboard.getFilters(); + expect(filters.length).to.equal(1); await pieChart.expectPieSliceCount(1); }); @@ -115,8 +115,8 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.loadSavedDashboard('with filters'); await PageObjects.header.waitUntilLoadingHasFinished(); - const filterCount = await filterBar.getFilterCount(); - expect(filterCount).to.equal(1); + const filters = await PageObjects.dashboard.getFilters(); + expect(filters.length).to.equal(1); await pieChart.expectPieSliceCount(1); }); diff --git a/test/functional/apps/dashboard/_dashboard_filtering.js b/test/functional/apps/dashboard/_dashboard_filtering.js index ebabc4c691cc0..a127f96f8bc7c 100644 --- a/test/functional/apps/dashboard/_dashboard_filtering.js +++ b/test/functional/apps/dashboard/_dashboard_filtering.js @@ -172,7 +172,7 @@ export default function ({ getService, getPageObjects }) { describe('disabling a filter unfilters the data on', async () => { before(async () => { - await filterBar.toggleFilterEnabled('bytes'); + await testSubjects.click('disableFilter-bytes'); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.dashboard.waitForRenderComplete(); }); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index f5612be7a611f..64e2a2fdc952e 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -413,7 +413,7 @@ export default function ({ getService, getPageObjects }) { it('should show the phrases if you re-open a phrases filter', async function () { await filterBar.clickEditFilter('extension.raw', 'jpg'); - const phrases = await filterBar.getFilterEditorSelectedPhrases(); + const phrases = await filterBar.getFilterEditorPhrases(); expect(phrases.length).to.be(1); expect(phrases[0]).to.be('jpg'); }); diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index fa12727f21434..fd20b35a74666 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -38,7 +38,6 @@ export default function ({ getService, getPageObjects }) { const retry = getService('retry'); const inspector = getService('inspector'); const testSubjects = getService('testSubjects'); - const filterBar = getService('filterBar'); const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize', 'discover']); describe('scripted fields', () => { @@ -129,7 +128,7 @@ export default function ({ getService, getPageObjects }) { ['20', '23'], ['19', '21'], ['6', '20'], ['17', '20'], ['30', '20'], ['13', '19'], ['18', '18'], ['16', '17'], ['5', '16'], ['8', '16'], ['15', '14'], ['3', '13'], ['2', '12'], ['9', '10'], ['4', '9'] ]; - await filterBar.removeAllFilters(); + await PageObjects.discover.removeAllFilters(); await PageObjects.discover.clickFieldListItemVisualize(scriptedPainlessFieldName); await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.visualize.waitForVisualization(); @@ -186,7 +185,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('27'); }); - await filterBar.removeAllFilters(); + await PageObjects.discover.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { @@ -248,7 +247,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('359'); }); - await filterBar.removeAllFilters(); + await PageObjects.discover.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { @@ -310,7 +309,7 @@ export default function ({ getService, getPageObjects }) { await retry.try(async function () { expect(await PageObjects.discover.getHitCount()).to.be('1'); }); - await filterBar.removeAllFilters(); + await PageObjects.discover.removeAllFilters(); }); it('should visualize scripted field in vertical bar chart', async function () { diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js index 902f016f13ee8..988fd99c386c4 100644 --- a/test/functional/page_objects/dashboard_page.js +++ b/test/functional/page_objects/dashboard_page.js @@ -530,6 +530,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) { } } + async getFilters(timeout = defaultFindTimeout) { + return await find.allByCssSelector('.filter-bar .filter', timeout); + } + async getFilterDescriptions(timeout = defaultFindTimeout) { const filters = await find.allByCssSelector( '.filter-bar > .filter > .filter-description', diff --git a/test/functional/page_objects/discover_page.js b/test/functional/page_objects/discover_page.js index bc2bc7cd0d7f3..48fdfe47d92fe 100644 --- a/test/functional/page_objects/discover_page.js +++ b/test/functional/page_objects/discover_page.js @@ -264,6 +264,13 @@ export function DiscoverPageProvider({ getService, getPageObjects }) { await PageObjects.header.waitUntilLoadingHasFinished(); } + async removeAllFilters() { + await testSubjects.click('showFilterActions'); + await testSubjects.click('removeAllFilters'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.waitUntilUrlIncludes('filters:!()'); + } + async removeHeaderColumn(name) { await testSubjects.moveMouseTo(`docTableHeader-${name}`); await testSubjects.click(`docTableRemoveHeader-${name}`); diff --git a/test/functional/services/dashboard/expectations.js b/test/functional/services/dashboard/expectations.js index 72b3bbf7e8847..2f5fe2d7a7958 100644 --- a/test/functional/services/dashboard/expectations.js +++ b/test/functional/services/dashboard/expectations.js @@ -61,12 +61,10 @@ export function DashboardExpectProvider({ getService, getPageObjects }) { }); } - async fieldSuggestions(expectedFields) { - log.debug(`DashboardExpect.fieldSuggestions(${expectedFields})`); - const fields = await filterBar.getFilterEditorFields(); - expectedFields.forEach(expectedField => { - expect(fields).to.contain(expectedField); - }); + async fieldSuggestionIndexPatterns(expectedIndexPatterns) { + log.debug(`DashboardExpect.fieldSuggestionIndexPatterns(${expectedIndexPatterns})`); + const indexPatterns = await filterBar.getFilterFieldIndexPatterns(); + expect(indexPatterns).to.eql(expectedIndexPatterns); } async legendValuesToExist(legendValues) { diff --git a/test/functional/services/filter_bar.js b/test/functional/services/filter_bar.js index 413e46becaa0c..18f0917814726 100644 --- a/test/functional/services/filter_bar.js +++ b/test/functional/services/filter_bar.js @@ -18,10 +18,19 @@ */ export function FilterBarProvider({ getService, getPageObjects }) { + const browser = getService('browser'); const testSubjects = getService('testSubjects'); - const comboBox = getService('comboBox'); + const find = getService('find'); const PageObjects = getPageObjects(['common', 'header']); + async function typeIntoReactSelect(testSubj, value) { + const select = await testSubjects.find(testSubj); + const input = await select.findByClassName('ui-select-search'); + await input.type(value); + const activeSelection = await select.findByClassName('active'); + await activeSelection.click(); + } + class FilterBar { hasFilter(key, value, enabled = true) { const filterActivationState = enabled ? 'enabled' : 'disabled'; @@ -31,33 +40,23 @@ export function FilterBarProvider({ getService, getPageObjects }) { } async removeFilter(key) { - await testSubjects.click(`filter & filter-key-${key}`); - await testSubjects.click(`deleteFilter`); + const filterElement = await testSubjects.find(`filter & filter-key-${key}`); + await browser.moveMouseTo(filterElement); + await testSubjects.click(`filter & filter-key-${key} removeFilter-${key}`); await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); } - async removeAllFilters() { - await testSubjects.click('showFilterActions'); - await testSubjects.click('removeAllFilters'); - await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.common.waitUntilUrlIncludes('filters:!()'); - } - async toggleFilterEnabled(key) { - await testSubjects.click(`filter & filter-key-${key}`); - await testSubjects.click(`disableFilter`); + const filterElement = await testSubjects.find(`filter & filter-key-${key}`); + await browser.moveMouseTo(filterElement); + await testSubjects.click(`filter & filter-key-${key} disableFilter-${key}`); await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); } async toggleFilterPinned(key) { - await testSubjects.click(`filter & filter-key-${key}`); - await testSubjects.click(`pinFilter`); - await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); - } - - async getFilterCount() { - const filters = await testSubjects.findAll('filter'); - return filters.length; + const filterElement = await testSubjects.find(`filter & filter-key-${key}`); + await browser.moveMouseTo(filterElement); + await testSubjects.click(`filter & filter-key-${key} pinFilter-${key}`); } /** @@ -80,26 +79,18 @@ export function FilterBarProvider({ getService, getPageObjects }) { */ async addFilter(field, operator, ...values) { await testSubjects.click('addFilter'); - await comboBox.set('filterFieldSuggestionList', field); - await comboBox.set('filterOperatorList', operator); + await typeIntoReactSelect('filterfieldSuggestionList', field); + await typeIntoReactSelect('filterOperatorList', operator); const params = await testSubjects.find('filterParams'); - const paramsComboBoxes = await params.findAllByCssSelector('[data-test-subj~="filterParamsComboBox"]'); const paramFields = await params.findAllByTagName('input'); for (let i = 0; i < values.length; i++) { let fieldValues = values[i]; if (!Array.isArray(fieldValues)) { fieldValues = [fieldValues]; } - - if (paramsComboBoxes && paramsComboBoxes.length > 0) { - for (let j = 0; j < fieldValues.length; j++) { - await comboBox.setElement(paramsComboBoxes[i], fieldValues[j]); - } - } - else if (paramFields && paramFields.length > 0) { - for (let j = 0; j < fieldValues.length; j++) { - await paramFields[i].type(fieldValues[j]); - } + for (let j = 0; j < fieldValues.length; j++) { + await paramFields[i].type(fieldValues[j]); + await paramFields[i].pressKeys(browser.keys.RETURN); } } await testSubjects.click('saveFilter'); @@ -107,25 +98,30 @@ export function FilterBarProvider({ getService, getPageObjects }) { } async clickEditFilter(key, value) { - await testSubjects.click(`filter & filter-key-${key} & filter-value-${value}`); - await testSubjects.click(`editFilter`); - await PageObjects.header.awaitGlobalLoadingIndicatorHidden(); + const pill = await testSubjects.find(`filter & filter-key-${key} & filter-value-${value}`); + await browser.moveMouseTo(pill); + await testSubjects.click('editFilter'); } - async getFilterEditorSelectedPhrases() { - return await comboBox.getComboBoxSelectedOptions('filterParamsComboBox'); + async getFilterEditorPhrases() { + const spans = await testSubjects.findAll('filterEditorPhrases'); + return await Promise.all(spans.map(el => el.getVisibleText())); } - async getFilterEditorFields() { - const optionsString = await comboBox.getOptionsList('filterFieldSuggestionList'); - return optionsString.split('\n'); + async ensureFieldEditorModalIsClosed() { + const closeFilterEditorModalButtonExists = await testSubjects.exists('filterEditorModalCloseButton'); + if (closeFilterEditorModalButtonExists) { + await testSubjects.click('filterEditorModalCloseButton'); + } } - async ensureFieldEditorModalIsClosed() { - const cancelSaveFilterModalButtonExists = await testSubjects.exists('cancelSaveFilter'); - if (cancelSaveFilterModalButtonExists) { - await testSubjects.click('cancelSaveFilter'); + async getFilterFieldIndexPatterns() { + const indexPatterns = []; + const groups = await find.allByCssSelector('.ui-select-choices-group-label'); + for (let i = 0; i < groups.length; i++) { + indexPatterns.push(await groups[i].getVisibleText()); } + return indexPatterns; } } diff --git a/x-pack/plugins/beats_management/types/kibana.d.ts b/x-pack/plugins/beats_management/types/kibana.d.ts index 07a5985f55a13..e95dc0df93bea 100644 --- a/x-pack/plugins/beats_management/types/kibana.d.ts +++ b/x-pack/plugins/beats_management/types/kibana.d.ts @@ -4,6 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ +declare module 'ui/index_patterns' { + export type IndexPattern = any; + + export interface StaticIndexPatternField { + name: string; + type: string; + aggregatable: boolean; + searchable: boolean; + } + + export interface StaticIndexPattern { + fields: StaticIndexPatternField[]; + title: string; + } +} + declare module 'ui/autocomplete_providers' { import { StaticIndexPattern } from 'ui/index_patterns'; diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js index e7120ca428acb..04cbce3281eb3 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/__tests__/value.js @@ -21,78 +21,101 @@ describe('Kuery value suggestions', function () { beforeEach(() => fetchMock.post(fetchUrlMatcher, mockValues)); afterEach(() => fetchMock.restore()); - beforeEach(() => { - config = getConfigStub(true); - indexPatterns = [indexPatternResponse]; - getSuggestions = getSuggestionsProvider({ config, indexPatterns }); - }); + describe('with config setting turned off', () => { + beforeEach(() => { + config = getConfigStub(false); + indexPatterns = [indexPatternResponse]; + getSuggestions = getSuggestionsProvider({ config, indexPatterns }); + }); - it('should return a function', function () { - expect(typeof getSuggestions).to.be('function'); - }); + it('should return a function', function () { + expect(typeof getSuggestions).to.be('function'); + }); - it('should return boolean suggestions for boolean fields', async () => { - const fieldName = 'ssl'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.map(({ text }) => text)).to.eql(['true ', 'false ']); + it('should not make a request for suggestions', async () => { + const fieldName = 'machine.os.raw'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(fetchMock.called(fetchUrlMatcher)).to.be(false); + expect(suggestions).to.eql([]); + }); }); - it('should filter boolean suggestions for boolean fields', async () => { - const fieldName = 'ssl'; - const prefix = 'fa'; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.map(({ text }) => text)).to.eql(['false ']); - }); + describe('with config setting turned on', () => { + beforeEach(() => { + config = getConfigStub(true); + indexPatterns = [indexPatternResponse]; + getSuggestions = getSuggestionsProvider({ config, indexPatterns }); + }); - it('should not make a request for non-aggregatable fields', async () => { - const fieldName = 'non-sortable'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(fetchMock.called(fetchUrlMatcher)).to.be(false); - expect(suggestions).to.eql([]); - }); + it('should return a function', function () { + expect(typeof getSuggestions).to.be('function'); + }); - it('should not make a request for non-string fields', async () => { - const fieldName = 'bytes'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(fetchMock.called(fetchUrlMatcher)).to.be(false); - expect(suggestions).to.eql([]); - }); + it('should return boolean suggestions for boolean fields', async () => { + const fieldName = 'ssl'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.map(({ text }) => text)).to.eql(['true ', 'false ']); + }); - it('should make a request for string fields', async () => { - const fieldName = 'machine.os.raw'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - - const lastCall = fetchMock.lastCall(fetchUrlMatcher, 'POST'); - expect(lastCall[0]).to.eql('/api/kibana/suggestions/values/logstash-*'); - expect(lastCall[1]).to.eql({ - method: 'POST', - body: '{"query":"","field":"machine.os.raw","boolFilter":[]}', - credentials: 'same-origin', - headers: { - 'Content-Type': 'application/json', - 'kbn-version': '1.2.3', - }, + it('should filter boolean suggestions for boolean fields', async () => { + const fieldName = 'ssl'; + const prefix = 'fa'; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.map(({ text }) => text)).to.eql(['false ']); + }); + + it('should not make a request for non-aggregatable fields', async () => { + const fieldName = 'non-sortable'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(fetchMock.called(fetchUrlMatcher)).to.be(false); + expect(suggestions).to.eql([]); + }); + + it('should not make a request for non-string fields', async () => { + const fieldName = 'bytes'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(fetchMock.called(fetchUrlMatcher)).to.be(false); + expect(suggestions).to.eql([]); + }); + + it('should make a request for string fields', async () => { + const fieldName = 'machine.os.raw'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + + const lastCall = fetchMock.lastCall(fetchUrlMatcher, 'POST'); + expect(lastCall[0]).to.eql('/api/kibana/suggestions/values/logstash-*'); + expect(lastCall[1]).to.eql({ + method: 'POST', + body: '{"query":"","field":"machine.os.raw"}', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + 'kbn-version': '1.2.3', + }, + }); + expect(suggestions.map(({ text }) => text)).to.eql(['"foo" ', '"bar" ']); }); - expect(suggestions.map(({ text }) => text)).to.eql(['"foo" ', '"bar" ']); - }); - it('should not have descriptions', async () => { - const fieldName = 'ssl'; - const prefix = ''; - const suffix = ''; - const suggestions = await getSuggestions({ fieldName, prefix, suffix }); - expect(suggestions.length).to.be.greaterThan(0); - suggestions.forEach(suggestion => { - expect(suggestion.description).to.not.be.ok(); + it('should not have descriptions', async () => { + const fieldName = 'ssl'; + const prefix = ''; + const suffix = ''; + const suggestions = await getSuggestions({ fieldName, prefix, suffix }); + expect(suggestions.length).to.be.greaterThan(0); + suggestions.forEach(suggestion => { + expect(suggestion.description).to.not.be.ok(); + }); }); }); }); diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js index 9ea853ab63271..762ab51324668 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/field.js @@ -23,12 +23,11 @@ function getDescription(fieldName) { } export function getSuggestionsProvider({ indexPatterns }) { - const allFields = flatten(indexPatterns.map(indexPattern => { - return indexPattern.fields.filter(isFilterable); - })); + const allFields = flatten(indexPatterns.map(indexPattern => indexPattern.fields)); return function getFieldSuggestions({ start, end, prefix, suffix }) { const search = `${prefix}${suffix}`.toLowerCase(); - const fieldNames = allFields.map(field => field.name); + const filterableFields = allFields.filter(isFilterable); + const fieldNames = filterableFields.map(field => field.name); const matchingFieldNames = fieldNames.filter(name => name.toLowerCase().includes(search)); const sortedFieldNames = sortPrefixFirst(matchingFieldNames.sort(keywordComparator), search); const suggestions = sortedFieldNames.map(fieldName => { diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js index 5ad41494d4216..76139e4e76728 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/operator.js @@ -96,9 +96,7 @@ function getDescription(operator) { } export function getSuggestionsProvider({ indexPatterns }) { - const allFields = flatten(indexPatterns.map(indexPattern => { - return indexPattern.fields.slice(); - })); + const allFields = flatten(indexPatterns.map(indexPattern => indexPattern.fields)); return function getOperatorSuggestions({ end, fieldName }) { const fields = allFields.filter(field => field.name === fieldName); return flatten(fields.map(field => { diff --git a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js index 36fb77a30acd0..faea99c8f0f6a 100644 --- a/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js +++ b/x-pack/plugins/kuery_autocomplete/public/autocomplete_providers/value.js @@ -4,13 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import { flatten } from 'lodash'; +import { flatten, memoize } from 'lodash'; import { escapeQuotes } from './escape_kuery'; -import { getSuggestions } from 'ui/value_suggestions'; +import { kfetch } from 'ui/kfetch'; const type = 'value'; -export function getSuggestionsProvider({ indexPatterns, boolFilter }) { +const requestSuggestions = memoize((query, field, boolFilter) => { + return kfetch({ + pathname: `/api/kibana/suggestions/values/${field.indexPatternTitle}`, + method: 'POST', + body: JSON.stringify({ query, field: field.name, boolFilter }), + }); +}, resolver); + +export function getSuggestionsProvider({ config, indexPatterns, boolFilter }) { const allFields = flatten( indexPatterns.map(indexPattern => { return indexPattern.fields.map(field => ({ @@ -19,6 +27,7 @@ export function getSuggestionsProvider({ indexPatterns, boolFilter }) { })); }) ); + const shouldSuggestValues = config.get('filterEditor:suggestValues'); return function getValueSuggestions({ start, @@ -31,8 +40,18 @@ export function getSuggestionsProvider({ indexPatterns, boolFilter }) { const query = `${prefix}${suffix}`; const suggestionsByField = fields.map(field => { - return getSuggestions(field.indexPatternTitle, field, query, boolFilter).then(data => { - const quotedValues = data.map(value => typeof value === 'string' ? `"${escapeQuotes(value)}"` : `${value}`); + if (field.type === 'boolean') { + return wrapAsSuggestions(start, end, query, ['true', 'false']); + } else if ( + !shouldSuggestValues || + !field.aggregatable || + field.type !== 'string' + ) { + return []; + } + + return requestSuggestions(query, field, boolFilter).then(data => { + const quotedValues = data.map(value => `"${escapeQuotes(value)}"`); return wrapAsSuggestions(start, end, query, quotedValues); }); }); @@ -51,3 +70,9 @@ function wrapAsSuggestions(start, end, query, values) { return { type, text, start, end }; }); } + +function resolver(query, field, boolFilter) { + // Only cache results for a minute + const ttl = Math.floor(Date.now() / 1000 / 60); + return [ttl, query, field.indexPatternTitle, field.name, JSON.stringify(boolFilter)].join('|'); +} diff --git a/x-pack/plugins/ml/public/explorer/explorer.html b/x-pack/plugins/ml/public/explorer/explorer.html index 6ffd8816de30f..9fff39b76deeb 100644 --- a/x-pack/plugins/ml/public/explorer/explorer.html +++ b/x-pack/plugins/ml/public/explorer/explorer.html @@ -6,11 +6,9 @@ + ng-show="queryFilters.length" + state="appState"> +
diff --git a/x-pack/plugins/ml/public/explorer/explorer_controller.js b/x-pack/plugins/ml/public/explorer/explorer_controller.js index 32507fb10e1b1..dd3638f1727e6 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_controller.js +++ b/x-pack/plugins/ml/public/explorer/explorer_controller.js @@ -5,6 +5,7 @@ */ + /* * Angular controller for the Machine Learning Explorer dashboard. The controller makes * multiple queries to Elasticsearch to obtain the data to populate all the components @@ -48,16 +49,13 @@ uiRoutes CheckLicense: checkFullLicense, privileges: checkGetJobsPrivilege, indexPatterns: loadIndexPatterns, - }, + } }); import { uiModules } from 'ui/modules'; -import { getFromSavedObject } from 'ui/index_patterns/static_utils'; - const module = uiModules.get('apps/ml'); module.controller('MlExplorerController', function ( - $route, $injector, $scope, $timeout, @@ -77,7 +75,6 @@ module.controller('MlExplorerController', function ( // For the moment that's the job selector and the (hidden) filter bar. $scope.jobs = []; $scope.queryFilters = []; - $scope.indexPatterns = $route.current ? $route.current.locals.indexPatterns.map(getFromSavedObject) : []; timefilter.enableTimeRangeSelector(); timefilter.enableAutoRefreshSelector(); @@ -99,11 +96,6 @@ module.controller('MlExplorerController', function ( return job; }); - $scope.updateFilters = filters => { - // The filters will automatically be set when the queryFilter emits an update event (see below) - queryFilter.setFilters(filters); - }; - const selectedJobs = jobs.filter(job => job.selected); function fieldFormatServiceCallback() { @@ -116,7 +108,7 @@ module.controller('MlExplorerController', function ( loading: false, noJobsFound, selectedCells, - selectedJobs, + selectedJobs }); } @@ -165,7 +157,7 @@ module.controller('MlExplorerController', function ( fullJobs: resp.jobs, selectedCells, selectedJobIds, - swimlaneViewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName, + swimlaneViewByFieldName: $scope.appState.mlExplorerSwimlane.viewByFieldName }); } else { mlExplorerDashboardService.explorer.changed(EXPLORER_ACTION.RELOAD, { @@ -179,7 +171,6 @@ module.controller('MlExplorerController', function ( }); } } - mlExplorerDashboardService.explorer.watch(loadJobsListener); // Listen for changes to job selection. @@ -206,7 +197,6 @@ module.controller('MlExplorerController', function ( // Only redraw 100ms after last resize event. resizeTimeout = $timeout(redrawOnResize, 100); } - $(window).resize(jqueryRedrawOnResize); const navListener = $scope.$on('globalNav:update', () => { diff --git a/x-pack/plugins/ml/public/util/index_utils.js b/x-pack/plugins/ml/public/util/index_utils.js index 582c1fae4f883..9e5353ab66851 100644 --- a/x-pack/plugins/ml/public/util/index_utils.js +++ b/x-pack/plugins/ml/public/util/index_utils.js @@ -22,7 +22,7 @@ export function loadIndexPatterns(Private, indexPatterns) { const savedObjectsClient = Private(SavedObjectsClientProvider); return savedObjectsClient.find({ type: 'index-pattern', - fields: ['id', 'title', 'type', 'fields'], + fields: ['title', 'type'], perPage: 10000 }).then((response) => { indexPatternCache = response.savedObjects; diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index b1739bdf4fb02..cb701ffb6f32b 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -16,7 +16,6 @@ export default function ({ getService, getPageObjects }) { const dashboardAddPanel = getService('dashboardAddPanel'); const dashboardPanelActions = getService('dashboardPanelActions'); const appsMenu = getService('appsMenu'); - const filterBar = getService('filterBar'); const PageObjects = getPageObjects([ 'security', 'common', @@ -141,8 +140,8 @@ export default function ({ getService, getPageObjects }) { it('can filter on a visualization', async () => { await PageObjects.dashboard.setTimepickerInHistoricalDataRange(); await pieChart.filterOnPieSlice(); - const filterCount = await filterBar.getFilterCount(); - expect(filterCount).to.equal(1); + const filters = await PageObjects.dashboard.getFilters(); + expect(filters.length).to.equal(1); }); it('does not show the edit menu item', async () => { From 434747b37ce974fa7228e218ab263ece03bacc46 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Wed, 30 Jan 2019 23:24:46 +0100 Subject: [PATCH 16/40] Allow select settings to specify labels for their values (#29584) --- .../advanced_settings.test.js.snap | 14 +++++++ .../field/__snapshots__/field.test.js.snap | 20 +++++----- .../settings/components/field/field.js | 17 +++++--- .../settings/components/field/field.test.js | 39 +++++++++++++++++++ .../settings/lib/to_editable_config.js | 1 + 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/__snapshots__/advanced_settings.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/settings/__snapshots__/advanced_settings.test.js.snap index 9287731aabf9b..df0f5819244c9 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/__snapshots__/advanced_settings.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/__snapshots__/advanced_settings.test.js.snap @@ -90,6 +90,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:array:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "array", @@ -106,6 +107,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:boolean:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "boolean", @@ -124,6 +126,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:customstring:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "string", @@ -140,6 +143,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:image:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "image", @@ -158,6 +162,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": true, "name": "test:isOverridden:json", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "json", @@ -174,6 +179,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": true, "name": "test:isOverridden:number", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "number", @@ -190,6 +196,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": true, "name": "test:isOverridden:select", + "optionLabels": undefined, "options": Array [ "apple", "orange", @@ -210,6 +217,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": true, "name": "test:isOverridden:string", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "string", @@ -226,6 +234,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:json:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "json", @@ -242,6 +251,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:markdown:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "markdown", @@ -258,6 +268,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:number:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "number", @@ -274,6 +285,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:select:setting", + "optionLabels": undefined, "options": Array [ "apple", "orange", @@ -294,6 +306,7 @@ exports[`AdvancedSettings should render normally 1`] = ` "isCustom": undefined, "isOverridden": false, "name": "test:string:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "string", @@ -434,6 +447,7 @@ exports[`AdvancedSettings should render specific setting if given setting key 1` "isCustom": undefined, "isOverridden": false, "name": "test:string:setting", + "optionLabels": undefined, "options": undefined, "readonly": false, "type": "string", diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/__snapshots__/field.test.js.snap b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/__snapshots__/field.test.js.snap index 195f864fa4288..f92a9d9209396 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/__snapshots__/field.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/__snapshots__/field.test.js.snap @@ -2518,7 +2518,7 @@ exports[`Field for select setting should render as read only with help text if o values={ Object { "value": - orange + Orange , } } @@ -2576,11 +2576,11 @@ exports[`Field for select setting should render as read only with help text if o options={ Array [ Object { - "text": "apple", + "text": "Apple", "value": "apple", }, Object { - "text": "orange", + "text": "Orange", "value": "orange", }, Object { @@ -2677,11 +2677,11 @@ exports[`Field for select setting should render custom setting icon if it is cus options={ Array [ Object { - "text": "apple", + "text": "Apple", "value": "apple", }, Object { - "text": "orange", + "text": "Orange", "value": "orange", }, Object { @@ -2767,11 +2767,11 @@ exports[`Field for select setting should render default value if there is no use options={ Array [ Object { - "text": "apple", + "text": "Apple", "value": "apple", }, Object { - "text": "orange", + "text": "Orange", "value": "orange", }, Object { @@ -2833,7 +2833,7 @@ exports[`Field for select setting should render user value if there is user valu values={ Object { "value": - orange + Orange , } } @@ -2899,11 +2899,11 @@ exports[`Field for select setting should render user value if there is user valu options={ Array [ Object { - "text": "apple", + "text": "Apple", "value": "apple", }, Object { - "text": "orange", + "text": "Orange", "value": "orange", }, Object { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.js index 6724fe59c5146..2d87ca4f69163 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.js @@ -103,13 +103,15 @@ class FieldUI extends PureComponent { } } - getDisplayedDefaultValue(type, defVal) { + getDisplayedDefaultValue(type, defVal, optionLabels = {}) { if (defVal === undefined || defVal === null || defVal === '') { return 'null'; } switch (type) { case 'array': return defVal.join(', '); + case 'select': + return optionLabels.hasOwnProperty(defVal) ? optionLabels[defVal] : String(defVal); default: return String(defVal); } @@ -348,7 +350,7 @@ class FieldUI extends PureComponent { renderField(setting) { const { loading, changeImage, unsavedValue } = this.state; - const { name, value, type, options, isOverridden, ariaName } = setting; + const { name, value, type, options, optionLabels = {}, isOverridden, ariaName } = setting; switch (type) { case 'boolean': @@ -426,8 +428,11 @@ class FieldUI extends PureComponent { { - return { text, value: text }; + options={options.map((option) => { + return { + text: optionLabels.hasOwnProperty(option) ? optionLabels[option] : option, + value: option + }; })} onChange={this.onFieldChange} isLoading={loading} @@ -542,7 +547,7 @@ class FieldUI extends PureComponent { } renderDefaultValue(setting) { - const { type, defVal } = setting; + const { type, defVal, optionLabels } = setting; if (isDefaultValue(setting)) { return; } @@ -574,7 +579,7 @@ class FieldUI extends PureComponent { id="kbn.management.settings.field.defaultValueText" defaultMessage="Default: {value}" values={{ - value: ({this.getDisplayedDefaultValue(type, defVal)}), + value: ({this.getDisplayedDefaultValue(type, defVal, optionLabels)}), }} /> diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.test.js index 91267758310e3..12994260afe96 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/components/field/field.test.js @@ -122,6 +122,11 @@ const settings = { isCustom: false, isOverridden: false, options: ['apple', 'orange', 'banana'], + optionLabels: { + apple: 'Apple', + orange: 'Orange', + // Deliberately left out `banana` to test if it also works with missing labels + } }, string: { name: 'string:test:setting', @@ -213,6 +218,40 @@ describe('Field', () => { }); }); + if(type === 'select') { + it('should use options for rendering values', () => { + const component = mountWithIntl( + + ); + const select = findTestSubject(component, `advancedSetting-editField-${setting.name}`); + const labels = select.find('option').map(option => option.prop('value')); + expect(labels).toEqual(['apple', 'orange', 'banana']); + }); + + it('should use optionLabels for rendering labels', () => { + const component = mountWithIntl( + + ); + const select = findTestSubject(component, `advancedSetting-editField-${setting.name}`); + const labels = select.find('option').map(option => option.text()); + expect(labels).toEqual(['Apple', 'Orange', 'banana']); + }); + } + if(type === 'image') { describe(`for changing ${type} setting`, () => { const component = mountWithIntl( diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/to_editable_config.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/to_editable_config.js index 0dd925d8c950a..e0f959e3c0cbf 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/to_editable_config.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/to_editable_config.js @@ -44,6 +44,7 @@ export function toEditableConfig({ def, name, value, isCustom, isOverridden }) { type: getValType(def, value), description: def.description, options: def.options, + optionLabels: def.optionLabels, }; return conf; From c1d6a1bd76345a9475670737d4472331246a7b7e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 30 Jan 2019 17:02:42 -0700 Subject: [PATCH 17/40] [Maps] use EuiSuperDatePicker in QueryBar instead of Angular timepicker in Top Nav (#29235) * Embed timepicker in query bar (#29130) * replace kbnTimepicker directive with EuiSuperDatePicker * remove kbnTimepicker directive * remove bootstrap datepicker * embed timepicker in query bar * flesh out date picker in query bar for maps app * wire up refresh config * fix bug with way update function called by watcher * get maps application functional tests working with new timepicker * remove some changes outside of scoped work * clean up typescript lint problems * fix query_bar I18n lint error * update query_bar jest test * grab some parts missing from one cherry-pick * pass dateRange to updateQueryAndDispatch when app state changes * use timefilter disable methods to hide timepicker from top naav * get selected refresh unit * use EuiSuperUpdate button * Fix responsive sizing of datepicker (#29) * set isDisabled on EuiSuperUpdateButton * review feedback * remove ts-ignore comment from defaultProps, fix query_bar snapshot * make new props optional * fighting with ts linter * do not include dateRangeFrom and dateRangeTo in isDirty when shoDateRange is not true * pull initial query from UI settings --- .../kibana/public/dashboard/dashboard_app.js | 6 +- .../public/discover/controllers/discover.js | 6 +- .../kibana/public/visualize/editor/editor.js | 6 +- src/ui/public/query_bar/_index.scss | 2 +- .../__snapshots__/query_bar.test.tsx.snap | 57 ++--- .../public/query_bar/components/_index.scss | 2 + .../query_bar/components/_query_bar.scss | 14 ++ .../query_bar/components/query_bar.test.tsx | 20 +- .../public/query_bar/components/query_bar.tsx | 226 ++++++++++++++---- src/ui/public/timefilter/time_history.d.ts | 31 +++ test/functional/config.js | 2 + test/functional/page_objects/index.js | 1 + test/functional/page_objects/time_picker.js | 122 ++++++++++ .../gis/public/actions/store_actions.js | 57 +---- .../gis/public/angular/get_initial_query.js | 32 +++ .../angular/get_initial_refresh_config.js | 28 +++ .../angular/get_initial_time_filters.js | 24 ++ x-pack/plugins/gis/public/angular/map.html | 6 + .../gis/public/angular/map_controller.js | 108 ++++++--- .../gis/public/components/gis_map/index.js | 12 +- .../gis/public/components/gis_map/view.js | 30 +-- x-pack/plugins/gis/public/store/map.js | 15 +- .../apps/gis/saved_object_management.js | 13 +- .../test/functional/page_objects/gis_page.js | 6 +- 24 files changed, 607 insertions(+), 219 deletions(-) create mode 100644 src/ui/public/query_bar/components/_index.scss create mode 100644 src/ui/public/query_bar/components/_query_bar.scss create mode 100644 src/ui/public/timefilter/time_history.d.ts create mode 100644 test/functional/page_objects/time_picker.js create mode 100644 x-pack/plugins/gis/public/angular/get_initial_query.js create mode 100644 x-pack/plugins/gis/public/angular/get_initial_refresh_config.js create mode 100644 x-pack/plugins/gis/public/angular/get_initial_time_filters.js diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js index ed3edbe6b69bb..959ebfc892bc6 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -215,7 +215,7 @@ app.directive('dashboardApp', function ($injector) { dashboardStateManager.getPanels().find((panel) => panel.panelIndex === panelIndex); }; - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { const oldQuery = $scope.model.query; if (_.isEqual(oldQuery, query)) { // The user can still request a reload in the query bar, even if the @@ -236,7 +236,9 @@ app.directive('dashboardApp', function ($injector) { $scope.indexPatterns = dashboardStateManager.getPanelIndexPatterns(); }; - $scope.$watch('model.query', $scope.updateQueryAndFetch); + $scope.$watch('model.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $scope.$listenAndDigestAsync(timefilter, 'fetch', () => { dashboardStateManager.handleTimeChange(timefilter.getTime()); diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index cedaa5fbb232a..2602ff5e053cd 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -525,7 +525,9 @@ function discoverController( } }); - $scope.$watch('state.query', $scope.updateQueryAndFetch); + $scope.$watch('state.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $scope.$watchMulti([ 'rows', @@ -643,7 +645,7 @@ function discoverController( .catch(notify.error); }; - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { $state.query = migrateLegacyQuery(query); $scope.fetch(); }; diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index 2ea7d44afed9d..da6471d005c78 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -311,7 +311,9 @@ function VisEditor( $appStatus.dirty = status.dirty || !savedVis.id; }); - $scope.$watch('state.query', $scope.updateQueryAndFetch); + $scope.$watch('state.query', (query) => { + $scope.updateQueryAndFetch({ query }); + }); $state.replace(); @@ -385,7 +387,7 @@ function VisEditor( } } - $scope.updateQueryAndFetch = function (query) { + $scope.updateQueryAndFetch = function ({ query }) { $state.query = migrateLegacyQuery(query); $scope.fetch(); }; diff --git a/src/ui/public/query_bar/_index.scss b/src/ui/public/query_bar/_index.scss index 81a69fd89db99..b6634debbfa96 100644 --- a/src/ui/public/query_bar/_index.scss +++ b/src/ui/public/query_bar/_index.scss @@ -1,4 +1,4 @@ // SASSTODO: Formalize this color in Kibana's styling constants $typeaheadConjunctionColor: #7800A6; -@import 'components/typeahead/index'; \ No newline at end of file +@import './components/index'; diff --git a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap index fb092e9f684c0..ec7b3c074e89b 100644 --- a/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap +++ b/src/ui/public/query_bar/components/__snapshots__/query_bar.test.tsx.snap @@ -3,6 +3,7 @@ exports[`QueryBar Should disable autoFocus on EuiFieldText when disableAutoFocus prop is true 1`] = ` - - - + /> `; @@ -112,6 +105,7 @@ exports[`QueryBar Should disable autoFocus on EuiFieldText when disableAutoFocus exports[`QueryBar Should pass the query language to the language switcher 1`] = ` - - - + /> `; @@ -221,6 +207,7 @@ exports[`QueryBar Should pass the query language to the language switcher 1`] = exports[`QueryBar Should render the given query 1`] = ` - - - + /> `; diff --git a/src/ui/public/query_bar/components/_index.scss b/src/ui/public/query_bar/components/_index.scss new file mode 100644 index 0000000000000..e17c416c13546 --- /dev/null +++ b/src/ui/public/query_bar/components/_index.scss @@ -0,0 +1,2 @@ +@import './query_bar'; +@import './typeahead/index'; diff --git a/src/ui/public/query_bar/components/_query_bar.scss b/src/ui/public/query_bar/components/_query_bar.scss new file mode 100644 index 0000000000000..f104c20daf064 --- /dev/null +++ b/src/ui/public/query_bar/components/_query_bar.scss @@ -0,0 +1,14 @@ +@include euiBreakpoint('xs', 's') { + .kbnQueryBar--withDatePicker { + > :last-child { + // EUI Flexbox adds too much margin between responded items, this just moves the last one up + margin-top: -$euiSize; + } + } +} + +@include euiBreakpoint('m', 'l', 'xl') { + .kbnQueryBar__datePickerWrapper { + max-width: 40vw; + } +} diff --git a/src/ui/public/query_bar/components/query_bar.test.tsx b/src/ui/public/query_bar/components/query_bar.test.tsx index 363464a5ca96e..8df14e4cf3210 100644 --- a/src/ui/public/query_bar/components/query_bar.test.tsx +++ b/src/ui/public/query_bar/components/query_bar.test.tsx @@ -207,8 +207,14 @@ describe('QueryBar', () => { component.find(QueryLanguageSwitcher).simulate('selectLanguage', 'lucene'); expect(mockStorage.set).toHaveBeenCalledWith('kibana.userQueryLanguage', 'lucene'); expect(mockCallback).toHaveBeenCalledWith({ - query: '', - language: 'lucene', + dateRange: { + from: 'now-15m', + to: 'now', + }, + query: { + query: '', + language: 'lucene', + }, }); }); @@ -235,8 +241,14 @@ describe('QueryBar', () => { expect(mockCallback).toHaveBeenCalledTimes(1); expect(mockCallback).toHaveBeenCalledWith({ - query: 'extension:jpg', - language: 'kuery', + dateRange: { + from: 'now-15m', + to: 'now', + }, + query: { + query: 'extension:jpg', + language: 'kuery', + }, }); }); diff --git a/src/ui/public/query_bar/components/query_bar.tsx b/src/ui/public/query_bar/components/query_bar.tsx index af91fea37eb43..5ffae8dc24743 100644 --- a/src/ui/public/query_bar/components/query_bar.tsx +++ b/src/ui/public/query_bar/components/query_bar.tsx @@ -19,12 +19,15 @@ import { IndexPattern } from 'ui/index_patterns'; -import { compact, debounce, isEqual } from 'lodash'; +import classNames from 'classnames'; +import _ from 'lodash'; +import { compact, debounce, get, isEqual } from 'lodash'; import React, { Component } from 'react'; import { getFromLegacyIndexPattern } from 'ui/index_patterns/static_utils'; import { kfetch } from 'ui/kfetch'; import { PersistedLog } from 'ui/persisted_log'; import { Storage } from 'ui/storage'; +import { timeHistory } from 'ui/timefilter/time_history'; import { AutocompleteSuggestion, AutocompleteSuggestionType, @@ -36,15 +39,12 @@ import { matchPairs } from '../lib/match_pairs'; import { QueryLanguageSwitcher } from './language_switcher'; import { SuggestionsComponent } from './typeahead/suggestions_component'; -import { - EuiButton, - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiOutsideClickDetector, -} from '@elastic/eui'; +import { EuiFieldText, EuiFlexGroup, EuiFlexItem, EuiOutsideClickDetector } from '@elastic/eui'; + +// @ts-ignore +import { EuiSuperDatePicker, EuiSuperUpdateButton } from '@elastic/eui'; -import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; const KEY_CODES = { LEFT: 37, @@ -66,14 +66,25 @@ interface Query { language: string; } +interface DateRange { + from: string; + to: string; +} + interface Props { query: Query; - onSubmit: (query: { query: string | object; language: string }) => void; + onSubmit: (payload: { dateRange: DateRange; query: Query }) => void; disableAutoFocus?: boolean; appName: string; indexPatterns: IndexPattern[]; store: Storage; intl: InjectedIntl; + showDatePicker?: boolean; + dateRangeFrom?: string; + dateRangeTo?: string; + isRefreshPaused?: boolean; + refreshInterval?: number; + onRefreshChange?: (isPaused: boolean, refreshInterval: number) => void; } interface State { @@ -84,6 +95,9 @@ interface State { suggestions: AutocompleteSuggestion[]; suggestionLimit: number; currentProps?: Props; + dateRangeFrom: string; + dateRangeTo: string; + isDateRangeInvalid: boolean; } export class QueryBarUI extends Component { @@ -92,25 +106,41 @@ export class QueryBarUI extends Component { return null; } + let nextQuery = null; if (nextProps.query.query !== prevState.query.query) { - return { - query: { - query: toUser(nextProps.query.query), - language: nextProps.query.language, - }, - currentProps: nextProps, + nextQuery = { + query: toUser(nextProps.query.query), + language: nextProps.query.language, }; } else if (nextProps.query.language !== prevState.query.language) { - return { - query: { - query: '', - language: nextProps.query.language, - }, - currentProps: nextProps, + nextQuery = { + query: '', + language: nextProps.query.language, }; } - return { currentProps: nextProps }; + let nextDateRange = null; + if ( + nextProps.dateRangeFrom !== get(prevState, 'currentProps.dateRangeFrom') || + nextProps.dateRangeTo !== get(prevState, 'currentProps.dateRangeTo') + ) { + nextDateRange = { + dateRangeFrom: nextProps.dateRangeFrom, + dateRangeTo: nextProps.dateRangeTo, + }; + } + + const nextState: any = { + currentProps: nextProps, + }; + if (nextQuery) { + nextState.query = nextQuery; + } + if (nextDateRange) { + nextState.dateRangeFrom = nextDateRange.dateRangeFrom; + nextState.dateRangeTo = nextDateRange.dateRangeTo; + } + return nextState; } /* @@ -136,6 +166,9 @@ export class QueryBarUI extends Component { index: null, suggestions: [], suggestionLimit: 50, + dateRangeFrom: _.get(this.props, 'dateRangeFrom', 'now-15m'), + dateRangeTo: _.get(this.props, 'dateRangeTo', 'now'), + isDateRangeInvalid: false, }; public updateSuggestions = debounce(async () => { @@ -151,7 +184,15 @@ export class QueryBarUI extends Component { private persistedLog: PersistedLog | null = null; public isDirty = () => { - return this.state.query.query !== this.props.query.query; + if (!this.props.showDatePicker) { + return this.state.query.query !== this.props.query.query; + } + + return ( + this.state.query.query !== this.props.query.query || + this.state.dateRangeFrom !== this.props.dateRangeFrom || + this.state.dateRangeTo !== this.props.dateRangeTo + ); }; public increaseLimit = () => { @@ -322,6 +363,22 @@ export class QueryBarUI extends Component { this.onInputChange(event.target.value); }; + public onTimeChange = ({ + start, + end, + isInvalid, + }: { + start: string; + end: string; + isInvalid: boolean; + }) => { + this.setState({ + dateRangeFrom: start, + dateRangeTo: end, + isDateRangeInvalid: isInvalid, + }); + }; + public onKeyUp = (event: React.KeyboardEvent) => { if ([KEY_CODES.LEFT, KEY_CODES.RIGHT, KEY_CODES.HOME, KEY_CODES.END].includes(event.keyCode)) { this.setState({ isSuggestionsVisible: true }); @@ -408,9 +465,20 @@ export class QueryBarUI extends Component { this.persistedLog.add(this.state.query.query); } + timeHistory.add({ + from: this.state.dateRangeFrom, + to: this.state.dateRangeTo, + }); + this.props.onSubmit({ - query: fromUser(this.state.query.query), - language: this.state.query.language, + query: { + query: fromUser(this.state.query.query), + language: this.state.query.language, + }, + dateRange: { + from: this.state.dateRangeFrom, + to: this.state.dateRangeTo, + }, }); this.setState({ isSuggestionsVisible: false }); }; @@ -427,8 +495,14 @@ export class QueryBarUI extends Component { this.props.store.set('kibana.userQueryLanguage', language); this.props.onSubmit({ - query: '', - language, + query: { + query: '', + language, + }, + dateRange: { + from: this.state.dateRangeFrom, + to: this.state.dateRangeTo, + }, }); }; @@ -462,8 +536,16 @@ export class QueryBarUI extends Component { } public render() { + const classes = classNames('kbnQueryBar', { + 'kbnQueryBar--withDatePicker': this.props.showDatePicker, + }); + return ( - + {/* position:relative required on container so the suggestions appear under the query bar*/} @@ -533,30 +615,74 @@ export class QueryBarUI extends Component {
- - - {this.isDirty() ? ( - - ) : ( - - )} - - + {this.renderUpdateButton()} ); } + + private renderUpdateButton() { + const button = ( + + ); + if (this.props.showDatePicker) { + return ( + + {this.renderDatePicker()} + {button} + + ); + } else { + return button; + } + } + + private renderDatePicker() { + if (!this.props.showDatePicker) { + return null; + } + + const recentlyUsedRanges = timeHistory + .get() + .map(({ from, to }: { from: string; to: string }) => { + return { + start: from, + end: to, + }; + }); + + const commonlyUsedRanges = config + .get('timepicker:quickRanges') + .map(({ from, to, display }: { from: string; to: string; display: string }) => { + return { + start: from, + end: to, + label: display, + }; + }); + + return ( + + + + ); + } } +// @ts-ignore export const QueryBar = injectI18n(QueryBarUI); diff --git a/src/ui/public/timefilter/time_history.d.ts b/src/ui/public/timefilter/time_history.d.ts new file mode 100644 index 0000000000000..4a7331dbb8c58 --- /dev/null +++ b/src/ui/public/timefilter/time_history.d.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +interface TimeRange { + from: string; + to: string; + mode?: string; +} + +export interface TimeHistory { + add: (options: TimeRange) => void; + get: () => TimeRange[]; +} + +export const timeHistory: TimeHistory; diff --git a/test/functional/config.js b/test/functional/config.js index aabc2c5eaea32..86d38e1782d0a 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -33,6 +33,7 @@ import { VisualBuilderPageProvider, TimelionPageProvider, SharePageProvider, + TimePickerPageProvider, } from './page_objects'; import { @@ -94,6 +95,7 @@ export default async function ({ readConfigFile }) { visualBuilder: VisualBuilderPageProvider, timelion: TimelionPageProvider, share: SharePageProvider, + timePicker: TimePickerPageProvider, }, services: { es: commonConfig.get('services.es'), diff --git a/test/functional/page_objects/index.js b/test/functional/page_objects/index.js index 04fc7240480ff..5d561a42e2fa2 100644 --- a/test/functional/page_objects/index.js +++ b/test/functional/page_objects/index.js @@ -32,3 +32,4 @@ export { PointSeriesPageProvider } from './point_series_page'; export { VisualBuilderPageProvider } from './visual_builder_page'; export { TimelionPageProvider } from './timelion_page'; export { SharePageProvider } from './share_page'; +export { TimePickerPageProvider } from './time_picker'; diff --git a/test/functional/page_objects/time_picker.js b/test/functional/page_objects/time_picker.js new file mode 100644 index 0000000000000..77ba480c2907f --- /dev/null +++ b/test/functional/page_objects/time_picker.js @@ -0,0 +1,122 @@ +/* + * 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 function TimePickerPageProvider({ getService }) { + const log = getService('log'); + const retry = getService('retry'); + const find = getService('find'); + const testSubjects = getService('testSubjects'); + + class TimePickerPage { + + async isQuickSelectMenuOpen() { + return await testSubjects.exists('superDatePickerQuickMenu'); + } + + async openQuickSelectTimeMenu() { + log.debug('openQuickSelectTimeMenu'); + const isMenuOpen = await this.isQuickSelectMenuOpen(); + if (!isMenuOpen) { + log.debug('opening quick select menu'); + await retry.try(async () => { + await testSubjects.click('superDatePickerToggleQuickMenuButton'); + }); + } + } + + async closeQuickSelectTimeMenu() { + log.debug('closeQuickSelectTimeMenu'); + const isMenuOpen = await this.isQuickSelectMenuOpen(); + if (isMenuOpen) { + log.debug('closing quick select menu'); + await retry.try(async () => { + await testSubjects.click('superDatePickerToggleQuickMenuButton'); + }); + } + } + + async showStartEndTimes() { + const isShowDatesButton = await testSubjects.exists('superDatePickerShowDatesButton'); + if (isShowDatesButton) { + await testSubjects.click('superDatePickerShowDatesButton'); + } + } + + async getRefreshConfig(keepQuickSelectOpen = false) { + await this.openQuickSelectTimeMenu(); + const interval = await testSubjects.getAttribute('superDatePickerRefreshIntervalInput', 'value'); + + let selectedUnit; + const select = await testSubjects.find('superDatePickerRefreshIntervalUnitsSelect'); + const options = await find.allDescendantDisplayedByCssSelector('option', select); + await Promise.all(options.map(async (optionElement) => { + const isSelected = await optionElement.isSelected(); + if (isSelected) { + selectedUnit = await optionElement.getVisibleText(); + } + })); + + const toggleButtonText = await testSubjects.getVisibleText('superDatePickerToggleRefreshButton'); + if (!keepQuickSelectOpen) { + await this.closeQuickSelectTimeMenu(); + } + + return { + interval, + units: selectedUnit, + isPaused: toggleButtonText === 'Start' ? true : false + }; + } + + async getTimeConfig() { + await this.showStartEndTimes(); + const start = await testSubjects.getVisibleText('superDatePickerstartDatePopoverButton'); + const end = await testSubjects.getVisibleText('superDatePickerendDatePopoverButton'); + return { + start, + end + }; + } + + async pauseAutoRefresh() { + log.debug('pauseAutoRefresh'); + const refreshConfig = await this.getRefreshConfig(true); + if (!refreshConfig.isPaused) { + log.debug('pause auto refresh'); + await testSubjects.click('superDatePickerToggleRefreshButton'); + await this.closeQuickSelectTimeMenu(); + } + + await this.closeQuickSelectTimeMenu(); + } + + async resumeAutoRefresh() { + log.debug('resumeAutoRefresh'); + const refreshConfig = await this.getRefreshConfig(true); + if (refreshConfig.isPaused) { + log.debug('resume auto refresh'); + await testSubjects.click('superDatePickerToggleRefreshButton'); + } + + await this.closeQuickSelectTimeMenu(); + } + } + + return new TimePickerPage(); +} diff --git a/x-pack/plugins/gis/public/actions/store_actions.js b/x-pack/plugins/gis/public/actions/store_actions.js index c7a2571695393..8c8d8c71f06ff 100644 --- a/x-pack/plugins/gis/public/actions/store_actions.js +++ b/x-pack/plugins/gis/public/actions/store_actions.js @@ -16,7 +16,6 @@ import { getMapReady, getWaitingForMapReadyLayerListRaw, } from '../selectors/map_selectors'; -import { timeService } from '../kibana_services'; export const SET_SELECTED_LAYER = 'SET_SELECTED_LAYER'; export const UPDATE_LAYER_ORDER = 'UPDATE_LAYER_ORDER'; @@ -35,7 +34,6 @@ export const LAYER_DATA_LOAD_STARTED = 'LAYER_DATA_LOAD_STARTED'; export const LAYER_DATA_LOAD_ENDED = 'LAYER_DATA_LOAD_ENDED'; export const LAYER_DATA_LOAD_ERROR = 'LAYER_DATA_LOAD_ERROR'; export const SET_JOINS = 'SET_JOINS'; -export const SET_TIME_FILTERS = 'SET_TIME_FILTERS'; export const SET_QUERY = 'SET_QUERY'; export const TRIGGER_REFRESH_TIMER = 'TRIGGER_REFRESH_TIMER'; export const UPDATE_LAYER_PROP = 'UPDATE_LAYER_PROP'; @@ -418,43 +416,17 @@ export function removeLayer(id) { } export function setMeta(metaJson) { - return async dispatch => { - dispatch({ - type: SET_META, - meta: metaJson - }); - }; -} - -export function setTimeFiltersToKbnGlobalTime() { - return (dispatch) => { - dispatch(setTimeFilters(timeService.getTime())); - }; -} - -export function setTimeFilters({ from, to }) { - return async (dispatch, getState) => { - dispatch({ - type: SET_TIME_FILTERS, - from, - to, - }); - - // Update Kibana global time - const kbnTime = timeService.getTime(); - if ((to && to !== kbnTime.to) || (from && from !== kbnTime.from)) { - timeService.setTime({ from, to }); - } - - const dataFilters = getDataFilters(getState()); - await syncDataForAllLayers(getState, dispatch, dataFilters); + return { + type: SET_META, + meta: metaJson }; } -export function setQuery({ query }) { +export function setQuery({ query, timeFilters }) { return async (dispatch, getState) => { dispatch({ type: SET_QUERY, + timeFilters, query: { ...query, // ensure query changes to trigger re-fetch even when query is the same because "Refresh" clicked @@ -468,21 +440,10 @@ export function setQuery({ query }) { } export function setRefreshConfig({ isPaused, interval }) { - return async (dispatch) => { - dispatch({ - type: SET_REFRESH_CONFIG, - isPaused, - interval, - }); - - // Update Kibana global refresh - const kbnRefresh = timeService.getRefreshInterval(); - if (isPaused !== kbnRefresh.pause || interval !== kbnRefresh.value) { - timeService.setRefreshInterval({ - pause: isPaused, - value: interval, - }); - } + return { + type: SET_REFRESH_CONFIG, + isPaused, + interval, }; } diff --git a/x-pack/plugins/gis/public/angular/get_initial_query.js b/x-pack/plugins/gis/public/angular/get_initial_query.js new file mode 100644 index 0000000000000..e30e7e4ad9f58 --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_query.js @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import chrome from 'ui/chrome'; + +const settings = chrome.getUiSettingsClient(); + +export function getInitialQuery({ + mapStateJSON, + appState = {}, + userQueryLanguage, +}) { + + if (appState.query) { + return appState.query; + } + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.query) { + return mapState.query; + } + } + + return { + query: '', + language: userQueryLanguage || settings.get('search:queryLanguage') + }; +} diff --git a/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js b/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js new file mode 100644 index 0000000000000..5d042028c1ef8 --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_refresh_config.js @@ -0,0 +1,28 @@ +/* + * 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 chrome from 'ui/chrome'; + +const uiSettings = chrome.getUiSettingsClient(); + +export function getInitialRefreshConfig({ + mapStateJSON, + globalState = {}, +}) { + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.refreshConfig) { + return mapState.refreshConfig; + } + } + + const defaultRefreshConfig = uiSettings.get('timepicker:refreshIntervalDefaults'); + const refreshInterval = { ...defaultRefreshConfig, ...globalState.refreshInterval }; + return { + isPaused: refreshInterval.pause, + interval: refreshInterval.value, + }; +} diff --git a/x-pack/plugins/gis/public/angular/get_initial_time_filters.js b/x-pack/plugins/gis/public/angular/get_initial_time_filters.js new file mode 100644 index 0000000000000..8ce57e0d0991b --- /dev/null +++ b/x-pack/plugins/gis/public/angular/get_initial_time_filters.js @@ -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. + */ +import chrome from 'ui/chrome'; + +const uiSettings = chrome.getUiSettingsClient(); + +export function getInitialTimeFilters({ + mapStateJSON, + globalState = {}, +}) { + + if (mapStateJSON) { + const mapState = JSON.parse(mapStateJSON); + if (mapState.timeFilters) { + return mapState.timeFilters; + } + } + + const defaultTime = uiSettings.get('timepicker:timeDefaults'); + return { ...defaultTime, ...globalState.time }; +} diff --git a/x-pack/plugins/gis/public/angular/map.html b/x-pack/plugins/gis/public/angular/map.html index 34f953f0525ea..8bffe59548dcd 100644 --- a/x-pack/plugins/gis/public/angular/map.html +++ b/x-pack/plugins/gis/public/angular/map.html @@ -27,6 +27,12 @@ app-name="'maps'" on-submit="updateQueryAndDispatch" index-patterns="indexPatterns" + show-date-picker="showDatePicker" + date-range-from="time.from" + date-range-to="time.to" + is-refresh-paused="refreshConfig.isPaused" + refresh-interval="refreshConfig.interval" + on-refresh-change="onRefreshChange" >
diff --git a/x-pack/plugins/gis/public/angular/map_controller.js b/x-pack/plugins/gis/public/angular/map_controller.js index 6faae6a414e21..d1474f1e82f42 100644 --- a/x-pack/plugins/gis/public/angular/map_controller.js +++ b/x-pack/plugins/gis/public/angular/map_controller.js @@ -14,7 +14,6 @@ import { getStore } from '../store/store'; import { GisMap } from '../components/gis_map'; import { setSelectedLayer, - setTimeFilters, setRefreshConfig, setGotoWithCenter, replaceLayerList, @@ -28,40 +27,95 @@ import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_s import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal'; import { toastNotifications } from 'ui/notify'; import { getInitialLayers } from './get_initial_layers'; +import { getInitialQuery } from './get_initial_query'; +import { getInitialTimeFilters } from './get_initial_time_filters'; +import { getInitialRefreshConfig } from './get_initial_refresh_config'; const REACT_ANCHOR_DOM_ELEMENT_ID = 'react-gis-root'; -const DEFAULT_QUERY_LANGUAGE = 'kuery'; + const app = uiModules.get('app/gis', []); -app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage, AppState) => { +app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage, AppState, globalState) => { const savedMap = $scope.map = $route.current.locals.map; let unsubscribe; inspectorAdapters.requests.reset(); + $scope.$listen(globalState, 'fetch_with_changes', (diff) => { + if (diff.includes('time')) { + $scope.updateQueryAndDispatch({ query: $scope.query, dateRange: globalState.time }); + } + if (diff.includes('refreshInterval')) { + $scope.onRefreshChange({ isPaused: globalState.pause, refreshInterval: globalState.value }); + } + }); + const $state = new AppState(); $scope.$listen($state, 'fetch_with_changes', function (diff) { if (diff.includes('query')) { - $scope.updateQueryAndDispatch($state.query); + $scope.updateQueryAndDispatch({ query: $state.query, dateRange: $scope.time }); } }); - $scope.query = {}; + + function syncAppAndGlobalState() { + $scope.$evalAsync(() => { + $state.query = $scope.query; + $state.save(); + globalState.time = $scope.time; + globalState.refreshInterval = { + pause: $scope.refreshConfig.isPaused, + value: $scope.refreshConfig.interval, + }; + globalState.save(); + }); + } + + $scope.query = getInitialQuery({ + mapStateJSON: savedMap.mapStateJSON, + appState: $state, + userQueryLanguage: localStorage.get('kibana.userQueryLanguage') + }); + $scope.time = getInitialTimeFilters({ + mapStateJSON: savedMap.mapStateJSON, + globalState: globalState, + }); + $scope.refreshConfig = getInitialRefreshConfig({ + mapStateJSON: savedMap.mapStateJSON, + globalState: globalState, + }); + syncAppAndGlobalState(); + $scope.indexPatterns = []; - $scope.updateQueryAndDispatch = function (newQuery) { - $scope.query = newQuery; + $scope.updateQueryAndDispatch = function ({ dateRange, query }) { + $scope.query = query; + $scope.time = dateRange; getStore().then(store => { // ignore outdated query - if ($scope.query !== newQuery) { + if ($scope.query !== query && $scope.time !== dateRange) { return; } - store.dispatch(setQuery({ query: $scope.query })); + store.dispatch(setQuery({ query: $scope.query, timeFilters: $scope.time })); - // update appState - $state.query = $scope.query; - $state.save(); + syncAppAndGlobalState(); + }); + }; + $scope.onRefreshChange = function ({ isPaused, refreshInterval }) { + $scope.refreshConfig = { + isPaused, + interval: refreshInterval ? refreshInterval : $scope.refreshConfig.interval + }; + getStore().then(store => { + // ignore outdated + if ($scope.refreshConfig.isPaused !== isPaused && $scope.refreshConfig.interval !== refreshInterval) { + return; + } + + store.dispatch(setRefreshConfig($scope.refreshConfig)); + + syncAppAndGlobalState(); }); }; @@ -76,36 +130,20 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage }); // sync store with savedMap mapState - let queryFromSavedObject; if (savedMap.mapStateJSON) { const mapState = JSON.parse(savedMap.mapStateJSON); - queryFromSavedObject = mapState.query; - const timeFilters = mapState.timeFilters ? mapState.timeFilters : timefilter.getTime(); - store.dispatch(setTimeFilters(timeFilters)); store.dispatch(setGotoWithCenter({ lat: mapState.center.lat, lon: mapState.center.lon, zoom: mapState.zoom, })); - if (mapState.refreshConfig) { - store.dispatch(setRefreshConfig(mapState.refreshConfig)); - } } const layerList = getInitialLayers(savedMap.layerListJSON, getDataSources(store.getState())); store.dispatch(replaceLayerList(layerList)); - // Initialize query, syncing appState and store - if ($state.query) { - $scope.updateQueryAndDispatch($state.query); - } else if (queryFromSavedObject) { - $scope.updateQueryAndDispatch(queryFromSavedObject); - } else { - $scope.updateQueryAndDispatch({ - query: '', - language: localStorage.get('kibana.userQueryLanguage') || DEFAULT_QUERY_LANGUAGE - }); - } + store.dispatch(setRefreshConfig($scope.refreshConfig)); + store.dispatch(setQuery({ query: $scope.query, timeFilters: $scope.time })); const root = document.getElementById(REACT_ANCHOR_DOM_ELEMENT_ID); render( @@ -136,9 +174,7 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage } function handleStoreChanges(store) { - const state = store.getState(); - - const nextIndexPatternIds = getUniqueIndexPatternIds(state); + const nextIndexPatternIds = getUniqueIndexPatternIds(store.getState()); if (nextIndexPatternIds !== prevIndexPatternIds) { prevIndexPatternIds = nextIndexPatternIds; updateIndexPatterns(nextIndexPatternIds); @@ -197,6 +233,10 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage return { id }; } + // Hide angular timepicer/refresh UI from top nav + timefilter.disableTimeRangeSelector(); + timefilter.disableAutoRefreshSelector(); + $scope.showDatePicker = true; // used by query-bar directive to enable timepikcer in query bar $scope.topNavMenu = [{ key: 'inspect', description: 'Open Inspector', @@ -238,6 +278,4 @@ app.controller('GisMapController', ($scope, $route, config, kbnUrl, localStorage showSaveModal(saveModal); } }]; - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); }); diff --git a/x-pack/plugins/gis/public/components/gis_map/index.js b/x-pack/plugins/gis/public/components/gis_map/index.js index b0e31b7e2f470..cff886a1ff123 100644 --- a/x-pack/plugins/gis/public/components/gis_map/index.js +++ b/x-pack/plugins/gis/public/components/gis_map/index.js @@ -7,26 +7,22 @@ import { connect } from 'react-redux'; import { GisMap } from './view'; import { getFlyoutDisplay, FLYOUT_STATE } from '../../store/ui'; -import { - setTimeFiltersToKbnGlobalTime, - triggerRefreshTimer, - setRefreshConfig -} from '../../actions/store_actions'; +import { triggerRefreshTimer } from '../../actions/store_actions'; +import { getRefreshConfig } from '../../selectors/map_selectors'; function mapStateToProps(state = {}) { const flyoutDisplay = getFlyoutDisplay(state); return { layerDetailsVisible: flyoutDisplay === FLYOUT_STATE.LAYER_PANEL, addLayerVisible: flyoutDisplay === FLYOUT_STATE.ADD_LAYER_WIZARD, - noFlyoutVisible: flyoutDisplay === FLYOUT_STATE.NONE + noFlyoutVisible: flyoutDisplay === FLYOUT_STATE.NONE, + refreshConfig: getRefreshConfig(state), }; } function mapDispatchToProps(dispatch) { return { - setTimeFiltersToKbnGlobalTime: () => dispatch(setTimeFiltersToKbnGlobalTime()), triggerRefreshTimer: () => dispatch(triggerRefreshTimer()), - setRefreshConfig: (({ isPaused, interval }) => dispatch(setRefreshConfig({ isPaused, interval }))), }; } diff --git a/x-pack/plugins/gis/public/components/gis_map/view.js b/x-pack/plugins/gis/public/components/gis_map/view.js index d3a08630e970c..2abad91c4b974 100644 --- a/x-pack/plugins/gis/public/components/gis_map/view.js +++ b/x-pack/plugins/gis/public/components/gis_map/view.js @@ -12,39 +12,41 @@ import { AddLayerPanel } from '../layer_addpanel/index'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Toasts } from '../toasts'; -import { timeService } from '../../kibana_services'; - export class GisMap extends Component { componentDidMount() { - timeService.on('timeUpdate', this.props.setTimeFiltersToKbnGlobalTime); - timeService.on('refreshIntervalUpdate', this.setRefreshTimer); + this.setRefreshTimer(); + } + + componentDidUpdate() { this.setRefreshTimer(); } componentWillUnmount() { - timeService.off('timeUpdate', this.props.setTimeFiltersToKbnGlobalTime); - timeService.off('refreshIntervalUpdate', this.setRefreshTimer); this.clearRefreshTimer(); } setRefreshTimer = () => { + const { isPaused, interval } = this.props.refreshConfig; + + if (this.isPaused === isPaused && this.interval === interval) { + // refreshConfig is the same, nothing to do + return; + } + + this.isPaused = isPaused; + this.interval = interval; + this.clearRefreshTimer(); - const { value, pause } = timeService.getRefreshInterval(); - if (!pause && value > 0) { + if (!isPaused && interval > 0) { this.refreshTimerId = setInterval( () => { this.props.triggerRefreshTimer(); }, - value + interval ); } - - this.props.setRefreshConfig({ - isPaused: pause, - interval: value, - }); } clearRefreshTimer = () => { diff --git a/x-pack/plugins/gis/public/store/map.js b/x-pack/plugins/gis/public/store/map.js index 3aa6146486b39..9b5c48a20fe9b 100644 --- a/x-pack/plugins/gis/public/store/map.js +++ b/x-pack/plugins/gis/public/store/map.js @@ -20,7 +20,6 @@ import { MAP_EXTENT_CHANGED, MAP_READY, MAP_DESTROYED, - SET_TIME_FILTERS, SET_QUERY, UPDATE_LAYER_PROP, UPDATE_LAYER_STYLE_FOR_SELECTED_LAYER, @@ -163,12 +162,16 @@ export function map(state = INITIAL_STATE, action) { buffer: action.mapState.buffer, }; return { ...state, mapState: { ...state.mapState, ...newMapState } }; - case SET_TIME_FILTERS: - const { from, to } = action; - return { ...state, mapState: { ...state.mapState, timeFilters: { from, to } } }; case SET_QUERY: - const { query } = action; - return { ...state, mapState: { ...state.mapState, query } }; + const { query, timeFilters } = action; + return { + ...state, + mapState: { + ...state.mapState, + query, + timeFilters, + } + }; case SET_REFRESH_CONFIG: const { isPaused, interval } = action; return { diff --git a/x-pack/test/functional/apps/gis/saved_object_management.js b/x-pack/test/functional/apps/gis/saved_object_management.js index bbfb6c7a2dd24..6ad4415bb423d 100644 --- a/x-pack/test/functional/apps/gis/saved_object_management.js +++ b/x-pack/test/functional/apps/gis/saved_object_management.js @@ -8,7 +8,7 @@ import expect from 'expect.js'; export default function ({ getPageObjects, getService }) { - const PageObjects = getPageObjects(['gis', 'header']); + const PageObjects = getPageObjects(['gis', 'header', 'timePicker']); const queryBar = getService('queryBar'); const browser = getService('browser'); const inspector = getService('inspector'); @@ -25,13 +25,16 @@ export default function ({ getPageObjects, getService }) { }); it('should update global Kibana time to value stored with map', async () => { - const kibanaTime = await PageObjects.header.getPrettyDuration(); - expect(kibanaTime).to.equal('Last 17m'); + const timeConfig = await PageObjects.timePicker.getTimeConfig(); + expect(timeConfig.start).to.equal('~ 17 minutes ago'); + expect(timeConfig.end).to.equal('now'); }); it('should update global Kibana refresh config to value stored with map', async () => { - const kibanaRefreshConfig = await PageObjects.header.getRefreshConfig(); - expect(kibanaRefreshConfig).to.equal('inactive 1 second'); + const kibanaRefreshConfig = await PageObjects.timePicker.getRefreshConfig(); + expect(kibanaRefreshConfig.interval).to.equal('0.02'); + expect(kibanaRefreshConfig.units).to.equal('minutes'); + expect(kibanaRefreshConfig.isPaused).to.equal(true); }); it('should set map location to value stored with map', async () => { diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index 0ee327e984c87..75a5bf22b800b 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -5,7 +5,7 @@ */ export function GisPageProvider({ getService, getPageObjects }) { - const PageObjects = getPageObjects(['common', 'header']); + const PageObjects = getPageObjects(['common', 'header', 'timePicker']); const log = getService('log'); const testSubjects = getService('testSubjects'); @@ -204,10 +204,10 @@ export function GisPageProvider({ getService, getPageObjects }) { async triggerSingleRefresh(refreshInterval) { log.debug(`triggerSingleRefresh, refreshInterval: ${refreshInterval}`); - await PageObjects.header.resumeAutoRefresh(); + await PageObjects.timePicker.resumeAutoRefresh(); log.debug('waiting to give time for refresh timer to fire'); await PageObjects.common.sleep(refreshInterval + (refreshInterval / 2)); - await PageObjects.header.pauseAutoRefresh(); + await PageObjects.timePicker.pauseAutoRefresh(); await PageObjects.header.waitUntilLoadingHasFinished(); } } From 06bbf1da65a47b1d2275b2bfd76dbe1ca660093d Mon Sep 17 00:00:00 2001 From: Bill McConaghy Date: Wed, 30 Jan 2019 21:02:07 -0500 Subject: [PATCH 18/40] making badges clickable to filter in index management (#29635) * making badges clickable to filter in index management * improving a11y for clickable badge --- .../public/extend_index_management/index.js | 3 ++- .../public/index_management_extensions.js | 1 + .../public/lib/render_badges.js | 27 ++++++++++++++++--- .../components/index_table/index_table.js | 23 +++++++++------- .../public/extend_index_management/index.js | 3 ++- 5 files changed, 41 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js b/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js index 4ee2e8908b708..3c7aa90b4073d 100644 --- a/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js +++ b/x-pack/plugins/cross_cluster_replication/public/extend_index_management/index.js @@ -17,7 +17,8 @@ export const followerBadgeExtension = { label: i18n.translate('xpack.crossClusterReplication.indexMgmtBadge.followerLabel', { defaultMessage: 'Follower', }), - color: 'default' + color: 'default', + filterExpression: 'isFollowerIndex:true' }; addBadgeExtension(followerBadgeExtension); diff --git a/x-pack/plugins/index_management/public/index_management_extensions.js b/x-pack/plugins/index_management/public/index_management_extensions.js index 32d07e89c1fdf..28c5ad974b538 100644 --- a/x-pack/plugins/index_management/public/index_management_extensions.js +++ b/x-pack/plugins/index_management/public/index_management_extensions.js @@ -47,6 +47,7 @@ const badgeExtensions = [ label: i18n.translate('xpack.idxMgmt.frozenBadgeLabel', { defaultMessage: 'Frozen', }), + filterExpression: 'isFrozen:true', color: 'primary' } ]; diff --git a/x-pack/plugins/index_management/public/lib/render_badges.js b/x-pack/plugins/index_management/public/lib/render_badges.js index 4f8c224c084c5..661dad876a7f0 100644 --- a/x-pack/plugins/index_management/public/lib/render_badges.js +++ b/x-pack/plugins/index_management/public/lib/render_badges.js @@ -6,15 +6,34 @@ import React, { Fragment } from 'react'; -import { EuiBadge } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiBadge, EuiSearchBar } from '@elastic/eui'; import { getBadgeExtensions } from '../index_management_extensions'; -export const renderBadges = (index) => { +export const renderBadges = (index, filterChanged) => { const badgeLabels = []; - getBadgeExtensions().forEach(({ matchIndex, label, color }) => { + getBadgeExtensions().forEach(({ matchIndex, label, color, filterExpression }) => { if (matchIndex(index)) { + const clickHandler = () => { + filterChanged + && filterExpression + && filterChanged(EuiSearchBar.Query.parse(filterExpression)); + }; badgeLabels.push( - {' '}{label} + {' '} + + {label} + ); } diff --git a/x-pack/plugins/index_management/public/sections/index_list/components/index_table/index_table.js b/x-pack/plugins/index_management/public/sections/index_list/components/index_table/index_table.js index 6ff588a6a4fe0..944d8fcec87c0 100644 --- a/x-pack/plugins/index_management/public/sections/index_list/components/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/sections/index_list/components/index_table/index_table.js @@ -213,20 +213,23 @@ export class IndexTableUi extends Component { } buildRowCell(fieldName, value, index) { - const { openDetailPanel } = this.props; + const { openDetailPanel, filterChanged } = this.props; if (fieldName === 'health') { return {value}; } else if (fieldName === 'name') { return ( - { - openDetailPanel(value); - }} - > - {value}{renderBadges(index)} - + + { + openDetailPanel(value); + }} + > + {value} + + {renderBadges(index, filterChanged)} + ); } return value; diff --git a/x-pack/plugins/rollup/public/extend_index_management/index.js b/x-pack/plugins/rollup/public/extend_index_management/index.js index aa376736786e2..b0d94b94029d2 100644 --- a/x-pack/plugins/rollup/public/extend_index_management/index.js +++ b/x-pack/plugins/rollup/public/extend_index_management/index.js @@ -27,7 +27,8 @@ export const rollupBadgeExtension = { label: i18n.translate('xpack.rollupJobs.indexMgmtBadge.rollupLabel', { defaultMessage: 'Rollup', }), - color: 'secondary' + color: 'secondary', + filterExpression: 'isRollupIndex:true' }; addBadgeExtension(rollupBadgeExtension); From db147984f874578fbf92929d0b05c172618e9cb3 Mon Sep 17 00:00:00 2001 From: Oliver Gupte Date: Thu, 31 Jan 2019 01:16:32 -0800 Subject: [PATCH 19/40] [APM] fixes infinite recursion for multiple waterfall item references (#29659) (#29683) * [APM] fixes #29564 by bailing out of recursion when a multiple references of the same object are detected * [APM] minimized test fixure to isolate logic being tested * [APM] improve readabilty by using better var name --- .../waterfall_helpers.test.ts.snap | 24 +++++++++++++++++++ .../waterfall_helpers.test.ts | 14 +++++++++++ .../waterfall_helpers/waterfall_helpers.ts | 5 ++++ 3 files changed, 43 insertions(+) diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap index 9fd18e285d0d4..4684f18241212 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap @@ -1,5 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`waterfall_helpers getWaterfallItems should handle cyclic references 1`] = ` +Array [ + Object { + "childIds": Array [ + "a", + ], + "id": "a", + "offset": 0, + "skew": 0, + "timestamp": 10, + }, + Object { + "childIds": Array [ + "a", + ], + "id": "a", + "offset": 10, + "parentId": "a", + "skew": undefined, + "timestamp": 20, + }, +] +`; + exports[`waterfall_helpers getWaterfallItems should order items correctly 1`] = ` Array [ Object { diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts index 70e517d4ff365..6dcc6c032cf50 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts @@ -98,6 +98,20 @@ describe('waterfall_helpers', () => { getWaterfallItems(childrenByParentId, entryTransactionItem) ).toMatchSnapshot(); }); + + it('should handle cyclic references', () => { + const items = [ + { id: 'a', timestamp: 10 } as IWaterfallItem, + { id: 'a', parentId: 'a', timestamp: 20 } as IWaterfallItem + ]; + const childrenByParentId = groupBy(items, hit => + hit.parentId ? hit.parentId : 'root' + ); + const entryTransactionItem = childrenByParentId.root[0]; + expect( + getWaterfallItems(childrenByParentId, entryTransactionItem) + ).toMatchSnapshot(); + }); }); describe('getClockSkew', () => { diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts index 9807787727448..4ecd9d8bf6678 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts @@ -155,10 +155,15 @@ export function getWaterfallItems( childrenByParentId: IWaterfallGroup, entryTransactionItem: IWaterfallItem ) { + const visitedWaterfallItemSet = new Set(); function getSortedChildren( item: IWaterfallItem, parentItem?: IWaterfallItem ): IWaterfallItem[] { + if (visitedWaterfallItemSet.has(item)) { + return []; + } + visitedWaterfallItemSet.add(item); const children = sortBy(childrenByParentId[item.id] || [], 'timestamp'); item.childIds = children.map(child => child.id); From 53307404e6e7c4f5e298caddab1d4f0e62199dad Mon Sep 17 00:00:00 2001 From: Nox911 Date: Thu, 31 Jan 2019 13:19:50 +0300 Subject: [PATCH 20/40] [i18n] Translate fatal errors (#29410) * Translate fatal_errors * Update snapshot * Update snapshots * Fix ids * Add path to translations in scr/core folder --- .i18nrc.json | 2 ++ .../fatal_errors_screen.test.tsx.snap | 25 ++++++++++++++--- .../fatal_errors_service.test.ts.snap | 12 ++++---- .../fatal_errors/fatal_errors_screen.test.tsx | 12 ++++---- .../fatal_errors/fatal_errors_screen.tsx | 28 +++++++++++++++---- .../fatal_errors/fatal_errors_service.tsx | 14 ++++++---- src/server/i18n/index.js | 2 +- 7 files changed, 69 insertions(+), 26 deletions(-) diff --git a/.i18nrc.json b/.i18nrc.json index 650182830796f..fb3d83f561d7b 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -3,6 +3,7 @@ "common.ui": "src/ui", "server": "src/server", "console": "src/legacy/core_plugins/console", + "core": "src/core", "inputControl": "src/legacy/core_plugins/input_control_vis", "inspectorViews": "src/legacy/core_plugins/inspector_views", "interpreter": "src/legacy/core_plugins/interpreter", @@ -45,6 +46,7 @@ "xpack.watcher": "x-pack/plugins/watcher" }, "exclude": [ + "src/core/public/fatal_errors/get_error_info.ts", "src/ui/ui_render/bootstrap/app_bootstrap.js", "src/ui/ui_render/ui_render_mixin.js", "x-pack/plugins/infra/public/graphql/types.ts", diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap index 1e280f1dedf07..531ce175cfd61 100644 --- a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap +++ b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap @@ -28,7 +28,11 @@ exports[`rendering render matches snapshot 1`] = ` onClick={[Function]} type="button" > - Clear your session + , - Go back + , ] } body={

- Try refreshing the page. If that doesn't work, go back to the previous page or clear your session data. +

} iconColor="danger" iconType="alert" title={

- Something went wrong +

} /> diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap b/src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap index 841ba0f148aed..9210ca50fbe8c 100644 --- a/src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap +++ b/src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap @@ -3,11 +3,13 @@ exports[`#add() deletes all children of rootDomElement and renders into it: fatal error screen component 1`] = ` Array [ Array [ - , + + + ,
, ], ] diff --git a/src/core/public/fatal_errors/fatal_errors_screen.test.tsx b/src/core/public/fatal_errors/fatal_errors_screen.test.tsx index 3165162db8519..89406baa35f3c 100644 --- a/src/core/public/fatal_errors/fatal_errors_screen.test.tsx +++ b/src/core/public/fatal_errors/fatal_errors_screen.test.tsx @@ -19,9 +19,9 @@ import { EuiCallOut } from '@elastic/eui'; import testSubjSelector from '@kbn/test-subj-selector'; -import { mount, shallow } from 'enzyme'; import React from 'react'; import * as Rx from 'rxjs'; +import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import { FatalErrorsScreen } from './fatal_errors_screen'; @@ -54,7 +54,7 @@ describe('reloading', () => { const locationReloadSpy = jest.spyOn(window.location, 'reload').mockImplementation(noop); - shallow(); + shallowWithIntl(); expect(addEventListenerSpy).toHaveBeenCalledTimes(1); expect(addEventListenerSpy).toHaveBeenCalledWith('hashchange', expect.any(Function), undefined); @@ -67,13 +67,13 @@ describe('reloading', () => { describe('rendering', () => { it('render matches snapshot', () => { - expect(shallow()).toMatchSnapshot(); + expect(shallowWithIntl()).toMatchSnapshot(); }); it('rerenders when errorInfo$ emits more errors', () => { const errorInfo$ = new Rx.ReplaySubject(); - const el = shallow(); + const el = shallowWithIntl(); expect(el.find(EuiCallOut)).toHaveLength(0); @@ -111,7 +111,7 @@ describe('buttons', () => { window.location.hash = '/foo/bar'; jest.spyOn(window.location, 'reload').mockImplementation(noop); - const el = mount(); + const el = mountWithIntl(); const button = el.find('button').find(testSubjSelector('clearSession')); button.simulate('click'); @@ -126,7 +126,7 @@ describe('buttons', () => { it('calls window.history.back()', () => { jest.spyOn(window.history, 'back').mockImplementation(noop); - const el = mount(); + const el = mountWithIntl(); const button = el.find('button').find(testSubjSelector('goBack')); button.simulate('click'); diff --git a/src/core/public/fatal_errors/fatal_errors_screen.tsx b/src/core/public/fatal_errors/fatal_errors_screen.tsx index ccd87fdf8e6c2..a139e501e44aa 100644 --- a/src/core/public/fatal_errors/fatal_errors_screen.tsx +++ b/src/core/public/fatal_errors/fatal_errors_screen.tsx @@ -31,6 +31,8 @@ import React from 'react'; import * as Rx from 'rxjs'; import { tap } from 'rxjs/operators'; +import { FormattedMessage } from '@kbn/i18n/react'; + import { ErrorInfo } from './get_error_info'; interface Props { @@ -91,11 +93,21 @@ export class FatalErrorsScreen extends React.Component { Something went wrong} + title={ +

+ +

+ } body={

- Try refreshing the page. If that doesn't work, go back to the previous page or - clear your session data. +

} actions={[ @@ -105,10 +117,16 @@ export class FatalErrorsScreen extends React.Component { onClick={this.onClickClearSession} data-test-subj="clearSession" > - Clear your session + , - Go back + , ]} /> diff --git a/src/core/public/fatal_errors/fatal_errors_service.tsx b/src/core/public/fatal_errors/fatal_errors_service.tsx index 942d05c41a51c..c4a5478d42a3c 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.tsx +++ b/src/core/public/fatal_errors/fatal_errors_service.tsx @@ -26,6 +26,8 @@ import { InjectedMetadataService } from '../injected_metadata'; import { FatalErrorsScreen } from './fatal_errors_screen'; import { ErrorInfo, getErrorInfo } from './get_error_info'; +import { I18nProvider } from '@kbn/i18n/react'; + export interface FatalErrorsParams { rootDomElement: HTMLElement; injectedMetadata: InjectedMetadataService; @@ -85,11 +87,13 @@ export class FatalErrorsService { this.params.rootDomElement.appendChild(container); render( - , + + + , container ); } diff --git a/src/server/i18n/index.js b/src/server/i18n/index.js index 467b545d3b2d2..fff394f5bb21c 100644 --- a/src/server/i18n/index.js +++ b/src/server/i18n/index.js @@ -26,7 +26,7 @@ import { fromRoot } from '../../utils'; export async function i18nMixin(kbnServer, server, config) { const locale = config.get('i18n.locale'); - const translationsDirs = [fromRoot('src/ui/translations'), fromRoot('src/server/translations')]; + const translationsDirs = [fromRoot('src/ui/translations'), fromRoot('src/server/translations'), fromRoot('src/core/translations')]; const groupedEntries = await Promise.all([ ...config.get('plugins.scanDirs').map(async path => { From 5521917a242fe6743e37670457dcd0fac454c594 Mon Sep 17 00:00:00 2001 From: Silvia Mitter Date: Thu, 31 Jan 2019 12:01:15 +0100 Subject: [PATCH 21/40] [APM] align index pattern (#29691) --- .../server/tutorials/apm/saved_objects/index_pattern.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json index 917ed2abef878..961365e6393ff 100644 --- a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json +++ b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json @@ -1,7 +1,7 @@ { "attributes": { "fieldFormatMap": "{\"client.bytes\":{\"id\":\"bytes\"},\"destination.bytes\":{\"id\":\"bytes\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\"}},\"file.size\":{\"id\":\"bytes\"},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"network.bytes\":{\"id\":\"bytes\"},\"server.bytes\":{\"id\":\"bytes\"},\"source.bytes\":{\"id\":\"bytes\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"view spans\":{\"id\":\"url\",\"params\":{\"labelTemplate\":\"View Spans\"}}}", - "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.patch\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.minor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.major\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.minor\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.keyword\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]", + "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.patch\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.minor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.major\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.minor\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version_major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]", "sourceFilters": "[{\"value\":\"sourcemap.sourcemap\"}]", "timeFieldName": "@timestamp" }, From 0467735ce8456506c2aed9a8a31716d2e6306876 Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Thu, 31 Jan 2019 11:30:03 +0000 Subject: [PATCH 22/40] [ML] Add anomaly marker to charts when gap exists in data (#29628) * [ML] Add anomaly marker to charts when gap exists in data * [ML] Amend check for anomaly markers on gaps and update Jest tests --- .../__mocks__/mock_chart_data.js | 5 ++++ .../explorer_chart_single_metric.js | 6 +++-- .../explorer_chart_single_metric.test.js | 4 ++-- .../timeseries_chart/timeseries_chart.js | 23 +++++++++++++++---- .../ml/public/util/__tests__/chart_utils.js | 20 ++++++++++++++++ x-pack/plugins/ml/public/util/chart_utils.js | 12 +++++++--- 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/__mocks__/mock_chart_data.js b/x-pack/plugins/ml/public/explorer/explorer_charts/__mocks__/mock_chart_data.js index e150335114a20..82f8b8d30580f 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/__mocks__/mock_chart_data.js +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/__mocks__/mock_chart_data.js @@ -22,5 +22,10 @@ export const chartData = [ date: new Date('2017-02-23T13:00:00.000Z'), value: 201039318, anomalyScore: 59.83488, numberOfCauses: 1, actual: [201039318], typical: [132739.5267403542] + }, + { + date: new Date('2017-02-23T14:00:00.000Z'), + value: null, anomalyScore: 98.56166, + actual: [201039318], typical: [132739.5267403542] } ]; diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js index a1d79be061edc..f849271f91c2d 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.js @@ -267,11 +267,13 @@ export const ExplorerChartSingleMetric = injectI18n(class ExplorerChartSingleMet function drawLineChartMarkers(data) { // Render circle markers for the points. // These are used for displaying tooltips on mouseover. - // Don't render dots where value=null (data gaps) or for multi-bucket anomalies. + // Don't render dots where value=null (data gaps, with no anomalies) + // or for multi-bucket anomalies. const dots = lineChartGroup.append('g') .attr('class', 'chart-markers') .selectAll('.metric-value') - .data(data.filter(d => (d.value !== null && !showMultiBucketAnomalyMarker(d)))); + .data(data.filter(d => ((d.value !== null || typeof d.anomalyScore === 'number') && + !showMultiBucketAnomalyMarker(d)))); // Remove dots that are no longer needed i.e. if number of chart points has decreased. dots.exit().remove(); diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js index ad8a04e1af75d..3398eb2e168ec 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_single_metric.test.js @@ -135,8 +135,8 @@ describe('ExplorerChart', () => { expect(dots[0].getAttribute('r')).toBe('1.5'); const chartMarkers = wrapper.getDOMNode().querySelector('.chart-markers').querySelectorAll('circle'); - expect([...chartMarkers]).toHaveLength(3); - expect([...chartMarkers].map(d => +d.getAttribute('r'))).toEqual([7, 7, 7]); + expect([...chartMarkers]).toHaveLength(4); + expect([...chartMarkers].map(d => +d.getAttribute('r'))).toEqual([7, 7, 7, 7]); }); it('Anomaly Explorer Chart with single data point', () => { diff --git a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index 91129acf772d0..ee08c9376c8dc 100644 --- a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -677,10 +677,20 @@ export const TimeseriesChart = injectI18n(class TimeseriesChart extends React.Co } yMin = d3.min(combinedData, (d) => { - return d.lower !== undefined ? Math.min(d.value, d.lower) : d.value; + let metricValue = d.value; + if (metricValue === null && d.anomalyScore !== undefined && d.actual !== undefined) { + // If an anomaly coincides with a gap in the data, use the anomaly actual value. + metricValue = Array.isArray(d.actual) ? d.actual[0] : d.actual; + } + return d.lower !== undefined ? Math.min(metricValue, d.lower) : metricValue; }); yMax = d3.max(combinedData, (d) => { - return d.upper !== undefined ? Math.max(d.value, d.upper) : d.value; + let metricValue = d.value; + if (metricValue === null && d.anomalyScore !== undefined && d.actual !== undefined) { + // If an anomaly coincides with a gap in the data, use the anomaly actual value. + metricValue = Array.isArray(d.actual) ? d.actual[0] : d.actual; + } + return d.upper !== undefined ? Math.max(metricValue, d.upper) : metricValue; }); if (yMax === yMin) { @@ -702,9 +712,10 @@ export const TimeseriesChart = injectI18n(class TimeseriesChart extends React.Co if (mlAnnotationsEnabled && focusAnnotationData && focusAnnotationData.length > 0) { const levels = getAnnotationLevels(focusAnnotationData); const maxLevel = d3.max(Object.keys(levels).map(key => levels[key])); - // TODO needs revisting to be a more robust normalization + // TODO needs revisiting to be a more robust normalization yMax = yMax * (1 + (maxLevel + 1) / 5); } + this.focusYScale.domain([yMin, yMax]); } else { @@ -758,9 +769,11 @@ export const TimeseriesChart = injectI18n(class TimeseriesChart extends React.Co // Render circle markers for the points. // These are used for displaying tooltips on mouseover. - // Don't render dots where value=null (data gaps) or for multi-bucket anomalies. + // Don't render dots where value=null (data gaps, with no anomalies) + // or for multi-bucket anomalies. const dots = d3.select('.focus-chart-markers').selectAll('.metric-value') - .data(data.filter(d => (d.value !== null && !showMultiBucketAnomalyMarker(d)))); + .data(data.filter(d => ((d.value !== null || typeof d.anomalyScore === 'number') && + !showMultiBucketAnomalyMarker(d)))); // Remove dots that are no longer needed i.e. if number of chart points has decreased. dots.exit().remove(); diff --git a/x-pack/plugins/ml/public/util/__tests__/chart_utils.js b/x-pack/plugins/ml/public/util/__tests__/chart_utils.js index 75d575889eaec..979615f2778be 100644 --- a/x-pack/plugins/ml/public/util/__tests__/chart_utils.js +++ b/x-pack/plugins/ml/public/util/__tests__/chart_utils.js @@ -71,6 +71,26 @@ describe('ML - chart utils', () => { expect(limits.max).to.be(105); }); + it('returns minimum of 0 when data includes an anomaly for missing data', () => { + const data = [ + { date: new Date('2017-02-23T09:00:00.000Z'), value: 22.2 }, + { date: new Date('2017-02-23T10:00:00.000Z'), value: 23.3 }, + { date: new Date('2017-02-23T11:00:00.000Z'), value: 24.4 }, + { + date: new Date('2017-02-23T12:00:00.000Z'), + value: null, anomalyScore: 97.32085, + actual: [0], typical: [22.2] + }, + { date: new Date('2017-02-23T13:00:00.000Z'), value: 21.3 }, + { date: new Date('2017-02-23T14:00:00.000Z'), value: 21.2 }, + { date: new Date('2017-02-23T15:00:00.000Z'), value: 21.1 } + ]; + + const limits = chartLimits(data); + expect(limits.min).to.be(0); + expect(limits.max).to.be(24.4); + }); + }); describe('filterAxisLabels', () => { diff --git a/x-pack/plugins/ml/public/util/chart_utils.js b/x-pack/plugins/ml/public/util/chart_utils.js index 0a061f32fbf6f..0163116bd3367 100644 --- a/x-pack/plugins/ml/public/util/chart_utils.js +++ b/x-pack/plugins/ml/public/util/chart_utils.js @@ -24,10 +24,16 @@ export const SCHEDULED_EVENT_SYMBOL_HEIGHT = 5; const MAX_LABEL_WIDTH = 100; export function chartLimits(data = []) { - const limits = { max: 0, min: 0 }; + const domain = d3.extent(data, (d) => { + let metricValue = d.value; + if (metricValue === null && d.anomalyScore !== undefined && d.actual !== undefined) { + // If an anomaly coincides with a gap in the data, use the anomaly actual value. + metricValue = Array.isArray(d.actual) ? d.actual[0] : d.actual; + } + return metricValue; + }); + const limits = { max: domain[1], min: domain[0] }; - limits.max = d3.max(data, (d) => d.value); - limits.min = d3.min(data, (d) => d.value); if (limits.max === limits.min) { limits.max = d3.max(data, (d) => { if (d.typical) { From 413d37d5edc1b5d1efcbad971d182f228ddd8b96 Mon Sep 17 00:00:00 2001 From: Sophie Chang Date: Thu, 31 Jan 2019 11:39:18 +0000 Subject: [PATCH 23/40] [ML] Update http access modules for ECS (#29383) * [ML] Initial commit for apache ecs module * [ML] Update apache2 module for ECS Rename following fields event.module:apache event.dataset:access source.address url.original http.response.status_code source.geo.location Rationalise to only use one set of kibana saved objects for all http web access logs Rename files from apache Combined URL explorer into Count explorer dashboard as there was a lot of duplication Add filter to custom url Rename custom urls to Investigate Source IP and Status Code Add chart to show overall event rate split by event.module - can tell if multiple datasets are included Increase limit for top source ips from 5 to 50 Add created_by to custom setting for telemetry Rename jobs and saved objects to include ecs tag Tested side by side against v6 jobs * [ML] Rename apache files from hyphen to underscores * [ML] Further apache renames Also change custom URLs to lower case to match "View series" Change created_by to ml-module-apache-access * [ML] Initial commit of nginx ml module * [ML] Rename dashboard to generic explorer * [ML] Further refinement for apache Rename http_status_code to status_code_rate Update custom url to use filters instead of lucene query bar * [ML] Convert apache module to nginx Copy files, keeping nginx logo Multiple renames to nginx * [ML] Make chart legend visible by default --- .../ml_http_access_explorer_ecs.json | 13 ++ .../search/ml_http_access_filebeat_ecs.json | 16 +++ .../ml_http_access_events_timechart_ecs.json | 11 ++ .../visualization/ml_http_access_map_ecs.json | 11 ++ ...l_http_access_source_ip_timechart_ecs.json | 11 ++ ...http_access_status_code_timechart_ecs.json | 11 ++ ..._http_access_top_source_ips_table_ecs.json | 11 ++ .../ml_http_access_top_urls_table_ecs.json | 11 ++ ...access_unique_count_url_timechart_ecs.json | 11 ++ .../modules/apache_ecs/logo.json | 6 + .../modules/apache_ecs/manifest.json | 111 ++++++++++++++++++ .../ml/datafeed_low_request_rate_ecs.json | 34 ++++++ .../datafeed_source_ip_request_rate_ecs.json | 13 ++ .../ml/datafeed_source_ip_url_count_ecs.json | 13 ++ .../ml/datafeed_status_code_rate_ecs.json | 13 ++ .../ml/datafeed_visitor_rate_ecs.json | 39 ++++++ .../apache_ecs/ml/low_request_rate_ecs.json | 34 ++++++ .../ml/source_ip_request_rate_ecs.json | 34 ++++++ .../ml/source_ip_url_count_ecs.json | 35 ++++++ .../apache_ecs/ml/status_code_rate_ecs.json | 41 +++++++ .../apache_ecs/ml/visitor_rate_ecs.json | 34 ++++++ .../ml_http_access_explorer_ecs.json | 13 ++ .../search/ml_http_access_filebeat_ecs.json | 16 +++ .../ml_http_access_events_timechart_ecs.json | 11 ++ .../visualization/ml_http_access_map_ecs.json | 11 ++ ...l_http_access_source_ip_timechart_ecs.json | 11 ++ ...http_access_status_code_timechart_ecs.json | 11 ++ ..._http_access_top_source_ips_table_ecs.json | 11 ++ .../ml_http_access_top_urls_table_ecs.json | 11 ++ ...access_unique_count_url_timechart_ecs.json | 11 ++ .../modules/nginx_ecs/logo.json | 5 + .../modules/nginx_ecs/manifest.json | 111 ++++++++++++++++++ .../ml/datafeed_low_request_rate_ecs.json | 34 ++++++ .../datafeed_source_ip_request_rate_ecs.json | 13 ++ .../ml/datafeed_source_ip_url_count_ecs.json | 13 ++ .../ml/datafeed_status_code_rate_ecs.json | 13 ++ .../ml/datafeed_visitor_rate_ecs.json | 39 ++++++ .../nginx_ecs/ml/low_request_rate_ecs.json | 34 ++++++ .../ml/source_ip_request_rate_ecs.json | 34 ++++++ .../nginx_ecs/ml/source_ip_url_count_ecs.json | 35 ++++++ .../nginx_ecs/ml/status_code_rate_ecs.json | 41 +++++++ .../nginx_ecs/ml/visitor_rate_ecs.json | 34 ++++++ 42 files changed, 1025 insertions(+) create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/search/ml_http_access_filebeat_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_map_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/logo.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_low_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_url_count_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_status_code_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_visitor_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/search/ml_http_access_filebeat_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_map_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/logo.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_low_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_url_count_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_status_code_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_visitor_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json create mode 100644 x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json new file mode 100644 index 0000000000000..681ad572417f6 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json @@ -0,0 +1,13 @@ +{ + "hits": 0, + "timeRestore": false, + "description": "", + "title": "ML HTTP Access Explorer (ECS)", + "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", + "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ml_http_access_events_timechart_ecs\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ml_http_access_unique_count_url_timechart_ecs\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ml_http_access_status_code_timechart_ecs\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ml_http_access_source_ip_timechart_ecs\",\"col\":7,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ml_http_access_top_source_ips_table_ecs\",\"col\":1,\"row\":8},{\"size_x\":6,\"size_y\":3,\"panelIndex\":6,\"type\":\"visualization\",\"id\":\"ml_http_access_map_ecs\",\"col\":7,\"row\":8},{\"size_x\":12,\"size_y\":9,\"panelIndex\":7,\"type\":\"visualization\",\"id\":\"ml_http_access_top_urls_table_ecs\",\"col\":1,\"row\":11}]", + "optionsJSON": "{\"darkTheme\":false}", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\n \"filter\": [],\n \"highlightAll\": true,\n \"version\": true,\n \"query\": {\n \"query\": \"\",\n \"language\": \"lucene\"\n }\n}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/search/ml_http_access_filebeat_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/search/ml_http_access_filebeat_ecs.json new file mode 100644 index 0000000000000..6575c7e65d78d --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/search/ml_http_access_filebeat_ecs.json @@ -0,0 +1,16 @@ +{ + "sort": [ + "@timestamp", + "desc" + ], + "hits": 0, + "description": "Filebeat HTTP Access Data (ECS)", + "title": "ML HTTP Access Data (ECS)", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"INDEX_PATTERN_ID\",\"query\":{\"query_string\":{\"query\":\"fileset.name:access\",\"analyze_wildcard\":true}},\"filter\":[],\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@/kibana-highlighted-field@\"],\"fields\":{\"*\":{}},\"require_field_match\":false,\"fragment_size\":2147483647}}" + }, + "columns": [ + "_source" + ] +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json new file mode 100644 index 0000000000000..ff507da41d1a5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Event Timechart (ECS)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"event.module\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"event.dataset\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Event Timechart (ECS)", + "uiStateJSON": "{\"vis\":{\"colors\":{\"apache - access\":\"#629E51\",\"nginx - access\":\"#1F78C1\"}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } + } \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_map_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_map_ecs.json new file mode 100644 index 0000000000000..4cf3982f5ac6a --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_map_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"autoPrecision\":true,\"field\":\"source.geo.location\"},\"schema\":\"segment\",\"type\":\"geohash_grid\"}],\"listeners\":{},\"params\":{\"addTooltip\":true,\"heatBlur\":15,\"heatMaxZoom\":16,\"heatMinOpacity\":0.1,\"heatNormalizeData\":true,\"heatRadius\":25,\"isDesaturated\":true,\"legendPosition\":\"bottomright\",\"mapCenter\":[15,5],\"mapType\":\"Scaled Circle Markers\",\"mapZoom\":2,\"wms\":{\"enabled\":false,\"options\":{\"attribution\":\"Maps provided by USGS\",\"format\":\"image/png\",\"layers\":\"0\",\"styles\":\"\",\"transparent\":true,\"version\":\"1.3.0\"},\"url\":\"https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer\"}},\"title\":\"ML HTTP Access Map (ECS)\",\"type\":\"tile_map\"}", + "description": "", + "title": "ML HTTP Access Map (ECS)", + "uiStateJSON": "{\n \"mapCenter\": [\n 12.039320557540572,\n -0.17578125\n ]\n}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json new file mode 100644 index 0000000000000..7525752abb053 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Source IP Timechart (ECS)\",\"type\":\"area\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"@timestamp per 5 minutes\"},\"type\":\"category\"}],\"defaultYExtents\":false,\"drawLinesBetweenPoints\":true,\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"interpolate\":\"linear\",\"legendPosition\":\"right\",\"radiusRatio\":9,\"scale\":\"linear\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"interpolate\":\"linear\",\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"area\",\"valueAxis\":\"ValueAxis-1\"}],\"setYExtents\":false,\"showCircles\":true,\"times\":[],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"source.address\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Source IP Timechart (ECS)", + "uiStateJSON": "{}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json new file mode 100644 index 0000000000000..e104b047f924b --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Status Code Timechart (ECS)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"http.response.status_code\",\"size\":50,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Status Code Timechart (ECS)", + "uiStateJSON": "{\n \"vis\": {\n \"colors\": {\n \"200\": \"#7EB26D\",\n \"404\": \"#614D93\"\n }\n }\n}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json new file mode 100644 index 0000000000000..c9afd66ea39b1 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Top Source IPs Table (ECS)\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"source.address\",\"size\":50,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Top Source IPs Table (ECS)", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json new file mode 100644 index 0000000000000..34fbcb621085c --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Top URLs Table (ECS)\",\"type\":\"table\",\"params\":{\"perPage\":100,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"url.original\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Top URLs Table (ECS)", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json new file mode 100644 index 0000000000000..d14592e68bb6e --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Unique Count URL Timechart (ECS)\",\"type\":\"line\",\"params\":{\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{\"text\":\"@timestamp per day\"}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Unique count of url.original\"}}],\"seriesParams\":[{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"lineWidth\":2,\"data\":{\"id\":\"1\",\"label\":\"Unique count of url.original\"},\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"showCircles\":true,\"interpolate\":\"linear\",\"scale\":\"linear\",\"drawLinesBetweenPoints\":true,\"radiusRatio\":9,\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"url.original\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Unique Count URL Timechart (ECS)", + "uiStateJSON": "{}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/logo.json new file mode 100644 index 0000000000000..e15620ed29fcc --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/logo.json @@ -0,0 +1,6 @@ +{ + "src": "data:image/png;base64,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", + "height": 25, + "width": 125 +} + diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json new file mode 100644 index 0000000000000..031cf05ca39cd --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json @@ -0,0 +1,111 @@ +{ + "id": "apache_ecs", + "title": "Apache access logs", + "description": "Find unusual activity in HTTP access logs from filebeat (ECS)", + "type": "Web Access Logs", + "logoFile": "logo.json", + "defaultIndexPattern": "filebeat-*", + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } }, + { "exists": { "field": "source.address" } }, + { "exists": { "field": "url.original" } }, + { "exists": { "field": "http.response.status_code" } } + ] + } + }, + "jobs": [ + { + "id": "visitor_rate_ecs", + "file": "visitor_rate_ecs.json" + }, + { + "id": "status_code_rate_ecs", + "file": "status_code_rate_ecs.json" + }, + { + "id": "source_ip_url_count_ecs", + "file": "source_ip_url_count_ecs.json" + }, + { + "id": "source_ip_request_rate_ecs", + "file": "source_ip_request_rate_ecs.json" + }, + { + "id": "low_request_rate_ecs", + "file": "low_request_rate_ecs.json" + } + ], + "datafeeds": [ + { + "id": "datafeed-visitor_rate_ecs", + "file": "datafeed_visitor_rate_ecs.json", + "job_id": "visitor_rate_ecs" + }, + { + "id": "datafeed-status_code_rate_ecs", + "file": "datafeed_status_code_rate_ecs.json", + "job_id": "status_code_rate_ecs" + }, + { + "id": "datafeed-source_ip_url_count_ecs", + "file": "datafeed_source_ip_url_count_ecs.json", + "job_id": "source_ip_url_count_ecs" + }, + { + "id": "datafeed-source_ip_request_rate_ecs", + "file": "datafeed_source_ip_request_rate_ecs.json", + "job_id": "source_ip_request_rate_ecs" + }, + { + "id": "datafeed-low_request_rate_ecs", + "file": "datafeed_low_request_rate_ecs.json", + "job_id": "low_request_rate_ecs" + } + ], + "kibana": { + "dashboard": [ + { + "id": "ml_http_access_explorer_ecs", + "file": "ml_http_access_explorer_ecs.json" + } + ], + "search": [ + { + "id": "ml_http_access_filebeat_ecs", + "file": "ml_http_access_filebeat_ecs.json" + } + ], + "visualization": [ + { + "id": "ml_http_access_map_ecs", + "file": "ml_http_access_map_ecs.json" + }, + { + "id": "ml_http_access_source_ip_timechart_ecs", + "file": "ml_http_access_source_ip_timechart_ecs.json" + }, + { + "id": "ml_http_access_status_code_timechart_ecs", + "file": "ml_http_access_status_code_timechart_ecs.json" + }, + { + "id": "ml_http_access_top_source_ips_table_ecs", + "file": "ml_http_access_top_source_ips_table_ecs.json" + }, + { + "id": "ml_http_access_top_urls_table_ecs", + "file": "ml_http_access_top_urls_table_ecs.json" + }, + { + "id": "ml_http_access_unique_count_url_timechart_ecs", + "file": "ml_http_access_unique_count_url_timechart_ecs.json" + }, + { + "id": "ml_http_access_events_timechart_ecs", + "file": "ml_http_access_events_timechart_ecs.json" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_low_request_rate_ecs.json new file mode 100644 index 0000000000000..b08a8526b17e5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_low_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } } + ] + } + }, + "aggregations": { + "buckets": { + "date_histogram": { + "field": "@timestamp", + "interval": 900000, + "offset": 0, + "order": { + "_key": "asc" + }, + "keyed": false, + "min_doc_count": 0 + }, + "aggregations": { + "@timestamp": { + "max": { + "field": "@timestamp" + } + } + } + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_request_rate_ecs.json new file mode 100644 index 0000000000000..824d6a934d865 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_request_rate_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_url_count_ecs.json new file mode 100644 index 0000000000000..824d6a934d865 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_source_ip_url_count_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_status_code_rate_ecs.json new file mode 100644 index 0000000000000..824d6a934d865 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_status_code_rate_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_visitor_rate_ecs.json new file mode 100644 index 0000000000000..b88b66f15b329 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/datafeed_visitor_rate_ecs.json @@ -0,0 +1,39 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "apache.access" } } + ] + } + }, + "aggregations": { + "buckets": { + "date_histogram": { + "field": "@timestamp", + "interval": 900000, + "offset": 0, + "order": { + "_key": "asc" + }, + "keyed": false, + "min_doc_count": 0 + }, + "aggregations": { + "@timestamp": { + "max": { + "field": "@timestamp" + } + }, + "dc_source_address": { + "cardinality": { + "field": "source.address" + } + } + } + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json new file mode 100644 index 0000000000000..1bfb864bef9ee --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/low_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["apache"], + "description": "HTTP Access Logs: Detect low request rate (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "summary_count_field_name": "doc_count", + "detectors": [ + { + "detector_description": "apache_access_low_request_rate", + "function": "low_count" + } + ], + "influencers": [] + }, + "analysis_limits": { + "model_memory_limit": "10mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-apache-access", + "custom_urls": [ + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json new file mode 100644 index 0000000000000..25c51caec8727 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["apache"], + "description": "HTTP Access Logs: Detect unusual source ips - high request rates (ECS)", + "analysis_config" : { + "bucket_span": "1h", + "detectors": [ + { + "detector_description": "apache_access_source_ip_high_count", + "function": "high_count", + "over_field_name": "source.address" + } + ], + "influencers": [ + "source.address" + ] + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "custom_settings": { + "created_by": "ml-module-apache-access", + "custom_urls": [ + { + "url_name": "Investigate source IP", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json new file mode 100644 index 0000000000000..2982e04771086 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/source_ip_url_count_ecs.json @@ -0,0 +1,35 @@ +{ + "groups": ["apache"], + "description": "HTTP Access Logs: Detect unusual source ips - high distinct count of urls (ECS)", + "analysis_config" : { + "bucket_span": "1h", + "detectors": [ + { + "detector_description": "apache_access_source_ip_high_dc_url", + "function": "high_distinct_count", + "field_name": "url.original", + "over_field_name": "source.address" + } + ], + "influencers": [ + "source.address" + ] + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "custom_settings": { + "created_by": "ml-module-apache-access", + "custom_urls": [ + { + "url_name": "Investigate source IP", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json new file mode 100644 index 0000000000000..39bf67c71ae31 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/status_code_rate_ecs.json @@ -0,0 +1,41 @@ +{ + "groups": ["apache"], + "description": "HTTP Access Logs: Detect unusual status_code rates (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "detectors": [ + { + "detector_description": "apache_access_status_code_rate", + "function": "count", + "partition_field_name": "http.response.status_code" + } + ], + "influencers": [ + "http.response.status_code", + "source.address" + ] + }, + "analysis_limits": { + "model_memory_limit": "100mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-apache-access", + "custom_urls": [ + { + "url_name": "Investigate status code", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027,type:phrase),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json new file mode 100644 index 0000000000000..66ffde6bccf84 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/ml/visitor_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["apache"], + "description": "HTTP Access Logs: Detect unusual visitor rate (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "summary_count_field_name": "dc_source_address", + "detectors": [ + { + "detector_description": "apache_access_visitor_rate", + "function": "non_zero_count" + } + ], + "influencers": [] + }, + "analysis_limits": { + "model_memory_limit": "10mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-apache-access", + "custom_urls": [ + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027apache.access\u0027,type:phrase),type:phrase,value:\u0027apache.access\u0027),query:(match:(event.dataset:(query:\u0027apache.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json new file mode 100644 index 0000000000000..681ad572417f6 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/dashboard/ml_http_access_explorer_ecs.json @@ -0,0 +1,13 @@ +{ + "hits": 0, + "timeRestore": false, + "description": "", + "title": "ML HTTP Access Explorer (ECS)", + "uiStateJSON": "{\"P-3\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}},\"P-5\":{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}}", + "panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"ml_http_access_events_timechart_ecs\",\"col\":1,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":2,\"type\":\"visualization\",\"id\":\"ml_http_access_unique_count_url_timechart_ecs\",\"col\":7,\"row\":1},{\"size_x\":6,\"size_y\":3,\"panelIndex\":3,\"type\":\"visualization\",\"id\":\"ml_http_access_status_code_timechart_ecs\",\"col\":1,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":4,\"type\":\"visualization\",\"id\":\"ml_http_access_source_ip_timechart_ecs\",\"col\":7,\"row\":4},{\"size_x\":6,\"size_y\":3,\"panelIndex\":5,\"type\":\"visualization\",\"id\":\"ml_http_access_top_source_ips_table_ecs\",\"col\":1,\"row\":8},{\"size_x\":6,\"size_y\":3,\"panelIndex\":6,\"type\":\"visualization\",\"id\":\"ml_http_access_map_ecs\",\"col\":7,\"row\":8},{\"size_x\":12,\"size_y\":9,\"panelIndex\":7,\"type\":\"visualization\",\"id\":\"ml_http_access_top_urls_table_ecs\",\"col\":1,\"row\":11}]", + "optionsJSON": "{\"darkTheme\":false}", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\n \"filter\": [],\n \"highlightAll\": true,\n \"version\": true,\n \"query\": {\n \"query\": \"\",\n \"language\": \"lucene\"\n }\n}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/search/ml_http_access_filebeat_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/search/ml_http_access_filebeat_ecs.json new file mode 100644 index 0000000000000..6575c7e65d78d --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/search/ml_http_access_filebeat_ecs.json @@ -0,0 +1,16 @@ +{ + "sort": [ + "@timestamp", + "desc" + ], + "hits": 0, + "description": "Filebeat HTTP Access Data (ECS)", + "title": "ML HTTP Access Data (ECS)", + "version": 1, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"index\":\"INDEX_PATTERN_ID\",\"query\":{\"query_string\":{\"query\":\"fileset.name:access\",\"analyze_wildcard\":true}},\"filter\":[],\"highlight\":{\"pre_tags\":[\"@kibana-highlighted-field@\"],\"post_tags\":[\"@/kibana-highlighted-field@\"],\"fields\":{\"*\":{}},\"require_field_match\":false,\"fragment_size\":2147483647}}" + }, + "columns": [ + "_source" + ] +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json new file mode 100644 index 0000000000000..ff507da41d1a5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_events_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Event Timechart (ECS)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"event.module\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\"}},{\"id\":\"4\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"event.dataset\",\"size\":10,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Event Timechart (ECS)", + "uiStateJSON": "{\"vis\":{\"colors\":{\"apache - access\":\"#629E51\",\"nginx - access\":\"#1F78C1\"}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } + } \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_map_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_map_ecs.json new file mode 100644 index 0000000000000..4cf3982f5ac6a --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_map_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"aggs\":[{\"enabled\":true,\"id\":\"1\",\"params\":{},\"schema\":\"metric\",\"type\":\"count\"},{\"enabled\":true,\"id\":\"2\",\"params\":{\"autoPrecision\":true,\"field\":\"source.geo.location\"},\"schema\":\"segment\",\"type\":\"geohash_grid\"}],\"listeners\":{},\"params\":{\"addTooltip\":true,\"heatBlur\":15,\"heatMaxZoom\":16,\"heatMinOpacity\":0.1,\"heatNormalizeData\":true,\"heatRadius\":25,\"isDesaturated\":true,\"legendPosition\":\"bottomright\",\"mapCenter\":[15,5],\"mapType\":\"Scaled Circle Markers\",\"mapZoom\":2,\"wms\":{\"enabled\":false,\"options\":{\"attribution\":\"Maps provided by USGS\",\"format\":\"image/png\",\"layers\":\"0\",\"styles\":\"\",\"transparent\":true,\"version\":\"1.3.0\"},\"url\":\"https://basemap.nationalmap.gov/arcgis/services/USGSTopo/MapServer/WMSServer\"}},\"title\":\"ML HTTP Access Map (ECS)\",\"type\":\"tile_map\"}", + "description": "", + "title": "ML HTTP Access Map (ECS)", + "uiStateJSON": "{\n \"mapCenter\": [\n 12.039320557540572,\n -0.17578125\n ]\n}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json new file mode 100644 index 0000000000000..8b2a9e14a74b8 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_source_ip_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Source IP Timechart (ECS)\",\"type\":\"area\",\"params\":{\"addLegend\":true,\"addTimeMarker\":false,\"addTooltip\":true,\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"labels\":{\"show\":true,\"truncate\":100},\"position\":\"bottom\",\"scale\":{\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{\"text\":\"@timestamp per 5 minutes\"},\"type\":\"category\"}],\"defaultYExtents\":false,\"drawLinesBetweenPoints\":true,\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"interpolate\":\"linear\",\"legendPosition\":\"right\",\"radiusRatio\":9,\"scale\":\"linear\",\"seriesParams\":[{\"data\":{\"id\":\"1\",\"label\":\"Count\"},\"drawLinesBetweenPoints\":true,\"interpolate\":\"linear\",\"mode\":\"stacked\",\"show\":\"true\",\"showCircles\":true,\"type\":\"area\",\"valueAxis\":\"ValueAxis-1\"}],\"setYExtents\":false,\"showCircles\":true,\"times\":[],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"labels\":{\"filter\":false,\"rotate\":0,\"show\":true,\"truncate\":100},\"name\":\"LeftAxis-1\",\"position\":\"left\",\"scale\":{\"mode\":\"normal\",\"type\":\"linear\"},\"show\":true,\"style\":{},\"title\":{},\"type\":\"value\"}]},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"source.address\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Source IP Timechart (ECS)", + "uiStateJSON": "{}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json new file mode 100644 index 0000000000000..e104b047f924b --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_status_code_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Status Code Timechart (ECS)\",\"type\":\"histogram\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"scale\":\"linear\",\"mode\":\"stacked\",\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"http.response.status_code\",\"size\":50,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Status Code Timechart (ECS)", + "uiStateJSON": "{\n \"vis\": {\n \"colors\": {\n \"200\": \"#7EB26D\",\n \"404\": \"#614D93\"\n }\n }\n}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json new file mode 100644 index 0000000000000..c9afd66ea39b1 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_source_ips_table_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Top Source IPs Table (ECS)\",\"type\":\"table\",\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"source.address\",\"size\":50,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Top Source IPs Table (ECS)", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json new file mode 100644 index 0000000000000..34fbcb621085c --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_top_urls_table_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Top URLs Table (ECS)\",\"type\":\"table\",\"params\":{\"perPage\":100,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"url.original\",\"size\":1000,\"order\":\"desc\",\"orderBy\":\"1\"}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Top URLs Table (ECS)", + "uiStateJSON": "{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json new file mode 100644 index 0000000000000..d14592e68bb6e --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/kibana/visualization/ml_http_access_unique_count_url_timechart_ecs.json @@ -0,0 +1,11 @@ +{ + "visState": "{\"title\":\"ML HTTP Access Unique Count URL Timechart (ECS)\",\"type\":\"line\",\"params\":{\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{\"text\":\"@timestamp per day\"}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Unique count of url.original\"}}],\"seriesParams\":[{\"show\":true,\"mode\":\"normal\",\"type\":\"line\",\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"lineWidth\":2,\"data\":{\"id\":\"1\",\"label\":\"Unique count of url.original\"},\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"showCircles\":true,\"interpolate\":\"linear\",\"scale\":\"linear\",\"drawLinesBetweenPoints\":true,\"radiusRatio\":9,\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"cardinality\",\"schema\":\"metric\",\"params\":{\"field\":\"url.original\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}", + "description": "", + "title": "ML HTTP Access Unique Count URL Timechart (ECS)", + "uiStateJSON": "{}", + "version": 1, + "savedSearchId": "ml_http_access_filebeat_ecs", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/logo.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/logo.json new file mode 100644 index 0000000000000..9372c36cbfa6d --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/logo.json @@ -0,0 +1,5 @@ +{ + "src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAlCAMAAAAUaRt1AAACPVBMVEUAcQAAdgAAfQAAfgAAfwAAgAAAggAAhAAAhQAAhgAAhwIAhwUAiAcAiAoAiQkAiQwAiQ8Aig4AihEAixMAixUAixcAjBYAjBcAjBkAjRgAjRoAjRwAjh0Ajh8Ajx8AjyAAkCIAkCMAkSMAkSUAkSYAkiYAkicAkigAkikAkykAkyoAkywAlCsAlC0AlS4AlTAAli8AljEAljIAlzIAlzMAlzUAmDQAmDYAmDcAmTcAmTgAmToAmTsAmjgAmjkAmjsEmToLmz0TnD4TnEAYnEAanUEcnkMfnkMhn0Qhn0UnoUcroksvo0svo0w4pVI+qFY+qFdEq1xFq1xIrF5KrF9KrWFLrWBNrWFNrmJPr2NTsWhUsGdVsWdXsWlYsmtZs2xbtW5puXhvvH1vvH5zv4N2v4R3wId3wYd6w4p/w4uAw4uAxIyBxIyBxY6CxY6ExY+FxpCHyJSJyZaMypmOy5uQypmRy5uSzJyUzZ2b0aed0aig06yj06ul1K2p1rCq1rGs2LWu2reu2rix2rex3Ly84MS94MO+4MO+4cS+4ca/4sfB4cbC48nJ5c3L5s7L5s/M59DM6NLN6NLO6NLO6dXQ6tbR69jU69bY7t7Z7t3Z7t7a79/b8OHc8OHe8OLf8ePh8OTh8uXm9Oro8+no9Ovp9Orp9ezq9ezq9u3r9u3s9e3s9e/u9e/u9/Hv+PPw9/Lx+PPy+fTy+fXz+fXz+vb0+vb3+/n3/Pn4/Pr5+/n6/Pr9/v3+/v7+//7///+8pzoSAAACRElEQVR42nXU91/TQBQA8CiUpli4po22jaVNRevosulLzgQXuAruiVi3uPceqKgI4sK6994b9wD927ykkRJI3g/Ju8v3k1zu7h311xCPly58YOwxgE/7AiGe29NpBU6nXQmME+74yW4zcGMBimAggSNo3rV+4FUjG5BE0EKUgp51zwzgd1Mlm5KgJySB5Y/8KIALdWgMBkPgKJpxVgf3Vrt4LMbjUAgxERdxmFl5h4DP2/1+kIVSjqMjiv58opfl0DgM3JCNX6hZZUkMac/ajovbOC4vJO/M8x1ZBoM0FtVSUfXjzqz6uTZHhayCmO82aVUHSCpHqIxA7iUHtBE327Sxhmp+kcaKQSqemgf2Xfmf3lGUFgH48e9IXo96g536tCy3yQRUvSHpElPQPc2uWIIrr8nleRApVuDQdPUdOTo4wgKcodar4nixb5I5aC8deEwVmwdUvTUFbYOH0pdUMafkozlwiyjwlCTfaq9agORk+5Qukr18ZAVAsTVo82EJRCjaqoNFqO9atBMAUrS42fiGwmrmGAJArqBzGsjqq6ktcFk96TlIqxYUxN8krfdCOL8fZjuThHjWtOwfPkrfcO6RW1qO1rEy4FR5hvq6yceBDE6nY/T/LalU0k6Hb4Ikct4NnWRX313FhDGk0tArUoKIh7mW3dLr4lzGFe1bFzFXTWuhsn428axgrKzQ4e+G2nzR6DHW5pN+1X19fk91l8+9bHY+/DmVYhIYJ92xE11WJ8xeLsT7d3+wOmFIPGxYfN/Y8w+Jrert1P9yBgAAAABJRU5ErkJggg==", + "height": 25, + "width": 120 +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json new file mode 100644 index 0000000000000..bd31fcd23f504 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json @@ -0,0 +1,111 @@ +{ + "id": "nginx_ecs", + "title": "Nginx access logs", + "description": "Find unusual activity in HTTP access logs from filebeat (ECS)", + "type": "Web Access Logs", + "logoFile": "logo.json", + "defaultIndexPattern": "filebeat-*", + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } }, + { "exists": { "field": "source.address" } }, + { "exists": { "field": "url.original" } }, + { "exists": { "field": "http.response.status_code" } } + ] + } + }, + "jobs": [ + { + "id": "visitor_rate_ecs", + "file": "visitor_rate_ecs.json" + }, + { + "id": "status_code_rate_ecs", + "file": "status_code_rate_ecs.json" + }, + { + "id": "source_ip_url_count_ecs", + "file": "source_ip_url_count_ecs.json" + }, + { + "id": "source_ip_request_rate_ecs", + "file": "source_ip_request_rate_ecs.json" + }, + { + "id": "low_request_rate_ecs", + "file": "low_request_rate_ecs.json" + } + ], + "datafeeds": [ + { + "id": "datafeed-visitor_rate_ecs", + "file": "datafeed_visitor_rate_ecs.json", + "job_id": "visitor_rate_ecs" + }, + { + "id": "datafeed-status_code_rate_ecs", + "file": "datafeed_status_code_rate_ecs.json", + "job_id": "status_code_rate_ecs" + }, + { + "id": "datafeed-source_ip_url_count_ecs", + "file": "datafeed_source_ip_url_count_ecs.json", + "job_id": "source_ip_url_count_ecs" + }, + { + "id": "datafeed-source_ip_request_rate_ecs", + "file": "datafeed_source_ip_request_rate_ecs.json", + "job_id": "source_ip_request_rate_ecs" + }, + { + "id": "datafeed-low_request_rate_ecs", + "file": "datafeed_low_request_rate_ecs.json", + "job_id": "low_request_rate_ecs" + } + ], + "kibana": { + "dashboard": [ + { + "id": "ml_http_access_explorer_ecs", + "file": "ml_http_access_explorer_ecs.json" + } + ], + "search": [ + { + "id": "ml_http_access_filebeat_ecs", + "file": "ml_http_access_filebeat_ecs.json" + } + ], + "visualization": [ + { + "id": "ml_http_access_map_ecs", + "file": "ml_http_access_map_ecs.json" + }, + { + "id": "ml_http_access_source_ip_timechart_ecs", + "file": "ml_http_access_source_ip_timechart_ecs.json" + }, + { + "id": "ml_http_access_status_code_timechart_ecs", + "file": "ml_http_access_status_code_timechart_ecs.json" + }, + { + "id": "ml_http_access_top_source_ips_table_ecs", + "file": "ml_http_access_top_source_ips_table_ecs.json" + }, + { + "id": "ml_http_access_top_urls_table_ecs", + "file": "ml_http_access_top_urls_table_ecs.json" + }, + { + "id": "ml_http_access_unique_count_url_timechart_ecs", + "file": "ml_http_access_unique_count_url_timechart_ecs.json" + }, + { + "id": "ml_http_access_events_timechart_ecs", + "file": "ml_http_access_events_timechart_ecs.json" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_low_request_rate_ecs.json new file mode 100644 index 0000000000000..cf143071aa519 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_low_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } } + ] + } + }, + "aggregations": { + "buckets": { + "date_histogram": { + "field": "@timestamp", + "interval": 900000, + "offset": 0, + "order": { + "_key": "asc" + }, + "keyed": false, + "min_doc_count": 0 + }, + "aggregations": { + "@timestamp": { + "max": { + "field": "@timestamp" + } + } + } + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_request_rate_ecs.json new file mode 100644 index 0000000000000..bccf1bd8de6d5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_request_rate_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_url_count_ecs.json new file mode 100644 index 0000000000000..bccf1bd8de6d5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_source_ip_url_count_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_status_code_rate_ecs.json new file mode 100644 index 0000000000000..bccf1bd8de6d5 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_status_code_rate_ecs.json @@ -0,0 +1,13 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } } + ] + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_visitor_rate_ecs.json new file mode 100644 index 0000000000000..297bd16db4edf --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/datafeed_visitor_rate_ecs.json @@ -0,0 +1,39 @@ +{ + "job_id": "JOB_ID", + "indexes": [ + "INDEX_PATTERN_NAME" + ], + "query": { + "bool": { + "filter": [ + { "term": { "event.dataset": "nginx.access" } } + ] + } + }, + "aggregations": { + "buckets": { + "date_histogram": { + "field": "@timestamp", + "interval": 900000, + "offset": 0, + "order": { + "_key": "asc" + }, + "keyed": false, + "min_doc_count": 0 + }, + "aggregations": { + "@timestamp": { + "max": { + "field": "@timestamp" + } + }, + "dc_source_address": { + "cardinality": { + "field": "source.address" + } + } + } + } + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json new file mode 100644 index 0000000000000..22631813346dc --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/low_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["nginx"], + "description": "HTTP Access Logs: Detect low request rate (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "summary_count_field_name": "doc_count", + "detectors": [ + { + "detector_description": "nginx_access_low_request_rate", + "function": "low_count" + } + ], + "influencers": [] + }, + "analysis_limits": { + "model_memory_limit": "10mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-nginx-access", + "custom_urls": [ + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json new file mode 100644 index 0000000000000..7d91ec8a81cd2 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_request_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["nginx"], + "description": "HTTP Access Logs: Detect unusual source ips - high request rates (ECS)", + "analysis_config" : { + "bucket_span": "1h", + "detectors": [ + { + "detector_description": "nginx_access_source_ip_high_count", + "function": "high_count", + "over_field_name": "source.address" + } + ], + "influencers": [ + "source.address" + ] + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "custom_settings": { + "created_by": "ml-module-nginx-access", + "custom_urls": [ + { + "url_name": "Investigate source IP", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json new file mode 100644 index 0000000000000..dc965e7061b95 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/source_ip_url_count_ecs.json @@ -0,0 +1,35 @@ +{ + "groups": ["nginx"], + "description": "HTTP Access Logs: Detect unusual source ips - high distinct count of urls (ECS)", + "analysis_config" : { + "bucket_span": "1h", + "detectors": [ + { + "detector_description": "nginx_access_source_ip_high_dc_url", + "function": "high_distinct_count", + "field_name": "url.original", + "over_field_name": "source.address" + } + ], + "influencers": [ + "source.address" + ] + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "custom_settings": { + "created_by": "ml-module-nginx-access", + "custom_urls": [ + { + "url_name": "Investigate source IP", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:source.address,negate:!f,type:phrase,value:\u0027$source.address$\u0027),query:(match:(source.address:(query:\u0027$source.address$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json new file mode 100644 index 0000000000000..14cba15dd14f4 --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/status_code_rate_ecs.json @@ -0,0 +1,41 @@ +{ + "groups": ["nginx"], + "description": "HTTP Access Logs: Detect unusual status_code rates (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "detectors": [ + { + "detector_description": "nginx_access_status_code_rate", + "function": "count", + "partition_field_name": "http.response.status_code" + } + ], + "influencers": [ + "http.response.status_code", + "source.address" + ] + }, + "analysis_limits": { + "model_memory_limit": "100mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-nginx-access", + "custom_urls": [ + { + "url_name": "Investigate status code", + "url_value": "kibana#/dashboard/ml_http_access_explorer_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(description:\u0027\u0027,filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,params:(query:\u0027$http.response.status_code$\u0027,type:phrase),type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),query:(language:lucene,query:\u0027\u0027))" + }, + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase)))),(\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:http.response.status_code,negate:!f,type:phrase,value:\u0027$http.response.status_code$\u0027),query:(match:(http.response.status_code:(query:\u0027$http.response.status_code$\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} \ No newline at end of file diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json new file mode 100644 index 0000000000000..e0ba814facb8d --- /dev/null +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/ml/visitor_rate_ecs.json @@ -0,0 +1,34 @@ +{ + "groups": ["nginx"], + "description": "HTTP Access Logs: Detect unusual visitor rate (ECS)", + "analysis_config" : { + "bucket_span": "15m", + "summary_count_field_name": "dc_source_address", + "detectors": [ + { + "detector_description": "nginx_access_visitor_rate", + "function": "non_zero_count" + } + ], + "influencers": [] + }, + "analysis_limits": { + "model_memory_limit": "10mb" + }, + "data_description": { + "time_field": "@timestamp", + "time_format": "epoch_ms" + }, + "model_plot_config": { + "enabled": true + }, + "custom_settings": { + "created_by": "ml-module-nginx-access", + "custom_urls": [ + { + "url_name": "Raw data", + "url_value": "kibana#/discover/ml_http_access_filebeat_ecs?_g=(time:(from:\u0027$earliest$\u0027,mode:absolute,to:\u0027$latest$\u0027))&_a=(columns:!(_source),filters:!((\u0027$state\u0027:(store:appState),meta:(alias:!n,disabled:!f,index:\u0027INDEX_PATTERN_ID\u0027,key:event.dataset,negate:!f,params:(query:\u0027nginx.access\u0027,type:phrase),type:phrase,value:\u0027nginx.access\u0027),query:(match:(event.dataset:(query:\u0027nginx.access\u0027,type:phrase))))),index:\u0027INDEX_PATTERN_ID\u0027,interval:auto,query:(language:lucene,query:\u0027\u0027),sort:!(\u0027@timestamp\u0027,desc))" + } + ] + } +} From bc4b075de2c10faf62249282b2bbea2ca564a3de Mon Sep 17 00:00:00 2001 From: Leanid Shutau Date: Thu, 31 Jan 2019 15:04:29 +0300 Subject: [PATCH 24/40] [I18n] Add README.md for i18n_integrate tool (#21035) Add i18n build tools readme --- src/dev/i18n/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/dev/i18n/README.md b/src/dev/i18n/README.md index 5f629617dfc66..8280f2b81a5a0 100644 --- a/src/dev/i18n/README.md +++ b/src/dev/i18n/README.md @@ -168,3 +168,23 @@ The tool generates a JSON/JSON5 file only if `--output` path is provided. It con } } ``` + +## Locale files verification / integration tool + +### Description + +The tool is used for verifying locale file, finding unused / missing messages, key duplications, grouping messages by namespaces and creating JSON files in right folders. + +### Notes + +The tool throws an exception if `formats` object is missing in locale file. + +### Usage + +```bash +node scripts/i18n_integrate --path path/to/locale.json +``` + +### Output + +The tool generates locale files in plugin folders and few other special locations based on namespaces and corresponding mappings defined in [.i18nrc.json](../../../.i18nrc.json). From e2d5e1048b13b2420f19aad1f84f905137cfbf64 Mon Sep 17 00:00:00 2001 From: Nox911 Date: Thu, 31 Jan 2019 15:13:04 +0300 Subject: [PATCH 25/40] [i18n] Translate filter_bar (#26250) * Translate ui -> filter_bar * Fix issue * Resolve review comments --- src/ui/public/filter_bar/filter_bar.html | 122 +++++++++++++++--- src/ui/public/filter_bar/filter_bar.js | 13 +- .../filter_bar/filter_pill/filter_pill.html | 28 ++-- .../filter_bar/filter_pill/filter_pill.js | 16 ++- 4 files changed, 141 insertions(+), 38 deletions(-) diff --git a/src/ui/public/filter_bar/filter_bar.html b/src/ui/public/filter_bar/filter_bar.html index 5cd239781d192..625be4dbd98b0 100644 --- a/src/ui/public/filter_bar/filter_bar.html +++ b/src/ui/public/filter_bar/filter_bar.html @@ -1,24 +1,43 @@ -
+
    -
  • Apply these filters?
  • +
  • - NOT {{ filter.meta.key }}: {{ filter.meta.value }} + + {{ filter.meta.key }}: {{ filter.meta.value }} +
  • +
  • + + {{changeTimeFilter.meta.value}}
  • -
  • Change time to: {{changeTimeFilter.meta.value}}
  • - + + i18n-id="common.ui.filterBar.cancelButtonLabel" + i18n-default-message="Cancel" + >
@@ -50,7 +69,10 @@ class="euiLink euiLink--primary" data-test-subj="addFilter" > - Add a filter +
@@ -68,7 +90,10 @@ aria-expanded="{{!!showFilterActions}}" aria-controls="filterActionsAllContainer" > - Actions + @@ -121,28 +146,83 @@ >
diff --git a/src/ui/public/filter_bar/filter_bar.js b/src/ui/public/filter_bar/filter_bar.js index 0a1648ac75d4a..88cc6146706a7 100644 --- a/src/ui/public/filter_bar/filter_bar.js +++ b/src/ui/public/filter_bar/filter_bar.js @@ -37,7 +37,7 @@ export { disableFilter, enableFilter, toggleFilterDisabled } from './lib/disable const module = uiModules.get('kibana'); -module.directive('filterBar', function (Private, Promise, getAppState) { +module.directive('filterBar', function (Private, Promise, getAppState, i18n) { const mapAndFlattenFilters = Private(FilterBarLibMapAndFlattenFiltersProvider); const mapFlattenAndWrapFilters = Private(FilterBarLibMapFlattenAndWrapFiltersProvider); const extractTimeFilter = Private(FilterBarLibExtractTimeFilterProvider); @@ -74,20 +74,25 @@ module.directive('filterBar', function (Private, Promise, getAppState) { return pill[pill.length - 1].offsetTop > 10; }; + const collapseFilterTooltip = i18n('common.ui.filterBar.collapseFilterTooltip', { + defaultMessage: 'Collapse filter bar \n to show less' + }); + const expandFilterTooltip = i18n('common.ui.filterBar.expandFilterTooltip', { defaultMessage: 'Expand filter bar \n to show more' }); + $scope.filterNavToggle = { isOpen: true, - tooltipContent: 'Collapse filter bar \n to show less' + tooltipContent: collapseFilterTooltip }; $scope.toggleFilterShown = () => { const collapser = $elem.find('.filter-nav-link__collapser'); const filterPanelPill = $elem.find('.filter-panel__pill'); if ($scope.filterNavToggle.isOpen) { - $scope.filterNavToggle.tooltipContent = 'Expand filter bar \n to show more'; + $scope.filterNavToggle.tooltipContent = expandFilterTooltip; collapser.attr('aria-expanded', 'false'); filterPanelPill.attr('style', 'width: calc(100% - 80px)'); } else { - $scope.filterNavToggle.tooltipContent = 'Collapse filter bar \n to show less'; + $scope.filterNavToggle.tooltipContent = collapseFilterTooltip; collapser.attr('aria-expanded', 'true'); filterPanelPill.attr('style', 'width: auto'); } diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.html b/src/ui/public/filter_bar/filter_pill/filter_pill.html index f79d42665e8fc..f1cdadad492f6 100644 --- a/src/ui/public/filter_bar/filter_pill/filter_pill.html +++ b/src/ui/public/filter_bar/filter_pill/filter_pill.html @@ -13,7 +13,11 @@ aria-disabled="{{pill.filter.meta.disabled}}" > - NOT + {{ pill.filter.meta.alias }} {{ pill.filter.meta.key }}: "{{ pill.filter.meta.value }}" @@ -26,8 +30,8 @@ data-test-subj="disableFilter-{{ pill.filter.meta.key }}" ng-focus="pill.activateActions()" ng-blur="pill.deactivateActions()" - aria-label="{{pill.filter.meta.disabled ? 'Enable filter' : 'Disable filter'}}" - tooltip="{{pill.filter.meta.disabled ? 'Enable filter' : 'Disable filter'}}" + aria-label="{{pill.filter.meta.disabled ? pill.i18n.enableFilterAriaLabel : pill.i18n.disableFilterAriaLabel}}" + tooltip="{{pill.filter.meta.disabled ? pill.i18n.enableFilterTooltip : pill.i18n.disableFilterTooltip}}" tooltip-append-to-body="true" > @@ -40,8 +44,8 @@ data-test-subj="pinFilter-{{ pill.filter.meta.key }}" ng-focus="pill.activateActions()" ng-blur="pill.deactivateActions()" - aria-label="{{pill.filter.$state.store == 'globalState' ? 'Unpin filter' : 'Pin filter'}}" - tooltip="{{pill.filter.$state.store == 'globalState' ? 'Unpin filter' : 'Pin filter'}}" + aria-label="{{pill.filter.$state.store == 'globalState' ? pill.i18n.unpinFilterAriaLabel : pill.i18n.pinFilterAriaLabel}}" + tooltip="{{pill.filter.$state.store == 'globalState' ? pill.i18n.unpinFilterTooltip : pill.i18n.pinFilterTooltip}}" tooltip-append-to-body="true" > @@ -54,8 +58,8 @@ data-test-subj="invertFilter-{{ pill.filter.meta.key }}" ng-focus="pill.activateActions()" ng-blur="pill.deactivateActions()" - aria-label="{{pill.filter.meta.negate ? 'Include matches' : 'Exclude matches'}}" - tooltip="{{pill.filter.meta.negate ? 'Include matches' : 'Exclude matches'}}" + aria-label="{{pill.filter.meta.negate ? pill.i18n.includeMatchesAriaLabel : pill.i18n.excludeMatchesAriaLabel}}" + tooltip="{{pill.filter.meta.negate ? pill.i18n.includeMatchesTooltip : pill.i18n.excludeMatchesTooltip}}" tooltip-append-to-body="true" > @@ -67,8 +71,8 @@ ng-click="pill.onDeleteFilter(pill.filter)" ng-focus="pill.activateActions()" ng-blur="pill.deactivateActions()" - aria-label="Remove filter" - tooltip="Remove filter" + aria-label="{{ ::'common.ui.filterBar.filterPill.removeFilterAriaLabel' | i18n: { defaultMessage: 'Remove filter' } }}" + tooltip="{{ ::'common.ui.filterBar.filterPill.removeFilterTooltip' | i18n: { defaultMessage: 'Remove filter' } }}" tooltip-append-to-body="true" > @@ -80,14 +84,14 @@ ng-disabled="pill.isControlledByPanel()" ng-focus="pill.activateActions()" ng-blur="pill.deactivateActions()" - aria-label="Edit filter" - tooltip="Edit filter" + aria-label="{{ ::'common.ui.filterBar.filterPill.editFilterAriaLabel' | i18n: { defaultMessage: 'Edit filter' } }}" + tooltip="{{ ::'common.ui.filterBar.filterPill.editFilterTooltip' | i18n: { defaultMessage: 'Edit filter' } }}" tooltip-append-to-body="true" data-test-subj="editFilter" > diff --git a/src/ui/public/filter_bar/filter_pill/filter_pill.js b/src/ui/public/filter_bar/filter_pill/filter_pill.js index 03b19427af930..cd15d9df7d888 100644 --- a/src/ui/public/filter_bar/filter_pill/filter_pill.js +++ b/src/ui/public/filter_bar/filter_pill/filter_pill.js @@ -23,7 +23,7 @@ import { uiModules } from '../../modules'; const module = uiModules.get('kibana'); -module.directive('filterPill', function () { +module.directive('filterPill', function (i18n) { return { template, restrict: 'E', @@ -51,6 +51,20 @@ module.directive('filterPill', function () { return _.has(this.filter, 'meta.controlledBy'); }; + this.i18n = { + enableFilterAriaLabel: i18n('common.ui.filterBar.filterPill.enableFilterAriaLabel', { defaultMessage: 'Enable filter' }), + enableFilterTooltip: i18n('common.ui.filterBar.filterPill.enableFilterTooltip', { defaultMessage: 'Enable filter' }), + disableFilterAriaLabel: i18n('common.ui.filterBar.filterPill.disableFilterAriaLabel', { defaultMessage: 'Disable filter' }), + disableFilterTooltip: i18n('common.ui.filterBar.filterPill.disableFilterTooltip', { defaultMessage: 'Disable filter' }), + pinFilterAriaLabel: i18n('common.ui.filterBar.filterPill.pinFilterAriaLabel', { defaultMessage: 'Pin filter' }), + pinFilterTooltip: i18n('common.ui.filterBar.filterPill.pinFilterTooltip', { defaultMessage: 'Pin filter' }), + unpinFilterAriaLabel: i18n('common.ui.filterBar.filterPill.unpinFilterAriaLabel', { defaultMessage: 'Unpin filter' }), + unpinFilterTooltip: i18n('common.ui.filterBar.filterPill.unpinFilterTooltip', { defaultMessage: 'Unpin filter' }), + includeMatchesAriaLabel: i18n('common.ui.filterBar.filterPill.includeMatchesAriaLabel', { defaultMessage: 'Include matches' }), + includeMatchesTooltip: i18n('common.ui.filterBar.filterPill.includeMatchesTooltip', { defaultMessage: 'Include matches' }), + excludeMatchesAriaLabel: i18n('common.ui.filterBar.filterPill.excludeMatchesAriaLabel', { defaultMessage: 'Exclude matches' }), + excludeMatchesTooltip: i18n('common.ui.filterBar.filterPill.excludeMatchesTooltip', { defaultMessage: 'Exclude matches' }), + }; } }; }); From db64c791a2d5a4c8b06f3ed7a6526ab915eb0390 Mon Sep 17 00:00:00 2001 From: Peter Pisljar Date: Thu, 31 Jan 2019 04:41:21 -0800 Subject: [PATCH 26/40] adding tests for vilisb legend filtering (#29604) --- test/functional/apps/visualize/_pie_chart.js | 63 +++++++++++++++++++ .../apps/visualize/_vertical_bar_chart.js | 11 ++++ 2 files changed, 74 insertions(+) diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index dcab846c277a1..3b9442e1ffad0 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -213,6 +213,69 @@ export default function ({ getService, getPageObjects }) { }); }); describe('multi series slice', () => { + before(async () => { + log.debug('navigateToApp visualize'); + await PageObjects.visualize.navigateToNewVisualization(); + log.debug('clickPieChart'); + await PageObjects.visualize.clickPieChart(); + await PageObjects.visualize.clickNewSearch(); + log.debug('Set absolute time range from \"' + fromTime + '\" to \"' + toTime + '\"'); + await PageObjects.header.setAbsoluteRange(fromTime, toTime); + log.debug('select bucket Split Slices'); + await PageObjects.visualize.clickBucket('Split Slices'); + log.debug('Click aggregation Histogram'); + await PageObjects.visualize.selectAggregation('Histogram'); + log.debug('Click field memory'); + await PageObjects.visualize.selectField('memory'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.common.sleep(1003); + log.debug('setNumericInterval 4000'); + await PageObjects.visualize.setNumericInterval('40000'); + log.debug('Toggle previous editor'); + await PageObjects.visualize.toggleAggregationEditor(2); + await PageObjects.visualize.clickAddBucket(); + log.debug('select bucket Split Slices'); + await PageObjects.visualize.clickBucket('Split Slices'); + await PageObjects.visualize.selectAggregation('Terms'); + await PageObjects.visualize.selectField('geo.dest'); + await PageObjects.visualize.clickGo(); + }); + + it ('should show correct chart', async () => { + const expectedTableData = [ [ '0', '55', 'CN', '14' ], [ '0', '55', 'IN', '9' ], [ '0', '55', 'MX', '3' ], + [ '0', '55', 'US', '3' ], [ '0', '55', 'BR', '2' ], [ '40,000', '50', 'CN', '7' ], + [ '40,000', '50', 'IN', '7' ], [ '40,000', '50', 'US', '5' ], [ '40,000', '50', 'MY', '3' ], + [ '40,000', '50', 'ET', '2' ], [ '80,000', '41', 'CN', '9' ], [ '80,000', '41', 'IN', '4' ], + [ '80,000', '41', 'US', '4' ], [ '80,000', '41', 'BR', '3' ], [ '80,000', '41', 'IT', '2' ], + [ '120,000', '43', 'CN', '8' ], [ '120,000', '43', 'IN', '5' ], [ '120,000', '43', 'US', '4' ], + [ '120,000', '43', 'JP', '3' ], [ '120,000', '43', 'RU', '3' ], [ '160,000', '44', 'CN', '15' ], + [ '160,000', '44', 'IN', '5' ], [ '160,000', '44', 'IQ', '2' ], [ '160,000', '44', 'JP', '2' ], + [ '160,000', '44', 'NG', '2' ], [ '200,000', '40', 'IN', '7' ], [ '200,000', '40', 'CN', '6' ], + [ '200,000', '40', 'MX', '3' ], [ '200,000', '40', 'BR', '2' ], [ '200,000', '40', 'ID', '2' ], + [ '240,000', '46', 'CN', '6' ], [ '240,000', '46', 'IN', '6' ], [ '240,000', '46', 'US', '6' ], + [ '240,000', '46', 'NG', '3' ], [ '240,000', '46', 'CH', '2' ], [ '280,000', '39', 'CN', '11' ], + [ '280,000', '39', 'IN', '5' ], [ '280,000', '39', 'BR', '2' ], [ '280,000', '39', 'IT', '2' ], + [ '280,000', '39', 'NG', '2' ], [ '320,000', '40', 'CN', '7' ], [ '320,000', '40', 'US', '6' ], + [ '320,000', '40', 'MX', '4' ], [ '320,000', '40', 'BD', '2' ], [ '320,000', '40', 'ID', '2' ], + [ '360,000', '47', 'IN', '8' ], [ '360,000', '47', 'CN', '6' ], [ '360,000', '47', 'US', '4' ], + [ '360,000', '47', 'BD', '3' ], [ '360,000', '47', 'BR', '2' ] ]; + + await inspector.open(); + await inspector.setTablePageSize(50); + await inspector.expectTableData(expectedTableData); + await inspector.close(); + }); + + it('should correctly filter on legend', async () => { + const expectedTableData = [ '0', 'CN', '40,000', 'CN', '80,000', 'CN', '120,000', 'CN', '160,000', 'CN', + '200,000', 'CN', '240,000', 'CN', '280,000', 'CN', '320,000', 'CN', '360,000', 'CN' ]; + await PageObjects.visualize.filterLegend('CN'); + await PageObjects.visualize.waitForVisualization(); + await pieChart.expectPieChartLabels(expectedTableData); + await filterBar.removeFilter('geo.dest'); + await PageObjects.visualize.waitForVisualization(); + }); + it('should still showing pie chart when a subseries have zero data', async function () { await PageObjects.visualize.navigateToNewVisualization(); log.debug('clickPieChart'); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index 330f99d53340d..0954f4e5e7f88 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -23,6 +23,7 @@ export default function ({ getService, getPageObjects }) { const log = getService('log'); const retry = getService('retry'); const inspector = getService('inspector'); + const filterBar = getService('filterBar'); const PageObjects = getPageObjects(['common', 'visualize', 'header']); describe('vertical bar chart', function () { @@ -257,6 +258,16 @@ export default function ({ getService, getPageObjects }) { const legendEntries = await PageObjects.visualize.getLegendEntries(); expect(legendEntries).to.eql(expectedEntries); }); + + it ('should correctly filter by legend', async () => { + await PageObjects.visualize.filterLegend('200'); + await PageObjects.visualize.waitForVisualization(); + const legendEntries = await PageObjects.visualize.getLegendEntries(); + const expectedEntries = ['200']; + expect(legendEntries).to.eql(expectedEntries); + await filterBar.removeFilter('response.raw'); + await PageObjects.visualize.waitForVisualization(); + }); }); describe('vertical bar with multiple splits', function () { From 17bb0d04838e1a93533add87527a8c6e1887c6e6 Mon Sep 17 00:00:00 2001 From: Maryia Lapata Date: Thu, 31 Jan 2019 15:54:22 +0300 Subject: [PATCH 27/40] Update kbn-i18n dependencies (#29699) --- packages/kbn-i18n/package.json | 18 +- yarn.lock | 593 ++++++++++++++++++++------------- 2 files changed, 375 insertions(+), 236 deletions(-) diff --git a/packages/kbn-i18n/package.json b/packages/kbn-i18n/package.json index af7485773acb9..4cdba0ac1317a 100644 --- a/packages/kbn-i18n/package.json +++ b/packages/kbn-i18n/package.json @@ -12,19 +12,19 @@ "kbn:watch": "node scripts/build --watch --source-maps" }, "devDependencies": { - "@babel/cli": "^7.1.0", - "@babel/core": "^7.1.0", - "@babel/plugin-proposal-class-properties": "^7.1.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/preset-env": "^7.1.0", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.2.2", + "@babel/plugin-proposal-class-properties": "^7.3.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.1", + "@babel/preset-env": "^7.3.1", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.1.0", "@kbn/dev-utils": "1.0.0", "@types/intl-relativeformat": "^2.1.0", - "@types/react-intl": "^2.3.11", + "@types/react-intl": "^2.3.15", "del": "^3.0.0", "getopts": "^2.2.3", - "supports-color": "^5.5.0", + "supports-color": "^6.1.0", "typescript": "^3.0.3" }, "dependencies": { @@ -32,7 +32,7 @@ "intl-messageformat": "^2.2.0", "intl-relativeformat": "^2.1.0", "prop-types": "^15.6.2", - "react": "^16.3.0", - "react-intl": "^2.7.0" + "react": "^16.6.0", + "react-intl": "^2.8.0" } } diff --git a/yarn.lock b/yarn.lock index b45d7700f7cdf..66dc27e569585 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@babel/cli@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.1.0.tgz#a9429fd63911711b0fa93ae50d73beee6c42aef8" - integrity sha512-+OdtGZcJNH92CnDqwaPxh7P7gddFyhoiHV3GBzgKpYbxIJlQ4WDEiC8m+AMcueYzlI+bXqrYlIU/Pp17NaC0hg== +"@babel/cli@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.2.3.tgz#1b262e42a3e959d28ab3d205ba2718e1923cfee6" + integrity sha512-bfna97nmJV6nDJhXNPeEfxyMjWnt6+IjUAaDPiYRTBlm8L41n8nvw6UAqUCbvpFfU246gHPxW7sfWwqtF4FcYA== dependencies: commander "^2.8.1" convert-source-map "^1.1.0" @@ -35,21 +35,21 @@ esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/core@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.0.tgz#08958f1371179f62df6966d8a614003d11faeb04" - integrity sha512-9EWmD0cQAbcXSc+31RIoYgEHx3KQ2CCSMDBhnXrShWvo45TMw+3/55KVxlhkG53kw9tl87DqINgHDgFVhZJV/Q== +"@babel/core@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.2.2.tgz#07adba6dde27bb5ad8d8672f15fde3e08184a687" + integrity sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw== dependencies: "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/helpers" "^7.1.0" - "@babel/parser" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helpers" "^7.2.0" + "@babel/parser" "^7.2.2" + "@babel/template" "^7.2.2" + "@babel/traverse" "^7.2.2" + "@babel/types" "^7.2.2" convert-source-map "^1.1.0" - debug "^3.1.0" - json5 "^0.5.0" + debug "^4.1.0" + json5 "^2.1.0" lodash "^4.17.10" resolve "^1.3.2" semver "^5.4.1" @@ -77,6 +77,17 @@ source-map "^0.5.0" trim-right "^1.0.1" +"@babel/generator@^7.2.2": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.3.0.tgz#f663838cd7b542366de3aa608a657b8ccb2a99eb" + integrity sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg== + dependencies: + "@babel/types" "^7.3.0" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + "@babel/helper-annotate-as-pure@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" @@ -109,6 +120,17 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-create-class-features-plugin@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.0.tgz#2b01a81b3adc2b1287f9ee193688ef8dc71e718f" + integrity sha512-DUsQNS2CGLZZ7I3W3fvh0YpPDd6BuWJlDl+qmZZpABZHza2ErE3LxtEzLJFHFC1ZwtlAXvHhbFYbtM5o5B0WBw== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.2.3" + "@babel/helper-define-map@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" @@ -215,6 +237,16 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/helper-replace-supers@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz#19970020cf22677d62b3a689561dbd9644d8c5e5" + integrity sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.2.3" + "@babel/types" "^7.0.0" + "@babel/helper-simple-access@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" @@ -240,14 +272,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helpers@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.0.tgz#429bf0f0020be56a4242883432084e3d70a8a141" - integrity sha512-V1jXUTNdTpBn37wqqN73U+eBpzlLHmxA4aDaghJBggmzly/FpIJMHXse9lgdzQQT4gs5jZ5NmYxOL8G3ROc29g== +"@babel/helpers@^7.2.0": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.3.1.tgz#949eec9ea4b45d3210feb7dc1c22db664c9e44b9" + integrity sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA== dependencies: - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.5" + "@babel/types" "^7.3.0" "@babel/highlight@^7.0.0": version "7.0.0" @@ -268,78 +300,72 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77" integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w== -"@babel/plugin-proposal-async-generator-functions@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" - integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== +"@babel/parser@^7.2.2", "@babel/parser@^7.2.3": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.1.tgz#8f4ffd45f779e6132780835ffa7a215fa0b2d181" + integrity sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" -"@babel/plugin-proposal-class-properties@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.1.0.tgz#9af01856b1241db60ec8838d84691aa0bd1e8df4" - integrity sha512-/PCJWN+CKt5v1xcGn4vnuu13QDoV+P7NcICP44BoonAJoPSGwVkgrXihFIQGiEjjPlUDBIw1cM7wYFLARS2/hw== +"@babel/plugin-proposal-class-properties@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.0.tgz#272636bc0fa19a0bc46e601ec78136a173ea36cd" + integrity sha512-wNHxLkEKTQ2ay0tnsam2z7fGZUi+05ziDJflEt3AZTP3oXLKHJp9HqhfroB/vdMvt3sda9fAbq7FsG8QPDrZBg== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.0.0" - "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-create-class-features-plugin" "^7.3.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.1.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" -"@babel/plugin-proposal-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" - integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== +"@babel/plugin-proposal-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" + integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" -"@babel/plugin-proposal-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" - integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== +"@babel/plugin-proposal-object-rest-spread@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.1.tgz#f69fb6a1ea6a4e1c503994a91d9cf76f3c4b36e8" + integrity sha512-Nmmv1+3LqxJu/V5jU9vJmxR/KIRWFk2qLHmbB56yRRRFhlaSuOVXscX3gUmhaKgUhzA3otOHVubbIEVYsZ0eZg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" - integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== dependencies: "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" -"@babel/plugin-proposal-unicode-property-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" - integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== +"@babel/plugin-proposal-unicode-property-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.2.0.tgz#abe7281fe46c95ddc143a65e5358647792039520" + integrity sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.2.0" -"@babel/plugin-syntax-async-generators@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" - integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-class-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.0.0.tgz#e051af5d300cbfbcec4a7476e37a803489881634" - integrity sha512-cR12g0Qzn4sgkjrbrzWy2GE7m9vMl/sFkqZ3gIpAQdrvPDnLM8180i+ANDFIXfjHo9aqp0ccJlQ0QNZcFUbf9w== +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-json-strings@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" - integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== +"@babel/plugin-syntax-json-strings@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" + integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -350,17 +376,17 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" - integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-syntax-optional-catch-binding@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" - integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -371,41 +397,41 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" - integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== +"@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" + integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" - integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== +"@babel/plugin-transform-async-to-generator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz#68b8a438663e88519e65b776f8938f3445b1a2ff" + integrity sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-remap-async-to-generator" "^7.1.0" -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" - integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== +"@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" + integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.0.0.tgz#1745075edffd7cdaf69fab2fb6f9694424b7e9bc" - integrity sha512-GWEMCrmHQcYWISilUrk9GDqH4enf3UmhOEbNbNrlNAX1ssH3MsS1xLOS6rdjRVPgA7XXVPn87tRkdTEoA/dxEg== +"@babel/plugin-transform-block-scoping@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.2.0.tgz#f17c49d91eedbcdf5dd50597d16f5f2f770132d4" + integrity sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q== dependencies: "@babel/helper-plugin-utils" "^7.0.0" lodash "^4.17.10" -"@babel/plugin-transform-classes@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" - integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== +"@babel/plugin-transform-classes@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.2.2.tgz#6c90542f210ee975aa2aa8c8b5af7fa73a126953" + integrity sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-define-map" "^7.1.0" @@ -416,99 +442,106 @@ "@babel/helper-split-export-declaration" "^7.0.0" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" - integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== +"@babel/plugin-transform-computed-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" + integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.0.0.tgz#68e911e1935dda2f06b6ccbbf184ffb024e9d43a" - integrity sha512-Fr2GtF8YJSXGTyFPakPFB4ODaEKGU04bPsAllAIabwoXdFrPxL0LVXQX5dQWoxOjjgozarJcC9eWGsj0fD6Zsg== +"@babel/plugin-transform-destructuring@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.2.0.tgz#e75269b4b7889ec3a332cd0d0c8cff8fed0dc6f3" + integrity sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-dotall-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" - integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== +"@babel/plugin-transform-dotall-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz#f0aabb93d120a8ac61e925ea0ba440812dbe0e49" + integrity sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/plugin-transform-duplicate-keys@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" - integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== +"@babel/plugin-transform-duplicate-keys@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3" + integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-exponentiation-operator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" - integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== +"@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" + integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-for-of@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" - integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== +"@babel/plugin-transform-for-of@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.2.0.tgz#ab7468befa80f764bb03d3cb5eef8cc998e1cad9" + integrity sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" - integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== +"@babel/plugin-transform-function-name@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.2.0.tgz#f7930362829ff99a3174c39f0afcc024ef59731a" + integrity sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ== dependencies: "@babel/helper-function-name" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" - integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== +"@babel/plugin-transform-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" + integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" - integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== +"@babel/plugin-transform-modules-amd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6" + integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-commonjs@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" - integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== +"@babel/plugin-transform-modules-commonjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz#c4f1933f5991d5145e9cfad1dfd848ea1727f404" + integrity sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.1.0" -"@babel/plugin-transform-modules-systemjs@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.0.0.tgz#8873d876d4fee23209decc4d1feab8f198cf2df4" - integrity sha512-8EDKMAsitLkiF/D4Zhe9CHEE2XLh4bfLbb9/Zf3FgXYQOZyZYyg7EAel/aT2A7bHv62jwHf09q2KU/oEexr83g== +"@babel/plugin-transform-modules-systemjs@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.2.0.tgz#912bfe9e5ff982924c81d0937c92d24994bb9068" + integrity sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ== dependencies: "@babel/helper-hoist-variables" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-umd@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" - integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== +"@babel/plugin-transform-modules-umd@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" + integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== dependencies: "@babel/helper-module-transforms" "^7.1.0" "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-named-capturing-groups-regex@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz#140b52985b2d6ef0cb092ef3b29502b990f9cd50" + integrity sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw== + dependencies: + regexp-tree "^0.1.0" + "@babel/plugin-transform-new-target@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" @@ -516,18 +549,18 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-object-super@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" - integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== +"@babel/plugin-transform-object-super@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz#b35d4c10f56bab5d650047dad0f1d8e8814b6598" + integrity sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-replace-supers" "^7.1.0" -"@babel/plugin-transform-parameters@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" - integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== +"@babel/plugin-transform-parameters@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.2.0.tgz#0d5ad15dc805e2ea866df4dd6682bfe76d1408c2" + integrity sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA== dependencies: "@babel/helper-call-delegate" "^7.1.0" "@babel/helper-get-function-arity" "^7.0.0" @@ -572,40 +605,40 @@ dependencies: regenerator-transform "^0.13.3" -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" - integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== +"@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" + integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-spread@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" - integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== +"@babel/plugin-transform-spread@^7.2.0": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" + integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" - integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== +"@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" + integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" - integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== +"@babel/plugin-transform-template-literals@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.2.0.tgz#d87ed01b8eaac7a92473f608c97c089de2ba1e5b" + integrity sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg== dependencies: "@babel/helper-annotate-as-pure" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-typeof-symbol@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" - integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== +"@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" + integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -617,58 +650,60 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-typescript" "^7.0.0" -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" - integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== +"@babel/plugin-transform-unicode-regex@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.2.0.tgz#4eb8db16f972f8abb5062c161b8b115546ade08b" + integrity sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" -"@babel/preset-env@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.0.tgz#e67ea5b0441cfeab1d6f41e9b5c79798800e8d11" - integrity sha512-ZLVSynfAoDHB/34A17/JCZbyrzbQj59QC1Anyueb4Bwjh373nVPq5/HMph0z+tCmcDjXDe+DlKQq9ywQuvWrQg== +"@babel/preset-env@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.1.tgz#389e8ca6b17ae67aaf9a2111665030be923515db" + integrity sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.1.0" - "@babel/plugin-proposal-json-strings" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" - "@babel/plugin-syntax-async-generators" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.1.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.1.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-dotall-regex" "^7.0.0" - "@babel/plugin-transform-duplicate-keys" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.1.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.1.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-amd" "^7.1.0" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" - "@babel/plugin-transform-modules-systemjs" "^7.0.0" - "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-json-strings" "^7.2.0" + "@babel/plugin-proposal-object-rest-spread" "^7.3.1" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.2.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-json-strings" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-arrow-functions" "^7.2.0" + "@babel/plugin-transform-async-to-generator" "^7.2.0" + "@babel/plugin-transform-block-scoped-functions" "^7.2.0" + "@babel/plugin-transform-block-scoping" "^7.2.0" + "@babel/plugin-transform-classes" "^7.2.0" + "@babel/plugin-transform-computed-properties" "^7.2.0" + "@babel/plugin-transform-destructuring" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.2.0" + "@babel/plugin-transform-duplicate-keys" "^7.2.0" + "@babel/plugin-transform-exponentiation-operator" "^7.2.0" + "@babel/plugin-transform-for-of" "^7.2.0" + "@babel/plugin-transform-function-name" "^7.2.0" + "@babel/plugin-transform-literals" "^7.2.0" + "@babel/plugin-transform-modules-amd" "^7.2.0" + "@babel/plugin-transform-modules-commonjs" "^7.2.0" + "@babel/plugin-transform-modules-systemjs" "^7.2.0" + "@babel/plugin-transform-modules-umd" "^7.2.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.3.0" "@babel/plugin-transform-new-target" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.1.0" - "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-object-super" "^7.2.0" + "@babel/plugin-transform-parameters" "^7.2.0" "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typeof-symbol" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - browserslist "^4.1.0" + "@babel/plugin-transform-shorthand-properties" "^7.2.0" + "@babel/plugin-transform-spread" "^7.2.0" + "@babel/plugin-transform-sticky-regex" "^7.2.0" + "@babel/plugin-transform-template-literals" "^7.2.0" + "@babel/plugin-transform-typeof-symbol" "^7.2.0" + "@babel/plugin-transform-unicode-regex" "^7.2.0" + browserslist "^4.3.4" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.3.0" @@ -709,6 +744,15 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" +"@babel/template@^7.1.2", "@babel/template@^7.2.2": + version "7.2.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" + integrity sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.2.2" + "@babel/types" "^7.2.2" + "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0": version "7.1.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.0.tgz#503ec6669387efd182c3888c4eec07bcc45d91b2" @@ -739,6 +783,21 @@ globals "^11.1.0" lodash "^4.17.10" +"@babel/traverse@^7.1.5", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8" + integrity sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.2.2" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.2.3" + "@babel/types" "^7.2.2" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + "@babel/types@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0.tgz#6e191793d3c854d19c6749989e3bc55f0e962118" @@ -757,6 +816,15 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@babel/types@^7.2.2", "@babel/types@^7.3.0": + version "7.3.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.3.0.tgz#61dc0b336a93badc02bf5f69c4cd8e1353f2ffc0" + integrity sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + "@elastic/eui@0.0.23": version "0.0.23" resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-0.0.23.tgz#01a3d88aeaff175da5d42b70d407d08a32783f3d" @@ -1695,10 +1763,10 @@ "@types/node" "*" "@types/react" "*" -"@types/react-intl@^2.3.11": - version "2.3.11" - resolved "https://registry.yarnpkg.com/@types/react-intl/-/react-intl-2.3.11.tgz#8d9e8a5931c665ce9086cbcda5b7467d668dfa33" - integrity sha512-UWTuvlPfpwZII8sUIxXMHX85opFBT0Iq/qQlspcQOCJdvcQiArD/7N5JqBEcmWWdr/vu7rA43erx9i1ig436mA== +"@types/react-intl@^2.3.15": + version "2.3.15" + resolved "https://registry.yarnpkg.com/@types/react-intl/-/react-intl-2.3.15.tgz#4768425b6a9bd680c1076761244b2b96a337dfa7" + integrity sha512-a2D0gSDdj9lJjEZ/tGP+lS489uaJSuBxzlW1A/1JqVnadbB+/5ZbFK3QkWaesR/ROcSsLTJxAfPorhT4jn6CUA== "@types/react-redux@^6.0.6": version "6.0.6" @@ -4518,7 +4586,7 @@ browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.0.1, browserslist@^4.1.0: +browserslist@^4.0.1, browserslist@^4.3.4: version "4.4.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.4.1.tgz#42e828954b6b29a7a53e352277be429478a69062" integrity sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A== @@ -5325,6 +5393,16 @@ cli-spinners@^1.1.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" integrity sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg== +cli-table3@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + cli-table@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" @@ -5597,6 +5675,11 @@ colors@^1.1.0, colors@^1.2.1: resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ== +colors@^1.1.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -6755,12 +6838,19 @@ debug@3.X, debug@^3.1.0, debug@^3.2.5: dependencies: ms "^2.1.1" +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -12968,6 +13058,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + jsonfile@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" @@ -17576,10 +17673,10 @@ react-input-range@^1.3.0: autobind-decorator "^1.3.4" prop-types "^15.5.8" -react-intl@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.7.0.tgz#be1244769ce51f71476afb9556485a46090db5fa" - integrity sha512-H7Exnn+PwHCe4YlwBTSpfkSFb8+ex346b6NVaKtAXvTJr1Xnq2HvsEPpLjLfwBdt3/SS9dq4oAkY9/0g8Kj+ug== +react-intl@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-2.8.0.tgz#20b0c1f01d1292427768aa8ec9e51ab7e36503ba" + integrity sha512-1cSasNkHxZOXYYhms9Q1tSEWF8AWZQNq3nPLB/j8mYV0ZTSt2DhGQXHfKrKQMu4cgj9J1Crqg7xFPICTBgzqtQ== dependencies: hoist-non-react-statics "^2.5.5" intl-format-cache "^2.0.5" @@ -18287,6 +18384,15 @@ regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexp-tree@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.1.tgz#27b455f9b138ca2e84c090e9aff1ffe2a04d97fa" + integrity sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw== + dependencies: + cli-table3 "^0.5.0" + colors "^1.1.2" + yargs "^12.0.5" + regexpp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365" @@ -20474,6 +20580,13 @@ supports-color@^5.4.0, supports-color@^5.5.0: dependencies: has-flag "^3.0.0" +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + svgo@^0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" @@ -23529,6 +23642,14 @@ yargs-parser@^10.1.0: dependencies: camelcase "^4.1.0" +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" @@ -23625,6 +23746,24 @@ yargs@^12.0.1: y18n "^3.2.1 || ^4.0.0" yargs-parser "^10.1.0" +yargs@^12.0.5: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + yargs@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" From a6291afd7d42b380f7e08c0e1de5d65d735d890e Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 31 Jan 2019 13:11:27 +0000 Subject: [PATCH 28/40] [ML] Fixing data recognizer panel refresh on new job page (#29701) --- .../new_job/wizard/steps/job_type/job_type_controller.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js b/x-pack/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js index 56d8b9b2567ba..970107e474b8c 100644 --- a/x-pack/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js +++ b/x-pack/plugins/ml/public/jobs/new_job/wizard/steps/job_type/job_type_controller.js @@ -74,7 +74,12 @@ module.controller('MlNewJobStepJobType', $scope.indexPattern = indexPattern; $scope.savedSearch = savedSearch; - $scope.recognizerResults = { count: 0 }; + $scope.recognizerResults = { + count: 0, + onChange() { + $scope.$applyAsync(); + } + }; $scope.pageTitleLabel = (savedSearch.id !== undefined) ? i18n('xpack.ml.newJob.wizard.jobType.savedSearchPageTitleLabel', { From 779c9e1fd3688818551942fee65be1a8e43d9be2 Mon Sep 17 00:00:00 2001 From: Bill McConaghy Date: Thu, 31 Jan 2019 08:28:37 -0500 Subject: [PATCH 29/40] Update xpack console specs (#29506) * updating xpack console specs for _xpack namespace deprecation * fixing stray xpack * adding additional spec * fixing issues with stray _xpack --- .../spec/generated/ccr.follow.json | 2 +- .../spec/generated/ccr.follow_stats.json | 2 +- .../spec/generated/ccr.pause_follow.json | 2 +- .../spec/generated/ccr.resume_follow.json | 2 +- .../spec/generated/ccr.unfollow.json | 4 +-- .../spec/generated/ilm.remove_policy.json | 3 +- .../spec/generated/indices.freeze.json | 24 ++++++++++++++ .../spec/generated/indices.unfreeze.json | 24 ++++++++++++++ ...ck.ml.close_job.json => ml.close_job.json} | 4 +-- ...te_filter.json => ml.delete_calendar.json} | 4 +-- .../generated/ml.delete_calendar_event.json | 10 ++++++ .../generated/ml.delete_calendar_job.json | 10 ++++++ ..._datafeed.json => ml.delete_datafeed.json} | 4 +-- .../generated/ml.delete_expired_data.json | 10 ++++++ .../spec/generated/ml.delete_filter.json | 10 ++++++ .../spec/generated/ml.delete_forecast.json | 16 ++++++++++ ....ml.delete_job.json => ml.delete_job.json} | 7 +++-- ...hot.json => ml.delete_model_snapshot.json} | 4 +-- .../generated/ml.find_file_structure.json | 31 +++++++++++++++++++ ...ck.ml.flush_job.json => ml.flush_job.json} | 4 +-- ...pack.ml.forecast.json => ml.forecast.json} | 4 +-- ...l.get_buckets.json => ml.get_buckets.json} | 6 ++-- ...vents.json => ml.get_calendar_events.json} | 4 +-- ...t_calendars.json => ml.get_calendars.json} | 6 ++-- ...categories.json => ml.get_categories.json} | 6 ++-- ..._stats.json => ml.get_datafeed_stats.json} | 6 ++-- ...t_datafeeds.json => ml.get_datafeeds.json} | 6 ++-- ...l.get_filters.json => ml.get_filters.json} | 6 ++-- ...fluencers.json => ml.get_influencers.json} | 4 +-- ...t_job_stats.json => ml.get_job_stats.json} | 6 ++-- ...pack.ml.get_jobs.json => ml.get_jobs.json} | 6 ++-- ...shots.json => ml.get_model_snapshots.json} | 6 ++-- ...ckets.json => ml.get_overall_buckets.json} | 4 +-- ...l.get_records.json => ml.get_records.json} | 4 +-- .../{xpack.ml.info.json => ml.info.json} | 4 +-- ...pack.ml.open_job.json => ml.open_job.json} | 4 +-- .../generated/ml.post_calendar_events.json | 10 ++++++ ...ck.ml.post_data.json => ml.post_data.json} | 4 +-- ...datafeed.json => ml.preview_datafeed.json} | 4 +-- ...l.put_filter.json => ml.put_calendar.json} | 4 +-- .../spec/generated/ml.put_calendar_job.json | 10 ++++++ ...put_datafeed.json => ml.put_datafeed.json} | 4 +-- .../spec/generated/ml.put_filter.json | 10 ++++++ ...{xpack.ml.put_job.json => ml.put_job.json} | 4 +-- ...hot.json => ml.revert_model_snapshot.json} | 4 +-- .../spec/generated/ml.set_upgrade_mode.json | 15 +++++++++ ...t_datafeed.json => ml.start_datafeed.json} | 4 +-- ...op_datafeed.json => ml.stop_datafeed.json} | 4 +-- ..._datafeed.json => ml.update_datafeed.json} | 4 +-- .../spec/generated/ml.update_filter.json | 10 ++++++ ....ml.update_job.json => ml.update_job.json} | 4 +-- ...hot.json => ml.update_model_snapshot.json} | 4 +-- .../spec/generated/ml.upgrade.json | 14 +++++++++ .../spec/generated/ml.validate.json | 10 ++++++ .../spec/generated/ml.validate_detector.json | 10 ++++++ ...itoring.bulk.json => monitoring.bulk.json} | 6 ++-- .../security.get_user_privileges.json | 3 +- .../spec/generated/xpack.graph.explore.json | 4 +-- .../spec/generated/xpack.license.delete.json | 2 +- .../spec/generated/xpack.license.get.json | 2 +- .../xpack.license.get_basic_status.json | 2 +- .../xpack.license.get_trial_status.json | 2 +- .../spec/generated/xpack.license.post.json | 2 +- .../xpack.license.post_start_basic.json | 2 +- .../xpack.license.post_start_trial.json | 2 +- .../xpack.migration.deprecations.json | 4 +-- .../xpack.migration.get_assistance.json | 4 +-- .../generated/xpack.migration.upgrade.json | 2 +- .../generated/xpack.ml.delete_calendar.json | 10 ------ .../xpack.ml.delete_calendar_event.json | 10 ------ .../xpack.ml.delete_calendar_job.json | 10 ------ .../xpack.ml.delete_expired_data.json | 10 ------ .../xpack.ml.post_calendar_events.json | 10 ------ .../spec/generated/xpack.ml.put_calendar.json | 10 ------ .../generated/xpack.ml.put_calendar_job.json | 10 ------ .../spec/generated/xpack.ml.validate.json | 10 ------ .../generated/xpack.ml.validate_detector.json | 10 ------ .../generated/xpack.rollup.delete_job.json | 2 +- .../spec/generated/xpack.rollup.get_jobs.json | 4 +-- .../xpack.rollup.get_rollup_caps.json | 4 +-- .../xpack.rollup.get_rollup_index_caps.json | 10 ++++++ .../spec/generated/xpack.rollup.put_job.json | 2 +- .../generated/xpack.rollup.rollup_search.json | 4 +++ .../generated/xpack.rollup.start_job.json | 2 +- .../spec/generated/xpack.rollup.stop_job.json | 6 +++- .../xpack.security.authenticate.json | 11 ------- .../xpack.security.change_password.json | 20 ------------ .../xpack.security.clear_cached_realms.json | 14 --------- .../xpack.security.clear_cached_roles.json | 11 ------- .../generated/xpack.security.delete_role.json | 18 ----------- .../xpack.security.delete_role_mapping.json | 18 ----------- .../generated/xpack.security.delete_user.json | 18 ----------- .../xpack.security.disable_user.json | 19 ------------ .../generated/xpack.security.enable_user.json | 19 ------------ .../generated/xpack.security.get_role.json | 12 ------- .../xpack.security.get_role_mapping.json | 12 ------- .../generated/xpack.security.get_token.json | 11 ------- .../generated/xpack.security.get_user.json | 12 ------- .../xpack.security.invalidate_token.json | 11 ------- .../generated/xpack.security.put_role.json | 19 ------------ .../xpack.security.put_role_mapping.json | 19 ------------ .../generated/xpack.security.put_user.json | 19 ------------ .../generated/xpack.sql.clear_cursor.json | 2 +- .../spec/generated/xpack.sql.query.json | 2 +- .../spec/generated/xpack.sql.translate.json | 2 +- .../generated/xpack.watcher.ack_watch.json | 4 +-- .../xpack.watcher.activate_watch.json | 2 +- .../xpack.watcher.deactivate_watch.json | 2 +- .../generated/xpack.watcher.delete_watch.json | 2 +- .../xpack.watcher.execute_watch.json | 4 +-- .../generated/xpack.watcher.get_watch.json | 2 +- .../generated/xpack.watcher.put_watch.json | 2 +- .../spec/generated/xpack.watcher.start.json | 2 +- .../spec/generated/xpack.watcher.stats.json | 6 ++-- .../spec/generated/xpack.watcher.stop.json | 2 +- ...l.get_buckets.json => ml.get_buckets.json} | 2 +- ...vents.json => ml.get_calendar_events.json} | 2 +- ...t_calendars.json => ml.get_calendars.json} | 2 +- .../spec/overrides/ml.get_categories.json | 14 +++++++++ ...fluencers.json => ml.get_influencers.json} | 2 +- ...shots.json => ml.get_model_snapshots.json} | 2 +- ...ckets.json => ml.get_overall_buckets.json} | 2 +- ...l.get_records.json => ml.get_records.json} | 2 +- ...ents.json => ml.post_calendar_events.json} | 2 +- ...put_calendar.json => ml.put_calendar.json} | 2 +- ...put_datafeed.json => ml.put_datafeed.json} | 2 +- ...{xpack.ml.put_job.json => ml.put_job.json} | 2 +- ...hot.json => ml.revert_model_snapshot.json} | 2 +- ..._datafeed.json => ml.update_datafeed.json} | 2 +- ....ml.update_job.json => ml.update_job.json} | 2 +- ...hot.json => ml.update_model_snapshot.json} | 2 +- .../overrides/xpack.ml.get_categories.json | 18 ----------- .../spec/overrides/xpack.rollup.get_jobs.json | 7 ----- 133 files changed, 400 insertions(+), 519 deletions(-) create mode 100644 x-pack/plugins/console_extensions/spec/generated/indices.freeze.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/indices.unfreeze.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.close_job.json => ml.close_job.json} (78%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.delete_filter.json => ml.delete_calendar.json} (51%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_event.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_job.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.delete_datafeed.json => ml.delete_datafeed.json} (76%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.delete_expired_data.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.delete_filter.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.delete_forecast.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.delete_job.json => ml.delete_job.json} (61%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.delete_model_snapshot.json => ml.delete_model_snapshot.json} (61%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.find_file_structure.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.flush_job.json => ml.flush_job.json} (80%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.forecast.json => ml.forecast.json} (63%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_buckets.json => ml.get_buckets.json} (71%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_calendar_events.json => ml.get_calendar_events.json} (68%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_calendars.json => ml.get_calendars.json} (58%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_categories.json => ml.get_categories.json} (58%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_datafeed_stats.json => ml.get_datafeed_stats.json} (67%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_datafeeds.json => ml.get_datafeeds.json} (70%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_filters.json => ml.get_filters.json} (57%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_influencers.json => ml.get_influencers.json} (80%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_job_stats.json => ml.get_job_stats.json} (65%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_jobs.json => ml.get_jobs.json} (68%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_model_snapshots.json => ml.get_model_snapshots.json} (65%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_overall_buckets.json => ml.get_overall_buckets.json} (79%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.get_records.json => ml.get_records.json} (81%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.info.json => ml.info.json} (60%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.open_job.json => ml.open_job.json} (69%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.post_calendar_events.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.post_data.json => ml.post_data.json} (76%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.preview_datafeed.json => ml.preview_datafeed.json} (68%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.put_filter.json => ml.put_calendar.json} (51%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.put_calendar_job.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.put_datafeed.json => ml.put_datafeed.json} (71%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.put_filter.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.put_job.json => ml.put_job.json} (71%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.revert_model_snapshot.json => ml.revert_model_snapshot.json} (67%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.set_upgrade_mode.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.start_datafeed.json => ml.start_datafeed.json} (76%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.stop_datafeed.json => ml.stop_datafeed.json} (78%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.update_datafeed.json => ml.update_datafeed.json} (68%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.update_filter.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.update_job.json => ml.update_job.json} (68%) rename x-pack/plugins/console_extensions/spec/generated/{xpack.ml.update_model_snapshot.json => ml.update_model_snapshot.json} (59%) create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.upgrade.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.validate.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/ml.validate_detector.json rename x-pack/plugins/console_extensions/spec/generated/{xpack.monitoring.bulk.json => monitoring.bulk.json} (73%) delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_event.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_job.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_expired_data.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_calendar_events.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar_job.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate_detector.json create mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_index_caps.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.authenticate.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.change_password.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_realms.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_roles.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role_mapping.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_user.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.disable_user.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.enable_user.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role_mapping.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.get_token.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.get_user.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.invalidate_token.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role_mapping.json delete mode 100644 x-pack/plugins/console_extensions/spec/generated/xpack.security.put_user.json rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_buckets.json => ml.get_buckets.json} (92%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_calendar_events.json => ml.get_calendar_events.json} (69%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_calendars.json => ml.get_calendars.json} (72%) create mode 100644 x-pack/plugins/console_extensions/spec/overrides/ml.get_categories.json rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_influencers.json => ml.get_influencers.json} (90%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_model_snapshots.json => ml.get_model_snapshots.json} (82%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_overall_buckets.json => ml.get_overall_buckets.json} (88%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.get_records.json => ml.get_records.json} (91%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.post_calendar_events.json => ml.post_calendar_events.json} (64%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.put_calendar.json => ml.put_calendar.json} (71%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.put_datafeed.json => ml.put_datafeed.json} (90%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.put_job.json => ml.put_job.json} (94%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.revert_model_snapshot.json => ml.revert_model_snapshot.json} (75%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.update_datafeed.json => ml.update_datafeed.json} (89%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.update_job.json => ml.update_job.json} (93%) rename x-pack/plugins/console_extensions/spec/overrides/{xpack.ml.update_model_snapshot.json => ml.update_model_snapshot.json} (72%) delete mode 100644 x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_categories.json delete mode 100644 x-pack/plugins/console_extensions/spec/overrides/xpack.rollup.get_jobs.json diff --git a/x-pack/plugins/console_extensions/spec/generated/ccr.follow.json b/x-pack/plugins/console_extensions/spec/generated/ccr.follow.json index 704cb082161ae..ba993d25c60ec 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ccr.follow.json +++ b/x-pack/plugins/console_extensions/spec/generated/ccr.follow.json @@ -4,7 +4,7 @@ "PUT" ], "patterns": [ - "{index}/_ccr/follow" + "{indices}/_ccr/follow" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-put-follow.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ccr.follow_stats.json b/x-pack/plugins/console_extensions/spec/generated/ccr.follow_stats.json index 47553262c95d2..6d72e12df17d4 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ccr.follow_stats.json +++ b/x-pack/plugins/console_extensions/spec/generated/ccr.follow_stats.json @@ -4,7 +4,7 @@ "GET" ], "patterns": [ - "{index}/_ccr/stats" + "{indices}/_ccr/stats" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-get-follow-stats.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ccr.pause_follow.json b/x-pack/plugins/console_extensions/spec/generated/ccr.pause_follow.json index 4dcb0fdaf9b87..72afa796e1964 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ccr.pause_follow.json +++ b/x-pack/plugins/console_extensions/spec/generated/ccr.pause_follow.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "{index}/_ccr/pause_follow" + "{indices}/_ccr/pause_follow" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-pause-follow.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ccr.resume_follow.json b/x-pack/plugins/console_extensions/spec/generated/ccr.resume_follow.json index 00b889d0d5f9a..3710cdb8cc577 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ccr.resume_follow.json +++ b/x-pack/plugins/console_extensions/spec/generated/ccr.resume_follow.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "{index}/_ccr/resume_follow" + "{indices}/_ccr/resume_follow" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-resume-follow.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ccr.unfollow.json b/x-pack/plugins/console_extensions/spec/generated/ccr.unfollow.json index 9d9d6868a2fc9..92759d8222c63 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ccr.unfollow.json +++ b/x-pack/plugins/console_extensions/spec/generated/ccr.unfollow.json @@ -4,8 +4,8 @@ "POST" ], "patterns": [ - "{index}/_ccr/unfollow" + "{indices}/_ccr/unfollow" ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ccr-post-unfollow.html" + "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current" } } diff --git a/x-pack/plugins/console_extensions/spec/generated/ilm.remove_policy.json b/x-pack/plugins/console_extensions/spec/generated/ilm.remove_policy.json index fc835953c2c6d..5a3c760386f10 100644 --- a/x-pack/plugins/console_extensions/spec/generated/ilm.remove_policy.json +++ b/x-pack/plugins/console_extensions/spec/generated/ilm.remove_policy.json @@ -4,8 +4,7 @@ "POST" ], "patterns": [ - "{indices}/_ilm/remove", - "_ilm/remove" + "{indices}/_ilm/remove" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/ilm-remove-policy.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/indices.freeze.json b/x-pack/plugins/console_extensions/spec/generated/indices.freeze.json new file mode 100644 index 0000000000000..06e8c606f59f7 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/indices.freeze.json @@ -0,0 +1,24 @@ +{ + "indices.freeze": { + "url_params": { + "timeout": "", + "master_timeout": "", + "ignore_unavailable": "__flag__", + "allow_no_indices": "__flag__", + "expand_wildcards": [ + "open", + "closed", + "none", + "all" + ], + "wait_for_active_shards": "" + }, + "methods": [ + "POST" + ], + "patterns": [ + "{indices}/_freeze" + ], + "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/frozen.html" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/indices.unfreeze.json b/x-pack/plugins/console_extensions/spec/generated/indices.unfreeze.json new file mode 100644 index 0000000000000..186a671347240 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/indices.unfreeze.json @@ -0,0 +1,24 @@ +{ + "indices.unfreeze": { + "url_params": { + "timeout": "", + "master_timeout": "", + "ignore_unavailable": "__flag__", + "allow_no_indices": "__flag__", + "expand_wildcards": [ + "open", + "closed", + "none", + "all" + ], + "wait_for_active_shards": "" + }, + "methods": [ + "POST" + ], + "patterns": [ + "{indices}/_unfreeze" + ], + "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/frozen.html" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.close_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.close_job.json similarity index 78% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.close_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.close_job.json index 933f79a1028ed..310b0d125b1f9 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.close_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.close_job.json @@ -1,5 +1,5 @@ { - "xpack.ml.close_job": { + "ml.close_job": { "url_params": { "allow_no_jobs": "__flag__", "force": "__flag__", @@ -9,7 +9,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_close" + "_ml/anomaly_detectors/{job_id}/_close" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-close-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_filter.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar.json similarity index 51% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_filter.json rename to x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar.json index 5a4a8cd232448..97e5898072a08 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_filter.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar.json @@ -1,10 +1,10 @@ { - "xpack.ml.delete_filter": { + "ml.delete_calendar": { "methods": [ "DELETE" ], "patterns": [ - "_xpack/ml/filters/{filter_id}" + "_ml/calendars/{calendar_id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_event.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_event.json new file mode 100644 index 0000000000000..85ea5add0b60b --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_event.json @@ -0,0 +1,10 @@ +{ + "ml.delete_calendar_event": { + "methods": [ + "DELETE" + ], + "patterns": [ + "_ml/calendars/{calendar_id}/events/{event_id}" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_job.json new file mode 100644 index 0000000000000..6665f52eeb90d --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_calendar_job.json @@ -0,0 +1,10 @@ +{ + "ml.delete_calendar_job": { + "methods": [ + "DELETE" + ], + "patterns": [ + "_ml/calendars/{calendar_id}/jobs/{job_id}" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_datafeed.json similarity index 76% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.delete_datafeed.json index af1d5564cf9ca..7c7f3c40f23bb 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_datafeed.json @@ -1,5 +1,5 @@ { - "xpack.ml.delete_datafeed": { + "ml.delete_datafeed": { "url_params": { "force": "__flag__" }, @@ -7,7 +7,7 @@ "DELETE" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}" + "_ml/datafeeds/{datafeed_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.delete_expired_data.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_expired_data.json new file mode 100644 index 0000000000000..4afa9e323b030 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_expired_data.json @@ -0,0 +1,10 @@ +{ + "ml.delete_expired_data": { + "methods": [ + "DELETE" + ], + "patterns": [ + "_ml/_delete_expired_data" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.delete_filter.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_filter.json new file mode 100644 index 0000000000000..8210a2acd71d0 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_filter.json @@ -0,0 +1,10 @@ +{ + "ml.delete_filter": { + "methods": [ + "DELETE" + ], + "patterns": [ + "_ml/filters/{filter_id}" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.delete_forecast.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_forecast.json new file mode 100644 index 0000000000000..971a761cc77e9 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_forecast.json @@ -0,0 +1,16 @@ +{ + "ml.delete_forecast": { + "url_params": { + "allow_no_forecasts": "__flag__", + "timeout": "" + }, + "methods": [ + "DELETE" + ], + "patterns": [ + "_ml/anomaly_detectors/{job_id}/_forecast", + "_ml/anomaly_detectors/{job_id}/_forecast/{forecast_id}" + ], + "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-forecast.html" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_job.json similarity index 61% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.delete_job.json index 26c45ad0fc6fb..ab518071bf765 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_job.json @@ -1,13 +1,14 @@ { - "xpack.ml.delete_job": { + "ml.delete_job": { "url_params": { - "force": "__flag__" + "force": "__flag__", + "wait_for_completion": "__flag__" }, "methods": [ "DELETE" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}" + "_ml/anomaly_detectors/{job_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_model_snapshot.json b/x-pack/plugins/console_extensions/spec/generated/ml.delete_model_snapshot.json similarity index 61% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_model_snapshot.json rename to x-pack/plugins/console_extensions/spec/generated/ml.delete_model_snapshot.json index faf9da66f3bee..53d45bf0498ab 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_model_snapshot.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.delete_model_snapshot.json @@ -1,10 +1,10 @@ { - "xpack.ml.delete_model_snapshot": { + "ml.delete_model_snapshot": { "methods": [ "DELETE" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}" + "_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-delete-snapshot.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.find_file_structure.json b/x-pack/plugins/console_extensions/spec/generated/ml.find_file_structure.json new file mode 100644 index 0000000000000..93706ea628a28 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.find_file_structure.json @@ -0,0 +1,31 @@ +{ + "ml.find_file_structure": { + "url_params": { + "lines_to_sample": 0, + "timeout": "", + "charset": "", + "format": [ + "ndjson", + "xml", + "delimited", + "semi_structured_text" + ], + "has_header_row": "__flag__", + "column_names": [], + "delimiter": "", + "quote": "", + "should_trim_fields": "__flag__", + "grok_pattern": "", + "timestamp_field": "", + "timestamp_format": "", + "explain": "__flag__" + }, + "methods": [ + "POST" + ], + "patterns": [ + "_ml/find_file_structure" + ], + "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-file-structure.html" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.flush_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.flush_job.json similarity index 80% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.flush_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.flush_job.json index 190fa9813384e..2f496003a2834 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.flush_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.flush_job.json @@ -1,5 +1,5 @@ { - "xpack.ml.flush_job": { + "ml.flush_job": { "url_params": { "calc_interim": "__flag__", "start": "", @@ -11,7 +11,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_flush" + "_ml/anomaly_detectors/{job_id}/_flush" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-flush-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.forecast.json b/x-pack/plugins/console_extensions/spec/generated/ml.forecast.json similarity index 63% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.forecast.json rename to x-pack/plugins/console_extensions/spec/generated/ml.forecast.json index e96a5100e98dd..3a8849aad3e4d 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.forecast.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.forecast.json @@ -1,5 +1,5 @@ { - "xpack.ml.forecast": { + "ml.forecast": { "url_params": { "duration": "", "expires_in": "" @@ -8,7 +8,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_forecast" + "_ml/anomaly_detectors/{job_id}/_forecast" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_buckets.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_buckets.json similarity index 71% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_buckets.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_buckets.json index a63c47ab52429..2cbcb9d6155ec 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_buckets.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_buckets.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_buckets": { + "ml.get_buckets": { "url_params": { "expand": "__flag__", "exclude_interim": "__flag__", @@ -16,8 +16,8 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/buckets/{timestamp}", - "_xpack/ml/anomaly_detectors/{job_id}/results/buckets" + "_ml/anomaly_detectors/{job_id}/results/buckets/{timestamp}", + "_ml/anomaly_detectors/{job_id}/results/buckets" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-bucket.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendar_events.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_calendar_events.json similarity index 68% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendar_events.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_calendar_events.json index c6734d6cdc893..8999af6320dfa 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendar_events.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_calendar_events.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_calendar_events": { + "ml.get_calendar_events": { "url_params": { "job_id": "", "start": "", @@ -11,7 +11,7 @@ "GET" ], "patterns": [ - "_xpack/ml/calendars/{calendar_id}/events" + "_ml/calendars/{calendar_id}/events" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendars.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_calendars.json similarity index 58% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendars.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_calendars.json index 0b014b7f000e5..87f582b5c364d 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_calendars.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_calendars.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_calendars": { + "ml.get_calendars": { "url_params": { "from": 0, "size": 0 @@ -9,8 +9,8 @@ "POST" ], "patterns": [ - "_xpack/ml/calendars", - "_xpack/ml/calendars/{calendar_id}" + "_ml/calendars", + "_ml/calendars/{calendar_id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_categories.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_categories.json similarity index 58% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_categories.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_categories.json index 1157a0a375880..357a7b7fb0ccc 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_categories.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_categories.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_categories": { + "ml.get_categories": { "url_params": { "from": 0, "size": 0 @@ -9,8 +9,8 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/categories/{category_id}", - "_xpack/ml/anomaly_detectors/{job_id}/results/categories/" + "_ml/anomaly_detectors/{job_id}/results/categories/{category_id}", + "_ml/anomaly_detectors/{job_id}/results/categories/" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-category.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeed_stats.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_datafeed_stats.json similarity index 67% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeed_stats.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_datafeed_stats.json index 8b5613da5c935..5c300e444c794 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeed_stats.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_datafeed_stats.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_datafeed_stats": { + "ml.get_datafeed_stats": { "url_params": { "allow_no_datafeeds": "__flag__" }, @@ -7,8 +7,8 @@ "GET" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}/_stats", - "_xpack/ml/datafeeds/_stats" + "_ml/datafeeds/{datafeed_id}/_stats", + "_ml/datafeeds/_stats" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed-stats.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeeds.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_datafeeds.json similarity index 70% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeeds.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_datafeeds.json index 1f44b4aba572a..9979a685426be 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_datafeeds.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_datafeeds.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_datafeeds": { + "ml.get_datafeeds": { "url_params": { "allow_no_datafeeds": "__flag__" }, @@ -7,8 +7,8 @@ "GET" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}", - "_xpack/ml/datafeeds" + "_ml/datafeeds/{datafeed_id}", + "_ml/datafeeds" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_filters.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_filters.json similarity index 57% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_filters.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_filters.json index 0e33294934ba4..9b06e618a0b0c 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_filters.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_filters.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_filters": { + "ml.get_filters": { "url_params": { "from": 0, "size": 0 @@ -8,8 +8,8 @@ "GET" ], "patterns": [ - "_xpack/ml/filters", - "_xpack/ml/filters/{filter_id}" + "_ml/filters", + "_ml/filters/{filter_id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_influencers.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_influencers.json similarity index 80% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_influencers.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_influencers.json index a4a0a62a8fb5a..9471fac64d489 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_influencers.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_influencers.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_influencers": { + "ml.get_influencers": { "url_params": { "exclude_interim": "__flag__", "from": 0, @@ -15,7 +15,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/influencers" + "_ml/anomaly_detectors/{job_id}/results/influencers" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-influencer.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_job_stats.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_job_stats.json similarity index 65% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_job_stats.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_job_stats.json index 644c1a81eb7c5..b28a2655cbefe 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_job_stats.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_job_stats.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_job_stats": { + "ml.get_job_stats": { "url_params": { "allow_no_jobs": "__flag__" }, @@ -7,8 +7,8 @@ "GET" ], "patterns": [ - "_xpack/ml/anomaly_detectors/_stats", - "_xpack/ml/anomaly_detectors/{job_id}/_stats" + "_ml/anomaly_detectors/_stats", + "_ml/anomaly_detectors/{job_id}/_stats" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-job-stats.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_jobs.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_jobs.json similarity index 68% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_jobs.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_jobs.json index 2621d8b56c2ec..8f7de906578d7 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_jobs.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_jobs.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_jobs": { + "ml.get_jobs": { "url_params": { "allow_no_jobs": "__flag__" }, @@ -7,8 +7,8 @@ "GET" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}", - "_xpack/ml/anomaly_detectors" + "_ml/anomaly_detectors/{job_id}", + "_ml/anomaly_detectors" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_model_snapshots.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_model_snapshots.json similarity index 65% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_model_snapshots.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_model_snapshots.json index cf82bd258375f..a3b9702f4e4f0 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_model_snapshots.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_model_snapshots.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_model_snapshots": { + "ml.get_model_snapshots": { "url_params": { "from": 0, "size": 0, @@ -13,8 +13,8 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}", - "_xpack/ml/anomaly_detectors/{job_id}/model_snapshots" + "_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}", + "_ml/anomaly_detectors/{job_id}/model_snapshots" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-snapshot.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_overall_buckets.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_overall_buckets.json similarity index 79% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_overall_buckets.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_overall_buckets.json index ec6da8fb7a2a9..e89d63ae7f49f 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_overall_buckets.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_overall_buckets.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_overall_buckets": { + "ml.get_overall_buckets": { "url_params": { "top_n": 0, "bucket_span": "", @@ -14,7 +14,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/overall_buckets" + "_ml/anomaly_detectors/{job_id}/results/overall_buckets" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-overall-buckets.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_records.json b/x-pack/plugins/console_extensions/spec/generated/ml.get_records.json similarity index 81% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_records.json rename to x-pack/plugins/console_extensions/spec/generated/ml.get_records.json index e8159e97e1829..fd03c8d34214c 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.get_records.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.get_records.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_records": { + "ml.get_records": { "url_params": { "exclude_interim": "__flag__", "from": 0, @@ -15,7 +15,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/records" + "_ml/anomaly_detectors/{job_id}/results/records" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-get-record.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.info.json b/x-pack/plugins/console_extensions/spec/generated/ml.info.json similarity index 60% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.info.json rename to x-pack/plugins/console_extensions/spec/generated/ml.info.json index 6235f74cc6227..51b571776ead9 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.info.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.info.json @@ -1,10 +1,10 @@ { - "xpack.ml.info": { + "ml.info": { "methods": [ "GET" ], "patterns": [ - "_xpack/ml/info" + "_ml/info" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.open_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.open_job.json similarity index 69% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.open_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.open_job.json index d45214d813005..cd330ec4822c0 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.open_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.open_job.json @@ -1,10 +1,10 @@ { - "xpack.ml.open_job": { + "ml.open_job": { "methods": [ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_open" + "_ml/anomaly_detectors/{job_id}/_open" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-open-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.post_calendar_events.json b/x-pack/plugins/console_extensions/spec/generated/ml.post_calendar_events.json new file mode 100644 index 0000000000000..89ce2df63315b --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.post_calendar_events.json @@ -0,0 +1,10 @@ +{ + "ml.post_calendar_events": { + "methods": [ + "POST" + ], + "patterns": [ + "_ml/calendars/{calendar_id}/events" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_data.json b/x-pack/plugins/console_extensions/spec/generated/ml.post_data.json similarity index 76% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_data.json rename to x-pack/plugins/console_extensions/spec/generated/ml.post_data.json index 206d2e3e1c064..cc6f0b658e111 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_data.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.post_data.json @@ -1,5 +1,5 @@ { - "xpack.ml.post_data": { + "ml.post_data": { "url_params": { "reset_start": "", "reset_end": "" @@ -8,7 +8,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_data" + "_ml/anomaly_detectors/{job_id}/_data" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-post-data.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.preview_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.preview_datafeed.json similarity index 68% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.preview_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.preview_datafeed.json index 9aeca7e1363a0..be3c3d466f37d 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.preview_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.preview_datafeed.json @@ -1,10 +1,10 @@ { - "xpack.ml.preview_datafeed": { + "ml.preview_datafeed": { "methods": [ "GET" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}/_preview" + "_ml/datafeeds/{datafeed_id}/_preview" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-preview-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_filter.json b/x-pack/plugins/console_extensions/spec/generated/ml.put_calendar.json similarity index 51% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_filter.json rename to x-pack/plugins/console_extensions/spec/generated/ml.put_calendar.json index 2a2c5815046d4..7452d1b4b9707 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_filter.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.put_calendar.json @@ -1,10 +1,10 @@ { - "xpack.ml.put_filter": { + "ml.put_calendar": { "methods": [ "PUT" ], "patterns": [ - "_xpack/ml/filters/{filter_id}" + "_ml/calendars/{calendar_id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.put_calendar_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.put_calendar_job.json new file mode 100644 index 0000000000000..08dc3d77b5f25 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.put_calendar_job.json @@ -0,0 +1,10 @@ +{ + "ml.put_calendar_job": { + "methods": [ + "PUT" + ], + "patterns": [ + "_ml/calendars/{calendar_id}/jobs/{job_id}" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.put_datafeed.json similarity index 71% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.put_datafeed.json index db5cb27f4a790..a61f9ab465724 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.put_datafeed.json @@ -1,10 +1,10 @@ { - "xpack.ml.put_datafeed": { + "ml.put_datafeed": { "methods": [ "PUT" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}" + "_ml/datafeeds/{datafeed_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.put_filter.json b/x-pack/plugins/console_extensions/spec/generated/ml.put_filter.json new file mode 100644 index 0000000000000..6d57c433d71f4 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.put_filter.json @@ -0,0 +1,10 @@ +{ + "ml.put_filter": { + "methods": [ + "PUT" + ], + "patterns": [ + "_ml/filters/{filter_id}" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.put_job.json similarity index 71% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.put_job.json index ecd8f59d77574..d8e38a0bd4b9d 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.put_job.json @@ -1,10 +1,10 @@ { - "xpack.ml.put_job": { + "ml.put_job": { "methods": [ "PUT" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}" + "_ml/anomaly_detectors/{job_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-put-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.revert_model_snapshot.json b/x-pack/plugins/console_extensions/spec/generated/ml.revert_model_snapshot.json similarity index 67% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.revert_model_snapshot.json rename to x-pack/plugins/console_extensions/spec/generated/ml.revert_model_snapshot.json index 9193cbb80d2fd..7b6d74d47a711 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.revert_model_snapshot.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.revert_model_snapshot.json @@ -1,5 +1,5 @@ { - "xpack.ml.revert_model_snapshot": { + "ml.revert_model_snapshot": { "url_params": { "delete_intervening_results": "__flag__" }, @@ -7,7 +7,7 @@ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revert" + "_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revert" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-revert-snapshot.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.set_upgrade_mode.json b/x-pack/plugins/console_extensions/spec/generated/ml.set_upgrade_mode.json new file mode 100644 index 0000000000000..ad1734033d9a5 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.set_upgrade_mode.json @@ -0,0 +1,15 @@ +{ + "ml.set_upgrade_mode": { + "url_params": { + "enabled": "__flag__", + "timeout": "" + }, + "methods": [ + "POST" + ], + "patterns": [ + "_ml/set_upgrade_mode" + ], + "documentation": "TODO" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.start_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.start_datafeed.json similarity index 76% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.start_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.start_datafeed.json index 40479c8c3f687..8171a792d7e33 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.start_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.start_datafeed.json @@ -1,5 +1,5 @@ { - "xpack.ml.start_datafeed": { + "ml.start_datafeed": { "url_params": { "start": "", "end": "", @@ -9,7 +9,7 @@ "POST" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}/_start" + "_ml/datafeeds/{datafeed_id}/_start" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-start-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.stop_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.stop_datafeed.json similarity index 78% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.stop_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.stop_datafeed.json index 2af514532f16a..b10fed7010a7f 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.stop_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.stop_datafeed.json @@ -1,5 +1,5 @@ { - "xpack.ml.stop_datafeed": { + "ml.stop_datafeed": { "url_params": { "allow_no_datafeeds": "__flag__", "force": "__flag__", @@ -9,7 +9,7 @@ "POST" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}/_stop" + "_ml/datafeeds/{datafeed_id}/_stop" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-stop-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_datafeed.json b/x-pack/plugins/console_extensions/spec/generated/ml.update_datafeed.json similarity index 68% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_datafeed.json rename to x-pack/plugins/console_extensions/spec/generated/ml.update_datafeed.json index 953e08dd08c17..9c0d7502d2fbe 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.update_datafeed.json @@ -1,10 +1,10 @@ { - "xpack.ml.update_datafeed": { + "ml.update_datafeed": { "methods": [ "POST" ], "patterns": [ - "_xpack/ml/datafeeds/{datafeed_id}/_update" + "_ml/datafeeds/{datafeed_id}/_update" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-datafeed.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.update_filter.json b/x-pack/plugins/console_extensions/spec/generated/ml.update_filter.json new file mode 100644 index 0000000000000..3f48013c2be1c --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.update_filter.json @@ -0,0 +1,10 @@ +{ + "ml.update_filter": { + "methods": [ + "POST" + ], + "patterns": [ + "_ml/filters/{filter_id}/_update" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_job.json b/x-pack/plugins/console_extensions/spec/generated/ml.update_job.json similarity index 68% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_job.json rename to x-pack/plugins/console_extensions/spec/generated/ml.update_job.json index e3c8abf72d908..7276183b2e0c9 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.update_job.json @@ -1,10 +1,10 @@ { - "xpack.ml.update_job": { + "ml.update_job": { "methods": [ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/_update" + "_ml/anomaly_detectors/{job_id}/_update" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-job.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_model_snapshot.json b/x-pack/plugins/console_extensions/spec/generated/ml.update_model_snapshot.json similarity index 59% rename from x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_model_snapshot.json rename to x-pack/plugins/console_extensions/spec/generated/ml.update_model_snapshot.json index 848950d6f5394..80e533eb55826 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.update_model_snapshot.json +++ b/x-pack/plugins/console_extensions/spec/generated/ml.update_model_snapshot.json @@ -1,10 +1,10 @@ { - "xpack.ml.update_model_snapshot": { + "ml.update_model_snapshot": { "methods": [ "POST" ], "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_update" + "_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_update" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/ml-update-snapshot.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.upgrade.json b/x-pack/plugins/console_extensions/spec/generated/ml.upgrade.json new file mode 100644 index 0000000000000..4603b7d5a5e4d --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.upgrade.json @@ -0,0 +1,14 @@ +{ + "ml.upgrade": { + "url_params": { + "wait_for_completion": "__flag__" + }, + "methods": [ + "POST" + ], + "patterns": [ + "_ml/_upgrade" + ], + "documentation": "TODO" + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.validate.json b/x-pack/plugins/console_extensions/spec/generated/ml.validate.json new file mode 100644 index 0000000000000..298c7cf6dce26 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.validate.json @@ -0,0 +1,10 @@ +{ + "ml.validate": { + "methods": [ + "POST" + ], + "patterns": [ + "_ml/anomaly_detectors/_validate" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/ml.validate_detector.json b/x-pack/plugins/console_extensions/spec/generated/ml.validate_detector.json new file mode 100644 index 0000000000000..5e6d7daeea772 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/ml.validate_detector.json @@ -0,0 +1,10 @@ +{ + "ml.validate_detector": { + "methods": [ + "POST" + ], + "patterns": [ + "_ml/anomaly_detectors/_validate/detector" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.monitoring.bulk.json b/x-pack/plugins/console_extensions/spec/generated/monitoring.bulk.json similarity index 73% rename from x-pack/plugins/console_extensions/spec/generated/xpack.monitoring.bulk.json rename to x-pack/plugins/console_extensions/spec/generated/monitoring.bulk.json index f98aa70ce7cd3..7cb56a9d79d6e 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.monitoring.bulk.json +++ b/x-pack/plugins/console_extensions/spec/generated/monitoring.bulk.json @@ -1,5 +1,5 @@ { - "xpack.monitoring.bulk": { + "monitoring.bulk": { "url_params": { "system_id": "", "system_api_version": "", @@ -10,8 +10,8 @@ "PUT" ], "patterns": [ - "_xpack/monitoring/_bulk", - "_xpack/monitoring/{type}/_bulk" + "_monitoring/bulk", + "_monitoring/{type}/bulk" ], "documentation": "http://www.elastic.co/guide/en/monitoring/current/appendix-api-bulk.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/security.get_user_privileges.json b/x-pack/plugins/console_extensions/spec/generated/security.get_user_privileges.json index e5ada00828f73..1b939d2d9a29e 100644 --- a/x-pack/plugins/console_extensions/spec/generated/security.get_user_privileges.json +++ b/x-pack/plugins/console_extensions/spec/generated/security.get_user_privileges.json @@ -5,6 +5,7 @@ ], "patterns": [ "_security/user/_privileges" - ] + ], + "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-user-privileges.html" } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.graph.explore.json b/x-pack/plugins/console_extensions/spec/generated/xpack.graph.explore.json index f140af08686e2..b2a74408995d7 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.graph.explore.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.graph.explore.json @@ -9,8 +9,8 @@ "POST" ], "patterns": [ - "{indices}/_xpack/graph/_explore", - "{indices}/{type}/_xpack/graph/_explore" + "{indices}/_graph/explore", + "{indices}/{type}/_graph/explore" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/graph-explore-api.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.delete.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.delete.json index a60c3b8f70f5c..492a0403be62c 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.delete.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.delete.json @@ -4,7 +4,7 @@ "DELETE" ], "patterns": [ - "_xpack/license" + "_license" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get.json index f9ca4bc285ecb..ccd7d7eb77914 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get.json @@ -7,7 +7,7 @@ "GET" ], "patterns": [ - "_xpack/license" + "_license" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_basic_status.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_basic_status.json index c83cdd4a95a8d..5a5488208e218 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_basic_status.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_basic_status.json @@ -4,7 +4,7 @@ "GET" ], "patterns": [ - "_xpack/license/basic_status" + "_license/basic_status" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_trial_status.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_trial_status.json index cd79e6fdc2c1e..251d899febf53 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_trial_status.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.get_trial_status.json @@ -4,7 +4,7 @@ "GET" ], "patterns": [ - "_xpack/license/trial_status" + "_license/trial_status" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post.json index 6c5e2c65a56d6..79be105710904 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post.json @@ -8,7 +8,7 @@ "POST" ], "patterns": [ - "_xpack/license" + "_license" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_basic.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_basic.json index 27da929b25eab..fb858a65c2322 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_basic.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_basic.json @@ -7,7 +7,7 @@ "POST" ], "patterns": [ - "_xpack/license/start_basic" + "_license/start_basic" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_trial.json b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_trial.json index 905b8b324d5ef..bd3eaf476e022 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_trial.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.license.post_start_trial.json @@ -8,7 +8,7 @@ "POST" ], "patterns": [ - "_xpack/license/start_trial" + "_license/start_trial" ], "documentation": "https://www.elastic.co/guide/en/x-pack/current/license-management.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.deprecations.json b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.deprecations.json index d8dbea2c53d7a..dad2695f0d14c 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.deprecations.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.deprecations.json @@ -4,8 +4,8 @@ "GET" ], "patterns": [ - "_xpack/migration/deprecations", - "{indices}/_xpack/migration/deprecations" + "_migration/deprecations", + "{indices}/_migration/deprecations" ], "documentation": "http://www.elastic.co/guide/en/migration/current/migration-api-deprecation.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.get_assistance.json b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.get_assistance.json index dcd81df3770a2..4cc068ce2e460 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.get_assistance.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.get_assistance.json @@ -14,8 +14,8 @@ "GET" ], "patterns": [ - "_xpack/migration/assistance", - "_xpack/migration/assistance/{indices}" + "_migration/assistance", + "_migration/assistance/{indices}" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-assistance.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.upgrade.json b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.upgrade.json index 331a93f176320..93186f31a0876 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.migration.upgrade.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.migration.upgrade.json @@ -7,7 +7,7 @@ "POST" ], "patterns": [ - "_xpack/migration/upgrade/{indices}" + "_migration/upgrade/{indices}" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/migration-api-upgrade.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar.json deleted file mode 100644 index d5e47c1d78c7c..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.delete_calendar": { - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_event.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_event.json deleted file mode 100644 index 2be7a261b1d20..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_event.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.delete_calendar_event": { - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}/events/{event_id}" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_job.json deleted file mode 100644 index 7d3716f9ebfea..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_calendar_job.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.delete_calendar_job": { - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}/jobs/{job_id}" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_expired_data.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_expired_data.json deleted file mode 100644 index e8c04ff315731..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.delete_expired_data.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.delete_expired_data": { - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/ml/_delete_expired_data" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_calendar_events.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_calendar_events.json deleted file mode 100644 index ec580842f5120..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.post_calendar_events.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.post_calendar_events": { - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}/events" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar.json deleted file mode 100644 index 706373c53e852..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.put_calendar": { - "methods": [ - "PUT" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar_job.json deleted file mode 100644 index 98a4db0bf0e0e..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.put_calendar_job.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.put_calendar_job": { - "methods": [ - "PUT" - ], - "patterns": [ - "_xpack/ml/calendars/{calendar_id}/jobs/{job_id}" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate.json deleted file mode 100644 index 9af94e51db0f5..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.validate": { - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/ml/anomaly_detectors/_validate" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate_detector.json b/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate_detector.json deleted file mode 100644 index de0d19b09619a..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.ml.validate_detector.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "xpack.ml.validate_detector": { - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/ml/anomaly_detectors/_validate/detector" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.delete_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.delete_job.json index a7c381c2ee7f9..586ebd6ff6723 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.delete_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.delete_job.json @@ -4,7 +4,7 @@ "DELETE" ], "patterns": [ - "_xpack/rollup/job/{id}" + "_rollup/job/{id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_jobs.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_jobs.json index 54c535f3a81f7..657b68fc214b0 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_jobs.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_jobs.json @@ -4,8 +4,8 @@ "GET" ], "patterns": [ - "_xpack/rollup/job/{id}", - "_xpack/rollup/job/" + "_rollup/job/{id}", + "_rollup/job/" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_caps.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_caps.json index f619949e63be1..a8145f69eb50b 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_caps.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_caps.json @@ -4,8 +4,8 @@ "GET" ], "patterns": [ - "_xpack/rollup/data/{id}", - "_xpack/rollup/data/" + "_rollup/data/{id}", + "_rollup/data/" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_index_caps.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_index_caps.json new file mode 100644 index 0000000000000..e2f94ae5648ec --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.get_rollup_index_caps.json @@ -0,0 +1,10 @@ +{ + "xpack.rollup.get_rollup_index_caps": { + "methods": [ + "GET" + ], + "patterns": [ + "{indices}/_rollup/data" + ] + } +} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.put_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.put_job.json index d55fe948c450c..e36ec37c93b68 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.put_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.put_job.json @@ -4,7 +4,7 @@ "PUT" ], "patterns": [ - "_xpack/rollup/job/{id}" + "_rollup/job/{id}" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.rollup_search.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.rollup_search.json index 544d86249b40d..f6a8caff17201 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.rollup_search.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.rollup_search.json @@ -1,5 +1,9 @@ { "xpack.rollup.rollup_search": { + "url_params": { + "typed_keys": "__flag__", + "rest_total_hits_as_int": "__flag__" + }, "methods": [ "GET", "POST" diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.start_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.start_job.json index 7a1323f1f79b3..e7b1f48f8cdf5 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.start_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.start_job.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "_xpack/rollup/job/{id}/_start" + "_rollup/job/{id}/_start" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.stop_job.json b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.stop_job.json index e185077e35f16..58706694e2ff4 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.stop_job.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.rollup.stop_job.json @@ -1,10 +1,14 @@ { "xpack.rollup.stop_job": { + "url_params": { + "wait_for_completion": "__flag__", + "timeout": "" + }, "methods": [ "POST" ], "patterns": [ - "_xpack/rollup/job/{id}/_stop" + "_rollup/job/{id}/_stop" ] } } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.authenticate.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.authenticate.json deleted file mode 100644 index 6ebef7ce874d9..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.authenticate.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.security.authenticate": { - "methods": [ - "GET" - ], - "patterns": [ - "_xpack/security/_authenticate" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-authenticate.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.change_password.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.change_password.json deleted file mode 100644 index a811501e4d71f..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.change_password.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "xpack.security.change_password": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/user/{username}/_password", - "_xpack/security/user/_password" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-change-password.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_realms.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_realms.json deleted file mode 100644 index 2ef0bfaf79df1..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_realms.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "xpack.security.clear_cached_realms": { - "url_params": { - "usernames": [] - }, - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/security/realm/{realms}/_clear_cache" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-cache.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_roles.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_roles.json deleted file mode 100644 index 47baad3ef989f..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.clear_cached_roles.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.security.clear_cached_roles": { - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/security/role/{name}/_clear_cache" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-clear-role-cache.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role.json deleted file mode 100644 index ad95ac444ef98..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "xpack.security.delete_role": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/security/role/{name}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-role.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role_mapping.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role_mapping.json deleted file mode 100644 index 0734c784b80f8..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_role_mapping.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "xpack.security.delete_role_mapping": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/security/role_mapping/{name}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-role-mapping.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_user.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_user.json deleted file mode 100644 index 732721143503e..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.delete_user.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "xpack.security.delete_user": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/security/user/{username}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-delete-user.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.disable_user.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.disable_user.json deleted file mode 100644 index b9151cf3685a1..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.disable_user.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "xpack.security.disable_user": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/user/{username}/_disable" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-disable-user.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.enable_user.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.enable_user.json deleted file mode 100644 index 12d1b3c7cf0bb..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.enable_user.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "xpack.security.enable_user": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/user/{username}/_enable" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-enable-user.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role.json deleted file mode 100644 index e4b887e3d9329..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "xpack.security.get_role": { - "methods": [ - "GET" - ], - "patterns": [ - "_xpack/security/role/{name}", - "_xpack/security/role" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-role.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role_mapping.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role_mapping.json deleted file mode 100644 index 45c935277c865..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_role_mapping.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "xpack.security.get_role_mapping": { - "methods": [ - "GET" - ], - "patterns": [ - "_xpack/security/role_mapping/{name}", - "_xpack/security/role_mapping" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-role-mapping.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_token.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_token.json deleted file mode 100644 index 208d6e31346b7..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_token.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.security.get_token": { - "methods": [ - "POST" - ], - "patterns": [ - "_xpack/security/oauth2/token" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-token.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_user.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_user.json deleted file mode 100644 index d42d1afbb91c9..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.get_user.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "xpack.security.get_user": { - "methods": [ - "GET" - ], - "patterns": [ - "_xpack/security/user/{username}", - "_xpack/security/user" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-get-user.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.invalidate_token.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.invalidate_token.json deleted file mode 100644 index e9ffac7bd5f92..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.invalidate_token.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "xpack.security.invalidate_token": { - "methods": [ - "DELETE" - ], - "patterns": [ - "_xpack/security/oauth2/token" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-invalidate-token.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role.json deleted file mode 100644 index 6cc3523f8b647..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "xpack.security.put_role": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/role/{name}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-role.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role_mapping.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role_mapping.json deleted file mode 100644 index 7a426c420fffd..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_role_mapping.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "xpack.security.put_role_mapping": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/role_mapping/{name}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-role-mapping.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_user.json b/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_user.json deleted file mode 100644 index 19a13b37c7d91..0000000000000 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.security.put_user.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "xpack.security.put_user": { - "url_params": { - "refresh": [ - "true", - "false", - "wait_for" - ] - }, - "methods": [ - "PUT", - "POST" - ], - "patterns": [ - "_xpack/security/user/{username}" - ], - "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-user.html" - } -} diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.clear_cursor.json b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.clear_cursor.json index f1b357e909bd6..037df31e3277a 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.clear_cursor.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.clear_cursor.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "_xpack/sql/close" + "_sql/close" ], "documentation": "Clear SQL cursor" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.query.json b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.query.json index 20b8502f79bfc..6f1f9fda541a6 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.query.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.query.json @@ -8,7 +8,7 @@ "GET" ], "patterns": [ - "_xpack/sql" + "_sql" ], "documentation": "Execute SQL" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.translate.json b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.translate.json index 737a57f9f5ca6..32f49659194a1 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.sql.translate.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.sql.translate.json @@ -5,7 +5,7 @@ "GET" ], "patterns": [ - "_xpack/sql/translate" + "_sql/translate" ], "documentation": "Translate SQL into Elasticsearch queries" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.ack_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.ack_watch.json index 53edb6183e2d9..acda1c9e716dd 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.ack_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.ack_watch.json @@ -5,8 +5,8 @@ "POST" ], "patterns": [ - "_xpack/watcher/watch/{watch_id}/_ack", - "_xpack/watcher/watch/{watch_id}/_ack/{action_id}" + "_watcher/watch/{watch_id}/_ack", + "_watcher/watch/{watch_id}/_ack/{action_id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-ack-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.activate_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.activate_watch.json index 57a1804b8918d..d69d581f01195 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.activate_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.activate_watch.json @@ -5,7 +5,7 @@ "POST" ], "patterns": [ - "_xpack/watcher/watch/{watch_id}/_activate" + "_watcher/watch/{watch_id}/_activate" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-activate-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.deactivate_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.deactivate_watch.json index dd1bf97787855..2bc0ad6d9df21 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.deactivate_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.deactivate_watch.json @@ -5,7 +5,7 @@ "POST" ], "patterns": [ - "_xpack/watcher/watch/{watch_id}/_deactivate" + "_watcher/watch/{watch_id}/_deactivate" ], "documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-deactivate-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.delete_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.delete_watch.json index 555e76fb9de2e..5f4ca7c6d464a 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.delete_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.delete_watch.json @@ -4,7 +4,7 @@ "DELETE" ], "patterns": [ - "_xpack/watcher/watch/{id}" + "_watcher/watch/{id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-delete-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.execute_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.execute_watch.json index 2c64b9b842038..3697792424e26 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.execute_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.execute_watch.json @@ -8,8 +8,8 @@ "POST" ], "patterns": [ - "_xpack/watcher/watch/{id}/_execute", - "_xpack/watcher/watch/_execute" + "_watcher/watch/{id}/_execute", + "_watcher/watch/_execute" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-execute-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.get_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.get_watch.json index fc2a7d862fd9a..53aedbba8a5b4 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.get_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.get_watch.json @@ -4,7 +4,7 @@ "GET" ], "patterns": [ - "_xpack/watcher/watch/{id}" + "_watcher/watch/{id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-get-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.put_watch.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.put_watch.json index bc6951d058f74..ac24ba1599263 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.put_watch.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.put_watch.json @@ -9,7 +9,7 @@ "POST" ], "patterns": [ - "_xpack/watcher/watch/{id}" + "_watcher/watch/{id}" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-put-watch.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.start.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.start.json index 769b9e4e9c941..489965e741944 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.start.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.start.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "_xpack/watcher/_start" + "_watcher/_start" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-start.html" } diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stats.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stats.json index 1a1df49a44c74..429523ea5d2ec 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stats.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stats.json @@ -4,6 +4,7 @@ "metric": [ "_all", "queued_watches", + "current_watches", "pending_watches" ], "emit_stacktraces": "__flag__" @@ -12,12 +13,13 @@ "GET" ], "patterns": [ - "_xpack/watcher/stats", - "_xpack/watcher/stats/{metrics}" + "_watcher/stats", + "_watcher/stats/{metrics}" ], "url_components": { "metrics": [ "_all", + "current_watches", "pending_watches", "queued_watches" ] diff --git a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stop.json b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stop.json index 85e9c63158109..4e5b3f4c52dcf 100644 --- a/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stop.json +++ b/x-pack/plugins/console_extensions/spec/generated/xpack.watcher.stop.json @@ -4,7 +4,7 @@ "POST" ], "patterns": [ - "_xpack/watcher/_stop" + "_watcher/_stop" ], "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/current/watcher-api-stop.html" } diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_buckets.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_buckets.json similarity index 92% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_buckets.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_buckets.json index cfcb0270b9649..d920ea4db4e95 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_buckets.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_buckets.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_buckets": { + "ml.get_buckets": { "data_autocomplete_rules": { "desc": { "__one_of": ["true", "false"] }, "exclude_interim": { "__one_of": ["true", "false"] }, diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendar_events.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_calendar_events.json similarity index 69% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendar_events.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_calendar_events.json index 9af9354cccde3..e2ebea39a6bcf 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendar_events.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_calendar_events.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_calendar_events": { + "ml.get_calendar_events": { "data_autocomplete_rules": { "from": 0, "size": 100 diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendars.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_calendars.json similarity index 72% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendars.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_calendars.json index 146965574723e..fd961624b8afc 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_calendars.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_calendars.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_calendars": { + "ml.get_calendars": { "data_autocomplete_rules": { "from": 0, "size": 100 diff --git a/x-pack/plugins/console_extensions/spec/overrides/ml.get_categories.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_categories.json new file mode 100644 index 0000000000000..c32fb482ee4e4 --- /dev/null +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_categories.json @@ -0,0 +1,14 @@ +{ + "ml.get_categories": { + "data_autocomplete_rules": { + "page": { + "__template": { + "from": 0, + "size": 100 + }, + "from": 0, + "size": 100 + } + } + } +} diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_influencers.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_influencers.json similarity index 90% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_influencers.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_influencers.json index df1bc1487dd6b..4f31b3db1007c 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_influencers.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_influencers.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_influencers": { + "ml.get_influencers": { "data_autocomplete_rules": { "desc": { "__one_of": ["true", "false"] }, "exclude_interim": { "__one_of": ["true", "false"] }, diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_model_snapshots.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_model_snapshots.json similarity index 82% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_model_snapshots.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_model_snapshots.json index 1496851f0c7d9..02a86d39509f8 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_model_snapshots.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_model_snapshots.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_model_snapshots": { + "ml.get_model_snapshots": { "data_autocomplete_rules": { "desc": [true, false], "end": "", diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_overall_buckets.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_overall_buckets.json similarity index 88% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_overall_buckets.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_overall_buckets.json index cb41f5ef78aaa..312c44419ba90 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_overall_buckets.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_overall_buckets.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_overall_buckets": { + "ml.get_overall_buckets": { "data_autocomplete_rules": { "allow_no_jobs": { "__one_of": ["true", "false"] }, "bucket_span": "", diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_records.json b/x-pack/plugins/console_extensions/spec/overrides/ml.get_records.json similarity index 91% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_records.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.get_records.json index 16691960696b5..d68dabaeac367 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_records.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.get_records.json @@ -1,5 +1,5 @@ { - "xpack.ml.get_records": { + "ml.get_records": { "data_autocomplete_rules": { "desc": { "__one_of": ["true", "false"] }, "exclude_interim": { "__one_of": ["true", "false"] }, diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.post_calendar_events.json b/x-pack/plugins/console_extensions/spec/overrides/ml.post_calendar_events.json similarity index 64% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.post_calendar_events.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.post_calendar_events.json index 05e3e3697df3c..543a2758ff03a 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.post_calendar_events.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.post_calendar_events.json @@ -1,5 +1,5 @@ { - "xpack.ml.post_calendar_events": { + "ml.post_calendar_events": { "data_autocomplete_rules": { "events": [{}] } diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_calendar.json b/x-pack/plugins/console_extensions/spec/overrides/ml.put_calendar.json similarity index 71% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_calendar.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.put_calendar.json index d0ca83a2fd2af..9bfddb49f84c6 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_calendar.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.put_calendar.json @@ -1,5 +1,5 @@ { - "xpack.ml.put_calendar": { + "ml.put_calendar": { "data_autocomplete_rules": { "description": "" } diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_datafeed.json b/x-pack/plugins/console_extensions/spec/overrides/ml.put_datafeed.json similarity index 90% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_datafeed.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.put_datafeed.json index a3b50af4db036..bb42e485a621e 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.put_datafeed.json @@ -1,5 +1,5 @@ { - "xpack.ml.put_datafeed": { + "ml.put_datafeed": { "data_autocomplete_rules": { "aggregations": {}, "chunking_config": {}, diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_job.json b/x-pack/plugins/console_extensions/spec/overrides/ml.put_job.json similarity index 94% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_job.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.put_job.json index aee010691b964..ec62d7646aefc 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.put_job.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.put_job.json @@ -1,5 +1,5 @@ { - "xpack.ml.put_job": { + "ml.put_job": { "data_autocomplete_rules": { "analysis_config": {}, "background_persist_interval": "", diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.revert_model_snapshot.json b/x-pack/plugins/console_extensions/spec/overrides/ml.revert_model_snapshot.json similarity index 75% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.revert_model_snapshot.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.revert_model_snapshot.json index 806b326271bad..00f69cd0893f2 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.revert_model_snapshot.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.revert_model_snapshot.json @@ -1,5 +1,5 @@ { - "xpack.ml.revert_model_snapshot": { + "ml.revert_model_snapshot": { "data_autocomplete_rules": { "delete_intervening_results": { "__one_of": ["true", "false"] } } diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_datafeed.json b/x-pack/plugins/console_extensions/spec/overrides/ml.update_datafeed.json similarity index 89% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_datafeed.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.update_datafeed.json index f096707690eea..13616b23dbbbf 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_datafeed.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.update_datafeed.json @@ -1,5 +1,5 @@ { - "xpack.ml.update_datafeed": { + "ml.update_datafeed": { "data_autocomplete_rules": { "aggregations": {}, "chunking_config": {}, diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_job.json b/x-pack/plugins/console_extensions/spec/overrides/ml.update_job.json similarity index 93% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_job.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.update_job.json index 562fdef07c790..b95259c017a67 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_job.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.update_job.json @@ -1,5 +1,5 @@ { - "xpack.ml.update_job": { + "ml.update_job": { "data_autocomplete_rules": { "analysis_limits": {}, "background_persist_interval": "", diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_model_snapshot.json b/x-pack/plugins/console_extensions/spec/overrides/ml.update_model_snapshot.json similarity index 72% rename from x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_model_snapshot.json rename to x-pack/plugins/console_extensions/spec/overrides/ml.update_model_snapshot.json index bbf98c6ac05e7..c5cb3e0e90a63 100644 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.update_model_snapshot.json +++ b/x-pack/plugins/console_extensions/spec/overrides/ml.update_model_snapshot.json @@ -1,5 +1,5 @@ { - "xpack.ml.update_model_snapshot": { + "ml.update_model_snapshot": { "data_autocomplete_rules": { "description": "", "retain": [true, false] diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_categories.json b/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_categories.json deleted file mode 100644 index b3a46b02edefc..0000000000000 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.ml.get_categories.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "xpack.ml.get_categories": { - "data_autocomplete_rules": { - "page": { - "__template": { - "from": 0, - "size": 100 - }, - "from": 0, - "size": 100 - } - }, - "patterns": [ - "_xpack/ml/anomaly_detectors/{job_id}/results/categories/{category_id}", - "_xpack/ml/anomaly_detectors/{job_id}/results/categories" - ] - } -} diff --git a/x-pack/plugins/console_extensions/spec/overrides/xpack.rollup.get_jobs.json b/x-pack/plugins/console_extensions/spec/overrides/xpack.rollup.get_jobs.json deleted file mode 100644 index 06a89d35819f8..0000000000000 --- a/x-pack/plugins/console_extensions/spec/overrides/xpack.rollup.get_jobs.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "xpack.rollup.get_jobs": { - "patterns": [ - "_xpack/rollup/job/{id}" - ] - } -} From 6303731052f65ff1964d47188d04d49451c471af Mon Sep 17 00:00:00 2001 From: Nox911 Date: Thu, 31 Jan 2019 17:56:13 +0300 Subject: [PATCH 30/40] [i18n] Translate missed labels in src/ui folder (#29614) * Translate missed labels * Resolve review comment * Add missed translation --- .../public/ui_settings/ui_settings_service.ts | 6 +++++- src/ui/public/agg_types/buckets/terms.js | 17 ++++++++++++----- src/ui/public/agg_types/controls/ranges.html | 2 +- src/ui/public/notify/partials/toaster.html | 8 ++++++-- .../tool_bar_pager_text.html | 10 +++++++++- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/core/public/ui_settings/ui_settings_service.ts b/src/core/public/ui_settings/ui_settings_service.ts index 9d791b2e54f1b..131270adbb215 100644 --- a/src/core/public/ui_settings/ui_settings_service.ts +++ b/src/core/public/ui_settings/ui_settings_service.ts @@ -25,6 +25,8 @@ import { NotificationsStartContract } from '../notifications'; import { UiSettingsApi } from './ui_settings_api'; import { UiSettingsClient } from './ui_settings_client'; +import { i18n } from '@kbn/i18n'; + interface Deps { notifications: NotificationsStartContract; loadingCount: LoadingCountStartContract; @@ -47,7 +49,9 @@ export class UiSettingsService { api: this.uiSettingsApi, onUpdateError: error => { notifications.toasts.addDanger({ - title: 'Unable to update UI setting', + title: i18n.translate('core.uiSettings.unableUpdateUISettingNotificationMessageTitle', { + defaultMessage: 'Unable to update UI setting', + }), text: error.message, }); }, diff --git a/src/ui/public/agg_types/buckets/terms.js b/src/ui/public/agg_types/buckets/terms.js index 55e0625cec694..28bf458d03d32 100644 --- a/src/ui/public/agg_types/buckets/terms.js +++ b/src/ui/public/agg_types/buckets/terms.js @@ -108,10 +108,15 @@ export const termsBucketAgg = new BucketAggType({ const filterAgg = buildOtherBucketAgg(aggConfigs, aggConfig, resp); nestedSearchSource.setField('aggs', filterAgg); - const request = inspectorAdapters.requests.start('Other bucket', { - description: `This request counts the number of documents that fall - outside the criterion of the data buckets.` - }); + const request = inspectorAdapters.requests.start( + i18n.translate('common.ui.aggTypes.buckets.terms.otherBucketTitle', { defaultMessage: 'Other bucket' }), + { + description: i18n.translate('common.ui.aggTypes.buckets.terms.otherBucketDescription', { + defaultMessage: 'This request counts the number of documents that fall ' + + 'outside the criterion of the data buckets.' + }), + } + ); nestedSearchSource.getSearchRequestBody().then(body => { request.json(body); }); @@ -161,7 +166,9 @@ export const termsBucketAgg = new BucketAggType({ try { return agg.makeLabel(); } catch (e) { - return '- agg not valid -'; + return i18n.translate('common.ui.aggTypes.buckets.terms.aggNotValidLabel', { + defaultMessage: '- agg not valid -', + }); } }; diff --git a/src/ui/public/agg_types/controls/ranges.html b/src/ui/public/agg_types/controls/ranges.html index 4255c671628e1..e24b6f4378857 100644 --- a/src/ui/public/agg_types/controls/ranges.html +++ b/src/ui/public/agg_types/controls/ranges.html @@ -39,7 +39,7 @@
diff --git a/src/ui/public/pager_control/components/tool_bar_pager_text/tool_bar_pager_text.html b/src/ui/public/pager_control/components/tool_bar_pager_text/tool_bar_pager_text.html index b7e1014282199..72bbc3833630b 100644 --- a/src/ui/public/pager_control/components/tool_bar_pager_text/tool_bar_pager_text.html +++ b/src/ui/public/pager_control/components/tool_bar_pager_text/tool_bar_pager_text.html @@ -1,3 +1,11 @@
- {{ toolBarPagerText.startItem | number }}–{{ toolBarPagerText.endItem | number }} of {{ toolBarPagerText.totalItems | number }} +
\ No newline at end of file From caa31170d3e2161f952d66fa71f34da777630fc0 Mon Sep 17 00:00:00 2001 From: Nox911 Date: Thu, 31 Jan 2019 17:57:32 +0300 Subject: [PATCH 31/40] Translate filter editor (#29713) --- .../public/filter_editor/filter_editor.html | 75 ++++++++++++------- .../filter_editor/filter_field_select.html | 2 +- .../filter_editor/filter_operator_select.html | 2 +- .../filter_editor/lib/filter_operators.js | 34 +++++++-- .../filter_params_phrase_editor.html | 10 +-- .../filter_params_phrases_editor.html | 2 +- .../filter_params_range_editor.html | 10 +-- 7 files changed, 89 insertions(+), 46 deletions(-) diff --git a/src/ui/public/filter_editor/filter_editor.html b/src/ui/public/filter_editor/filter_editor.html index 0b69a1d5661d8..7070f6ac8e653 100644 --- a/src/ui/public/filter_editor/filter_editor.html +++ b/src/ui/public/filter_editor/filter_editor.html @@ -1,16 +1,22 @@
- Add - Edit - filter + +
@@ -18,9 +24,11 @@
@@ -87,7 +99,20 @@ >

- Filters are built using the Elasticsearch Query DSL. + + .

@@ -98,14 +123,14 @@ + i18n-id="common.ui.filterEditor.labelLabel" + i18n-default-message="Label" + >
- Cancel - + i18n-id="common.ui.filterEditor.cancelButtonLabel" + i18n-default-message="Cancel" + > + i18n-id="common.ui.filterEditor.saveButtonLabel" + i18n-default-message="Save" + >
diff --git a/src/ui/public/filter_editor/filter_field_select.html b/src/ui/public/filter_editor/filter_field_select.html index 65c45b1bae7b0..1aef71c2b0bb9 100644 --- a/src/ui/public/filter_editor/filter_field_select.html +++ b/src/ui/public/filter_editor/filter_field_select.html @@ -4,7 +4,7 @@ on-select="onSelect({ field: field })" uis-open-close="resetLimit()" > - + - + {{$select.selected.name}} diff --git a/src/ui/public/filter_editor/lib/filter_operators.js b/src/ui/public/filter_editor/lib/filter_operators.js index 140928eb1912d..a7a81aff3ddcf 100644 --- a/src/ui/public/filter_editor/lib/filter_operators.js +++ b/src/ui/public/filter_editor/lib/filter_operators.js @@ -19,48 +19,66 @@ import _ from 'lodash'; +import { i18n } from '@kbn/i18n'; + export const FILTER_OPERATORS = [ { - name: 'is', + name: i18n.translate('common.ui.filterEditor.operators.isLabel', { + defaultMessage: 'is' + }), type: 'phrase', negate: false, }, { - name: 'is not', + name: i18n.translate('common.ui.filterEditor.operators.isNotLabel', { + defaultMessage: 'is not' + }), type: 'phrase', negate: true, }, { - name: 'is one of', + name: i18n.translate('common.ui.filterEditor.operators.isOneOfLabel', { + defaultMessage: 'is one of' + }), type: 'phrases', negate: false, fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] }, { - name: 'is not one of', + name: i18n.translate('common.ui.filterEditor.operators.isNotOneOfLabel', { + defaultMessage: 'is not one of' + }), type: 'phrases', negate: true, fieldTypes: ['string', 'number', 'date', 'ip', 'geo_point', 'geo_shape'] }, { - name: 'is between', + name: i18n.translate('common.ui.filterEditor.operators.isBetweenLabel', { + defaultMessage: 'is between' + }), type: 'range', negate: false, fieldTypes: ['number', 'date', 'ip'], }, { - name: 'is not between', + name: i18n.translate('common.ui.filterEditor.operators.isNotBetweenLabel', { + defaultMessage: 'is not between' + }), type: 'range', negate: true, fieldTypes: ['number', 'date', 'ip'], }, { - name: 'exists', + name: i18n.translate('common.ui.filterEditor.operators.existsLabel', { + defaultMessage: 'exists' + }), type: 'exists', negate: false, }, { - name: 'does not exist', + name: i18n.translate('common.ui.filterEditor.operators.doesNotExistLabel', { + defaultMessage: 'does not exist' + }), type: 'exists', negate: true, }, diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html index 36d509f28dece..67d8acc8ed682 100644 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrase_editor.html @@ -5,7 +5,7 @@ spinner-enabled="true" spinner-class="kuiIcon kuiIcon--basic fa-spinner fa-spin" > - + - Accepted date formats - + i18n-id="common.ui.filterEditor.filterParamsPhraseEditor.acceptedDateFormatsLinkText" + i18n-default-message="Accepted date formats" + > diff --git a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html index 4a2935c4ba0b7..d2caea1066db1 100644 --- a/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html +++ b/src/ui/public/filter_editor/params_editor/filter_params_phrases_editor.html @@ -6,7 +6,7 @@ spinner-class="kuiIcon kuiIcon--basic fa-spinner fa-spin" > - Accepted date formats - + i18n-id="common.ui.filterEditor.filterParamsRangeEditor.acceptedDateFormatsLinkText" + i18n-default-message="Accepted date formats" + > From 7e9315a528a241a003fe692d9e26341f14d44435 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Thu, 31 Jan 2019 08:34:09 -0700 Subject: [PATCH 32/40] [Log UI] Flyout for Log Events (#28885) * Adding flyout to log viewer * Adding filtering * Fixing typescript errors * Adding a test for graphql; fixing test data for 7.0.0 * Adding terminate_after:1 to logItem request * fixing test data * Switching back to old data * Fixing data for tests * Adding i18n translations * changing label from add to set * Make flyout call more robust; fixing typings * Adding loading screen to flyout * Fixing linting errors * Update x-pack/plugins/infra/public/components/logging/log_flyout.tsx Co-Authored-By: simianhacker * Fixing visible mis-spelling * Fixing types * Change withLogFlyout to be conditional; Add icon instead of onClick for flyout * Adding dark mode support * Adding user-select:none to icon div * Removing remnants of a failed experiment * Adding aria-label to view details button * Fixing padding on date element * Removing unused variable that somehow got past the linters * Fixing empty_kibana * Fixing data for infra * Fixing merge weirdness --- .../public/components/logging/log_flyout.tsx | 114 ++++++++++++ .../log_text_stream/item_date_field.tsx | 1 + .../logging/log_text_stream/item_field.tsx | 2 +- .../log_text_stream/item_message_field.tsx | 1 - .../logging/log_text_stream/item_view.tsx | 4 +- .../log_text_stream/log_entry_item_view.tsx | 138 +++++++++----- .../scrollable_log_text_stream_view.tsx | 15 +- .../containers/logs/flyout_item.gql_query.ts | 23 +++ .../containers/logs/with_log_flyout.tsx | 60 ++++++ .../logs/with_log_flyout_options.tsx | 105 +++++++++++ .../containers/waffle/nodes_to_wafflemap.ts | 4 +- .../infra/public/graphql/introspection.json | 113 +++++++++++ x-pack/plugins/infra/public/graphql/types.ts | 60 ++++++ .../plugins/infra/public/pages/logs/logs.tsx | 32 +++- .../infra/public/pages/logs/page_content.tsx | 9 +- x-pack/plugins/infra/public/store/actions.ts | 1 + .../infra/public/store/local/actions.ts | 1 + .../public/store/local/log_flyout/actions.ts | 11 ++ .../public/store/local/log_flyout/index.ts | 11 ++ .../public/store/local/log_flyout/reducer.ts | 39 ++++ .../public/store/local/log_flyout/selector.ts | 10 + .../infra/public/store/local/reducer.ts | 4 + .../infra/public/store/local/selectors.ts | 6 + .../plugins/infra/public/store/selectors.ts | 2 + .../server/graphql/log_entries/resolvers.ts | 9 + .../server/graphql/log_entries/schema.gql.ts | 17 ++ x-pack/plugins/infra/server/graphql/types.ts | 79 ++++++++ .../log_entries/kibana_log_entries_adapter.ts | 37 ++++ ...document_source_to_log_item_fields.test.ts | 67 +++++++ ...vert_document_source_to_log_item_fields.ts | 36 ++++ .../log_entries_domain/log_entries_domain.ts | 35 ++++ .../test/api_integration/apis/infra/index.js | 1 + .../api_integration/apis/infra/log_item.ts | 175 ++++++++++++++++++ .../es_archives/empty_kibana/data.json.gz | Bin 218 -> 231 bytes .../logs_without_epoch_millis/data.json.gz | Bin 473 -> 484 bytes .../logs_without_epoch_millis/mappings.json | 2 +- .../infra/metrics_and_logs/data.json.gz | Bin 2682891 -> 3004417 bytes .../infra/metrics_and_logs/mappings.json | 2 +- 38 files changed, 1170 insertions(+), 56 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/logging/log_flyout.tsx create mode 100644 x-pack/plugins/infra/public/containers/logs/flyout_item.gql_query.ts create mode 100644 x-pack/plugins/infra/public/containers/logs/with_log_flyout.tsx create mode 100644 x-pack/plugins/infra/public/containers/logs/with_log_flyout_options.tsx create mode 100644 x-pack/plugins/infra/public/store/local/log_flyout/actions.ts create mode 100644 x-pack/plugins/infra/public/store/local/log_flyout/index.ts create mode 100644 x-pack/plugins/infra/public/store/local/log_flyout/reducer.ts create mode 100644 x-pack/plugins/infra/public/store/local/log_flyout/selector.ts create mode 100644 x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts create mode 100644 x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts create mode 100644 x-pack/test/api_integration/apis/infra/log_item.ts diff --git a/x-pack/plugins/infra/public/components/logging/log_flyout.tsx b/x-pack/plugins/infra/public/components/logging/log_flyout.tsx new file mode 100644 index 0000000000000..7c277dd78ba78 --- /dev/null +++ b/x-pack/plugins/infra/public/components/logging/log_flyout.tsx @@ -0,0 +1,114 @@ +/* + * 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 { + EuiBasicTable, + EuiButtonIcon, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutHeader, + EuiTitle, + EuiToolTip, +} from '@elastic/eui'; +import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react'; +import React from 'react'; +import styled from 'styled-components'; +import { InfraLogItem, InfraLogItemField } from '../../graphql/types'; +import { InfraLoadingPanel } from '../loading'; +interface Props { + flyoutItem: InfraLogItem | null; + hideFlyout: () => void; + setFilter: (filter: string) => void; + intl: InjectedIntl; + loading: boolean; +} + +export const LogFlyout = injectI18n( + ({ flyoutItem, loading, hideFlyout, setFilter, intl }: Props) => { + const handleFilter = (field: InfraLogItemField) => () => { + const filter = `${field.field}:"${field.value}"`; + setFilter(filter); + }; + + const columns = [ + { + field: 'field', + name: intl.formatMessage({ + defaultMessage: 'Field', + id: 'xpack.infra.logFlyout.fieldColumnLabel', + }), + sortable: true, + }, + { + field: 'value', + name: intl.formatMessage({ + defaultMessage: 'Value', + id: 'xpack.infra.logFlyout.valueColumnLabel', + }), + sortable: true, + render: (name: string, item: InfraLogItemField) => ( + + + + + {item.value} + + ), + }, + ]; + return ( + hideFlyout()} size="m"> + + +

+ +

+
+
+ + {loading || flyoutItem === null ? ( + + + + ) : ( + + )} + +
+ ); + } +); + +export const InfraFlyoutLoadingPanel = styled.div` + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +`; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_date_field.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_date_field.tsx index f75056e23aef0..8550033e471c6 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_date_field.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_date_field.tsx @@ -64,6 +64,7 @@ const LogTextStreamItemDateFieldWrapper = LogTextStreamItemField.extend.attrs<{ border-right: solid 2px ${props => props.theme.eui.euiColorLightShade}; color: ${props => props.theme.eui.euiColorDarkShade}; white-space: pre; + padding: 0 ${props => props.theme.eui.paddingSizes.l}; ${props => (props.hasHighlights ? highlightedFieldStyle : '')}; ${props => (props.isHovered ? hoveredFieldStyle : '')}; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_field.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_field.tsx index c9d360fc116a7..4b6dcdb635ad9 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_field.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_field.tsx @@ -19,5 +19,5 @@ export const LogTextStreamItemField = styled.div.attrs<{ [switchProp.default]: props.theme.eui.euiFontSize, })}; line-height: ${props => props.theme.eui.euiLineHeight}; - padding: 2px ${props => props.theme.eui.euiSize}; + padding: 2px ${props => props.theme.eui.euiSize} 2px 0; `; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_message_field.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_message_field.tsx index 77ef813261818..39f75d5b7ab64 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_message_field.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_message_field.tsx @@ -105,7 +105,6 @@ const LogTextStreamItemMessageFieldWrapper = LogTextStreamItemField.extend.attrs const HighlightSpan = styled.span` display: inline-block; - padding: 0 ${props => props.theme.eui.euiSizeXs}; background-color: ${props => props.theme.eui.euiColorSecondary}; color: ${props => props.theme.eui.euiColorGhost}; font-weight: ${props => props.theme.eui.euiFontWeightMedium}; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_view.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_view.tsx index c4a75771fa5a0..055b92250b0f8 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/item_view.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/item_view.tsx @@ -14,10 +14,11 @@ interface StreamItemProps { item: StreamItem; scale: TextScale; wrap: boolean; + openFlyoutWithItem: (id: string) => void; } export const LogTextStreamItemView = React.forwardRef( - ({ item, scale, wrap }, ref) => { + ({ item, scale, wrap, openFlyoutWithItem }, ref) => { switch (item.kind) { case 'logEntry': return ( @@ -27,6 +28,7 @@ export const LogTextStreamItemView = React.forwardRef( searchResult={item.searchResult} scale={scale} wrap={wrap} + openFlyoutWithItem={openFlyoutWithItem} /> ); } diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_item_view.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_item_view.tsx index 2e910cad56785..fb8642c3bd680 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_item_view.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/log_entry_item_view.tsx @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ +import { darken, transparentize } from 'polished'; import * as React from 'react'; import styled from 'styled-components'; +import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; +import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; import { LogEntry } from '../../../../common/log_entry'; import { SearchResult } from '../../../../common/log_search_result'; import { TextScale } from '../../../../common/log_text_scale'; @@ -20,65 +23,110 @@ interface LogTextStreamLogEntryItemViewProps { searchResult?: SearchResult; scale: TextScale; wrap: boolean; + openFlyoutWithItem: (id: string) => void; + intl: InjectedIntl; } interface LogTextStreamLogEntryItemViewState { isHovered: boolean; } -export class LogTextStreamLogEntryItemView extends React.PureComponent< - LogTextStreamLogEntryItemViewProps, - LogTextStreamLogEntryItemViewState -> { - public readonly state = { - isHovered: false, - }; +export const LogTextStreamLogEntryItemView = injectI18n( + class extends React.PureComponent< + LogTextStreamLogEntryItemViewProps, + LogTextStreamLogEntryItemViewState + > { + public readonly state = { + isHovered: false, + }; - public handleMouseEnter: React.MouseEventHandler = () => { - this.setState({ - isHovered: true, - }); - }; + public handleMouseEnter: React.MouseEventHandler = () => { + this.setState({ + isHovered: true, + }); + }; - public handleMouseLeave: React.MouseEventHandler = () => { - this.setState({ - isHovered: false, - }); - }; + public handleMouseLeave: React.MouseEventHandler = () => { + this.setState({ + isHovered: false, + }); + }; - public render() { - const { boundingBoxRef, logEntry, scale, searchResult, wrap } = this.props; - const { isHovered } = this.state; + public handleClick: React.MouseEventHandler = () => { + this.props.openFlyoutWithItem(this.props.logEntry.gid); + }; - return ( - - - {formatTime(logEntry.fields.time)} - - - {logEntry.fields.message} - - - ); + + {formatTime(logEntry.fields.time)} + + + {isHovered ? ( + + + + ) : ( + + )} + + + {logEntry.fields.message} + + + ); + } } +); + +interface IconProps { + isHovered: boolean; } +const EmptyIcon = styled.div` + width: 24px; +`; + +const LogTextStreamIconDiv = styled('div')` + flex-grow: 0; + background-color: ${props => + props.isHovered + ? props.theme.darkMode + ? transparentize(0.9, darken(0.05, props.theme.eui.euiColorHighlight)) + : darken(0.05, props.theme.eui.euiColorHighlight) + : 'transparent'}; + text-align: center; + user-select: none; +`; + const LogTextStreamLogEntryItemDiv = styled.div` font-family: ${props => props.theme.eui.euiCodeFontFamily}; font-size: ${props => props.theme.eui.euiFontSize}; diff --git a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx b/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx index eb74ffcc29394..47db7a6716de8 100644 --- a/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_text_stream/scrollable_log_text_stream_view.tsx @@ -42,6 +42,8 @@ interface ScrollableLogTextStreamViewProps { } ) => any; loadNewerItems: () => void; + setFlyoutItem: (id: string) => void; + showFlyout: () => void; } interface ScrollableLogTextStreamViewState { @@ -141,7 +143,13 @@ export class ScrollableLogTextStreamView extends React.PureComponent< key={getStreamItemId(item)} > {measureRef => ( - + )} ))} @@ -160,6 +168,11 @@ export class ScrollableLogTextStreamView extends React.PureComponent< } } + private handleOpenFlyout = (id: string) => { + this.props.setFlyoutItem(id); + this.props.showFlyout(); + }; + private handleReload = () => { const { jumpToTarget, target } = this.props; diff --git a/x-pack/plugins/infra/public/containers/logs/flyout_item.gql_query.ts b/x-pack/plugins/infra/public/containers/logs/flyout_item.gql_query.ts new file mode 100644 index 0000000000000..56b63a54b1126 --- /dev/null +++ b/x-pack/plugins/infra/public/containers/logs/flyout_item.gql_query.ts @@ -0,0 +1,23 @@ +/* + * 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 gql from 'graphql-tag'; + +export const flyoutItemQuery = gql` + query FlyoutItemQuery($sourceId: ID!, $itemId: ID!) { + source(id: $sourceId) { + id + logItem(id: $itemId) { + id + index + fields { + field + value + } + } + } + } +`; diff --git a/x-pack/plugins/infra/public/containers/logs/with_log_flyout.tsx b/x-pack/plugins/infra/public/containers/logs/with_log_flyout.tsx new file mode 100644 index 0000000000000..71c0a330fcb97 --- /dev/null +++ b/x-pack/plugins/infra/public/containers/logs/with_log_flyout.tsx @@ -0,0 +1,60 @@ +/* + * 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 { Query } from 'react-apollo'; +import { FlyoutItemQuery, InfraLogItem } from '../../graphql/types'; +import { FlyoutVisibility } from '../../store/local/log_flyout'; +import { WithOptions } from '../with_options'; +import { flyoutItemQuery } from './flyout_item.gql_query'; +import { WithFlyoutOptions } from './with_log_flyout_options'; + +interface WithFlyoutArgs { + flyoutItem: InfraLogItem | null; + setFlyoutItem: (id: string) => void; + showFlyout: () => void; + hideFlyout: () => void; + error?: string | undefined; + loading: boolean; +} + +interface WithFlyoutProps { + children: (args: WithFlyoutArgs) => React.ReactNode; +} + +export const WithLogFlyout = ({ children }: WithFlyoutProps) => { + return ( + + {({ sourceId }) => ( + + {({ showFlyout, hideFlyout, setFlyoutItem, flyoutId, flyoutVisibility }) => + flyoutVisibility === FlyoutVisibility.visible ? ( + + query={flyoutItemQuery} + fetchPolicy="no-cache" + variables={{ + itemId: (flyoutId != null && flyoutId) || '', + sourceId, + }} + > + {({ data, error, loading }) => { + return children({ + showFlyout, + hideFlyout, + setFlyoutItem, + flyoutItem: (data && data.source && data.source.logItem) || null, + error: error && error.message, + loading, + }); + }} + + ) : null + } + + )} + + ); +}; diff --git a/x-pack/plugins/infra/public/containers/logs/with_log_flyout_options.tsx b/x-pack/plugins/infra/public/containers/logs/with_log_flyout_options.tsx new file mode 100644 index 0000000000000..13e011cda876b --- /dev/null +++ b/x-pack/plugins/infra/public/containers/logs/with_log_flyout_options.tsx @@ -0,0 +1,105 @@ +/* + * 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 { connect } from 'react-redux'; +import { createSelector } from 'reselect'; + +import { isString } from 'lodash'; +import { flyoutOptionsActions, flyoutOptionsSelectors, State } from '../../store'; +import { FlyoutVisibility } from '../../store/local/log_flyout'; +import { asChildFunctionRenderer } from '../../utils/typed_react'; +import { bindPlainActionCreators } from '../../utils/typed_redux'; +import { UrlStateContainer } from '../../utils/url_state'; + +const selectOptionsUrlState = createSelector( + flyoutOptionsSelectors.selectFlyoutId, + flyoutOptionsSelectors.selectFlyoutVisibility, + (flyoutId, flyoutVisibility) => ({ + flyoutVisibility, + flyoutId, + }) +); + +export const withFlyoutOptions = connect( + (state: State) => ({ + flyoutVisibility: flyoutOptionsSelectors.selectFlyoutVisibility(state), + flyoutId: flyoutOptionsSelectors.selectFlyoutId(state), + urlState: selectOptionsUrlState(state), + }), + bindPlainActionCreators({ + setFlyoutItem: flyoutOptionsActions.setFlyoutItem, + showFlyout: flyoutOptionsActions.showFlyout, + hideFlyout: flyoutOptionsActions.hideFlyout, + }) +); + +export const WithFlyoutOptions = asChildFunctionRenderer(withFlyoutOptions); + +/** + * Url State + */ + +interface FlyoutOptionsUrlState { + flyoutId?: ReturnType; + flyoutVisibility?: ReturnType; +} + +export const WithFlyoutOptionsUrlState = () => ( + + {({ setFlyoutItem, showFlyout, hideFlyout, urlState }) => ( + { + if (newUrlState && newUrlState.flyoutId) { + setFlyoutItem(newUrlState.flyoutId); + } + if (newUrlState && newUrlState.flyoutVisibility === FlyoutVisibility.visible) { + showFlyout(); + } + if (newUrlState && newUrlState.flyoutVisibility === FlyoutVisibility.hidden) { + hideFlyout(); + } + }} + onInitialize={initialUrlState => { + if (initialUrlState && initialUrlState.flyoutId) { + setFlyoutItem(initialUrlState.flyoutId); + } + if (initialUrlState && initialUrlState.flyoutVisibility === FlyoutVisibility.visible) { + showFlyout(); + } + if (initialUrlState && initialUrlState.flyoutVisibility === FlyoutVisibility.hidden) { + hideFlyout(); + } + }} + /> + )} + +); + +const mapToUrlState = (value: any): FlyoutOptionsUrlState | undefined => + value + ? { + flyoutId: mapToFlyoutIdState(value.flyoutId), + flyoutVisibility: mapToFlyoutVisibilityState(value.flyoutVisibility), + } + : undefined; + +const mapToFlyoutIdState = (subject: any) => { + return subject && isString(subject) ? subject : undefined; +}; +const mapToFlyoutVisibilityState = (subject: any) => { + if (subject) { + if (subject === 'visible') { + return FlyoutVisibility.visible; + } + if (subject === 'hidden') { + return FlyoutVisibility.hidden; + } + } +}; diff --git a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts b/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts index 59a015d6d5ca3..ad623aa756770 100644 --- a/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts +++ b/x-pack/plugins/infra/public/containers/waffle/nodes_to_wafflemap.ts @@ -40,11 +40,11 @@ function findOrCreateGroupWithNodes( } } } + const lastPath = last(path); const existingGroup = groups.find(g => g.id === id); if (isWaffleMapGroupWithNodes(existingGroup)) { return existingGroup; } - const lastPath = last(path); return { id, name: @@ -65,11 +65,11 @@ function findOrCreateGroupWithGroups( path: InfraNodePath[] ): InfraWaffleMapGroupOfGroups { const id = path.length === 0 ? '__all__' : createId(path); + const lastPath = last(path); const existingGroup = groups.find(g => g.id === id); if (isWaffleMapGroupWithGroups(existingGroup)) { return existingGroup; } - const lastPath = last(path); return { id, name: diff --git a/x-pack/plugins/infra/public/graphql/introspection.json b/x-pack/plugins/infra/public/graphql/introspection.json index 5fad4b5cdc2b6..db057cc7f286e 100644 --- a/x-pack/plugins/infra/public/graphql/introspection.json +++ b/x-pack/plugins/infra/public/graphql/introspection.json @@ -299,6 +299,29 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "logItem", + "description": "", + "args": [ + { + "name": "id", + "description": "", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "ID", "ofType": null } + }, + "defaultValue": null + } + ], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "OBJECT", "name": "InfraLogItem", "ofType": null } + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "map", "description": "A hierarchy of hosts, pods, containers, services or arbitrary groups", @@ -1310,6 +1333,96 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "InfraLogItem", + "description": "", + "fields": [ + { + "name": "id", + "description": "The ID of the document", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "ID", "ofType": null } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "index", + "description": "The index where the document was found", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "fields", + "description": "An array of flattened fields and values", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "OBJECT", "name": "InfraLogItemField", "ofType": null } + } + } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "InfraLogItemField", + "description": "", + "fields": [ + { + "name": "field", + "description": "The flattened field name", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "value", + "description": "The value for the Field as a string", + "args": [], + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { "kind": "SCALAR", "name": "String", "ofType": null } + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "InfraTimerangeInput", diff --git a/x-pack/plugins/infra/public/graphql/types.ts b/x-pack/plugins/infra/public/graphql/types.ts index ce622a3283304..7143afe44257e 100644 --- a/x-pack/plugins/infra/public/graphql/types.ts +++ b/x-pack/plugins/infra/public/graphql/types.ts @@ -34,6 +34,8 @@ export interface InfraSource { logEntriesBetween: InfraLogEntryInterval; /** A consecutive span of summary buckets within an interval */ logSummaryBetween: InfraLogSummaryInterval; + + logItem: InfraLogItem; /** A hierarchy of hosts, pods, containers, services or arbitrary groups */ map?: InfraResponse | null; @@ -177,6 +179,22 @@ export interface InfraLogSummaryBucket { entriesCount: number; } +export interface InfraLogItem { + /** The ID of the document */ + id: string; + /** The index where the document was found */ + index: string; + /** An array of flattened fields and values */ + fields: InfraLogItemField[]; +} + +export interface InfraLogItemField { + /** The flattened field name */ + field: string; + /** The value for the Field as a string */ + value: string; +} + export interface InfraResponse { nodes: InfraNode[]; } @@ -395,6 +413,9 @@ export interface LogSummaryBetweenInfraSourceArgs { /** The query to filter the log entries by */ filterQuery?: string | null; } +export interface LogItemInfraSourceArgs { + id: string; +} export interface MapInfraSourceArgs { timerange: InfraTimerangeInput; @@ -522,6 +543,45 @@ export type InfraLogMessageSegment = InfraLogMessageFieldSegment | InfraLogMessa // Documents // ==================================================== +export namespace FlyoutItemQuery { + export type Variables = { + sourceId: string; + itemId: string; + }; + + export type Query = { + __typename?: 'Query'; + + source: Source; + }; + + export type Source = { + __typename?: 'InfraSource'; + + id: string; + + logItem: LogItem; + }; + + export type LogItem = { + __typename?: 'InfraLogItem'; + + id: string; + + index: string; + + fields: Fields[]; + }; + + export type Fields = { + __typename?: 'InfraLogItemField'; + + field: string; + + value: string; + }; +} + export namespace MetadataQuery { export type Variables = { sourceId: string; diff --git a/x-pack/plugins/infra/public/pages/logs/logs.tsx b/x-pack/plugins/infra/public/pages/logs/logs.tsx index 1b45d05de2842..11c0a7f038111 100644 --- a/x-pack/plugins/infra/public/pages/logs/logs.tsx +++ b/x-pack/plugins/infra/public/pages/logs/logs.tsx @@ -12,10 +12,14 @@ import { LogsToolbar } from './toolbar'; import { EmptyPage } from '../../components/empty_page'; import { Header } from '../../components/header'; +import { LogFlyout } from '../../components/logging/log_flyout'; import { ColumnarPage } from '../../components/page'; import { InfraHeaderFeedbackLink } from '../../components/header_feedback_link'; -import { WithLogFilterUrlState } from '../../containers/logs/with_log_filter'; +import { WithLogFilter, WithLogFilterUrlState } from '../../containers/logs/with_log_filter'; +import { WithLogFlyout } from '../../containers/logs/with_log_flyout'; +import { WithFlyoutOptions } from '../../containers/logs/with_log_flyout_options'; +import { WithFlyoutOptionsUrlState } from '../../containers/logs/with_log_flyout_options'; import { WithLogMinimapUrlState } from '../../containers/logs/with_log_minimap'; import { WithLogPositionUrlState } from '../../containers/logs/with_log_position'; import { WithLogTextviewUrlState } from '../../containers/logs/with_log_textview'; @@ -61,8 +65,32 @@ export const LogsPage = injectI18n( + - + + {({ applyFilterQueryFromKueryExpression }) => ( + + + {({ showFlyout, setFlyoutItem }) => ( + + )} + + + {({ flyoutItem, hideFlyout, loading }) => ( + + )} + + + )} + ) : isLoading ? ( diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx index e2efd2f1a333a..2ca93a310323a 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx @@ -17,7 +17,12 @@ import { WithLogTextview } from '../../containers/logs/with_log_textview'; import { WithStreamItems } from '../../containers/logs/with_stream_items'; import { WithSummary } from '../../containers/logs/with_summary'; -export const LogsPageContent: React.SFC = () => ( +interface Props { + setFlyoutItem: (id: string) => void; + showFlyout: () => void; +} + +export const LogsPageContent: React.SFC = ({ showFlyout, setFlyoutItem }) => ( {({ measureRef, content: { width = 0, height = 0 } }) => ( @@ -57,6 +62,8 @@ export const LogsPageContent: React.SFC = () => ( target={targetPosition} width={width} wrap={wrap} + setFlyoutItem={setFlyoutItem} + showFlyout={showFlyout} /> )} diff --git a/x-pack/plugins/infra/public/store/actions.ts b/x-pack/plugins/infra/public/store/actions.ts index ee9a2858f1c34..68a20f4dba98f 100644 --- a/x-pack/plugins/infra/public/store/actions.ts +++ b/x-pack/plugins/infra/public/store/actions.ts @@ -13,5 +13,6 @@ export { waffleFilterActions, waffleTimeActions, waffleOptionsActions, + flyoutOptionsActions, } from './local'; export { logEntriesActions, logSummaryActions } from './remote'; diff --git a/x-pack/plugins/infra/public/store/local/actions.ts b/x-pack/plugins/infra/public/store/local/actions.ts index 8b9e0c9f5b58a..ef988c9b956a0 100644 --- a/x-pack/plugins/infra/public/store/local/actions.ts +++ b/x-pack/plugins/infra/public/store/local/actions.ts @@ -12,3 +12,4 @@ export { metricTimeActions } from './metric_time'; export { waffleFilterActions } from './waffle_filter'; export { waffleTimeActions } from './waffle_time'; export { waffleOptionsActions } from './waffle_options'; +export { flyoutOptionsActions } from './log_flyout'; diff --git a/x-pack/plugins/infra/public/store/local/log_flyout/actions.ts b/x-pack/plugins/infra/public/store/local/log_flyout/actions.ts new file mode 100644 index 0000000000000..f0d75030dce1f --- /dev/null +++ b/x-pack/plugins/infra/public/store/local/log_flyout/actions.ts @@ -0,0 +1,11 @@ +/* + * 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 actionCreatorFactory from 'typescript-fsa'; +const actionCreator = actionCreatorFactory('x-pack/infra/local/log_flyout'); +export const setFlyoutItem = actionCreator('SET_FLYOUT_ITEM'); +export const showFlyout = actionCreator('SHOW_FLYOUT'); +export const hideFlyout = actionCreator('HIDE_FLYOUT'); diff --git a/x-pack/plugins/infra/public/store/local/log_flyout/index.ts b/x-pack/plugins/infra/public/store/local/log_flyout/index.ts new file mode 100644 index 0000000000000..8dda5c3890ce6 --- /dev/null +++ b/x-pack/plugins/infra/public/store/local/log_flyout/index.ts @@ -0,0 +1,11 @@ +/* + * 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 flyoutOptionsActions from './actions'; +import * as flyoutOptionsSelectors from './selector'; + +export { flyoutOptionsActions, flyoutOptionsSelectors }; +export * from './reducer'; diff --git a/x-pack/plugins/infra/public/store/local/log_flyout/reducer.ts b/x-pack/plugins/infra/public/store/local/log_flyout/reducer.ts new file mode 100644 index 0000000000000..695dc5e7d49b7 --- /dev/null +++ b/x-pack/plugins/infra/public/store/local/log_flyout/reducer.ts @@ -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. + */ + +import { combineReducers } from 'redux'; +import { reducerWithInitialState } from 'typescript-fsa-reducers'; + +import { hideFlyout, setFlyoutItem, showFlyout } from './actions'; + +export enum FlyoutVisibility { + hidden = 'hidden', + visible = 'visible', +} + +export interface FlyoutOptionsState { + visibility: FlyoutVisibility; + itemId: string; +} + +export const initialFlyoutOptionsState: FlyoutOptionsState = { + visibility: FlyoutVisibility.hidden, + itemId: '', +}; + +const currentFlyoutReducer = reducerWithInitialState(initialFlyoutOptionsState.itemId).case( + setFlyoutItem, + (current, target) => target +); + +const currentFlyoutVisibilityReducer = reducerWithInitialState(initialFlyoutOptionsState.visibility) + .case(hideFlyout, () => FlyoutVisibility.hidden) + .case(showFlyout, () => FlyoutVisibility.visible); + +export const flyoutOptionsReducer = combineReducers({ + itemId: currentFlyoutReducer, + visibility: currentFlyoutVisibilityReducer, +}); diff --git a/x-pack/plugins/infra/public/store/local/log_flyout/selector.ts b/x-pack/plugins/infra/public/store/local/log_flyout/selector.ts new file mode 100644 index 0000000000000..5024290b7bdc7 --- /dev/null +++ b/x-pack/plugins/infra/public/store/local/log_flyout/selector.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { FlyoutOptionsState } from './reducer'; + +export const selectFlyoutId = (state: FlyoutOptionsState) => state.itemId; +export const selectFlyoutVisibility = (state: FlyoutOptionsState) => state.visibility; diff --git a/x-pack/plugins/infra/public/store/local/reducer.ts b/x-pack/plugins/infra/public/store/local/reducer.ts index 59e890b748d5e..d7cff2f004f3f 100644 --- a/x-pack/plugins/infra/public/store/local/reducer.ts +++ b/x-pack/plugins/infra/public/store/local/reducer.ts @@ -7,6 +7,7 @@ import { combineReducers } from 'redux'; import { initialLogFilterState, logFilterReducer, LogFilterState } from './log_filter'; +import { flyoutOptionsReducer, FlyoutOptionsState, initialFlyoutOptionsState } from './log_flyout'; import { initialLogMinimapState, logMinimapReducer, LogMinimapState } from './log_minimap'; import { initialLogPositionState, logPositionReducer, LogPositionState } from './log_position'; import { initialLogTextviewState, logTextviewReducer, LogTextviewState } from './log_textview'; @@ -28,6 +29,7 @@ export interface LocalState { waffleFilter: WaffleFilterState; waffleTime: WaffleTimeState; waffleMetrics: WaffleOptionsState; + logFlyout: FlyoutOptionsState; } export const initialLocalState: LocalState = { @@ -39,6 +41,7 @@ export const initialLocalState: LocalState = { waffleFilter: initialWaffleFilterState, waffleTime: initialWaffleTimeState, waffleMetrics: initialWaffleOptionsState, + logFlyout: initialFlyoutOptionsState, }; export const localReducer = combineReducers({ @@ -50,4 +53,5 @@ export const localReducer = combineReducers({ waffleFilter: waffleFilterReducer, waffleTime: waffleTimeReducer, waffleMetrics: waffleOptionsReducer, + logFlyout: flyoutOptionsReducer, }); diff --git a/x-pack/plugins/infra/public/store/local/selectors.ts b/x-pack/plugins/infra/public/store/local/selectors.ts index 85188e144ade1..46e6fbafb686e 100644 --- a/x-pack/plugins/infra/public/store/local/selectors.ts +++ b/x-pack/plugins/infra/public/store/local/selectors.ts @@ -6,6 +6,7 @@ import { globalizeSelectors } from '../../utils/typed_redux'; import { logFilterSelectors as innerLogFilterSelectors } from './log_filter'; +import { flyoutOptionsSelectors as innerFlyoutOptionsSelectors } from './log_flyout'; import { logMinimapSelectors as innerLogMinimapSelectors } from './log_minimap'; import { logPositionSelectors as innerLogPositionSelectors } from './log_position'; import { logTextviewSelectors as innerLogTextviewSelectors } from './log_textview'; @@ -54,3 +55,8 @@ export const waffleOptionsSelectors = globalizeSelectors( (state: LocalState) => state.waffleMetrics, innerWaffleOptionsSelectors ); + +export const flyoutOptionsSelectors = globalizeSelectors( + (state: LocalState) => state.logFlyout, + innerFlyoutOptionsSelectors +); diff --git a/x-pack/plugins/infra/public/store/selectors.ts b/x-pack/plugins/infra/public/store/selectors.ts index a604580376ce3..8a2c96cb01039 100644 --- a/x-pack/plugins/infra/public/store/selectors.ts +++ b/x-pack/plugins/infra/public/store/selectors.ts @@ -9,6 +9,7 @@ import { createSelector } from 'reselect'; import { getLogEntryAtTime } from '../utils/log_entry'; import { globalizeSelectors } from '../utils/typed_redux'; import { + flyoutOptionsSelectors as localFlyoutOptionsSelectors, logFilterSelectors as localLogFilterSelectors, logMinimapSelectors as localLogMinimapSelectors, logPositionSelectors as localLogPositionSelectors, @@ -38,6 +39,7 @@ export const metricTimeSelectors = globalizeSelectors(selectLocal, localMetricTi export const waffleFilterSelectors = globalizeSelectors(selectLocal, localWaffleFilterSelectors); export const waffleTimeSelectors = globalizeSelectors(selectLocal, localWaffleTimeSelectors); export const waffleOptionsSelectors = globalizeSelectors(selectLocal, localWaffleOptionsSelectors); +export const flyoutOptionsSelectors = globalizeSelectors(selectLocal, localFlyoutOptionsSelectors); /** * remote selectors diff --git a/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts b/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts index 8a0dd691f9978..0c7049c1895a4 100644 --- a/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts +++ b/x-pack/plugins/infra/server/graphql/log_entries/resolvers.ts @@ -31,6 +31,11 @@ export type InfraSourceLogSummaryBetweenResolver = ChildResolverOf< QuerySourceResolver >; +export type InfraSourceLogItem = ChildResolverOf< + InfraResolverOf, + QuerySourceResolver +>; + export const createLogEntriesResolvers = (libs: { logEntries: InfraLogEntriesDomain; }): { @@ -38,6 +43,7 @@ export const createLogEntriesResolvers = (libs: { logEntriesAround: InfraSourceLogEntriesAroundResolver; logEntriesBetween: InfraSourceLogEntriesBetweenResolver; logSummaryBetween: InfraSourceLogSummaryBetweenResolver; + logItem: InfraSourceLogItem; }; InfraLogMessageSegment: { __resolveType( @@ -115,6 +121,9 @@ export const createLogEntriesResolvers = (libs: { buckets, }; }, + async logItem(source, args, { req }) { + return await libs.logEntries.getLogItem(req, args.id, source.configuration); + }, }, InfraLogMessageSegment: { __resolveType: (messageSegment: InfraLogMessageSegment) => { diff --git a/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts b/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts index e4947767ffbb1..302b5a374b524 100644 --- a/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts +++ b/x-pack/plugins/infra/server/graphql/log_entries/schema.gql.ts @@ -78,6 +78,22 @@ export const logEntriesSchema = gql` buckets: [InfraLogSummaryBucket!]! } + type InfraLogItemField { + "The flattened field name" + field: String! + "The value for the Field as a string" + value: String! + } + + type InfraLogItem { + "The ID of the document" + id: ID! + "The index where the document was found" + index: String! + "An array of flattened fields and values" + fields: [InfraLogItemField!]! + } + extend type InfraSource { "A consecutive span of log entries surrounding a point in time" logEntriesAround( @@ -114,5 +130,6 @@ export const logEntriesSchema = gql` "The query to filter the log entries by" filterQuery: String ): InfraLogSummaryInterval! + logItem(id: ID!): InfraLogItem! } `; diff --git a/x-pack/plugins/infra/server/graphql/types.ts b/x-pack/plugins/infra/server/graphql/types.ts index 10193b2998ee6..c3685a90eb981 100644 --- a/x-pack/plugins/infra/server/graphql/types.ts +++ b/x-pack/plugins/infra/server/graphql/types.ts @@ -62,6 +62,8 @@ export interface InfraSource { logEntriesBetween: InfraLogEntryInterval; /** A consecutive span of summary buckets within an interval */ logSummaryBetween: InfraLogSummaryInterval; + + logItem: InfraLogItem; /** A hierarchy of hosts, pods, containers, services or arbitrary groups */ map?: InfraResponse | null; @@ -205,6 +207,22 @@ export interface InfraLogSummaryBucket { entriesCount: number; } +export interface InfraLogItem { + /** The ID of the document */ + id: string; + /** The index where the document was found */ + index: string; + /** An array of flattened fields and values */ + fields: InfraLogItemField[]; +} + +export interface InfraLogItemField { + /** The flattened field name */ + field: string; + /** The value for the Field as a string */ + value: string; +} + export interface InfraResponse { nodes: InfraNode[]; } @@ -423,6 +441,9 @@ export interface LogSummaryBetweenInfraSourceArgs { /** The query to filter the log entries by */ filterQuery?: string | null; } +export interface LogItemInfraSourceArgs { + id: string; +} export interface MapInfraSourceArgs { timerange: InfraTimerangeInput; @@ -596,6 +617,8 @@ export namespace InfraSourceResolvers { logEntriesBetween?: LogEntriesBetweenResolver; /** A consecutive span of summary buckets within an interval */ logSummaryBetween?: LogSummaryBetweenResolver; + + logItem?: LogItemResolver; /** A hierarchy of hosts, pods, containers, services or arbitrary groups */ map?: MapResolver; @@ -688,6 +711,15 @@ export namespace InfraSourceResolvers { filterQuery?: string | null; } + export type LogItemResolver< + R = InfraLogItem, + Parent = InfraSource, + Context = InfraContext + > = Resolver; + export interface LogItemArgs { + id: string; + } + export type MapResolver< R = InfraResponse | null, Parent = InfraSource, @@ -1144,6 +1176,53 @@ export namespace InfraLogSummaryBucketResolvers { > = Resolver; } +export namespace InfraLogItemResolvers { + export interface Resolvers { + /** The ID of the document */ + id?: IdResolver; + /** The index where the document was found */ + index?: IndexResolver; + /** An array of flattened fields and values */ + fields?: FieldsResolver; + } + + export type IdResolver = Resolver< + R, + Parent, + Context + >; + export type IndexResolver = Resolver< + R, + Parent, + Context + >; + export type FieldsResolver< + R = InfraLogItemField[], + Parent = InfraLogItem, + Context = InfraContext + > = Resolver; +} + +export namespace InfraLogItemFieldResolvers { + export interface Resolvers { + /** The flattened field name */ + field?: FieldResolver; + /** The value for the Field as a string */ + value?: ValueResolver; + } + + export type FieldResolver< + R = string, + Parent = InfraLogItemField, + Context = InfraContext + > = Resolver; + export type ValueResolver< + R = string, + Parent = InfraLogItemField, + Context = InfraContext + > = Resolver; +} + export namespace InfraResponseResolvers { export interface Resolvers { nodes?: NodesResolver; diff --git a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts index f08cfe8f5ca0e..56126c0dd8064 100644 --- a/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/log_entries/kibana_log_entries_adapter.ts @@ -5,10 +5,12 @@ */ import { timeMilliseconds } from 'd3-time'; +import first from 'lodash/fp/first'; import get from 'lodash/fp/get'; import has from 'lodash/fp/has'; import zip from 'lodash/fp/zip'; +import { JsonObject } from 'x-pack/plugins/infra/common/typed_json'; import { compareTimeKeys, isTimeKey, TimeKey } from '../../../../common/time'; import { LogEntriesAdapter, @@ -28,6 +30,12 @@ const DAY_MILLIS = 24 * 60 * 60 * 1000; const LOOKUP_OFFSETS = [0, 1, 7, 30, 365, 10000, Infinity].map(days => days * DAY_MILLIS); const TIMESTAMP_FORMAT = 'epoch_millis'; +interface LogItemHit { + _index: string; + _id: string; + _source: JsonObject; +} + export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { constructor(private readonly framework: InfraBackendFrameworkAdapter) {} @@ -152,6 +160,35 @@ export class InfraKibanaLogEntriesAdapter implements LogEntriesAdapter { : []; } + public async getLogItem( + request: InfraFrameworkRequest, + id: string, + sourceConfiguration: InfraSourceConfiguration + ) { + const search = (searchOptions: object) => + this.framework.callWithRequest(request, 'search', searchOptions); + + const params = { + index: sourceConfiguration.logAlias, + terminate_after: 1, + body: { + size: 1, + query: { + ids: { + values: [id], + }, + }, + }, + }; + + const response = await search(params); + const document = first(response.hits.hits); + if (!document) { + throw new Error('Document not found'); + } + return document; + } + private async getLogEntryDocumentsBetween( request: InfraFrameworkRequest, sourceConfiguration: InfraSourceConfiguration, diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts new file mode 100644 index 0000000000000..d46ebbb26fbb8 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.test.ts @@ -0,0 +1,67 @@ +/* + * 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 { convertDocumentSourceToLogItemFields } from './convert_document_source_to_log_item_fields'; + +describe('convertDocumentSourceToLogItemFields', () => { + test('should convert document', () => { + const doc = { + agent: { + hostname: 'demo-stack-client-01', + id: '7adef8b6-2ab7-45cd-a0d5-b3baad735f1b', + type: 'filebeat', + ephemeral_id: 'a0c8164b-3564-4e32-b0bf-f4db5a7ae566', + version: '7.0.0', + }, + tags: ['prod', 'web'], + metadata: [{ key: 'env', value: 'prod' }, { key: 'stack', value: 'web' }], + host: { + hostname: 'packer-virtualbox-iso-1546820004', + name: 'demo-stack-client-01', + }, + }; + + const fields = convertDocumentSourceToLogItemFields(doc); + expect(fields).toEqual([ + { + field: 'agent.hostname', + value: 'demo-stack-client-01', + }, + { + field: 'agent.id', + value: '7adef8b6-2ab7-45cd-a0d5-b3baad735f1b', + }, + { + field: 'agent.type', + value: 'filebeat', + }, + { + field: 'agent.ephemeral_id', + value: 'a0c8164b-3564-4e32-b0bf-f4db5a7ae566', + }, + { + field: 'agent.version', + value: '7.0.0', + }, + { + field: 'tags', + value: '["prod","web"]', + }, + { + field: 'metadata', + value: '[{"key":"env","value":"prod"},{"key":"stack","value":"web"}]', + }, + { + field: 'host.hostname', + value: 'packer-virtualbox-iso-1546820004', + }, + { + field: 'host.name', + value: 'demo-stack-client-01', + }, + ]); + }); +}); diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts new file mode 100644 index 0000000000000..923c0c22211fe --- /dev/null +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/convert_document_source_to_log_item_fields.ts @@ -0,0 +1,36 @@ +/* + * 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 { isArray, isPlainObject } from 'lodash'; +import { JsonObject } from 'x-pack/plugins/infra/common/typed_json'; +import { InfraLogItemField } from '../../../graphql/types'; + +const isJsonObject = (subject: any): subject is JsonObject => { + return isPlainObject(subject); +}; + +const serializeValue = (value: any): string => { + if (isArray(value) || isPlainObject(value)) { + return JSON.stringify(value); + } + return `${value}`; +}; + +export const convertDocumentSourceToLogItemFields = ( + source: JsonObject, + path: string[] = [], + fields: InfraLogItemField[] = [] +): InfraLogItemField[] => { + return Object.keys(source).reduce((acc, key) => { + const value = source[key]; + const nextPath = [...path, key]; + if (isJsonObject(value)) { + return convertDocumentSourceToLogItemFields(value, nextPath, acc); + } + const field = { field: nextPath.join('.'), value: serializeValue(value) }; + return [...acc, field]; + }, fields); +}; diff --git a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts index 5781ca3ad8ef8..e605efc105617 100644 --- a/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts +++ b/x-pack/plugins/infra/server/lib/domains/log_entries_domain/log_entries_domain.ts @@ -4,8 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ +import { sortBy } from 'lodash'; import { TimeKey } from '../../../../common/time'; import { JsonObject } from '../../../../common/typed_json'; +import { InfraLogItem } from '../../../graphql/types'; import { InfraLogEntry, InfraLogMessageSegment, @@ -14,6 +16,7 @@ import { import { InfraDateRangeAggregationBucket, InfraFrameworkRequest } from '../../adapters/framework'; import { InfraSourceConfiguration, InfraSources } from '../../sources'; import { builtinRules } from './builtin_rules'; +import { convertDocumentSourceToLogItemFields } from './convert_document_source_to_log_item_fields'; import { compileFormattingRules } from './message'; export class InfraLogEntriesDomain { @@ -121,6 +124,32 @@ export class InfraLogEntriesDomain { const buckets = dateRangeBuckets.map(convertDateRangeBucketToSummaryBucket); return buckets; } + + public async getLogItem( + request: InfraFrameworkRequest, + id: string, + sourceConfiguration: InfraSourceConfiguration + ): Promise { + const document = await this.adapter.getLogItem(request, id, sourceConfiguration); + const defaultFields = [ + { field: '_index', value: document._index }, + { field: '_id', value: document._id }, + ]; + return { + id: document._id, + index: document._index, + fields: sortBy( + [...defaultFields, ...convertDocumentSourceToLogItemFields(document._source)], + 'field' + ), + }; + } +} + +interface LogItemHit { + _index: string; + _id: string; + _source: JsonObject; } export interface LogEntriesAdapter { @@ -153,6 +182,12 @@ export interface LogEntriesAdapter { bucketSize: number, filterQuery?: LogEntryQuery ): Promise; + + getLogItem( + request: InfraFrameworkRequest, + id: string, + source: InfraSourceConfiguration + ): Promise; } export type LogEntryQuery = JsonObject; diff --git a/x-pack/test/api_integration/apis/infra/index.js b/x-pack/test/api_integration/apis/infra/index.js index 595f931a1e8fc..1471e4fe8084a 100644 --- a/x-pack/test/api_integration/apis/infra/index.js +++ b/x-pack/test/api_integration/apis/infra/index.js @@ -14,5 +14,6 @@ export default function ({ loadTestFile }) { loadTestFile(require.resolve('./metrics')); loadTestFile(require.resolve('./sources')); loadTestFile(require.resolve('./waffle')); + loadTestFile(require.resolve('./log_item')); }); } diff --git a/x-pack/test/api_integration/apis/infra/log_item.ts b/x-pack/test/api_integration/apis/infra/log_item.ts new file mode 100644 index 0000000000000..bfdde32fa57ae --- /dev/null +++ b/x-pack/test/api_integration/apis/infra/log_item.ts @@ -0,0 +1,175 @@ +/* + * 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 expect from 'expect.js'; +import { flyoutItemQuery } from '../../../../plugins/infra/public/containers/logs/flyout_item.gql_query'; +import { FlyoutItemQuery } from '../../../../plugins/infra/public/graphql/types'; +import { KbnTestProvider } from './types'; + +const logItemTests: KbnTestProvider = ({ getService }) => { + const esArchiver = getService('esArchiver'); + const client = getService('infraOpsGraphQLClient'); + describe('Log Item GraphQL Endpoint', () => { + before(() => esArchiver.load('infra/metrics_and_logs')); + after(() => esArchiver.unload('infra/metrics_and_logs')); + + it('should basically work', () => { + return client + .query({ + query: flyoutItemQuery, + variables: { + sourceId: 'default', + itemId: 'yT2Mg2YBh-opCxJv8Vqj', + }, + }) + .then(resp => { + expect(resp.data.source).to.have.property('logItem'); + const { logItem } = resp.data.source; + if (!logItem) { + throw new Error('Log item should not be falsey'); + } + expect(logItem).to.have.property('id', 'yT2Mg2YBh-opCxJv8Vqj'); + expect(logItem).to.have.property('index', 'filebeat-7.0.0-alpha1-2018.10.17'); + expect(logItem).to.have.property('fields'); + expect(logItem.fields).to.eql([ + { + field: '@timestamp', + value: '2018-10-17T19:42:22.000Z', + __typename: 'InfraLogItemField', + }, + { + field: '_id', + value: 'yT2Mg2YBh-opCxJv8Vqj', + __typename: 'InfraLogItemField', + }, + { + field: '_index', + value: 'filebeat-7.0.0-alpha1-2018.10.17', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.body_sent.bytes', + value: '1336', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.http_version', + value: '1.1', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.method', + value: 'GET', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.referrer', + value: '-', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.remote_ip', + value: '10.128.0.11', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.response_code', + value: '200', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.url', + value: '/a-fresh-start-will-put-you-on-your-way', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.user_agent.device', + value: 'Other', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.user_agent.name', + value: 'Other', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.user_agent.os', + value: 'Other', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.user_agent.os_name', + value: 'Other', + __typename: 'InfraLogItemField', + }, + { + field: 'apache2.access.user_name', + value: '-', + __typename: 'InfraLogItemField', + }, + { + field: 'beat.hostname', + value: 'demo-stack-apache-01', + __typename: 'InfraLogItemField', + }, + { + field: 'beat.name', + value: 'demo-stack-apache-01', + __typename: 'InfraLogItemField', + }, + { + field: 'beat.version', + value: '7.0.0-alpha1', + __typename: 'InfraLogItemField', + }, + { + field: 'fileset.module', + value: 'apache2', + __typename: 'InfraLogItemField', + }, + { + field: 'fileset.name', + value: 'access', + __typename: 'InfraLogItemField', + }, + { + field: 'host.name', + value: 'demo-stack-apache-01', + __typename: 'InfraLogItemField', + }, + { + field: 'input.type', + value: 'log', + __typename: 'InfraLogItemField', + }, + { + field: 'offset', + value: '5497614', + __typename: 'InfraLogItemField', + }, + { + field: 'prospector.type', + value: 'log', + __typename: 'InfraLogItemField', + }, + { + field: 'read_timestamp', + value: '2018-10-17T19:42:23.160Z', + __typename: 'InfraLogItemField', + }, + { + field: 'source', + value: '/var/log/apache2/access.log', + __typename: 'InfraLogItemField', + }, + ]); + }); + }); + }); +}; + +// tslint:disable-next-line no-default-export +export default logItemTests; diff --git a/x-pack/test/functional/es_archives/empty_kibana/data.json.gz b/x-pack/test/functional/es_archives/empty_kibana/data.json.gz index 2aa6460986df499d43898b88bbb230cbfa9aa1d6..1fd039ebc7c640ced0a152fcb52df69c5115855f 100644 GIT binary patch literal 231 zcmVQOZ*Bm!kY5XeFcih#_bJw%O$@@q*P_Rs>^ZL6 z%#m)QTU6qAZ}U$k1U&^~aL)bR!_FFnG0~5blL(VDQn1?WgWUEC?&kzw4T@orIzQ1hqObqSP5jHh67{kw06Pj!1aYb&AX$o(v`ughy% hiBbzC9T8`u#`frp5o+qJP08$vtMR2Ey9?XyXGXpgegh_Z(O0Y-f5k1Qb@*c9tbZY0|`CkedbN7WG>E0 z97bWZgi;rxn$AIQtAyIsedV4g5A{GjRzOky5B?v(Dx zIPTDNcc??C{l8$Nf%1g$9BgTRSL^Y)*&siPNvL{q{}DMf;|;BaHbO~Hq=jg(JEq`x U`~dC)7hmf>0lQ9X6wUzv0Mh(nn*aa+ diff --git a/x-pack/test/functional/es_archives/infra/logs_without_epoch_millis/data.json.gz b/x-pack/test/functional/es_archives/infra/logs_without_epoch_millis/data.json.gz index b07c21c1550750f73fd1d1da0fe9e93df7bc1d95..80eb707ec1aa778967e7f12bab7786eccf1c0eaa 100644 GIT binary patch literal 484 zcmVQOZ*BnXR6TElFc97O6_Muv2J*?&O0CqbOQ$Z# z#YeCT*s@L9D9V4YO-cfUw(8QM?SkOFyLWfy`S#9ag7i)RiYF+cJVjHBY)MgDXm38u zC#xvD+K7x5@B~D=FHGmW)^5p)f~h8HOvvU^i)c_fXd%UGnV#hh!m~_)HpnsxXUo-W z+7i`|pHuM{LHr%ihy#>0q`Ye<-|Y=FHWTzTdh z^rK2JGdI)R-Cp1HxmtltDpJBo{akC2Y(Xlo8ACQqGL@r2><{SnDYey literal 473 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%0A=LeJilz?75uN+nC=Q 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%0AY>(QNa8=qMr514byR=OlQtg4ya2QaA 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 UM9josj!PvIlwQ#gl&&c(aO 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≫k<~-84HxQ~EHlI_ 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

+H2Q+|@E)y)7l{?Vx!Z1rR_hR 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 eUv`A;ZMw2Nr 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%0D6iq-5%-S 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

YAnXC+igy`14$x4$XL? z*r}Fi3?~ZW6p}>=GHau^DSvNfG7J+$(V~51lQ36-yikedUw17#J?~X~D_1t|ONm5%|=*@{1g+cf^Lw8&DD*?DR%p3JP5ekq2=;AQ-IrYCw|>pSUBIzS31#WGC6^^ZNDqv&%}| zqn_l8*Fm~4fFX($th)tB72^pmhXG6_a?X3E?<1xjUPbP zaPLYL4^nbBl#CoUSj+yVsj{SfpT&I2os7(t#1u@$x!oAim{kdXRR1}q_d|+trwA?P zRtuq|s}6c;fm5fXZ>?Eh_Qxb6)&h4Y#BTrEfK~X_hFR?}C4}74Ssn824rUV!YH*Hq z@s`J@p$+^u=x!)A?Lo+wa36MF)F(o`fU|HLlh9cAR($lIj9j}PN*-$O4N>%9+w+`B zqLaH$rf2N0gxgStDFP8-q122()NJI2V1^=IKWzMgT|u|5i`hnrpi*@Lq=KCdC7mQu ztyYE!Y$XX!1moDO>)@8qU?mADF}T7w3cgSxj{I+^u(Gvt$gAOew_qz1@#jE%L*6nd z=9FC6XIfmRyCNyCg{6g?;nJEPu zvoK4TO*YzcVd5%TQ=P{+E_SO^Rh2Hpl8LHC=u^n>nfcMebzbi%0EH?kX-pd!c`Fo* zNqLBvUL$%C?5~tZHjad@vpN)C<2b)0O56}s$C&N^x7tskz5Yv~8u`+d)<*hO_%4A_P_D2VdH!+bEvzf5?FX2f_m0J zr{zR4^V}5M{HQe~lL-Jf-*D4#pwW2Z)w{r|cv+UQU=7%8o(A@1zv&sBQTZAv6$HZz zI@qCPt*5R^_fyVURVanmQd3X(QOU+)z~hl6F!qu$iNq4>3tbwP|v za<*zkpDB&pZ{!AK;p0%FLQ05h!@(gZ2e{Gw$|J+|N*KSpg62HaWXYdv(Pc}s5CsX% zJ~R}KJH#R!+EniKp3;g)`8PhUUr&f%R4lF>w!nKEKb*aMqUcFptb+JU)2`t$b2pi*FqD3Ii*kj%h#k;Rb{ZgJ znX&wNdqn#o6I9HZFejXF*d+xHACj}+Mi!Y5+(xdh&-=5sIg1OW1My~kq!ww>_d*2M zGy01$M%DR>j?z~hc+iKXsK9abLpZPEt*89E8|D0tU(5`FLmUM>p6*48Ys`Siv!YKHLowrU5n!gwj;)MpuDfYjAk3|PDYO60$n;@v|@@S<&Vpp)XRtf-pj{m z=`{UuNjIlLOfOH>)Zf+O^Um^WmwXZoOWNtT_^>Zmt1MjxNiA#P`J}c1&EWg82q_$9 zM$d}*1nz?`(%~~F&svy#4YR=RFYyS4&=3%izK_>|f|2>yf4Y7=^w+XDPI|14^aWE{ zSlFf*Mtx9fRCK_Fz&j>4Xd@t*DE@y4=%JXga7(2I-qY&g0jHI;bjCxh;QoDy08zD0 zj`L~ruqCBke1QBcKH$D7Z>cTL@fTd${Z%1(*Y9CIZutgjt0HE!vqhXuu+A(>(cVG? zu4rb+)hrm9nZ@_ASWD*kG1?|&mu>+QhQayJTqB^=qV1Tw;gc{EH^1rfx%=d71bn2X zbnNn}=$qOW?jmB;!9Olc`=zP;dc8O9k1gN%8h9^D_igkkqnq(*9otz)CzTL`?-eAE z6$9nxJ6^=(-Swat@^2Kc(g3L$VGtkumNP~Ghp!1&-#?FiUtsYWA9`q-qm0*FHKEI$ zpEvxUa`vRb+iXou++;po+w%pxPB&8Q0MMq{^Q*nq$FK>KRXq5C95eZ18Cc!b)C!T# zpO0K>ffCo3Ls!tUo$T0tEpKF2mENhDQ~6Y+}>( zDJ^d?hW~-lj^5M69944I8^Qm9rxSbEq~5)acJ$%i3T%467pX`6pn_>7#c3oqZ3OY* zC*P+0PjpsNIgw4b#yNxO`d0~Mn=wn&t2w+x>*mXIwFd;oa*H7mi<3svbO8+cf#1%% zL{7$vLt2RCBy|S?$mh-V;&>V*3~zc<`ugA&ee1Yp^y9$nw~m!d2R0tRji2`h4)68! z$uuEoxqR)P&8_Il=M63YjcdP$ZT8zqwO;;h&|m>O*zcav)_SUFmazD;TW57f^XH>l z`%(UY+>d4pJvYav^A-QL054T4sbBkfkqYf2oEDDrl9edM zLaWKpSmd+~j9m+o(qMO;*d20OR&dfggm!XTRl%}~Jo}QFlol(l^KiVNDTytOrNm>6 zuvtyzEvqz68Z|ROzoI&=BfFLD=hCZMJp(OfTxJJF-8{d}SL&ar5i9i(Cj$2-7*h7u zRk!~(6L|NFei2mX{DbQQWZpCB;=vr8v`7_aJWy2#5~jrUz+rJ!N7}yJ{53DxgP*s;UL`pp=|xS59BnQ zb2bQ8b@o$KOjni>2Tz7d<7X?GMiS3kN114A&ZQ6SxJaJcv7k9)U=eWyytMJpvkk*U zZ#U)vMME@!4+XvSZg5TVBjqF|IS%1fw+*aDpvNKAbKa7P{9PW-vT_nB$wj#S7f6So zw>a0!OyvW1yo4m}(SQ)W0*L=r# zruO*QvQ!L$8X&m$W3K5PlLcUT0^&#KV;sU5;BPFF66Cm|S&(_U153Y}42Nf8cdWNq z!cNb1JM2OeR?NZ1;H(az$UUJpvu|ssm-bQxYE2KLl4Ks1>XMz!qsQZ~8=}cU|5Upz z;L}N!{j8ht;!c`O9h{;3T5k`A>`s5mG@mu>U+=&r4meL3VgmBZ)GJb7^Y8jjbY7pl zkF>hGl5>H)4W{vDQTD^1cXcNY@&rdQZ@7+vFdVQsI(YTLJXle`^IG`hpwh)|8Z<)l zQsjx#Ma+n%{Bb)iI_9alWk~w6eCDZz$1mWEK0C{bjO)4TVojL&WBP{2|AYq+C7yG&}o1rirE20FO&q0IW3FVXC#x0 zjKjor_=q~BA}V+DaA)Hk;}O`AMF3$IY?ZZ$vAh{1F+9CM_&hW(4I-5Nk9rppM4j1~ zJWlVFbc14qK{GMIf-bU2GxCtn;hCV4-eZ_vmQYu<3BwecPtk+{fMW$6GWJ1ngiAR2l7H&U@Ug5tj|kN1cH*z*$;FrZ#$i67r8-` z?SfxWSe#VLtj_PlMGG-FTJq!c1~;`2QVJb2Ous~|aQ@`W<5&)P{o|_3P0L<$K%+eY zx2KMmEWP>G64#^S&NoJoTun!-KRgV=brclli(RunhJPx6q7ON5&U;bqi^Ij+9(3n6 zL}w8rE>yx!bTy$2m4!?>ue-EJ4t#c1=?Gmlx?8@;pnDrv#wC9l=M#ovAo&)4fayGR z`z2DUveK4PrJ9N|=rec#jiv{2r9sW6PF8|F?o*hg=^UP?iCM_i3}|H~C=G31iH2xK z7Y2&Og~y7z;Rg&)Cm9=~=#U#!e>yzW4nkR05c!Etx}ox#wF^oz>XnzB7{9lww1@mg09bOFhYZ zc4(xUi;EFtofi=RS;QWA!FJ>87;lJPcF&`8czz3nG4<=BSml~kY}3k8h-q~5CXrwk zT#+MDX!j^?%$3Zk-W!v?Dv-Z#sO+fVXYo)N^O3lD1%MKr>VQ5i1CqEAL#_j zveIs1$sCC4NUh9L2wPa=&6Q_TU?FI@^Ml0Vqg3j}fON8NBZH9S==Sz8ueHnsc(mkBYq4ct}*jN{#BS$h@L8CnnSQW<@2F|hTJJi_(g+o7128we3NAa;@f6)TSVCXFou8JVbfJ^f z_^V|nLih${FF;|RXhOk{B*h#_+vNv^%lRlFR%zsl<#R$7cKfQSMQqXeWb4kq`Q$*v z-`jxlQ5dE`yEW(wJ8`W-6?|$B!CUa-V2GuWE;5MDaq{}Z>0hW zvFl}s6XjXV)H#E?gKBWzf2V@1B{#BPmmsnG5=Svvf2*Zs%cu?lA77pcso^o5ZCI^| zicRQ4c2#<$^vdnP*1jRB=xub}7?aMwZ6tpdTo+>0eNHY6FT>4Bsmvg~yu9-)>Ew0UKT3dB?; zuhkNCMrfXpUZRgkO;O!Z4u2PG5^W0J#^udNKGhcYTK%e22L2l!E21bp)o=glGWz~( zIsnzZY7YDD1IZbtxy3pf85j5r&#*}+2ydAlUg|cCEeOJJ4Ubdkn2ryI^KA|1d-&9B zdxd7IUQxGi^LQ6C^cUA_0Jv2bn)SFM3E+ek0~5weH@|d>)>Y1`y0jCvXP60p31IEF z|Exs22LOh!52i#|t)02Q7}+0v>F9CL-qaW&h0PzZ3~dGr^I=CAycKr`P1iLc&YcPs zZ@f@>2kMA9j@$A8b+K?O1 z>XkG}^dowQ&kXiUokJ$Pov zTx40=YWP)Wxe{TgZfo zfjwXYXyE%97az0$Jc*FyJgKp&MUPH4AxG>XS=7xjPf1;9n|r{MKf;=bQIUzlMMZf< zsk}UtAN(@S;QesP8tFO!BIddQmb+=AC1wZX51xy3*Jpzf3To-(wqg0)`hw6ygj8FA zpVG86EpAKaJ`q$eN>J^TOp^Azf+OFM?tEl>k`xx~R75JZAfT4@XBDlm7^@Dyf}K72 znR`>@K|49Zrh>?G{dm}+Rdb1(o8T3NeMU|KdG`gek$RXVCd7f023l-BvgF4qoU055 z6Dj%x2}j6qsbEVKo+i!KjJ{kps#x(c`Wd3^l<7S+&YI?jx)R zQtTxp;Mk{aROD12;Q0Oim%3&oy6L53CUbYC4}#1{(C{856R49ZhqtiS&#aK^EpxQ3 z#V|tw1tCxGwLaLh;hyD9s!25XbmPk~L82#5?{*w$X)O&tqA+?*>$41@=E=G|Do@02fyf%HSV70+8rEH_AYfA4%G`6f$e(?w=5gM0^tCB%` zeky;S2W(EDwYwM7gYBI7en*^5Iq8ABFvYAYE?y0e8?pH|)ujJ`UwUP{#YSx6+xGtL z6vJaOpOEn#+paI+KXn3hN+VOCcS5e|ZSMT9kKx;9GJV4PY^_Xkt=gyIf4L&461G)> zy74LDWtoRkb)zQ3`6Oq!BlZtq3)g?)F~6>a(7!UIH{E!wRN}dB5BD|BGE7oOe4RMm z+ttt0(?<`kZMxp^t5B;fHXv;Wl~@rbZr?5&+#Ai;1J=Lh$B65?E^0Jvo4Sv;t&U;| ztKgf<)O?-kVohPtjSie~MVMx$3EVL#ceD zGny2|8VxqonAoOgvda1TL{oY|ktFMJ!}~e-R`-kzye$KhQ0`w2gO<04QFZgQ+?=J{ zHekdn#2A@4GW~-Cu(a0~s7GM+Q-Ms4Je_Uv0Fpg$WOKB{L!C4Hi|mLH3E;JB=y=Gj zv0%WauxJ!*!`m;{zA?6nB@K@rz2BVT)yjLbzre6Vp-3;V8zEh zP}3+PA;jiV+(ifQ|MEN!XNH?GDS)GA)U9tNbY99#$Hyuj;(!Uw*(#6O4iOTaPl|Gz zHy9{;?<-pRlM9q*HNbisI|R6U*tfnX`=YB|L2-s{6lx2VubGFhduN=`TsNZHTe~)G zNVW#m2f)PjiAX7%-l}WvLGldxs5;=;1Onf8ZlEda27xTqKq2n&gHK zG>OP+TWhFN8eBp}HO1WfFb-;l`f=7xTiHCHs!*`#AQ3&Es`1*IQEx~20`UEbkNf^w zUq3qO;{7jX^71);Waqn4LD0X)I?P)3uemr-+rj2XP;?vBU!V15;)=sJv;rLE+kSEucA->5^uA3=m9O6Cyd6-$L1_@w$OXt;8EpW3Ez7EP$NU zXrk*XLk^-5L~6s=UqC=tD1)2CxPIDN=on*?ZxM|O3vsYp2|8$GZCN+DD4$~r>0zRgJP^!%w6dz&}`H`A{>wu=}%^C8huNIMo* zI%bJ^16L&I#YT6&sHki;2}PdTTt$D6yU(8!?8aej66>x+FvUjW;2PBSu=uokSe(oi zN3!oJ|8L@f9Q<7~DxpQm{RiLi>h8+Uw2XKcQE4-5E4aJ)sn)oq=$UkaSui%py`{j&QxH)#C$|)3^XA%B)1asN(2n7Nor{} zGj3ZMQX3g`S-2_5O1%_yR6-)&D(XBf9T{nu*;)x%9PB2?vY+ubL*B}<9*GWPdE#w+ zT|cOoVrP9A>#O-4YxEI}Ew`guldoDM9?1^(AyFACcB{frg+g%W(IVN{SC{WsTTn-) zZ9883=QNI8;hh2}M?Qi8RoI&Gjitoz{2hmZB)N=?el{0#y*#OI*90q@y|4z;1jioF8QaR&|g<- z?evPgbJ=pk9=hnK5672u=j+qy%g*;v^S)c3w;xXLQljwQ{|hW=QQOiVk2hcDZ>qcB z8vG|;y`SB@{(k=_U-@z;B|k?;jxV)35@>4iaS7$LAubf}&Dg-$61KZf#N)*UwUfEC z&Sd*|ZDrzQ^Fh1X5rLEiIitLc$*DNT5KTbhG0Gx5wlFI!=*2*zZ(fxd#Mx2)U3y7# z8FpQ?q%!L%u~aM^&9hUfp{g)-Zrwwdpz?0;;L2Yfl%$L;kXH@hD%&jRlhdXrVTq*b zN|>oq5X}wP&Pg#}0ARELaaK1=-)7c*tSq54gzV3fKZ<~`=|Xz0ZV@Q~xr!)@91Kbb z32(9G^mMOyGE1{TyhMHid1J9TY!F4Du1b+%%GhSifm)(I*oc5ukW6FH6&gG>8VoD= znOdDl50WP{s&46R^xmoQN0w(7{g`9wzsFpSr9EeMm(5J1%OXimlePl%5kOnX2?d#! zRUEYz5Ay0f;iT=1LHXG4ygPrkT}$?$IEHOQs9a{_?QYA(J~h%6b#Z6lUay5{XjW!o z1pMopzC9ZPOpn~ITKk!$Nm7T{o2?ctq|@O{HbOI1GwwMz0w?$CoI2ur$cas##&p`q zM+zCqBM<|Ll?|-59q=e>WrlJf0e4>C_VQkze|Xy|0Ao^R^}%_Iv)yilvHU>HJ;!T@ zxBZ$}ERo|AyJ&-*Xb(F@jjR)Y#z}@PwBc-$8V+5dvTdQk$kwlaKVst5yVfE8ty_`A z+NkWJ8hRK_gO?OvK3|wl(7MpQrlWAVhFMZQic$uSun;6BvB1vfv>--nD7X@fZbXlv z%s0XY{wVOq*@%!7p%3rJ9r_cjID?(ZK&FJUJV<;Z)aY3DS*aQ2Ld||)CI{d}jHr3S zj{W;b5{9XXX9kw>3&Xd|LF~b!re_uPpe{KG;8Q;fVaUWTlL){ljR`@(ZRW;&38yEO z8!g=K18O*@lI$s_i5rrh06~FM~p}%9h*9BwFViqM~&(z+XJpeWWL{ANe+ME zpJ3wgLpnP)w(HxyyJ6eWnl}W)5-yk$8yW!Fn|f48j-9TcvviNfVR9?&Y2zoEZ4ta` zKu~OOE2KM5tP1|D0DN1PRiAY;gq-PCy=(WyNrl_tb_;PKWdeo!J+i1>WaGNNOn}&^ zWFaag{r5NDQrRyC$@T&B;E6LblT=2{Zn>GHWFzCs8>XV<5#{tMsHuvQ^1uVCLB(9r zNtWLyl2^ye+%zGIOO)~#Y9y((`pou>S5Pu>l=&A*XLPU$=%;#ASF24eTve0A)acR| z&6y~FBBun0*RrBLJ7)2%D@g}4uNLA>?HWFj6ML1 z`2+fMGiQa&(vm?IDbIs^>m0@_nwq|QNI@ovmzJoJws_VUCP?p!5-JWjyJ!#BANnb2 z3dr`1v&SQ$P9Ay%?gw3xxoO7dccLuLh^8&+@W41q@Bw{B&CbXyLuWb;fW-c~w7gYO z*gZ(|cbhw@d42C690u?Nk60u=r?l`wpUU&=WdZ)>L9>%mC)xJq$w6qvdp`@Jre%k{ z?}3Whn^UxcqqwGYYFlm+BRsj;)S(qDr{v950P>>4mUYDIPjF9Stoq#q-#wKCe2JNH z97%>IYzz_fEEb3^TI9eDKEUs$JqQao0Ps34W!7{#_}Dg!<=1e|zzMi&%`s0vtV!d{ z-YK>0(GDhp<8bSx$KG@0`^5_8AB*;A=OYKE6%gP?ZlgG+(H>^;bAgyW6!ZmE9yZPl z#Cjy-3O#30hGtQ|jtf50l}@4h=a}AwuVK-`WuX@v z6#pJJ^n&G>0!q$VnEE7$OyTk7U-bkki%ZS#YXq z1Yq>Sv9sC!eTB3%6E99}!3>fQAsY`T+j(4DDq4vaiOwG7qy55}vpycBkIza^5+PNW z@t5XofBk0z05o}r$$(wMg7P%=o54VY4P`7V5=t^RlYCZB||< z{Y1xsqk~csk_VjEG@J?QyFgKd<82s2rU)@9B4Nh^f7B`t3q}}&xc%H$dYt3E$YM}A zj)Jnr4s^vwF&(JVF3s)*J+RY<8YPg?wgp;$V;w6r{xVw8erDF~_g1^KF%>Y^7BbR# zz%F@Nlw#Ut4TSg^LqbV4Wt z4GRW{jR_*2cQ(ozINDzxQX5(UhDFjIoiq(PCyTvI89$}x5X?aoF|kZ}B?QG-vPuyD zw1RA$LR4Mgqdf{{!+bMhuBoMSpkuAF?r@EP?RA+hnJ)@vZ=8umBfvQL4+zl@5i*EM zVuQr*JS-2jAjbyc!cvQ31x*-icUb3>4yf12OP;y06RDrc3w@@cN~ZfY<$Wq7Sbzz{ zDJ`N$YQ(0IPY^--ivpNXK-+7F++MWUV9!SB3(iPbv>;BE0zu@uF?#I7O z;5ra;KzkBad-tEf11#$F|MCR+>?)%AgY2GSW=L;Nr)1!ezw0sx|Sk)?~ouQZCq}UHloH@bKL;(FcYo@+1T(`LsX4OI{I_cT*0qXczV=a%G_Okf4Ij`TJ5bUNMLehS8E` zf@#o;OyM@VL9~#)>a`lgAgnt&5xsM}NtfqX`HP74|Oci^zoV$Ny@QA zl-=wm;f2a?J=nj^jp@w2C*bWP!Wj`4I?@U(ffIh-=O8aN=D~|tYX>>5f|;e5qCvuu zjtQx@(SJP?(#Q0iPQR@O^oRv1TRbX(WE+%bq?d&TQtdO4G>D zbuqZKN1cu-ShFKPtlb0q{5$qm6N_6?B!>DK<8=O37sp8f$;U9zx3R> z>N14xoa8IC+E_N8>C)VtW7ml9^Yw9RuDP1L!B_1vbTfid70frWx$gYlwLkxL>}_<+ zRR}0cj&Y={Scbg!NK;jJ|10Wb9FN9k?X)L9Xs|BOaBd`|T+FiB{j-(t1APiXlf^g_ zf6+7RscGx-s(*5~h7aJETDIG7jRMrPosOyp;n?$=kTzc#p1qnjt-?O zs&>!K3uS${qBZwI6`=?qTKITTnId+h-$GATFPDP)=~HWY?Z|w66XX0hEW4IQxCnh} zP9ifNkC*=XpEABI-x8Y8h9T}n?UPKK>)iL;7!+D>_e3uRiXM1v!nedge?1=E-?4R)iQu=La+OF<1p@!h$m>Jrcf zC&44As)pCQ$sT`uvkeD%Wj6cylpp|#i7v{lIj(iuK4+!4C)wXNXbP#E-rR3Hq| zI*9O_S%`zXtySaBB> zBqBkBIT@N6DOF6O4mgZb5e9<#n)^heOgV_<-=!v#kLG^TcX}IR+Wd@$#_+^diWu)- zE+x036*1|!I?1Z@X{P=uml0%K4$T+IvEK=X1DYAqN&c{hJj&DW0c;oB-g*h@t1IiH z)Dnc#yLO%yP8E~8t~0T|UR)jAo&HnbGFhqidWCgF`Hm|n9z|d3ZbPUm?{~k@U03L; zr6OQ>p@jE4TjAD?lCEN$@{llG^OCK###zJH9`III?I)SGoGhU$pKaZZNeE=$Hj61M z#}}lC9W8%cxY>o=`P9L%#wQC| z5Gmtjx>9G(iJ0x4#}lVU$szV4={^~(NI5&3d(aikY(>GR#Zz``wadu))3;J;21;>t z9!Hi;5tC3=4Xf(`lE=Fm!7JK?`jbPp8DF|u?E1((Kbf;R6S^{DPB?D1LE&7PN` z&)y^>2?RUVt63&xTXDagR3ZF#5fq!vfeQlrf?NBP{=qdAh*+v;aq2sZr#s47NP4Q; zC6jhntrHolOJs-a(5TmtsaPXDkU7Xe1QMK{+sjw?M9i?9keQ_$Ts_tEAtqOocUP77 zsR>f}AvNokn#poHzRUlDB@mgu>z^x^zE^%!C<&MRrY!NOc9%Cz>wpUsWEgyj#_uC> zl#BY(aaL+hPH+u)X1Zo3HQZ4#R(SLx@6|?P67npfVXTGX2>L5jvGl?|$jD(J_DjD! z&PzbE7pU0bc({d)SZ$BS)l4ixw{m<&-c2l&A(c$3#Q~Su1 z4|RO~{q06gca4XYTzO9`PqBsiVpfKHO(U+)f1Q9Uz(Amk5aX6bI9^uA`Tc99ftu&IQAbf!#auJlH+yL91Tl zurTeE^?>U3J5dqv$N~&hpL2P%5!ub2llL1_xc3vWL}K2z&}A`$!lX&HkDPkbX->z) z?CfY_b=*qxp#USij9ZAJ*lXd8NgZ+2Vd=gFi21hI%I@m3(85Diue2Y9eM$fJ&$_s( z%LGQhEJE%FR-WjG=2`Vb0oYiD7=4XSE)aT7U7VtfutOvZ%IG66I}23$l}2QcT`!3V zKZ|=#XT6$HEB|Xufd+bY!5B!8c-o=Ik36=b-0`Y2pIrDGnQ|}8o@<1rn{IbMUiIRH zB?hsqJwn&VL>Z7L&wD3vwZ8HWr5M`Wh^3qtbe%p=99r^CT0KX7`@MW+}tAt;SeEI_l!%eMJMA#u%Jma{F+N6Yhz#8koqCZ;}pd zL=+-j2^W~{jGc25zbK?NHjv^5=2%nQ!YZ2C4a|rV`zj(24~19Ai3@Kacv?S_Sj=BL z!$+MoSCHxI4L+?lx3fmtN=JH_@$i3bBIz#q4S$n>6kBjvnEmWj4%PhZMLd=#4ZX@Q zB0tY8To-w{b49HC2HGZs>9f2-I9`vW#{8RrGsX>am{jl_6|8n{q`I?yJYaSq0-$pa z>4u2*>~le)F`eRqSH6pbKP34Gp_8yeL=8h>Gxog@0yTo{m=O@TB;NRc&t23?Dm?hx zs{8I&6nA)T$eBlYMD0NQa!>b7;v7YC#*%YHEC70Oq4J3fLdpG~?-W2m(^1mUGHG~E5XMqe0b4nSK10G=23<*P^S04lb_UGI zKsYde#53maX+tRnsz)^}_h`eOvHXsIk)$EXFeJ}OMg_na{ojKw3l5wGs?OaAG-gs+ zV;t%5h|7LRkj~0IQj$2y0*pfiyrt`UFM&w!;SsEo6)GqAIq)KAw~LLsF8;x++n`Sm zzH0u#%x^#QhM#2ySuERIWdCkg8q;_g!w=iTMat&8>=e9LXnw%>JIzQoxi-=JRZdd| z1IW#-g0@&boga0+)55LS778_+){~;z=~JX4L!Nly7F@(irtlkEB)J~r36{TnvZ*^Z zsTk%VHMlb8{v=x$U#Hp+fv_aOUpAp~@=Q}if)-V+i%gUlQ^+1e$TcNs>P{Vdx$h_L zM$EeVrIN4GZ9U!C1=Ksi4r-uw%d@1ko~y-3}U78S$p%RZIwHD4V}dhYU;< zF;Cb^g}SRUuPt-7)pv(7=o>m=lKXLu;#eO9MYv!`rvT6kFuP$(BLyYv|7|F5807FH z6B8_YW=}qWBOQW@W5bz_C?xGvqF%95qC`LU2U7|Q6`JRxxADFu2YeAi&z?`%!RMWEEB_-^#GzE zxL~!_60ok7jZCBDZWhE{+eZC0X7RTWryjq-ikZd?9sWW!$ggo7)BmyH!^2FO^A7-5 zvMSD>5%#`aD8;N7{#Pngy_OfjR4hCnZ1_a?`&g2e*6Tk|5sWVA}x%_1;;`in@&YX9>e2j zrX9Fd9@8)X<(e4(;-%-NbnW|;Qw zSgDL4$tl7cTk5zoI}%}d<#qnF-RduSKfmHmrI9?85Nm(SkbfbxDp=^Y=?I#T#mEZfr*SKIqAysIP$$4^rel<76;`jo`c8MM+&fxGPB@ zjG})KG9{0LJbWmMBW2!(DA;i7Gi4CbZ})g0u380}cMxtAkE`)#w0xrPyURlkmO~^r zMsqY6ih|r4o%f2DK*BFGmu$?}u9s$wX?MoIRjdm33#s;5A2As6j^kypSIJXOdB4%b z%@$z?S`8zN6-(c1PN~~s7uIsDh-4#vmLhCIDE$rT4ij_R!t!nW)YkEj)5g!or$}$9 z*<%@y&X;Z*;<%Kh1!96*o3u7h$V4Q*10JfFNK&a0badE0)vNhJ38hQ$A>i)9O<(m~ z9eQ_o?_eB1v(xfuvH7mf;F;0>v}!ssa~wXto669+`EKINw`z&hpQvVD3m+y? zWzOC>EUu~+9rpSKYY>O%F^^co5bPHj9Sp&$NT9Vx!R{ySNK7BcH z$HRYgab3+8Ze1;zuNm#rZc}xNPy1U12|l}O`5Pq%--i3z4t{-kjd6>gyfWRS${UCz=mK{6Jp)Vz-$5nI}S<)0#e7?lM z2%cR!1(h-m*M+lgm)umpvaxnY)T}&bC?PQxVrH;*rQp?K&sZZ!&-9r3*p&ng2d6pV z;IuHop^|`t3->O)VPj9=dKHzPL|h8Sj(m`iU#Sdu8A~z{fmG8VIltzmikuWSBGRAS zFD7m_f5jAW8W`qD_|`e|4~y9vv&iHtFEJ;hFRzV?v$RCq-&Fy9Z-VwceMEilEBD7=rejZO6Y%W;PwIdfH zB1s>O&jG3`@!m?Go($S%inP(W7|b{|LxqeNX>1zyC<4lR|Miau5PQXV;V~KLnd|6O zXIBreLN8ewo1vi;d?Z&&tKkm?^+iP3+IMOc6NZMw@=^1M|8Yua+HRRW()u%hkS>F9 zir!Psov9RlvSC6Uk_#mxhkt1cixMxT~HEFS8AYw;^q=3l-%uJJQFOa_9kTbEyxZlazV+eixHFN0_In%xg!PwfD&iM z;6rw%i!Gws%!gru6F@42#0pPyVIrt~QLn!?dZkO?K~}@-p>4ySZ{>=2cm)U_& zKq|DUOqsx7W^Q1oD&flh`N;&aYx_6A?W{4_e(NfAnvFAK@1=t-9W{IZwW-n%e;eLK zA*p5>-DhMM&|d*W>~uW^wB>#^(1-njygGvYM`0q@+Zf4zR&yl_N3$V)cM^O2-1n1# zxW1ZY(4Kss7JFBqFX+=-0bPW5owwCYmB03*6ClaKFpPry8Kx?@*ij0-;ya1&3T5vI z{-+nU@sws+KN9&SHg-n@z1MBy=;%y)-P^R=n*-H1>FE&&T_L?kTV+w?+RSW|W$Dc? zDA@B|>UAFv*QDb{+?#2G`WK@ES?k=-=K@S-AkbnHs<+;P zuzy6s$ere!w0CB+%>w~ z{a*zt_=y=q=!IEM(}55nS6U0HaUEl~9<-u)XoNgM%XzS((9i>tResetHIrq_ic_s@ zIq=y1(}g_+6!KzoFLQyff7OE3tk3@15N{~&KS3*)D>}W2SGt3Z*(Kh)l;h9Wl}S0E zpGg=B`b*hApX!;y$md%3nvsS?0a2S0Y|NEIBdX5^Llw(t$pKOA_ZR5>^Yk?1A@@qw1_yHHNh;wcx+X~ zlw4pm-TU@OY8u|re1^*KV&L6)g$us>yBA^i{PaIdN(=IA?bPwwqW6dk0{8*_rIsIwK1&hXZqz7>4_QpMqCm|Z=-p4lp zJ5a{4+UpDvGR2dWN|zM{_V?P`Cg1Yo>WWchbD{G4+Vtep?RzR~q@^6pWimbSJCaBzrjVGa+!a7mJuHt_SkhRZ^A2#UXI18JP^Vr$|xA zsv*bshTn`gqtx)7Vy1TDtY@T=>$H5jb_kTaG^KuAU>xip{N4e*q)I1_>4` z1Nq^|$tW&Tzq)Q%`;(Xfs6mxZ+{_%5MR4J83d#3VGN3U_K6*;jIDpaR(tcVvDbq?` zcgIiP*g2{U%9%3^tO}-t(6kF?6EaL?%<8t;W0Zf#?G=r+4}ecFLu8Xi6}Xs^T2|H& zfV1$jpI&r|82dt$r2|Ce_) zkPxw=c0BoMcM$KU3gp{KLDX1aP@^~ytGv+keM>2MtR_=2?foeC-P5WiaOCg7o+YIU z_rpui`4-~|E3tx_FqP6c=X}Lv0qOOMXjmOl!(}e56UJY??!G3_jwB-NfL8_dYi{;Z z1`q3MIB$-55{NUSs50ivG9$FiY-OYmHb)dX`FB~dTTBO-*y0MjJ~Hgib*{ngn;G$g zk_#E4tk3fVIFF@T!4Jon?KVhN!PsTInPg(y!X8b3^DKeo(Ylw=`iwMV zLNBE;QOZM`@#%jgsKp?^wz-70D3`3VF>NrTCvq8N==6oP;tBFgHbkByd2Z%JV~Rwu zSl>2Fqnb)K7MQN4PP7`FwW6E_Q`_;H;rH&(! zj3_1#WLOR%WSPY=muG7}f4=yI1OuEllcP<%neP74w2Eu3Br@AB&xx`o z_NgEV+xrL+y##ytA)~fC(QmTMADRrfOn$ z3H8D6#h+U%DlttN+jid_G;ki@6!%GT_n%eVT=>l-b}I{>qVPlN;&^fcd~bAO^~HqG z!`sd) zd)d5X7Siw^@w*VGy3W8U*v=bY#@wlh4ERaGnrbA-QT8pbm0_miXUAK7ZzFs#etElQ z&FB8Q#~&8}t_0S*16~?)2N(7{AZ_+uyYj8_la}URSiQ=EjX_*~RUgsich!8ihhqn? zP6a&icIxB+7Ib;MufZ{@RT~mLxjZ@y9xT>NnYy zkgeO`Dhq*6A&?;f4alRV^BVrOF-u79MMp+~>Dq$H?+~>K^49zK8=!viw^7h_|5Hlg z1KFtF-_0_&m=BuuCREK!18?=l;kOzMz=MGEPpzwXe096^d-))0lf*0?_CiBr#SqHU zkG!X2188;4$8ZkAwY?mk&NN0z@@8PM^g*CHb$E(~r+s^Xe8I(zqc|nx8M-F`S+8@U z8;9ImH@!Hdz)U3Giq=iAc;O8L*~l1*FW9D5N@qIHGRhSIAmX}SFRm}Z4;b2H{ptHn zyAcR(UDn|DzC!R;EKIe^@G7iBC%PL}yi3s)N5Jag2fB75h}3u~0&4jrINMo|z%nJl@PzDqg^FM= zMsgZR9;trfO~Hdnic|8OSb~md&J{;|07X^jHC$O>Ksl<+`rc$pG#iorb2nSJ<4ig| z9b(RHC*+jZ^x#!@OI8ymm$Jk-!vpgK0S}F1;_&a^ubE9`L`$38QDz&FAh-wA*U>T$ zAVOgH@H`6XD+ai<{K1lOa2A22kTcO_CPlXz(}JGrASG&kQ8+M&MEvEuo@>=<+DHfi zDlG*-F&`6HO-*zz2NfOamlQ;w=-gZhC1l0*Z?xSUe2_@5j z1;U%aJ0ag zLIUL4I6*+2C9O(YvDFKOY)Y?1mV zvCxiq%Pu?-(y$o*FKU<|byqV=HLKi%CLl`MaAprkTQp9El23G|<81DlzMTF3Clg2K zfJW1@cbxq8=d_I_(vND5LC;*zm;z^tDxSi2?4QM|D zRS2k}R4}bPDTA$6>mdbsb@E!X(rs!NJ6YScZl;Uat@vk_kY3O9QUg<$b}CoNn&A7 zXs>zlu3K&J9JowZcMT>>v*n>5D4&~;;#!&w)inaw9xr->=lWX#dh=cA>1Fdv=f2-s zRX$ug)RJ)(mwgkP&3{ZXk#~1q(p=`-GZ^sRukE!8M2849U^d&)3+mgy7krv5-CJ~m zG3`pD?JW9e4TPeQ1@@&#hz!Og9zpidR$qlV;b*Eu3XR;)_P__k&Q-D&9za0arq`>7 zcKvC43%Q{NIo=Y|)zJ3WOI<{E=jw6Wy$t1o#lHVpr4^_s@dHdTQAm7v2~u0A?xUNK z=$7heHoeitB+c6hI#w3WJn0{Op4CcD=;QkK^<%K;5=H&;LKKS(TZgt|_RC^fmOj@1 zY}qReMp!oPfj64qh%+uQNsc`DJjcv~>Ha&L;Zyo6R()MZfpEvC5m=p!>mAs_4WO}h z5nf@)fnH2W+0z-V+u9$Qq}-%5)Kt2rBq>`hHJ+?&vqf%NLRjpQ5Pe|2+}1r|(%XOR zAa&mbH1eY=FgMEc^8U>Bz2E!k?wy-_s96Ci$zbm6wQCdGVR_u+(MgXS>Ny@4YLNZd z51WaG9OUS}dFW3qH!x4$^KiC(X7pC+vj%{wn&rQt>qdb0x^=|YbKBdRC7_O=5^PzL zUbZ%CRKt-H@~+>+2swWqGTb!;XgAYQX_L_2At*W2?VUO@hj51u!qPZhc6#({*3yx9 zgOslqCD947fi~n3Jb6!E5w55#hss#gdz&@8J$)lo(ktKcy+QHLip9yAZ25#+`4z{- z^U~tuegAxuoxiUS7cTE{|E#*mj~?S1$!F`UvF)?fQI+n>eDpv0sxHX={|%C=U%USQ zjzIpCub%&J)ztfi4WHTdyKZz!gbRP!wcv1c7I#^2iYYr&MjYI{!uH}@({PVhQ+lJ% zxOHHlk?Wv$lnRV)0;}MQ)dN>}vYc)6A8K@*%ADjmI+(p(g@q8?^#x14+5@`*K1aQ1 zU_eH(2s*uu+f*%K5vQbJ%gOT_Bx4bVYmYLdzHRWYk=+tADJO(kVz>Sy6$6*3*KPx_ z*=0{or;D^f34{oT&_piY6}@r@D;agYC1Inez}StMnhP>visY`GF=VRs)!t+76ktOo z^fARUWPd=2>M6}my-j;>`@j)U)r?IF>~9hgL?<*r2+B$p1)dqsxV<_Swv3$SS?EKzQOQ0(QVYJC|&m zihSlfdGyI*Jita`>k{%0L3_ePVtXEGAX{Y9logM#YLoFG*_41(N4YDvu~xwq$n~@@ zVQ1V2!~W!8s>U2lqum4%+Bck_FG8XSmheGe|0q(xOaGF<)SY@9J%}HqkdzbrJS-nE z;xBbD2nq7^@TB?zyRLz>;I|5FlxLqL3}vEjjP+YQyM86I9~R06Dg1A5uA_yO6w{=* zF7~T_51%Bure!Q>PJB@$^i&B#DK6Io#FmVwm&=`=!%^v}A-yCcC}FAdBZr!Xuks;D zxn()JC!)e16Dnt+YiUU0$An5**#A2B3od64eH$)(m<*=#uI~al76?P@w6Am-EoawV zDR9d5JKvy~S-Rvj3zK3~EO^LDP9~ZzZ3~e23WCe-2wq{}s{L_?Ixl&2mkqz_-+vmP z_l3I7y}sjln8e=eKQAt=Mxh?4zvb0%{aEA;20(tSps#AD9D>410`flvMno`(uz%4+ zGiRPts`4TFSB@OYyC}yjMN6j6`~Y1eGs>A_uTMR^5UzWvP+2?zs08)-tn6Sg7z|My z`o$s-P~HZsh}6hPYenq>Yq|D2dvT2j((I#z-VkGOD~Vm=xTnJ%MNQI-`%;Erk5>go zXJ@a$l#3GV@)c~5dbQ&~`-D3=AW4WdiI9WMWW#&d@&OW%(Z`B0(Ku|3vP?(mWqN6l z(1vD^Lb?K{RsazSx~M?G*>Qr<{UMY?kwXF%m#nkriQwZF6Y1j#4x{?>poIE=u%H%M znYk)2j7j1~iE&%4S~u>ybk4pL&W$Vyz>rLaz|8Z;qOeiz+^%XkS~ko zCc6a!^aQmJH;-F*u-fQ8PL3jQ4*DDDKZot6RW3)Kv;;T*o6ghr>SOrR)6XRY{rW#l zy<>M~T^DW}+eyW?ZB}gCPAax-I~Aj1+qQAXwr%s|dH30;oz~V5m~DMnYmPCl(YwyB z%pZ^!1#@@)Z4CbY_uL*b@DK`!py%Y@MS4i#AHHBx!%xIU=R{p3;DwKhdg=PH;Veq~ zryzCUGK5H$8@%vVGE%`bjDT0xmi-rL-93{rdh0?_s|FL2&)K)d-qo^G&WkOEw@1K;<)5=f_Zv&UzKU=y~x+=MQoF2vTUUmK(-yuDFd#*rxHPbg0lUhNt zK{{MuyQ(Am<%bG^;E;jG@8N7-^|s!AWFfM}Kq74WL|2eVzaRpqOx(SE!%KteYO|de z18QAF&M*bdy4R@M7eZDIWLhWDo9!yE;*q}uC-On;YsGMzoa}Zsj8>W;!tOh>hReS^ zh)`Nt6Mh2?zy2l^N450K-TBM1O&`qy!;K1`sEXJAvlodLea}dhG^8_APp?x368tAM*vh`8%DBx?NPV?ZLp|c{o_qA3<67~_`>d55{w>;N8co&>!p8I3GA7+K?hgk zwO&$qC@{{Qu5`4eg^sBSfzp=HpBD`iMb(EOvUujUibGOd&@FTs`kRp z+I|Pr&T<*#JuS3xE?PXz85US}+x^G@LOpc?g$f|BG8|ZrD`KEMvV|WuQwlkicPF?@ z{k1QkZvc3GU}DxRbXkc{_#gXVcJ>(WoE8*WFqP|;!3@d2k%ys`w`!VZ6KF$D4&#=u z-|@Pt{M3Vo$;00zM}4@f+9;Vk8{ zhfZNt`7MFq?%v8Z3-Y=`V0OgaF6b4{gp3^ub((5h za4#Cn7=tWY%y5dvSEE0{C-dyvy_e9t*?NWD(*GZPYFI%5?iaSl3O>sKBWYZLiQQ^! zQ}hp`yQY^a8%HMBQAi@jdf`JEngB&+@;i%lQkhJQHbF#X%s<+mZmZqp-Yil$&aB(+ z+2JLsUU2K&)KQP@(dUehQ}$NS zm3mw9mZ+Z`h>MD!dSBhDM4BNIkpDs(37AC7WkSo)U?6Bb7oHIhZW$63pe#GD(b4O9 zdtZ6`E72SC6ehbiV@Q;R1rkv3*@vFW*O%4pK94j>4h?M~unK#63X2SUc=|RVaO*x# zTu}2{Oh4p?3-yVmJ#eNSzoZUsmWtTqAzsEIQ+$Pa$EI h4bHz6l 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

}=x!^rW{MW|`+S5&!u~57TGKj8uH;Ql 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%0AhY}Yq;b6APh^|*8c&` zJMTt#QbeeCn#L3e|c6b4Q8s$)bE7TNe4N~hIP=OGrSM%E334nT_j z2h8bQ;VNGu_zl@k^sSb1$kz7*78nH|YuY!fwxkbP$+nd75p7?Ek5?+B6`vykLTlU3 zKzSlQ48hTU?R7a@eTuKkmoxi+bi&)10vLZ8U~!U*XSxPuh-en;>T5pVK9&ubt4XkT zLE1TVvlwRjHNkM-F%1wa~|Tbc>+(pY1a~{KbhU+=7a=`r;5FpuJvone1B{@3hN?E&9Q^8D9$+ifKK|8jI_;v3}w?huOptxG9-J z&4ACY{B*6J+P3Nq{^})N$afmbn`%02x7V%W`&aesn6F##KUKl0?9h6Quc0Qq3<+uy z6B0IY3e#^rPId9CWW?LXD0DlR-w}Mw-Bo;i{udbj_s$m^1?}W*e5WLg)B9rd3qN=X-%=vi-JA{;qvrY*vacO29pXF{&cAuIm&94xaP8`G&*WAXIL* z(pSLQDSbUy7w##5t)6>uKivRjUwrHd6FKxhU(YroIa(s4r>xS^>eY zRO&`ibMY^eeFanWbjaFWT9aM@30ib@qnnBdBlK0KdN>KUUwg(z>|wTVb;y$f>DR(kixB6d(a z@urTr*)==YA}4vk|I}rkb5b%XwS&5Oo793*5lXz4M^H~SV}=jYI7wFb8|>tb z;)2gFU+k%8@&>jzUI`p+3HW;9ZQggAk=X3=zA(75*e9~2kxZi~vKC4q;_@aU$`u%F zj-&F0@iRsN(Hp6Ei57DYEb$#WM(>O}sPI8f#$Tr^l=$TA;y$Sm(+dc;H-4+UcJ>kh<}5b11|fyR7+Upg(2d}n~7dL z%rP11jt8mqtiPmwEo({M&yT+~g?C#13pPF+D4$AOO=Tgb#NLxK>JpDKG?B_3Q5gbc zsG8FXyZ?NgpNKta3w6r3?%dai9J6C&!YWR$+fW$(aY`qyiDC|**-lX5i5 zm@BD#2x_fXB(5!v)=CnKl`a{R+|;?bFt!qSUfm8ZB4MDTQv~$_Z8+ZBAN&7@b(G%U z-d@2C2W$e;uv+}ehNjVbT!eF;-ssQL3nlVLE*$6Bj zo%#E75l_?0L(V!;TCGeA+LV)EgPi`DBhwp$E5R131TuHiEDOk!4Oy`t$)=&kQ7SXC zTKumV)^L5XU<2yYXez3NRxw!*v#7t3NU+cI!y8nx0g=?y){Tae>d|&-SZt2IF?M~x zU6={LP>FEdW7+x5zE-7N;6n$f?4pq+uY|#aj*$%q1#1ov|W8Rgu4_W_4((*@e(j9f?nWMTEiauGILw?J}dJcl=}oJ58-;-tY*hm=}I!p8KS-=-}LPX2zGY7 zF=!8i2Jd+IAw0KBoF%o-%*{Mwq?+`M)=ZLzV7C=^u-6ItMhwBA?^(!Bcb1I%OEkH$ zKb-E;X#{V7zfXN%&;>B|FSA#D$MRUzryA*BOfMj7>}*C=E0w17hXwtQ6Ap^c2Cv~OW; zs881U3?1Hh+=hHb+yKjXK62wpHfbNH%>|TV5gF3P@Ix$oTA}<9v_WLc<~i)~Z$DfP z{b1U_+qfrt5_arpK&OIRn3K?H#$~10j4+kR;dYSEB`-a_J0AVr2LS=!R;GhfO5PwB zfH6NKyE*R93VEK-sy4fnESt@5)vUM3rHU!G%>pl@0C$4#=eBRqzX9%-Xr|$;0pFi? zy)QZp4nKtb_D*Yd4{(z0u8A&4*O|&2@ST%GrJ<66`t3s+Q*=2WjKh)9;fgN5L*DJW(sO4P(`%7+&LG+Ihn|7tp_?^(0^crfUql$l! z&V}xezo33|r-?xVy+7YGk(8ikGu!fr`%+UyAN)Ru~Lx^{e) zpeTi=X4iE;AeC6|#gsNa`MnM-s)@v7gbWr50wXWUG1P-Hjw~c&V&fMpdB(=qLn;nJ zmnX49^utTg@)`q~G&hzL5TFDkGzw*L;)u9K^Svu1C74h0ZP`1)ODxLvS2FsvY_DsU zFtma!#a~Zl{WA`QP~_=7ul7HZ4_Kf{Si3~nnY2p+-)<-lDcXz(H|`|o^l+ME_`&Vp z{^0h9w^=Q4&U{}S(}^2^F5W_tRQarK3dx8o{;MwX3W;?-!b4%E!Rh#5@&HBf1PtC3 z4Dd4An<%=-h3HEn-aT`6^S(}<=|d84UlvMJC$(}+-{-e*4TPeB1Hm~~h&m1;X>6TP z+uV_-5?J`}*2+wg3>HJ#q2YlVA|-r45V<#q)N&YC<-T72CQ5OZO66+f=2$D+s4_{- z);BW8Lg@ZkIg&VhkgGm<1I)vIN|ERYm;3t$4NeWZG zzU*Ee{z3H2=XRQD`q>dtjF0=SCh975c)(xqR3wM85Kr8%?4-U0x4xgjY8Bcx{!Z7} z1;3I3G9yT4{+>EZ?SvYwpPAKd|6iK5VX#i*6Gzst(!K2tIT@A50CY9-&-)XG4|GB! z)6#Eaqx^|d?=f=SJ!4Z3HikA}R0_N_r^bRWlnfv}D)uTjtJ6p0_Zc#E_!e30A&RR1 zUe>|7sSDDR(>y~bhRa=+Hp=`Lc5kU(-{IL-*>jLp2^V?-FW{NvFJZK?Fx2BFw;=Bd zHRfQfFKg5G$_ykCyD?)3d9DRxAS^!@9zR$AKz4R+4()Py;Wflw8xS0C~_%`5F)9=*lYpfc4^>M3~d(aEm5j-y+U;n|_ z{R@Ex8HMIdRJBKtRG$pXq%1sV#Bqlj~&rlQ6rfU8>N2 z9v`baM3WOz#mO52XqFD8t2+Oq*JIcEJ}2vK128lay4w7CX!3vBZuA~S26Se2nfE9GfqT^_i36}iwX4^(UlRKJX+Zta(WhE%QN zz*Px+dKQ>aQbVm)KbcGt&ENT&G4eQTQB5!@_x8Q6oq8h^BR56|ANuAmUrEuhCpYe~ zWRls$una6OGMJrbDxhVazy?d(ZKZ%7AQ^?#)JgNNjX}<^aV-u2?;vId$4M%L|4Mbo z5^rKv>qsD(e${X_-yc4zPj#LSq5Zqv$Gr`EpgVMI>r7QM+{sAnlreRnjb8^4aZdF% z@It0r*xp{jPq8HYXm;e`d_u7r^2+LTZd)q|WKUF~$x2eXsEwI0B2`Ma-cKd4p(7sq zm!EyZ(+1XV*^Y~*dBvZJG%<64of@Vufsv|JB|kd6ST%3$0mwsR&_3cs(gSdt{ zo9p1+=^k%>lsV$A<=+ojUt^w^pBVp4&)BnhfcoSBY|H{`a3Ga2E=O$9sE zl$j6EXOb{pPUNyKJ_V}O+<-s>qrK$?lW=~!$|*>SK}8Y~>~@R{bwe1CM3>;W2IOfO zBl#i>Z&q*Hxe+y>P2}GE0hjpBCp3 zv@;+P{=0;FoYro&TIrf-VYYebYT%iHZqRS`=?|oAqY`54jvQDUxaP{edUG@KMQu;GDz?=KBqul{?S_$~7#&?)JCq_5rJ?`uSUc=AO}= z)<442k>h>~!@THXp`YV)y6acIm8Bz!Q!|^zoh)S3rkpUQ5UEy>!r^{{zt$V_ei=a$ zFHmG%er|zSaLCh5%=*GNx`Za$M>ik}@M}?O}emC-Jn9d2#~ZYP~V8M0~jZ zhv|+~@k4)n9_(Pegx;j&Y;o+-vB?$qL!sxvOeo`5A)m-EEqvW#00)%DN`+T=;J$+jMT6#aN;9K^Kknf+01_QK za35Eyr5xgyF`{9|FC@=Ie7t~&7?c=36=0+3*V2P#sPc8p@v3*v7lTBy7|Q<0w2@F=Yx(B*%=fSHu^7NLb&eQZx20`>w6^moWUa!_#OQ52|bI)Kb&su zjY~mH2@1oZ&Ck69S-g`Zvijm8aFuC$+6^F^x;T5$%0%uiXybhdtvI-uo{@hQz>t|N zL}lOTROr02%W+`aQbo+@ z<8G_*KNi*W>+WRCpXBU_J>^D0bCg0LJ^zumr3@-ncL#3j8iFW|w$>Sm zYO+JMlGaSLlL0IB8h->6>Xns3zt@8zQ3xg(XOVs6`=5DCEopl0g{HYDhj)Xa8X5tv z;|LgMA#ZBRXfp#i&Ydej<7I1g(1BeL1>%Ht)?|Gv{m3T%1Zg z7;`|UdvL~RTw__$xF>&>(slJQ$`S%HpZGwwFrCJ!v{4J&s*+#VFqvrL53$~qc_dn5 zmMl#pNt8y?EU_mA8=~tTPd6AUjJc7iHL=NDMrk5y-c7;I?Va4#2s@uk(!AYx8cSpJ z52Fx%oi)@;E-Ytz1T(_9BQN(C!Nnqz39hr3tBE!?3qADVG#`*LGL#D`Yq;~b7{>j# z#qG8?&T6aM;L8ULiNf|k9qKLW<#pl9`Qu+mNXvg9@Q(T*WA4iO$7}lTJ=QC>{{kG8 zIb@Cq#iX5UNOx>*3X!EyM>acrcQHu|(Cd6aIUt+VjX4u+Q=(@DeOV?gp;7w~p} zmcl`FgM&aq4IuR{&2p3MSaZ(-JN`FquIk@Km`P*KqWCdLQAVa3J8ad!3WikEJ_VxZ zhdcm-PZYx~$AQp9DUYq&ssfD=EBb68l0iSbHO#i%^=>BYnBCU&*&OmG!Q^d7<*_<} z0u5%@;%SVSZ7ZAl;&@43smd?Pa?Z9fu3gHvo4<5(`98!fH8n7aeS1BzRPjiU@FtU4 zx^RL+MO!T1@X*2(($eQ}aKn`-%a{m@6vaAGijUZIh#7M@F#YZd~otZf6r$bhwW4B0=bo`%GLh z?jl@n^q0^CygQR+RvwhVNNNXy!&+4aD2YlUb^YO3r5U_?fe5!az}b_tpz-6khUlkF zUb@P2I}?!}r1CyD?j%Hk8Z0wNi^n?vMIDQ?R=NI)o1rByknq-v7BpprzXjYQnNXq? zcUT&(f6%F$7zYjdw^tV2R^4ph>TKr5nx#8A7@vB*XHOjgsfsyA9huL8vB>t0_@m+) z6nKhzvM;PdAU9P7t3!@ow=$=sy`l{v$+NCyB`o18=4q5MCD#HXku$9qiiSZIHdL`n zvBfAHP=dDTn`ga*?6BVp!p`@X_pdbY-xn|fM8eJ|!7y}Cw7ffLLnB;9?zmG}{(pv? zvHy+rR{?8&LLfD0rp{}B;b-{;ci_m$qNUu|r2ilGZ1&pAV~o zp3Pb*hr}9JfUtwNDA$H4t|+QXIXz7-H-=DSp&P- z|J*-5?`=qBx3irf_s7ld_v2ypuaj=wQBK>y1Ljm}O-h>#z&*$Hc2Oiq5_;KEYX@w% zdXwrYc2&ZA{pQokDV3e;1dG-FEx$wuvT_AzhZag(DNdU4y{g!x~O%^USi zv~kD(XCHC~b6Nr2TrYD8Y3Io@%@;EC-o;YPMSVbRmIwXz!^)^5(1%veDeeqF*)H~W zxLWGJfB$xlYx5!(`A6TqUi9Ee)QF#1KOo#!EjMc?noC+n&o}um4j8Bv z3g+}73fi6T&0xmueemAsjBioG>HLc6954SE`*=yt!sw1l>_Ri<>B)mE7p*3)G$M$L zI+rcAdQiUEIwYGb3wleniA@+=b$%$yk!maQ_tiOTYSTU*S4NIvJ)2xub?o*aOmP0Y zR3>7c)9GjwIpS^cxY!+5PrCvPw;Fvp%onTY z(`NHW8&uo%@hA9=dY-mReMOJ@KGzy8?}=U|^YVH%D|QP8yMNS@y8zwotH0;@=ss#K z_whV;(AS!=u7}!2Ws3Q0x8M{?+`YVbKGJ9f=J_09wy&Due_U)<^DTI}npkYtIlNzP zkB^((?pN_x#L_Nz8OqQ@#@ovp;(^qd3r74wDtk;SVP4`W&X`r#>t@^mo98OPgW>Pe zjM#g)Y#3|1199)?m91EP$H4nI@HfnZV^^GHziP9eDo(O9Uf^mCuEZWg5{H%lDN5Xb zjxBLTM?k&1g74Qmv-{n(ai+fbk2V-2JwJ;5dMJo1Hu*OG^Ry`R>3!J$AdHSSUh0ob z*G~q%)caT|G(0aK7}lKb0tgsBMN+@1{g% zoZC55s@F3~xe~%JYXK^0^(+yX62SrjcW3Nz_j&lEX0?G0T$<&)t2KCM zonr>UZLh1tOUs5(4_J#UCUB;|Ia5vy9Y_=_pA9fwIp=zrBS}c6Fc*S2?Y4fmZQ#nO z=?umE-!G3PQ#seb1R*R_iYp^)c@}KcKa9<0v9^)aLpWE^yi`Z=gG~~+FR{AHyNn*B zeMf1GqX#OmNsO6MyS;kr>-HKebp(qtcl!iTPc7q6W;l4UpWQyq&m`04sE!%|2jG9oEbZa`dcD6VN| z5-#Kek@f$=jh;=;#v}Rvx(v_^xBeGxj(Rst!y9A?ZrB}E?_xbsUUv_{nS)wa2ZZiW zCR8hxAz(*dU)39%oFY+o-hvp1W&=XMp z#yl>Q&a&Itar2c-#8;AY4%0j(nez@vYX-=SE|t+GGL|&Pw%Q9N>l%v}S<|uH9ejOx zFgE=m#-J*x^|)b;)~lsV;t^UeQHuji22wK>X=Z{8O$PtgOlg}dz_p;1WgHVJY%995 z6f(i2cNIJzR^}tPKAO1k#kEC)K7b+H1?*7cjX1L%dX4@{jFiIqOItVCUXQY06bmfu zm}bjRf}+9CT>Afr>$*3YK~zG!vbX-tX5xqQkm#xO)bU*9(H2lR*YR}NZ%)7)^--P2 z{a1c1g0!l@JA5@a19N%?=I7K;zNE<-p_F~eV20h;V7$Z~e9E$@roCLM;aY8v%--3q zY*-$4CTRTuW{Y|yGLxQfI%|F7>k zTOxS-+vtqcXN!<_UFgOaF+mZgn6s8MIV?*;s(v*UN!q^P&}(j-i%D=UrhW{6e(Qfc z>3S1c9+5RVsMr))6LZ$|kf59081hqF&zv%;Eohs9a+X+_V=a%UV_^3cpWW{sBw*|A z4wIgx7*xQNz(I+378LLzNPC8(-BvrLwFMwS8=689*?Kj*LjEA z*fBh^tXcLkZ}X@-+j!=oZ2zHZKT4c>3XoK7I8v%E&0uoB*zUs9b_?gpC^$_9E@qAaPZeBphiTnhakG_qq?rbwu0Km=x4CgS!% zLRo{jj=o#*2PzPDGMwZ$MHEy?8l%zcnHg3TgNGuGkEOHG2?>zbOin_&V4N4*t4GIdKu-64f5QgB0e*s8nLIQ zm`8+pbhv#@d;eyA*#PaNJ?po(C(@u#I@I)2^jj6NOx+wJSuROj{jJ-QXA-x2u0W zKg$QGe@R%pAD9g}fcxR=ogM$Mu=t4EGPqX)aQaoxhkW>mHggFkdV6R?*Es{+eslo# ziOmfI>=l+gL*wH0NSPSOXuLi+@qR45_jLBd;A>aCWP&+rN!4_e%N=8y2?0Rv@9Bvi z2ZrzK$nWo}4`LE=EBKup`OaYZ*&ma|kZL%UDQ?GGmA6DqW$}F6f{z+UKlfv@WBGn- zeu&IS!Pqm5k+db$7~p+I1rw1ij|ZSPX%b8!0&)O`g4sZmmnDD1qV(@hA82=paN*Ra z%5O^;Zj3lp2*r^;MkgCZv8FPi6)p+T^afIBD9bQ};&+m4 zqoW5@wjJ=8Ng)A#TwLP|Sl%wc=1?WkSxl@P9c(_zm;6(*iAHAS~RuUF%@V+!khmkwG2deI4MP>e4PJEc-#x4@&yS5MS$9E_NFMciJzL@p^Umj((sRsZ%y3h?EIuUB?0MRBZ|$?ENZ4 zRcHCgm4d$xO4(}dme>0hfY=A?b*6h7A&b{nDn4AUSEFylRSr!L#1xjG_e;uB8e+sU zAQ#$Mkmi>o<)shG_QOC!bHHJJB4tk4+b|yL2Tq8U;Pz7rlgNQ<`ff3n1bec#^<`HM zbLA1CqDkPFO9>a%Q)X`^U$Yi7SqkAA~Q*k^@L(^1_IVJ z%Yl^s>rOBxF@S4*yk&QTtXuu)9>KO=84K}@blgTDK7@0eAqbN!&>oC<(kFHFJfhz| zTIh!j;2%7VH^S10ywk=G!lv0+3~sfa)S0C+xkiq z-eLu>94i<=AZ}Pde)UtteL2&8Lm=|$`qxDhkzNLYkTtg73xTNL{&WBBdH<@1E-uGj zYBD9=zHZyR;zLGy2;DYOLwq9`QKhsJGLCnoQ%#({-)utk`hk8kPE8S_A!)p*P-b)p;H^Y%0mTcU&sJ{_3Zh~!_!k`Xlh_6%ujr6(weWJV!u0Q9U~CwNG&qR2%w zdeJtB(EwrdQ;uKhJlRT`kE;pZ1)l2y4`LL{{wiq%vXEgg=T!+S*n<-M)W|RD`#ouu zkzd_ENMsbNPU*{wyDx;jD%ux^0p^U`l0(0AmJaEpms+Iy~ zMBpP#887BgJfm~w?>uc(sD#K!OEVeO%Z{ZY{z#!Kc-hrAtp0(-4~*+1f!+a{aFCoc zY5ky~F6@U$J%QZKiFmH$CP;V+O7Mqsg$S`>q&h~=l+8A&GyUHUL1JIW4gV%e`2gJ5!6a%jvBer!AVIvg7avk*|6t;;mhr_Lp z+xdPuNZ&YfNrW4P)8HXWOf6TxH|Cx(=BCuH^bMkv7EFTq$tb}Bvi3mO*&LhitgY)suRzuD7P?RIMvRujbAa06*JKt~Pl*sy|APIc`I5<;a z++6_X7QFI#fSPK$@2a2ILOgz3=`;WDjrbou5fAc%(T7Z;_&Aeat3OA*f}5vB1AaKH zmg`mwO1UNOG08vo0sjzGDi@!i*v*7hG}h`x{dOBm&Ie}sWGx1B`@QYKUj4OS17cO5 zQ7?~gZ=05EclUS{>X!FB4s?TVjjk>gb>P%*n9c(J`-%&Ay?x$|ym(oyItLeT{$^|8 zE;ef|=3HY<>oB{;ua%QCwm2-eT2kcKEJwrrX1CS0@S8D)_op{)V;%vH(f!lc-Les72*wdB`C` zf*#y^OcTwUn0la2jDTtBK99^o57E$|57H~uU0V;GZ}cS2-*&l%_0QF7{`)ujAgnOC zz;G0Xyk2!$H*{ga{c8Rz_m*Ho9C9viPDTyXy1#G-soLLJCT+J_fO%yOCcPN8&Iz2a zz4_9BzmE7WK4kd>eV`M z5_sk5pqEVzM1mI3ab+}zZ#F#}wxx)B6WrjPaf0f^+8XIvBkYFHWFW-Zkr<0c;rwSj{qbbU)Fm08l_E-R0)zfhyLqn z^S0h^R)6VZ^Krgk=f>uKx7j!hfP#2a*rNsaSxZmY4w^7RMk=3TEd93h9Y>dOf)|3vX z$A!_c%$lJ{Y8}$T4en3-a??pA5YKEL&CkE@0S@%xv@Hj0fy8n-rz^x1T4FI5&v@}P zpKEda%$9Pom_MN>vREj)XN`%}gZLo)+-w-y(=+}0sz3YqST39Vw4#{Gj8L0XwLd)_ zPoQKrqIbL6fbK`*Bhy$(lG44Y*#R6!}I{2*mHC#V_Yv(CylQw z?TZeFo5L7UA-EDWEt0PE8#rH3xDEiL%v>`7S;R!Wu3rvwEroIrT1!b|=0Pc_wI1JDb7VJ#;_+?@V>E+a3LnE4%eYJ~ zt~IWYsgm#3_M7j1&jEx9;5}MW3Faa-2(Hxo?0N|R%=ME>1)eL#DiFh=Xo{~3?#ZyAkiBI z@;n(S=RDZnP3D3!_aEcRT*V`xfo|bSse~qeeKbUaD6w1KYi-^-d}KMdPK?894n)Q* zc6z_%da~fQzF4_Ik&t$@YJ=&61d;738Et_9yU6Mnb3!T4?BX)zt0~jRCAYoy&AI|e zA#TVhet`uLH>&1Up0qdgs4i;mp$Y2dxpE@zVv}3f*PX;<(N6&jvo|~f+B8$ zo=u8^?xYz}Bds!_9x|y+N_I&|2WQ3_3jMt&a3~D?TUFCDDqO4Mm<1d44`Z`gj-@dI zwCEF=Ndz3OoH{SHZ+kbD6r{=_j2`l)h&FM#%o}euJAzJkQ`>sPnzO{W8Ox{>)xZJjP&*}9m1kSIliLbF?q=%j3~yX6NFwHG6XBXx6EUV)aC|3rnp9jxgn(u2cNAOGbB9VR16s-jH?!V zy+hXuIeW|VD#_nV8HZkTbJMx^Pr*(1(N&w9o36ZXtYQa!w7%)6bR#o(weHX-=}w9| z961}YM|bxD-Qo?@?<^^#&TAkw7NncPRMAE>AmWq?r>xHzL_@p@hPMUY^I?@sRw1eW zzqZ^oVkmzXhiNX{+ip=E@>kc)tJ)hOQC2*sl3euY#*EV-1!T3{{&_-a~p%2s~hwl!!`HkcKQPMf1T5}2kT?>)A+NhD<7}MdF&3vNH?z~%o!qY8 ze(w&=%mzJG<*Fg)Yys4>c@;TFmBrw>lZq6$a?Wj+VZw-HxJhSe z>wh~S{IJhE8y}J}gt2m{-Bqtlh^XL1whK+dB#zbg$bjSJ`m$Fp|HAP`{u-R1d=aGwGK`lc66L@)Y! z`oqM$nWHI%laW$?j}1!MDe5A5dSCqiO z6=5cG7~fUdHQ?IewA~h$Y`v&-(mQOTH=iQ)_wMy+4Lx$&{@U(-+ex!}(4k8WS5TWc zSLNv`$MK;Yx`%44fPGn|%mQxlTBg^RI@iFzB8msHmPtBl@jzc)G=E7TI6wP&_l5obgwD1rMdGUGi#jB>rcBa_~{FM7YC0M=jJAf7;#hl$i)xX|$R8LSUnj%Ouwm+5WovjEIPZ?1_iXy=?E+RL_*af7T71t2S zkemK`c7?iINk!h0ChoGO*%Er4)L_g`^{=DOqpZ-H0oCs=@LX4UpcqZEzYZEG6jW3J zg4S`rsP4$m>H9ICuE_9ZC*E6bcmm~wA+g;og4{WPU!&ac)lPdvT$iIn|6+;ZUhO zbFItgP|#{ow6B{lukJbQcGgv24U#g*PbwvtauY7V3f-9?i+IWNmM5!k+|k%he_l7UZ)Vdy z{M@~+W?+lu4MhfgyRq`(a{e}-egF6T@O`s>axZUoFURuo?&Z60=AMDT+}%E}C*UNC z_i1nUy7NVvf1u!t;VMICa$q?_#dmy1P3_z)4+n3I=YziPTm$2j?5C1WWWA9Nb?J-3 z!-10sG9{U0vG zfh9ybg`Kvp6m#-OwZs;2uEhvDr-((Q%-+L8*3t{DT7@0ThYbsRm5)-v0F{r1ViK!- zc)-14HxygAD4>+)n}~VRaeSaNc~k{;aa=Fk`yfnkNrrx~{J}{-=togX zvJmj&aHFGupN?wd-a+f&_VA2Lr@Ng3U5g9is-KPCqISg|FR_Oyqab@b-_(MRMg@YV zzSMHGJ{tuT1svY6+F87FfVUST!7!toYPG%7_~~@^Cbc%qg)fjGbX*z|I})ej7ckh7!uNxQMz7_~6@)Wd-__-`yWNE(QX@ z3=ZXamgvJ4EOK!rxUjidu_=D+!p%=`H$Mav$&n7duBV1cXu=s4ctDgf5fX9W;P`kl z`Ud8E|1!v%eVJt+{96K);?;`9u==|)@`Rm-q zH!fb<3S;c$qjv;h9Unqj5F!YwYXERjj=uas$PdiBLKuq(MspCi zH!pzsj2lvFeMku?`4cvm;+C}kScqGzpk29?ewh^2tHXEngQNgN9irL?qJ$%$opFgP z^;&@=P8!7mvALy^zP`$mq&j>l>Dsu%RhiyHC2FrgS4SJ7GDWBkUyvPvE}CI<3Paqb z$HXZsP?3`{s2YQEdtgFz*IdG12LpgBB>?!dslv3uX`hf|#%gY{gkjD{F&-B3@5!sO z2lRsgpG8=NjBY}UA;|-!5Z-Vbys4%>AMd!>_yqQ!(uaP_Jto$9Tv+NNr# zO==BQ9U7{SyV2#2)kF7iTs53Rbzs-4uTK%(_IX)v&cd|E zXM+QG2QRG-F0`nD(Oz(nFOy_FYVH}5m_aaM z>{kk=2nLuNACH0%rU_1j8!+h+3`n4hM6;ebO#~@{plII)JyFXzP%BR0J`qU;CR4~= zJuXcwfwHHyI0~gx=wfOqLqA*WWiqznn#&_*3HA8OVXkq#w9?te7i0;K<l~ zxnb*fLo{0M(d9y@ISVehZ98j=bg$pO>%PlLUmQn_5UCjMX2o^+=@Xk97WAA+j+q)a z>Y3#>SkJN|(XRG^wMaS5u(n{GywpY8QJ!ic2~`5H)jyuME#M~qd@)fSGtoI%1Ks3$ zTZ(e02AFtp8aMg&B_v7rsWUb>}E&+GvrH zc~Dc_=uTE4U!xZ-B8oGN!K@9fT&j8oDOfNyrIPIVjw~ZQgI+r6jJ*jBCM}w{a<@!q z3DR>P4M3jyngxCJ_@G|d!L7TBF;Pzt7Yu3rA2Ov2+8q^&IuwZ*>Rm_wdJJtu#AxLf zgq=to!6+T6&R|aL%h~r<|9wc+vQG+Y!1s>=3v1&&Xmm}6Gy`2?E+|xApu^sxrZ|IJeQ#6)>GEmD zAUiOsCc~<<8SYmtz=YS=KMhX_obGHP7;V{oE}-)3WirL$$Q8wYiq|)i&AE(VNw z9?sI}+}**e6&dBs1fW=_NJoYYqB117%cg0h$dGMa+sCUV2xHzxc`dRd=<-jgc~Vn7 zS-+Ymg_p@SzAlw+!aEcpDyo&4`+`)|JNsWPgyjO6@K{EmH$`GOUpvO`6ptc6Tv->SQRO4{LrAuhyH|S$XcfKz45!@RA_T(^r zBBsorHWSnaJJ^YYt17c+f4t`s`?8Z|Dv8XH5SgSSgl7jDyYv0l_Ab#Wzsxs2D+OBoqnScce=?wWfIUAB3(>}?>4Jv1l zwR}jw0|OgMi5?4;^r`~m?LLg#)$@C2w~!2WOdeRU5tk`IGl5}u!H!90<+{br^ngj6 z$-V`ynDuedVkhHe1Cx5`m>RKhvgmB%3lsMqs_Vhqt{@+2A;UD2fw~^Hq%!Q2{hzm= zyDgp7e|XvLUN-u`T)mm9UXRPU{$_ipd0>fRwu%P6l?{9=8c4IZlA7??U(?seJ*sKS z$B#0CHOgdnRwRxfc2Z12t#-qmN)G?t&ai{dyC~gW|nl^j=a`s;h{M2Uw5N0?D zoU%QN5_5_%_9eF};dZmYId#C?DH$&xl^}$9#zBGKr6=HA2?rF6RFY6o&-9|gqfA;% z0xENwK{BU+o@0ZiQ&jCcPjfZm!DTy*dcdD=@mQ|v&#ydzmUAa9?@BNJEzK}uQ{~^% z4*u;Pp7h9MVD%q|S4sKoa7U}Pfq+q9*nui369xksjouKRV(0@1k2Bd*h!bgU_`bzW zSe5}Dw2PbERX?u<(qvXd%74RuWxYWfN*^-Wh>5(k0S|Xh9bLR3a7Rehdi%T^HjeJe!Q5~wU>oIcj>I|Vo6T-9f7|6+z&}^7`S0K8 zgFfADR8H$i5VTTycXWqI2B^FH)%;iPA;1}S%lF=IPV>sbcCJ-RBNI*@YR7|KSZ4tp z+H7Ne9&eq~#dKmfUmE4u5&gyYEuWyzHj35basF@EV!U7coNtZEeOwo>R1gWi)MK^T zt}?_a>9)zAUi`1jdlZ7Lj;lqqe`Ikw9JB@&(cU*3HG&%~#!DL{Ie2!z`{h`W`O_)wRxf7`HX813hgZ-Lt$N>^(4M5Wu?l zxiSZk_a*TQD00Gwt)TF>YWaBF=wkrz zoR$wZy5b!w<1Ycw)%%yVUcN@f(cP%PTDv1Ji^XF@GvW{Q0o(VyE%uN5T@KY7ab{ip z`FB31cDwrB%k|+cHyE6^Hr_}bDQzv^;y9@7K8x zV87dJoEx>}m0Kyf$-Xf*xphZw9^U`=_4f4Fj6GmI;#wcV>f6g=KXZ)9{E5s-?eW*s9z+f9cl+a`7WI#%q;vg;+vek8m16yJnCnfQ z!!&xs=_Rs)u!?F^>V*k*`LJ57^wDC5L}pB4HyTdg^3Qx%clOC+Am!J77VAeVT8I$l zL=5WhIUZMS`v-c(Mt`$D&z_Al@l*^Wk@k+*u0XeEF*~r7I!BTrDg>8227uUhHb<~l zim8;s$-Nf*%Ej*WRj>QwW4UDWv8R~Ij8J=b9{+3?(APenHje3;U)awNZ)=|`e04ZL z56yB#A=MjNTC`5r3WIqG_AW;WBi7pf^mIIdny*o9x2p}j1NZYcEq?&QT!3!BS!+E3 zI1ZlHFE3^>7Q6Q8^bG92Cv$c~pL!OS_kibqx6NBF&y&si7?zcb%_*11P8TiB&EEjz zYWG=GCF_Z1LLa)WU3C0&d|dq0GU1Rb6a+oE_n0P{H!<}JM&yn2}ijPr*88=PxdL+$4b_O0IT)QhCX7e>j(akfwy?xe)e|aAaC>bl@ z6z+Ts2EdvL=lr{TSCUv;f8DMjr$bja)=PkyQ1?P9|6mz}vEP8f49>=rgqY<^bVkvC|tNH?IV@_3FxLjfCX3t#r=5g#@wEoV4Wy?9e=$iTY`U7&1gP zN3SpX#tEfd*gYtFN0}A`tW|-+mRIh}%V$+a8B+ePuXo0M;XZy?{p++kf|jvCDoa12 zoAcE629<);4uCHCO_e{@zWj7L{wbui$wq<%BU~bqVQe$5;3*IGKVQ-Z17`%BE3+JB zd4xd*Ff66KH(=hUnZrIOdEC1g#t(!sC6&TT$gG=<796m~Sm;B^niOE{+yPGdcHNT` z`0b6QmnSE*S4ZyzytlNtQ%H+@BQI5d`RG}EZ;BeEsHu@jNRFbGWN&_D`!V(4yB%Y< zV{A5&W30XbTtEVG~;!nn#pF1MQ<^0DlYcQzRMeQT#3^zL>@+nauN zWh8kr2zH1awI@R=2lcHz85vQG%YZu|(vzW>!~3W`8C+(H+S{Y{WDqS)TfstrVRn5z zZDg*k;<($PRvf@YG+adW`Y0K%p`$$N*an%iFm&5UUynEy3S~C#T*Eggkkse-u*xT1 zNQ#g^?MS7$Rwf{Ls(OfU!6fF6XU>N;S6$8(w+u6X(jv^2MIG^e0T|@o*#&P*S@6Iq zKiu(BmMESd?J|+vc~~qUfUAcS2XWLdIIMDp9z<<8o(}uX2_hpcS9vsWbu#29rZdkO(a*ViRRCd9OLiQ9gen=Nl;KLqhxVLaOQms#{raL{ zbe=|6qS!K%hP|NHKs?dvaM&F{E&Q-E8LEIQ=bBI%CX8Uo?Ru*Fc@=0tmB<*y%3rc} z2hijD^s4dBj3JEu?huJ}ub5uw7<+qFE!5Ta$U0JH_>V(OIB*_Tlaq8L-t3l%*ey3D z=d&PKlhm`WF08(dj#Vd=aE&<{8`sKHwodsQ)*wAX@vNrW$JwaDlF*DGPL+coo#mGC zvU8I8g%T(#V&VthzK$D1u0eEMu+OijZ!r|O4aQ| znSBz4f0D;oq#2JPx2EwT4tHzjt=Pv(|ES4+(W1QqE!U39*)vGAcc^FoP~58piC$lB zjt)yT<)*u*N7$^9hkDwcmJHibYE@Q}a&r`Okcn}uVgyL<$0>31A>DtuM# zJB#l4<}?2O-n~ApAxg$+`)j-Vy#=mRL<*;DWu18$xOO;gx5Xv9x$+phfg;y8M3Z!` zo5J&1?BeN2op(pTJO^o+FrOf;MYUCznsHfutz~j`)L2wX7`CwuIdv3SfG4)M^~Slfi+Cd|&+A ztmi!S9xw2j&Xcz?i9@{%8u``rn{;~8df={0x3qNa`NW69qFha znb_R03X+%zp>@hpYe-@tlw>lxiezx^{k0qeAD&QZi|WD7cw{ZNc6lgZEjsAQfqSpGV~lU;h}?8;g^yHz;yd*Uh>5=apx@ zm4p*33E%mCYda+N9#2e1y}ynscdyIMy71zDKOGO>b6c}t^=Noc<3#cdx4%*kXA@k+$D%th~6Kzs+ag|2;o^->je9%bVTHvAn!{`R?;T zffW=3g&v){1l~%IjcSh0>TgtmjGWiH&|v$o{mL}vW|^J6Z`K6roEpd7#Tw01N%jy_ zuu&O@B*8zJ{DFajjd%9HqSJR&p34xH)VNkwRl*r&(3@_M$`l}#8_VRgfG*Bt-$>); zFV`TA*C!v5z|h7Vqt0X|AW62SVHAsEVv3qXM$DN1(j*7XKR&?x9MLOWd#|0eg8V;kbTY7J<1Q{y850m@w{yxfT6_ zjmGp+Zyrfl3P@W(oBF6w1S+`P6Xu(Yy5&VC;?M!b4Z_<0$fraw4(!^=`_)qbu`xRN zxg_)l2E?ddux?Jv{FbO8WJ(L~p5qwQD81a#30M==$7h+4gm91~QgBs?z__FGYU4Kx z#Coag1h@X~qYHQNfvMC-zN@7*JT&3Lw>2AB5~-+Nbg1Mi(+p!tr9UH22LcBIQ8gsj zn706M=Q_GVNS2*m$ctn(&?;9&FHo)oBx~>1fWC#TOcrDLKp;Znwm!&Ek75X;BS+_{ z86O#PCVL8@!gtlrt6?k`&3Nz;A~&O8@MhLG2MluFlmPey1k{z77KMCjr&bTsV>+Uk zob26UZKYqP@JdJV$932JUz{F~i=V3{sDHE&t}dOWAN@q@^duu8_K8!|A_`{1*2Q%8 zNrj?e`Gcws6s^=zZ%Pbw|HPD-Th@}#!Y7%I-f+>34`FTwL!@E54dZ6q%BoMKtorSY z`fO*^qztV-x_R|#1M;}cX_%2*szq2R-d3U0bj4o!o})FMHBPK`P8w7>`zVXqKL|3E zD@r<)#Xj`7}XY+af2xZ|3EX^Y=tn{fZ{8mz!99Iu^5;3mpsbG?Wj)(icboRLjTF%Ga7=>w% z&n}bs(1Erlee#>ZGNeSp(25vBn!*cW13bPkrE(-1XQQZeB=qVrp# z2CR7gs-rdzk>(cSJ9Gp)`L6}14QCiLh=ls?M8gQytIUjuiR5>VPJ11l5S+k+#DZpV z33B4HqA;OP3LeL-yZ{6AvK-m*vaX~h|Irp|Mr7RTjO9iPqA-h`sDx=s+DR?GyzUJp zP~rGCA3Vzl&!BS!B#-yimV$&96fCBVUJJeXmMVpH``2ametivAk8q8XBy4Z*O5 zmI)YG-u>7Mw?s;Z6J(!8#nKE^NtH{ zT0N^XXL!2=Q~B#vpL6-^-)b`d`Fj1Y0G+?_yu;_WueAyN_SH6{-?KM;KGL8A^!y!( z$b7_uUf*cT3)#;rcxm5hr>=7=%;(&&^(#?+Pw0re^~g~$hDZ1^_NB`iX9KP zxhy&QBE>(?FoIrstXch|bz6z3QKm((YbMX$g=&6r=x{`E#lKTJPqND^o*&Oe9S6%G zMzua5z$mI9E~Bu@q!JOc6;vuae5_ZpCC&kg1apLJVtCQPg51t1NuwgfeOUBo-Feh#>FG&am{k0~3M zh)uYvnAn%|+4q`4uN8cKe=6lnNFoMMv8cqE;g$n;T>u8S70>bhB?U9N{=(yV*hK#^ z;@WyvZpwp;VNV|rGwHw9f-bBJCYoWHgb<0gpOhhzL179lbVE=I6=6$3Ah6)_Y{>+^ zZgy#Rd|ChoF@E#N3?q|peA^7L{Kj#iwDEwKD6EN4!%~X`g%ZFP%uG&@$TfKZoFoR0 zNZB?i;Zc|)6CW(m)upKG|-&Ai(q|d6%(sg}&(=(k^I8bFHvI$9!X>53YC~tt(t0BeGoFM7W zBtV3oDYG}QW3ph!B0)~pZ#U=y=g z?lI4}g0gb=!w7GHs`oD+3s7astcw0)B$?s>FZ~9nx{Xg@CB9n_+BLJFVWv+@M3aKc z;zG7EAar9$oK9Rp4HH8er}{OZY^)74{XgClj!PNBcS5np!y_Bq0W(aTx_Ojme7$3H zrs2AFn~rVUwr$(CZ9D1Mwr$%sI<{>m9lz;0*Sq$v+Ex1>gnNnYj)L$V_dU;{f~ew-z#P<2>5IH+2Fx=jxxzu({uE?e_oc z9Pno(tIQv+_`UZ&^9W$R0sS+z@x>DlpKsKk{zG9stVXaVdF_@*0H;8t@8>-G_<)lq zw$PF&O36fws&yCbT3tuZYdZ3-hdOoIE)7m-C61QETwrX2Mbt(k7512Kjvw>%ATDSr02nrr(_-s&UoV~Rm+PYC*4>7 znSSz)hvtuXu6(W4=32?%ksma6%J^*>abQX%E&D$EFm2kJ)_djn`uu-IY+QMK>nUrk ze}46=agXUMaCAU?UF_&sTg=_a0^dqN-`Hym@wM?I3T}Z?SWEEG2|? z%2^Lr+0ANoY-iO6-ut6gYdmt!4hKfxT()Rcx74Kk6RZRLnTq}^Sc~(&za=hXvUZ}$ zb0(?yaX-c7tbpK4X6d~&uDKX*=#_^!r%LJj_xzN%}zB8`0C{cW1TL43J3dFU4_Ov$*R`G!-!nY~DzU~|ePOs{hjM#Xi;~ zJp6K_NqIzQ4$OMwUEu0{Ze%BZtRfUlL((kKbL6gBPhnY1jlK>`k)I9mb)oFZ7JpCE zzSPxg{=?3ja$?e>PhK)Yw7U32LuJ*t+yQToy@<$>DuhRM)d2PpS(JMH&SRc_X{!LE);6$f1@GZ!sCYCyDq~|YJ*(EzysGGhTHaQUE-N)&|f$Hg4rKf~m80ox~?6CK}y)mcXm*v5P z%D<@!hHxqb#^GcYVZi&QLX?5xyu81?)sG0Z$wd*!u8wRb9$(9gE=!FQ0=FV*T_}eQYXD~Dd*q?WNc%DTM0@IB?vYG1}Jn#vM#t)JC z{X3ogxN)8{k%U<^YVP^l8UYrL6P!-<{u+G);X2%)D{tke6APkyHMwA1E@40kPKkoe zoE;&MC}%d)fGna|vi0t(d_?>svL$UlL{>s0=TEyG`^NM9$TMy4$&6mzI~jd!$_DzP z_Ez4Dd)eLF?M(2HnFSG>p!>PRST8TJ+(p(0Ndmv6&Qe_SM8!*0iKg;Q#ByQb-;dk*I~o!$ zjQAACc#f~8&<=h=EF2^pcE;RKM~gyghBcKgGEVoZjB$cwX>;gUc<5MWV0v3`KxZ-p z&peGxeEBSFdQO3YQAL@OR_gTN?(vON&WumIxXMJ4#DE;nlU(mszPs;CU-GP|0YT5>zAgWk+yvnDpc{G;;=y+Jvt=%f{C8Z1kZd;S==A$+1*Bh8~Gv)Soe&AAp;i zo0yLRrdSFL#$?_&$G4Fa7SoxkncpR5;(&@TJWdW~NJf-ykDt>i?q_&P1!WTlRG?0w z#G<`Ct28|=r$R4-MWU8>Ykzb7k*nj9_m#P4eJzti(#X1xP_=?#0u0jmIYwrFeUKla zZoKdDWj$S1;;;IxcTxf<1_7U}5>w_&y1+WC!SoFshp7A-5;lhskJ1E#hsq~5n@a{b zc=<_Pf3g5|tE}uxUK2<%n3(fV^AwaONc~Dua0~^)eRQj|Smxkp4fNaYZTrn~6zHdp z$1qh*6Ssq;CXt{&P?v4TccXNl5ra9dHQw8S$FpqMcBr=k2G2vjNwaZ@kx)-n!UEaM zAk28U+?7UxD)b)?Y}+q+`c!Z7vE6OEe!7IRu`~AgD<2(MFNc2qMhA(m#kZK%07Jw9 ziZlOSe_piRdU&X8dp=2En2FJE5jAC%&Gb`+9Eg zDheKpm^wQUaSQ3(vLRld1|mn$C|Y%vH+Mxez9*Htoks$JkS?z&elSi+EmdsitMbuV zR{G=xpGnzXF*i z=HT%tNdg_P&jhZrmi^J32*0wRI0D`;fAyj{-A~4xiwpvY)4DeN6Q0jtdS2--d>_&K z{oOs>b~a9BXC^s+)9zDNc{gO4M({6r5OGhUOH{CFWMOh-q}rFoTBgY*(bMYe60gpt znLb3!QZ%Z0-akG%>><}=lDzUfF-s2YZ-&*=t|M$^DW9pJwvHKge_nCjcQm%Vm`F#@ zUj%v6B{B`HrJD#M4j8zTx_Kf7Ff@;n|J`ypFnMj!?c;2S37um{&ZNQGNqF6XQ}TNH zK;LC^$^hlbU?Hl!iy`oB76mq>YfV=wU$7{4)Heu17D_osI#5e&kCphqf8)D+Thhea zA*@a(Xc#GZ6jtp~+eM|btHnQ_`{B4(mVbD4w>c7PP)%tWx6w!KNoF&c$-|Ww^#aKc zky|=1T_D-8duuwB*`tuM254pOXMD+7{*uw0j^;TcdM?mZA0ST*Z zkDdGwT`L3Xi%3)Mv;lax?CmFpsr-uU)Z-VoKaYddFN#2kDXxe8$tR^pZ`C2mKh#F~ z^*>z?C0p(r{)wNiM}f7T4ba5Xk~{a>Oe%}8i~TNU?|EFw_=tJsYRBn{YIsUmSS9?- zW`09|hV@UdB8pT>Ba{@%^1B#ipLWa=!i%((2_3{>3ZqqJNb%&K)u!AnuH+d$5x46K zE@cH?9Hj$EAKV9og+_Mckw_9R%Zc~EKj}bs^|`)=7L9rqS}90d;45!uHcE%K-t_c7 z_6Zz_AaF#h-^NXZB9f-RA(sjZO~%RwjlOL66Y|9>4t%1RSd=$*A3`Gj34(BQ&^Jib z7-j7DTv@^rmC#5t(spxB%w?t{wh%fd7b%R890!ULqFmMHryCB1KV|6vBum_{l1#F}=$vjXGeo2htsVNW#q_^{+-a;&Qo1D4Y7rKd*6aPpmX9z)` z@fg^ucqe2a0`?fzYl8d?An{++@4i5WwR4WRK5wqE?5AEiQ^?MXx@hh2xS97KNY9BT zGrHEf3TOmq*7sH&hhWxNBz)=*y9#fvU*Ee;1z!ETw?Al+6lpjM%utSHQ4#t z1j(`=vxTnPx%r||32%^4ejRowC5lH+NNS0Wr9oM*`U{~ic?OQFF2SWdnojbJcV!>(M9 zxmSgdkk)9p5S7y5Hdz+#0!72@p+mJMML~iuz~j;wesEwyWr^{XTYCb#IFIxUyNnQ_ z77Hz<4MrPb4g;CqpT}$lBmKeG{AAmI)i=Zf<`8+cO_Ss?FglY!&6(m6y4wp+nqbif zqm%*zI`w6}@)7ktjUbRYSi^^1c!@$-uPXR2t~57_pt|D$Q>;%*W`oXJ&|J7@ z&{^bl^ofPk#j9uO&;L9p#E&JlfDXnL8pc7w$%?O~1?>jCAq-*h+6#E&m*j=)M&(%@ zPD)ak;#)We$tSSorU4wW8!QhXf-3?Fq)+gwv-Xs*=@1C!$zkGLgged{DLoQ7PGI$T z_>>@sKaUccNc4dyK#JIAyS?nkhVmElJAo^Z%bj&vh~uF(&Hfnd10CuXzoTP8B|BH) zTH)eEc=a|HLZ7i z;l6VokwNfixC8_}BJQ>%rW>k>u`;IdplBiFH!-x&(WC~Dj-Uxii({guukfyv2B-c& z6NTz)!(E{{Xd1*Q8)HO~uN13RD2EUxrs?>5<0hifnCP*T&r&DKe^sicPzz8f{|0gF z=bUlN#mK2VEf?N>783Ar4yz?tSf(;S#!MYp^AA6VRq)Qex%8D<R)xX?$p|6#>w?PS_2e?C=07d*poC#l6_$-z}mkbo}F5Y8{gpQI=3c8sfa3DcRB}aM~}4Wq`Y2!XIKRnIj+G{ zT>Hbm+$!ZwV2kQ<@r#$kVO3c-h??c26QF#5L7V(IKUe_grF|m zS7)Wz4L23NswQN#y=o@(Ts6LF(qdO8G!T2$Tq$~(DT0(l27cdwS2X*`<6)#YhyMF5 zqlq)MEAG$up8YmjLMkE{G0Bub#*4qVdOB&#Z7pfrLzzvDznWr0qyL{c25bNJJeb@? zS=~beEvD5|fp2GX)AY`b&8#_t=8q7Y^SGq<&XQMi5&ZPS?OQCuv(Tm4NnO^9WLFL*^!;`&`DNf3UYyxaA6&XXS2o0aa(b~L$Ew1Yy>dJJJRxEv zzlKNbC$`3asOL*IP0Yr+rIj^trVqfjPw(1vDkvf#+3i=IcOa_BT%CM#K7I%Fq+Ba2z#bqz*Pt+i)8@bbrQ?Zh(>RA&eySMrmRR8X~ zR&}>|=S$n%AjE2-X6StA(B8kK1h)0_6B!Nk5AifN;jV>yBZ^u+_u*!njj_wb4s)qR z5e0WIha?G69AATSQ^W2ZF8#}3SeOX3{Zyh}2-|3&s>px+zl5FQ^N*ZOjVEp(x<1q8Ksii8);coR!-x4jeW8aNp@=oU{r+IO&Q7NH;Yr2s^R6Dd>I1(t?fA**>W=%T zDY1)C4Wrb3Yf$3q``1qnmdH!2#Q? zRAZg)y*dH6*1R1Cr6B!L4nBFtTN3OM?XYbB5URNoN8>>{=johZ3zWQSHY=7r@yo;D z#`;P8+Gk)6!^M|9fODvNdiQEoGvhB@u;Q)|Sz8~$o-`E|+vMpt@QI5jDPOgEg8$Oa zU02uYtx+XfnQY!S6xqsOVL`5(ftR7!&%Qr)s@N-m8p==RWpN4O9!L^C0yinMGB0Sx zg0v~fbu;F8?-&c*Q$K#;sE~7-%@g~?u5**)f1@wB*lYXm*AwWf0fv1cXn?Wk1iqNP3LEU>D_t_Asl(1m}qkbPQ5$RshkCKc7uW_EaVXs z;I1}D1%pWf6et#xFZ#W0)}(gyuU_fWoY5rf2MU~LZOa#s^~6uBf_*$w&Y*iR^IHQh zVDaRBFRnaBI*DHF$&b~H*xK-djyK@9f&I+9O{N&Z#tydi5?{i!s|;X;KGTCDRXtTk zl6TZZfSsN%C(bwW7OWg{SGgfrPi7#Rw%j$~FI9yDOLx`JHxy zQhCyH8@3}W%?UN7A-_QRm5WLnqQ(U5W}0L4cS5k)wv@{&^dI$==@#AV8?*2LOCAxz zFhS@Inw+`~s7DPn34EB;3%YEblQ8K%YEVYWlzn9^#-lZwZdvv#SD*h34cLZm)gQA; zPfwZQ+Dx?g$mTvHjws#QqGaeuW?@&~8xo0e#2<2^56V4?ydnz=>Cc8J=>cWT!Ilk) zY38wQrIS=pF-REL;GXKsY$!^fUF975`wef_DwZ%fnc5w#4AO8i*ckwsw_&RH+4b(h z+_rI!14or(0xtj0lE#1i)oN-r4{z1xeu(*X3;r%uJV_>rAo>iq3&y|Q(av9Ch!xGw zS_8|cgoeJ~hObM?wun4zpzYFLO-MvAyd91aEODn%#hWc*lKv?V=cAuU*{E& zX`($^V0sD0)5Kgx41+e6x60@$ab0Z2C~vG|&*(XcvfCMtpO9GQ?? zq0M?hS&;@Nz-LIIoCLW~6t@1PvhhBHukbIDDR)0PO1kTnp~%>{3l32Nd+%9*1tvvF zA6=<~KtgH>NuRUdpGq1QY!o1p<#Pd?h|V?Ley0MLb2i>m7ALGVgMT;;4_v{pZe?Ne zEomNJVwB(Y1H5n0)mv?~a@ee#8kUb2ix;L-qEt9Yi8y184iu|{oFGX2{zaj=D zX851oUOt*a#8C^+E3PkCW2?$aWS5XMCzeco&4U)5G_-5e$)jF@8??k-mEJ;2^2Fl~ zJz$?OLgxgu39xUmc4eEw0!>VxfICs?v8nEh_Kw zE-$ZW>#hjz7M_c#wr4+L7Ch@e3Y>|^Ol6nf*)Wei&L~lYG$y~)uOvx-6td=qJaCX? z&H-T@#Cc+sf5m+pU~Q!TtDi}sgEMx0WpL^HazEr%-D{#9g75!nCnSje|Fjcs1|t>2fGI>aa=C34WF~L+q_uqQbkvau`Z3}TCRfrD zQQ^pI%cG$2|AHm*-TL2W*yeP&Rn(r9?}DpYm{+wlVMetw{?pVzQzbQNk{I* z_v+H=4lpaWGhRIlYuB>f^`{yOn*;j`c7%RDs36RNnbr*O!YQjfKPz17dX9EP*dc?; z`W$o4)>Q`$hICWge*Y5~nyv~7M3}savHbF|P-Q`371EHINV;w8<~ADs1R{B;?lvMz-w*zQ;1sH!VM=%DVU zi$FPta8wsD$1JD4Vm=WP5K zwu!qs;c;$@eipm0Bo(Q<@n9i#2m0FI|Dtm;dXoGgN^&GFtim1Fd7qSp zl|Dfs<~$BfNaqe{HhlN-4QJEfd)3${8tHy92B~nIDOqHsHTv2TV>Zf;9r(!sZWq@g zh7xQQwzt*3#{}chJ<{oqKFSGl(bLQyuOmwSbAa_($Cnl4w!yMhm8U-)Hn07 z1{Y!l5$2e|0Oon6@1Encjh?-1Gep++o>KB( zG{@ih+Z_cp@e5)@Hl-m;ma|^z=+dRVcZtZMB>knFJ(i1(ar3JhmRFCB8&cW&qz1Uw$?IkTW5(pEX+x3~2O{6&>vD>MqkKnjG? z_VcZBwvJn?3Y>G#T;}H`@uU9zB|4WXcc11rF?_|3k2)lBTOG^Ma4obAgZ*1!&}4h| zu2l_6A~8cPG(d$_WF^TD+QwVSv#>r=AjJ(W_?aPD*9SHp1>TMcKtAf72%wv zN9+7DB$A_tsFg@Qgj=T^s2Q8ZPQx8z9+aZh=x2`^C*6iEkyD4hr(Z=qGtCZ>Ombe{ zt{x3KJ1*-OR@u30()2X>KYL1hwy8Dh7fr_@2v3aTLh;vq%x+?{jo3Fhl50|2xL(Dt zu_SZghJ-r@?34}^o9Xh>!Y!+&-NxxH5BS?sz&Mhon$2DnxOK>#NheAiKj#K8~Sxep=1oj^#Q+n zn`8$t%As7{5g^o5=H}hfPxUh4aiylH1SG&1J9Kx~FKz`1B zAcptIIPxJFI7A4@oQbRUQy|lZO;Uyer4ZZkl^i{v&Dku03}TX^tXjxW7o@VoA79Vo&&4IwCA$vuo|z@^xEUC^W;INZJK*GVirEuT0eUnUpZ3_+Fr4&t z*V+EuHS^#Y4G<#&gJ|cy1+pYi>Qx++dirgi)G({pzbpGnyN#tx2!ZdGtc&CZnFXQ5 z4Do>`Ma>+axy432jDrsJh@)Y=erF|IEZVNO!1qqQ@)mI6&=Q7eB7L#}2;3+{65B-u zS1&Z!F@+Hj0?#hvmngSA|NN0as(iFc-jqO|4z!+Rd=#u$B;j+}ijag~!+U|g535s^ z2TNxLp04o+>mG2i&JlL3#i>T6Q#A4*jl@m;pzY(LC$D+{qT!KL@jeS%Jy6kK-nc(L zfiF}h0_4g`TfdOLIVjFEq!QMZHQpJtFDVQUshaVHdB+!uj=Gr9(lK3?7M zznpfN8CA+60z>lq!Y|>w6k;BGi0BGp-k7h3hXvgyJP z;dvRYj$QL2d5YGq$z{m8PnUd^Zh~o4uO3p&M=4xmN|l5VhRBE&7LHp+0}uvY%M8N@ z3sutniyq0h>B9^dNMY}cB|qu`Hbi4Tm;3&-r&sgWY0h`$@}AdZis&Eg+2yLuRgUn? z4XS<^kt+T!?%Z+e6TkY9=J5~sfe(X-ceZSxg-OwHw-<*$Lr{E{U)NSp+^(KmM)z-w zFS$Q;Qh{N8)tw~b%;FF^aW?UUc07R$0JCcu5qsqzI0`2#j0(6bW=TBI3fcfcH@7;t zo1O%cBVjx-Kv;OqPZ6J5xl1ylfD9UmiD~4c@Bg4OTxU*-QK+Urx_Nao^@zQkA;MLoAI`L8 z#rXO2{r;W%{rQg_`N;U*xwz0n*L|Mfx@*&Hsy<|5s#QngFEwA7sAspcxYU6OMUs2m9Ku|6C0_;aT_`vkYO;J zenzxqm+8o#A`@tGb_y(?osX6*D7xQ3!aY;%O(U`nOhe85^q(A zrM|df8(;H0C*|0C7LBvjlctS6XorD*pYE!;wx7Ou315cI+&L-l4D;X#+`{HSTbQd9 zEm1W`V%4o(zdW8~u8sgV!z3uCv|H8eT}>hQpLFM7xPDp7JLDX z5u)LIGJ+66G`-{}5K*i&{s%ckLk`@L{Y8P_TParz~LkRzx||%S@>}4FR&#Sn~bvcOW(8Goh+l()@K1X zA1ElEmSRn1U3!nEof|ftJX<_DS9hy)QHUA|?!paim1EP5azWqk#PR@;W7-~r#gHO~ zc)>B^0O4H(E1Em4w6I%xQGZ>2vWbu&7@IZ|;*XdT1Y_7uvg|8EN(b4$-@27021rV_ zB1~^DGHI0hnt0ihj3k*;en~fG7zsv?#c4J%nKR@3xu>FmO&{`_r`$Y_1ZB_k9@5#$lpQQvFWE15#z+TCWaTy}&iReBPd# ze7pc_7QvI7wze{-ltt6egRW>HXQh#I9wM{j+xaO54Nrt}7lED@J?69@P`NNh--ySr z&_#q9T1j^p`VfpZ+mEGe#gGjEUn`6t0>hKkUv(<39$ig-jCeD#^zG}v2j>r0=aa`r zEk2`nxhsCWyj8qt7WlP(ws>q*|Hj83_I!K44cJt5y0m($)bzg8@y-=EQt?{&{*8~v zE}K|=A1`t8W${$^8y_RfdfW@8h~8*i)(URv+6G(=jCZ#<`#-_&cRRJh&mTRuJZvN)8d3;sEF_MX3+}LeRNNLih`Z>jh zz78DhhA!rDRkfqI+&UX=GrJhC#FSR1>#Q&|q!x<`&>EpRh*#Da$ZASRuO;>XAJv3A zUMO&l()HLl1<`k`(4!(mlrk|^1|tY0lF1Lc|Jp7|mQxVVK;kh1!ZGJC?Epeq8>>(o z1X(zI9M(#R*fE}(Y#QFquMi8Gs2ocqn?t9qJr+7R6bDI}aW7fVUP6S!Rj3vOjkJ;0s%i?4ziVj5fL^&#%9|4MHWNlqpX(W)*sAtL5UdT zS}BgrQ(zEwfZ1UdGh|L}qK6TIqHbOJ)!f%3<9x4(ybiRRB6v5QC*817+9|Ja6Qrl&n-{B}slm@R zbys5^ZHm~ZpBkcaSg!~S>Wumsd$W))tVVhZF?iu-LfVJjx0%Tb;orow;+j#?1 zs~z0@CuYIJ8BYmL*@y61Co`~4qNe&O6=g8RtUxGl6xC>N)07c1JTZoRR^(h|u092U zkd?^aUpjMoUF9@+Y%V2>+E$;TvHlcp%RCh#=VJC}G1(wJnSRFW$>|QC&K%xZZ`LD&ABZ zvSJ={s=ys(*@Ag(JpFube3=?D9kipMm6;&PzA3Fi zZ%vV=L;4q{GxXWt9_*Bl8K=ghorP!Y_@pxLl6HRDxQ1+@fb_2WPvd?*KFqlNiJtcl z?=e4I4m|!;xOAb3;PLwPChr&AsusbzC|O8b%=Z@;vz1!67dl!V+?Xx%uoYtJ`k1n~ zEELui8Ak|{zWCjH^Sr11Wy@VR}y||2&+xioI=Tf zObGNcFKi&YU|%~|KMoAfZpJwaZzlwd6!;8dlZGt=T8P7pT*+*+I1GHJrqRZ_mzCjj z{TK8-;0m%~Ik;61dX)t<2kwLjOtx)?GBd775Jtg)yc6KPWoNZptk4W^L2P7(nsanhn3On zuqd5@(ahHaSqUAhf~Bt3%6G&=2{wH}nC1MM;HXd?)68-vy`j-)2^v~R5FtEk0s|NH znA}u5@&tSUeb8SCYW7}AJI#Lp)AUF`CRS$!M=+U38>h1&jLO7-3R zy~iE~BL5>@mmXeHJ8P^%??#R;;t25O?#^p7oN(-50GsI>RcRJIDN!segDwF@+|Pkf zm@1s15Z<%~S3dKMK|rH;hD#g^4;bXXK@3+qqMHL$oQgHuPfuD{dQ_NIBpUADkGP3O z?a&o!@hdw{Nj`kRG4}w({cvd9T`qu{h!7E&H(NHHf7^b%dC`?)Rpt43U3TdS)DvzppHBQe9`w=Bd<%mk|aCNy(Rxiv9}9Mrmhn zo|R|9Bue%IJM}ujB2yxAhPpVolncL6Hs*+kmz(iiY}3gY!0<3syKlvblthdL|_CUS!8^g6i#z2I8 z2DT{kNtT>CW+SZwHitcfD0lr5s~sSSygGdkVE&hbM*WmLelU96B5{0&KYJeWyi|H3 zy+g#P5j5i%(@ekqVt_EhLfXsw`3Q-@x^fN!D(P9vDS78Pj zW9&ox!UNnOr;bKGHHxD+ddi}tU@(CdE?v&O%a9!vyW}m8TF$$ZVkS_LF5QcDq0K|P zml=?OCcacyNBdM}8sNo?P3i|DpJy;T%gYq`=qk2l4fQV@C9o!%kCDB2xPH4Sx<@Pe zUIyw|Js)YNw!Ez`i%)2@+PYlu$x(B147TsVo(}9FWY@gkG9rnu>7hyUumwvA$puo?RLzq;X|B$F z9MlD1IEE@8)7#AX)#ikPq65VWC$XYWCd{q$+0jrAK%EFU(^k%Ch3(@%izH7AZ~UVL z5z6qru%-%tB?a6VXs0bCTBh(_EW7wY*~1ycIP2F?FQXaK0KYyYYQRTCy||PP#b7u5 zoh1}Wo1seRg%A_w3KJmB#+FiWPX~%rDdUI54Mw}597S#P@gJsw^rK+Fsfq(Lf{Cw* z^>E*@`I~p}tZ_8LPmN)mJ@l313G%a}5E@r+^cQGo;j(>)%;?KxL<#Fl*!_W2hXc|K z0QaAXphV+BLyX$$lhW3dNnI!oPrhk~~P8`iFAPsk1r8G>)-dtZL7_Gqa8# zXq5>QU%5+u7y~~o#7=53U{6)@kJ8ZUxs?e#Y;&dNxgH|PjxF9k__K%ElgyjhSlVk% zz0-kw5iZ!{ug4|^&%5VwmHvprA@ZbSC-08ePZy_EuVr6yKfe=O?n3Jw+Z??KsURca z`cLD|z06RdKX`Xsd}`{~pr@vv{r06$!98|<`A4MWrL&;Ak$bGOs~BAok)lh!Z5!#b zH>|-5?q)tbb#AX48<|2BC`9cZ+I;CkJ;o{5U(9YhJDThlgU{1lY~@d%HV z6)Td4xp1%7cKEh%H}``7{B>V#=T<;;xqUqNI;*u<{N-%L=(3xjn$I?MV*Y9~QCPfF z#2lNd)-ijdr`wBSK3gf2_@T|Wh4V+t$W20~!?C8Bfkkb8)ol6bNk;%?b>rE#mBw29 z%joU=%VGJrN@t>X~DvgOTZ@RPJ{hub6a4{{s>|v_T%`KV*>Vf4Yn@!IvmW$rKD zE_lC_hg^qgZwm1tw>;{Kzm9Hu9o|2S)zs`- zQ6>?289_sz*L@j+5Q*Uv!3`oJnJLM)=s^E2t1&&8*Eg3q2zt@Y+yw0)`o8-Vg6~;% zke<4Je#Yp3>i98z6KAvF?Yk8m_>y(FjR4IihBJ;GNHa@$q*V|h3j!;{dfU>WuPD?q z#kKooDjq*SB5KPH0)G!z72XSFlU8%l(q8!}3ln1}e=1@!)Q@Jl`qx?XwTtukP> zKVV&cRVd7Ma1sVZcGUXo&UckmBZRp0`a;~61Df_`rLTnresgjrO^C{dHI9XgSm`z$ zV^_aM72p@JsNq^^L@*UwZ13l>ZI%w`ls;BDnutXAuQu$tz`b?7d1%FjH>S7VbWVf1 zrz6;8ZsFmBH2Q7v@O1&&F-s|MQf@8Q9FJvDZ03@e;*zU0j3v``=&s$m$I4PBNl=qC z^1x!^i$NTVIaVk*4WyG6W$xGaS?UoWS9y+QU1v$rSfgRx050(i*xu)pRyU`J6LE2G z%p&~u4XcNB-`TbbW!_+}s?O3&M9=0ha8PXFRnK9iv)kCJ?Mf73L-n}TFW+d9O)2Cx zyTH2+@n9`IKIU(M4~{x*qcKgjfNfm4q1Nmg-%yDtX|=Uy6qDJ68<)owgVX9zf@I6e*#GW}c@ z`Ee14T{sxQbO8Aj1=H>0EP})Uxi2!3B^L+|mo2j*X}hv^%v!al0;`-CDkmFSoEIs6 zE0sw@{2GMuAFu?*Qejr!JijSFob*bhFyRlQ>+6>qGWRotW8Br&jg|R}$<=4qq}|f> z_BrhW-i1JffcA6KkPF8X9{rt0n~~QTofkz?vt;eu;)k2Ad~9f48!1bPsUP_&jDYzJP>O+sw_0Zu*Aw~uM88+F=behkCKyJhaIu3T$PbE!}B)OU7UT?^a@ggz2$7FE%N=!Owp@7B`UKQZ*nZiDcNSCIA}~2by5|yp69qm)Sk8zwEswZH<`uZ*g%ZKGn_s@S$| zS8Ut1Z9K8BFa9Kl5LV zR7AR+r#_xd5S$B-$Q|DeJ^^|2LgsWnrGqw2q^TlO0Mx(AdE@Dg zar^Z+-^QJbC^Kp&BT5O!y{L=-RZS~h4!8ds%WYWI``|5}fS@aMAvHe21kZu>r3jd( ztf!_}N}W!N3*;h$+4>TL&Sssm7cVD4U?tn!S$R7d(i;9!3CHTbkrmrY z@l7@xsonxzS_o*l{>g-o6}-^yTTl#*S>4MhtdCVZ3@6tsW}QvyPBh*N35Bb=F2nA4 zv4AHm*;Wdq%o%|$%<4CsX_(lA{~FGn&WGTX_cVFBD2`HOgpq@!-p#2}F`ulHqW3al zP**6ALX}H*RRJNF7LZUoRJr4EM+se!Rv{o_867~1+2eBgc_`7F9`{D$@gNzvqK}(C zCCL(Bo@e2v?joiPU5u8eXCLRzy+VcFT)<-(+Gt*5uM#^Q0=A5rhsH8I~C z92KM`Omh9>&D5gvf2+Hq_4mAg5CjL(qA%M5(|5273iq@gPgFd?b1)!{)?3K(TR56g!t2vb1CG=ujKg<|Qn(guaYp-DHta1{8}v-mUDn+~_f4 z3Rd!C!wDFWf+5A+u>%#90@H+u`epnQ3hs0>r;pcHxNy(hL=rI^=CEIJFA@c>G&&NM z$S2oFro_mwPigtPkU;$TxQ?_mYmmGK*8gXgh@;t10x^)jj>}77>_O-N>ZW!Nx=jO*=k2Yszu5iwI7%6GIJ7XZDkt z(^|%+82}8YL?ac(5!B`^HN5wq$9u)w{l3$!=8f&vT6xF19AeE0kfaNDmAb1Y_aCBT#Dr;N z_l~oN`&sO_t0E4t;xBRsI6a>*{VLae_kdrH+8075dn7c9X_^-km5h2CJE=8_d|j8x z6K{A+L+{r&O=QX#iIkN_$mZcAPUbdNXNdsf8|0e`^fVbN_Tu`{pb^-$1Yjgd(|}(6 zBcw@_cQr_!U@yk+MPNhzb_4hGAhFF(QC*2Bvr#H;m4jxXM+Bti*1tvP)uwqDzxW4g z8pRfLCd;}xMy+tae=5l=V)C=Uhbm=)J{o+;+ClkW6HL@A28TDvdFnw!SH&Mt#^K>j zGb!2yGY^V<3Mc9nw69wm`q_r>56YQBohz}|2D{W}ssL}7&H%QyKDan*GcV6Jgm@A^ z{-T9!HwnBujn4j_STvKq?7|O#doYPW#9^d@m3DvG85=)F81=DkLf}`Dr9dX9z=L_ZDf}RDE=nS%$isO`G ziZ_F3#w=)WbVelM#K$Iep>RINN3Z?d_phLOA4-ig{ zIl6BU0q=#0kGdX^{YV8o{J)R}k3mB#Z}m$-5WAT5r~>Ut-qZsPrrgEMrHw?v%s>dVY^2E{m{!3 zp56y*p$2s=n~kV3i@T2u@`}|H8&v&fN z4KbiDW@ayu4|M`OB>UK>B;N~S@z<6rJ;QXgZ*GI~p{Fk^GNNVs7ceN7S zZ{`@I!5R_4iP&#&j|M}JD$*DsCIpXhl5x*fU2s?e6N(ygd9x-C*@!d_uXI**KMpyt z)N>i!+b2Zyl9c0pAiaaeZ|BU>5I{IGdAMD3@wegjOPayN1D%YmlOVLbHZ_JN#2|i?pR_ z_-%SlSU3A|Em|v~fXSy1)%txt6wbGEygj}`$-w{bzop4Q===)yr~;u+IXtnF_g~RP zN91tu_!jc!!NT~8%&m%y_NATV?ewEFjD;r*CqU}i^t{*oPIccm^JeUpGYW}-S7CXl z9L!_Cc9LV`XcDT8y5GnfyYU}`x8$3iS>0^r;8S8FiIOeiFhiM65wXg=Y{GvIDy~UP ztYIVBtlAa^_ec!ijbvRHsjuW5YT+c<+&EWMApGJF*+RF z*^5Llh?TAD2n_YIQ|7DaTsDUX=X8o^sB}_Gj+_?<&D{7!(&WS1_GQw^snxnvy{ zw)2zKSLM=2PEKW|se3QN8CoMV=XPNH@oR?Dx7jhzTKw?<=ZoD8b&p-IEM)1Lq#G2Z z{XOV6H%CN!XaJpqH0002RV3ybkJ+A)f|ES-l>X*N9a~FFk-YbkL++$+nw@T$5?m&# zS_w54%ae*gWI9%&{0zDn_apct84<-Ov+f&%mS7pf7fy=wDnVYAS*>?{rRQl3#A}_g zy3noHsma)Bu*C^t%APoSyep0l7nAKMF1~MC&%{)JB;_P#?o3q>-{>&~7oNSO`iAJas15WqE{3*)hLm-ej?si*udF zBe|HABbCqy_ZQO`32}(9!@of00?1KJ9*&wugg`l}6>Q*HaWe$R27@!_u2xwo1rnch zJY1FSWPfI(fyw@iv}I-^m4%F2Z^%^g!4qi4H641jIyB5r-8#?i9k)cs`$?VpgA9 zXl6*NX>$r1!_wiM_BluJXi53aQE+`}V=1HCCPQ#p>Chkkz-J((&SO_wrEC&F`^Xfo zZEBkySo>NkIpWt6xFzsYnVox3(3JXAXQnLltWQmx;vi=gEH_5ueJ>sDAq%o>KxRxl zJKMQD3WqXqM0ShJqIOMd-}_jO1%%*{9H1Y#WLOi*pC5PD?NSekdTd~vm?CsLrd{3z z@BmJCN!lM*$PHM!Uc7EZ`QXVbvb)7?jmf_z@gs?vz)+rT6jbn)JYYq%H2&Fo0?PdOauP*&$I*z2v$q=&>j2Ps% zcU^yR$OS~vtWj7|nIW3C%xVXSFFbu95;;3&Oc=_ug4~XycKm{=w%}tdHmvN{vY8p9Od|VI~Y^ZaFVvNc(qhV3VTqBEw={>M${M-R0M6OT& zD9(;kPeaZg;Ru^sTU8H_wM-8F-=Cxs?Eo;_^Ih`-C8+kfrK4qebWukEdWmO+vrO71 zMmN(8y~tBYUSvt|U%>ZBUj?OB3`l`Y=+2jDTs#;qvMh38j(1p#HQi#gFoFsIR@suM zi>h)8!zfFs8S7P=_p6YLG`zK2gNE-eFS#L&3(g|;|CvYD{vBX^e*6x;U<{RuyuhRh zIiG2M4f}pG!#-W?Xy1XrwNpz&HxmBBNi@VfR6z$SN66JZssF^!O4(T1ny!MLEe9DgT$#6V&H%2j3w2QV zz_ls$9a7nbzwR5K>enSuC|`5Xk`5wE&?c7QS|hT|xdYE5+lUNpK0uYUK!q^dyVkOt z_Itbjeq-qU-0%GmR$E@AIhAXQPkhFqV6v(2)YBy#`iJsr#l#*+Vza1d=4Mcc}&&6n7LdiB$w-;vXndw$JLvcWFz_T*-3($&22 z`NII?G`;~Dj!p*G6>DEuI~T4SI;Y20S|!_bS>1}&uCb-DC9L||xCs4zpRIl$shoey zeyTxXon=mQXaizU9{Inf=B9jh+QsR&x-(4pvtp(JYiPXRZ!`F7fBH`P_6@?-c>dTb zboM=OJzb7nd7Djs%XaWm{ka`%&!Xe$!9pu`F0FgNo;F}A`vEX8F9vu(Rq|U|ZjzzG zuf!Yw?%WMg@o3>;?Had*^S<&f5gK@8u4+E_YCHbj{ObgMzw-U=@@2w-&Im2UcihTi z`%>}P*!+HZMMjs(f+R^|Ow6u!wbiuyrg=} z>Y92zQ^a>>FPmpbiKx9fdOCh97fFFa5i;@`MKE2OELbUJV^A6iyQ<>d#K?WP#mW2Q zW@}DGEJZ|KcgBUBO5heUs&P%A*au{5yi9Fjrqw6Tqm1%hdd7#r9T@_Lqghq*=Hw}rUu0HJnXjxaM-T1Idvo3 zATXLjdu&@fH-XCN*s=q<3T4y#rLy;@He>rV6aIXs7;d48op+ja)U6*dku<1+NrE=E%7Og?Q);+8V^#SrKK_gzE8g z@(n%snK;FXPt zqQ^u=_JoJ~FXTUZg$lV81gRWduiLN>0b|QJuTg%c3*jSoQn2Ee$+h&Bj!%NGPrnbd zP?D3JwT7}Ax+*0KCeZF>*Sx|^Pp=gv1eE5%9!o;ie`oH(>ZQ(bSR?`ND|3K<;h^(P zG|`_KdGb!u{|xI8>GzraBX22v&~#9YxIkMuG8CK~J=F4;ys9RFC7Y_q1J~p< zKx9XKNds&s)l>0+;@r?`h{SSaMUbbWgwjL|S4llm-n1;*9_cOTJd~j&4A1f#!u(%P`gu(A7xM5?NZMx{*bI}G;+cu5k^V#Z+hL#n1s=s zugu`&Ev@jn`+M)$070pa<+cF>WB!@R134!e>gTP6ne*I#j%sVI1pKwW>E+$@qalW{ z-3`OeZHs|_GU@(qZY`coTNes6lh{MO(9N|yOI$H@X%SNkY}xpSHv9!!)uQK^-M2B! z7xSD~+OC#v>7&#$9jtevwvZv83_Y0^{eezD$sURUWGe)K`MTf7ih^U;x_&BSexC`I zYUA(bHFajVkx^w0bPjtf!rE&WQ1qBLIf4w@ z!>?tWig8oB1c-KL%5=Z4{M^Y|#KbbF3*=ZMz8g#Tq{N8AA$~kP{aUUR0HnW-l6VD}52vC!r(_3U88@BF0s&JiS~1eao}F%~bjw$|bE)j^P2{-d&p zWa{=4-#5yacS?V{oY%6smg0o|j0xP{wr=t2C$KUcg;`YCNVj^jnItKkCc#)1?}|m} zlT#^fKZ6K9x!h++PXiy_eWLFYs_{{Fpz`qBR`?&+VIA)?b=p93pNDQucFfn{`nT^* z5UN(B^{#y8#?irC#_5|)An2sG4F7aJyChhMJdf)70w@%zTbnF}HinTXxkEJu-U1S`r$+Gz~N8v%x znxJylO0xU&JdMm1Fg^vwXrPW<)Y+B8p_7B1r+kjpv5Um((r#?4FMf2S`&xccS~jx; zvfv=}mviKXoNaB==?@@dGcwQRA>eXjxqdoY{Q)VQKK?B}Y;7G%O2>f6 zXhm6nX`4tvS7(oM<&V4WYUYO&bW%=)tBl^wk`;OeK@IQB!k z7c8gGYqY)VC8m8uW5zxUg(QnoxGaJN<=#9?)h~lIL;6}gRKHmyRn_-^)}xICyzXom z>B+r;ULVR)MDD?vT*9}OzOQWE57Hdu`LR z1kTS^82u+Te8?hTHfPz86v5Z{wbj+res!^oQZzc(m6TFS+1 z87>?6ZUa*bIcvvxG=IA!8LwP73bc{!i_yuH7{?)1W!C%eXU@51XE*y<#U`)W{lcJ| zle3IKO290WShQBmD?*8e;u4URxuy6`j3Z||So51#i$W`}i5Uq6&9eb&dmlnp&Jhld z`G-egXGBf-Er}7dhQ{GVB8J?>+lssTHE~Fmm(ZF}z!Tq=t%sXE{Tjb999*FGESCY- zz>hIk>u&gJ(T$On-(E`03}nnszsTvIKqX$Prn9113mBF(RG(^NW6vRVc28tS1ZM+rF52Zh}Y;L5lgAPpY#K1N$1oOr-^LZ=6Y(~{^)ip z;DAlLYk}6Fy~LOHjh-$Z|1aoUK;#wz815PlZUhJyWXws}`-}>c)=p639*)x~QXtaV zQSbw-u}UzU4V})4Ep2u7-TSIq=5MY5Zh2Uhfz|mAqbdl-Ym=hls>11u2rA3MQF&ZJHx>+6rpm`FzDg*BvPO9yr?nNeN2)m zsK&wfGlu|9{!4P!6-{WHb25`&Pir8S^mlf5uEZm&p|ybFKl4>>-9Tm_CmLQeA{6JT zZs*1H{BDNqm0t7c1WqwUcvxCbY+iMVzJ!u29`}wg$^B`=sa)UPn8;#rPIgVH3bEtH zv-KrK>=lFRcwFR3S-bu^Z=i-rwIK~Kr3E<>7hpuSkjW$A=9oqu-hk%vrXhGW><8dG z@4wm`1VauF&zX>lr&hjQH{S9jzB$IC5Hm64Cf}YWxJF`#25|xa+M8}8yB-{Y<7iR+ z_kE?VK;*3x?_|3NG7hH=IB0)#b*`XEdgE^Mw(%d{ZWRAxpsy}g;E0GL`I+cVZW3-{ zLS9a^lj#a5f^amT3IKZpg9jinRC48@0pxPUUj~w63XJYIE4W~{pN%-$3jAlAD5=tc zPM~VReQ7vtZaC*jX@kG~Ef}y;GkN>?c&*tFct(N4!{FR=q2m&XI_cTt!j6;m6$Sw-P4(T)q37FmtrZW*B3lm0q2*C3#$e3ig z2@>_qWs*4+=YeXe7$;6dU}6~MHZ)7Y4oZ|j=~K&8f(i zjSKGX=>82}@MJ|h0a?r@P{tLtBHp5&Y0Bi}MTCbT+49s!N#Trce-}7REXm8s{~4(8 zrNg2ug1OU5lpfM_F?<9@M#t}4YkMfTx=AK(bu>9#S5d&fpS96S$BiKyGrP!qHDn*f z-?-14XOJm8Ha)~OZew8UWMHU_Q`*5c>sHCD=ZT?0Q^*rmNx)7>s#_s^k)|diQf%pc z0W}^#u!)6T+$CsM10i5&a)bW`1*kGv1iS$)&3{lQlv}&%O_qGm7>N*hqz=6LwCM7b z|MgNo-7lIJw|cowED;-hDd>;RmAzWeeJVH1>yvN)$Oht%0st~W#9i;7-b=IWK6!Dy zJ$Am#_1aeM@U}YO%A676)dZa0}<+|RD=lwYlj|LXQmZ3d103@Xuh`}t~n+5~HC z$tJ6mqsr9T6%4RqPmOAP@x}AJqhs=?FvB6_S@&#K$3HEMf_?ddHrdMjwO+RgjvT?{ zd`!;;r86`9VqbKXqc*|qXlf_lDT6c8mq;>J1Zne<+`|)8vDnx*j@ZjVhiQOKAQ`Lt z)n1vEc^(N>!~~)d5IEbvD5H>Ey+pgJul%v!%i7i7NTaN--m7CQraEV)SdH|qPEku3 z$N&0;!WJP<6|>bB?S`@>_h$t{h+5LI;ct z34Z31{s#=n>{tfKiWb+UyR;P1l{;nLOnTCF%W+rUoBDL66C{3#{nw<3u;?&q6)`qM zm}a=*;%Jd{6V|r+?&$}pkq*i+OjPxEt(=u6&!JH|Id-0go{Um;y8>x~w7S(2Wa7nM zV)R$1BoJY*L1;4s&xC9!HPdR_39RCw#|z}pCq}N!zx~SgZseh~uXibuS`hD{o?u5) z7FSy=K$872N=!&mR$0^1KFaWxM?8oa$m~~6+Vkm&P}IZ_qD^O-R9H85Zrtm$J;GNU zpNAdpjjA~N<1SMW-%{B*t0CoeK?85x5GOOSL1@B8qCgb$k5y>2_yd0Z5wf3XhmWX= zXzNWM43!Yg9=NF&AZ9U{ri{fB4mXq_FL484J1oj->cc&Unsw24Zfa*EMYC8yN`Vhy zuR#haPDj*TG)3D_V(N1ZZHC>bj;1F`zWWmfmZSRSM)-cAfJzUs<)lN1g5=Mqr8+mh zcJ`d&TYGXaPCHq5(bCj<#DgWw7=@J+3;l}zKKxD$u zcM-&2^1e(2IcAQ4En!9y9TFlA4y=ZSv;8Wd=_PF6-Z>y_57)0u5Uvo!&5_5MsB#$n zC2?ha#x{vQHU&J2O5YGpYD$*{)Sm_XQ-c?b#5Pis7(B&S<`xtD?qNEtM=M*pzm0N7J7hb9A8(5xc3|BkXlOPv;xr?uU1nl89rNXzP^3P)iXIDHy-a*2?PGnXu3G*>|XZ>!M!3%Xr%7JJp{`@G~H!$_-3R zYEdE4?(il!ih-)vF?FP)tFOOj;;MVL;M7uO3?N~El*BoZ16|jD-M1|YS-dgT^dx~) z8xWOCWM#mT&Z^0Bqt!QlHjd+P6K2LC6R!aVd6joBv(|73?5*=>Bn%<#Co3a_857GR zQ-akq84%OO#A|h<(^I&bOHmZ4E+YV0hNGeGj?6}P=Ke@)iMr4>3fWP4^AxJl2ofwM z>LB;4RUk@YPRmavvf+a8kF*wyYB}t<(r~D)W+o)rTI4eW%=K;cA{0wpQy8Zx$9ih$ z&AKiH2aPRm*8dVU=?^jV1%*Xxm{jbe&#xH#`q-Z*Wwg9TScW)MU87^i4KmH6!O$iR z-3#D1#6D-CIlB}l47BXOY4z5=H6e4|gkC0T;8uiQIP5?E+mWcpN;;*>4PoEDF`kPv zPs*ghs1~VWl1>^SQCLtp`dYX0<42v^dv&sj5A!M3;gO~?jivpjFwNNI8YjDgt}YB8 zDens(u0%D+Vm!?LrR6~>WRdgj{o3wRPNF;asVK?Z(XQq->Pe^o-jYsv`ZoQsRnc!$m?3bsP{wGs#!&fLlb zpUi@{MS(Lg|GC92a4Py87EFB?6QyC6KR1~+Ze%zoMW|K$(3~3h!BP;csVrVl| zMl9AhDnIR==XzxBbtmySm8ET%lj-_)X%{w6xTkh(Z%WWSTIX;ACWq%I9LMrIrv#}3%zo8X3x3zed|5% zIluH>OKmEGPbInY{C0N&JT74lVB4DPx{h~)r+>hvT+DXg0s(X0A|LRqs1Pctm3z5? zT{oKFkATsWVsDtl@-t|_l8hH2DH7{&Z1HX42zI#Bb@|nTHMQ@nTXU>rNk^|pZ8Ce5 zHgz207Ir?W&!-O+-`m)oUU)FK)xU@9o($ed>fUUx!TcO3CJ;mK!Yzi`?tJ(8m1r`i zTd~Ew9(Pf_-oiIC5`AZDgD2lPg}vJ-y>X*_T6|Y^=Ep(dc15G_#7;b(O0O3Eu{>9+< z-Jn`p%PEx2kC<&N5BeJd$oAV|GyOeU$KC)wC82=o`+%&61;iKZ*zgk&i<8$>y%Fd) zziy)+5#I&xwNpi7Vq@HGjePQN%gRl|a}7exWRF8wK{#8DI9Zh8{=}qLCrx+6IKzmh zD)rSFDpz$@Uapg8C23rgzgi!cipRdF<_QtMqp(1`M^*omPqF-wdV+3{WadhL(aKH1 zkQ*BJ5}uCLgd?vTZ~;%wHjnDtT+bcGBvaDJjd&Ti7^&$BWw{3Yx0?XYQE`IDa!qeU zbwWg&E|Nx1U08G;Mv08BSi_^VI^nUv4}4aOH@(6)cmXJ-l$}b&mT2+PM=!_bU&c1Z zN|Qv9=_P%Ri&k){xO>dyK|C?f`I^^i&4vX!axiu2w2)9kqxI@~>?-HU|46COPk}&% zE?a5>3>La9H9Tp0l_Mf{nsY&BW-L>mXU=LD_z~t`@KuSFH^dMS)wa? z>Cr)XPfi?ivpH(x5+%A7R=(&EDQNn_pJy>#|`+8TG zja%=XoV`SB1x^EBrEmtY^v^l0&P#Yyt4^EvKfl`UtjWzl&_F?!ex;fFtgat7Zm{_w z@C@+JHtsVnfZY&dnGs>VOT;ax7aKsahy-@25qj_ynCHmk2co{eaS%8@t=QP)Jkk2z z{T`!bRV-l44Y}O&<*^7aNJCxQ=%%RAt8*U)rL53g;!We6MKx#uaDRd@nHBvuE4F>M zj7P*EB;tF?f2*mYGi%3SeIl%z9-h9Of?7+^SW!9KIR8A~-|vWI*BEoN^VixVR;UAy zgOlcxhu?lHj(K_6c)H!-4Swt9`}ADz;r*p%xhS{3S1Z|WXa$phS&?d8wnF(`~Y9F22WZ; zZjv(($?2uoz8;Pqaq#Hm)9d~3$So2}T(Vyh?K*FJ<0h? z*>uR#YcAW)U&;P?VL1;c`GebFT*z61*UB+lt5&N$RiV;714LUIcWA#6$gg&?@NhqL zf!E-Ss9vK+#?UYdB#AU(b#hN0j7s$5+*f)dyvu$tT|i@k*(g=A@YZZY9EEe>72D%P5R^7d*APPEGH`v?{qp}dIh(%Ue;hL9n~pi!^C4m-%jaSU@QAS z)KJf3@52)mnR?WRu({rr_=xJv0N1>#S=cPu3e( zNWUt6$GG4>l^2=6(x@>3@zpM4h@x|ta+BcimchCc^~doa-t7-mc~Ln+^B_; z6upwO1RTFO>H1nDi@`Jyz2Dop?b)EO{<+;aZ<;V5z2AQguzVL)ij1E;u?X z5`C63nR;_!tIagynIm*++4r}l*P}V=pKD}?hw+mZx+qQl*!RP@s#%S?DtRD1aHWpA zX>b~N*|fcOgRj{bWdc#rIf`q15rzRt{-AyRjjFR%`Q*`* zE9#lcv6i@cf58bsOluQ=q!CAl<{dvw`c$2juw2ZK*#`7Eq4TD0)$N~-Bz_kc(aQLrr;Nao$>8|TsKLyb6uk00z2&u53eOfqxWwd`!4c(Y zMYx>4ytyJ5)gvIFv*NDIxbCQCRa#F@pO(OKF4mpQi}{l#Dtwmfz&V z;kVWN5PG*2FIq(aP>XLhB?D8Pm)|N4yF|$G3zj1 zHRE)$6mDuV=JKl9Y%4#jAoas=?BzpReMoc^B4%l^#VDrx@(_gwF!DH)+#{H^mlJYH za!&*gOa3Oo(WN}+zKn1>q0)@keR!s*E;T0Y*Vkk6niV@l?D3a!S|TW+bZ(UBYwof& z$J;Myodf*9A{8iagGN=2{oub&hwa_BCnTeZvi0WV2$QY2^f2t>4ap1wT6M=p45fl* zcYu8;=pbwT1hH*?&bCVpFKRt`cO(D$5rb*U0V{oa4u*Np!&@8?g_3srq=^*nGKGI^ zm2L2oOvj*fNq}KRe5aCiGx>t7zvQRW=~Ek^DPH+J@JRse1R0T`ua63?A?i-0in8fw zEh5xYVmf_^Gg2r#vbx0x53e22{jjTAqFXQ6iIZ*XN<-0;iThjz{#JSCrH?&;>-&Dc zME2CghU@eBk*!V16!D+)*s+c!f`7n&7XANps0V}bQOYjE=JYWQ(bmbhz~0vA<2$*f zZOklf`ts2ZN?@tcrzd2%jU;EO;Fz4MT}P_G;U_DWT;nzp7y(m>3Q3KHpbw_^RgDP6 zzbdZF5ho{Cl80!amdUBJ;GwyHK_5*HNAo~VJI5@wz!S% zhyIgBWhaSUbTCgzX#vA;rK&Hv!f(*=)oAiP5+x}oqL~q%_3$l3_S@6Zu>0_YFiing zc#U9vv7|kciqXPLb4)QkW5fvm&|ewyJ4=VfGhCZHq!$^u{p8LPc*GC5HkejEjX6^_ zW0~Ee;tQqhUXYGO2yuFH{R9`(_eo(rksvEDDPGqDpFhE4iXrp>_!>aamoyHMuMd2G zl|bP{0lHo_IdK2y*~1;*to>LKviWmK9x+x@6s~#3za*U%Zp42Sm71!~+DN2?6;_lz z;#T`mb)zYgEVW@%GGkYPG%Ody-Zxj44-}9z8Z{*9056)@k6vwO*D3~dA=p8wV9yFQ zQ;kDVVo27CT>sHQpDkOfnbAPb~OE3Ti+9l?+FQe#tTo2s%#QLQ^7zCoNPdmswfZyY9%VCC60G z_aL5x3mCLGbirEC*%QZ-4hTiB57cqW_5PsYZ2dfP;V}{s#rQem$ij!^5a&PU`n`vH_Prx*6?k4 z>@p3}8}81TGLO4Vz`OS(S2CCqK7I3GmsvS~nq&pwofrixWNO4S{#!lz-pmOfm4 zo}}QM=nh^_!rAka&q#DOP1249-A`6$7QeZy&HSuAcp<1HTp6{F(|b@AQguyKc!t!! z6elzYDC7TpnuID66OGpx_9q=KsKZ!TjBI(@odhU8BPOuqV5$sro)Sl+GoRsioq*XglZin(~Iz!>)aOvb~gzHKc`l#MX{LTix09?E)}&Jpk+1 zbKc%Z7bX$J`B|WPuUR&#Mj-dMOAlw}uPld~g1cnPyNi4?i4B2M;l` zd6ExE$x4xls#)a!WWq3?i{uQA?c+BXqa87`h0YnJlY}1y`@6gcB~luEEtI~GWChVw zC=)gDIH`?zDwrdu$5zVH99r%jLJeN6ik8oh$phEK?#TmGhSD-K|CI>*rEew^Jq-DaO`?&ilrt?Y)iH zt_Us1E5O#L^Y!cP=B9LRCim)@Khg=E5~)RFC!L0U2`7O2>RPJEtI?NQ(dzwfeb2LW!IcDz-=)!S6+evZ{fvR6XBlCnpl&gxri}(dq0JIA+*v_08cL3K z`M{tP9KF5|eaf|!W%hQk_7cee{{rB!kB6aUm`jq(ePtM%0%PA6Z#vb5Y~WP>D`1qa@G%UwmpwdW}!` zzUA&lx3RbT*7{hCc;7BmVD?}pj^og|_pFfMk1B1+tNp(lKNra44}G=DPV>#`zt^^| zw;?_=MqBQ{PVxCd_hw$F(&IrGH6EBSb+}{J`OV|l>||5^QQWlwNdXl$nW6Sj)$++#@}MP2B)$4wJLpHn@7|(Y zi@!lT(3|f0ak$I$(VS&bfA8=t{7jl5e_Ez>`l6=KRpDl#w5dzIp9?{fg(gkUD_oGA z_bad9Zfrbs7s159>hmqG4HL{Qd)ON9<58Om`}>7QGZ{T}SfwDDg<=;5nn^f<#1izW zjQ@>LQq8B2ty%@mrbj#y@Y_;fUn{v$<60ICjY1k372fF=e%-cY4oeXGPPyOr)-k+v z%>TV*o6r7!jh+HeIaOfn$^I;douKIv5ehd_R|V%PnGA2R`VG!xCBS%po_;e@iDQ-k zU6eIXCVRg=I$KbH*4!A$&RZ%%ozGP)HNxP*mSAdnUUe6G4Ftr~vBWt{BB-QmRYIC_xbsiqqR^dmv5c(abt6SJ zrbE5e?_~qYHnQbp0i8nS{G@qA8#8hsFu79Wl$HYMU_|k~A*nL_;6p&b z{)o?pMP(=JP#3e=vHk1!Zv%!o%?nR+}WuD$yvnfuA}?ygQdyAtYC`$M>>d1~Io z#3c4UZv2O62;O~~Uib5;(2vAEQ0buTn@}tA)WJWKk~R*NOl$cOAM(AGf5 z4?vwx%Rz2a`|0BLAHV*mCa!BP3&MmrBx9LyG)t^2Xz%aLx&WcWJFXq*pU2y#!`BnV zA%cw6X*7(0L*8n`F3jRa<*1o|c<#O-hSs{edk-g}6>nBK3x%`OnnIq^TP;r39e37^ z8#ZovZL2nsA0mCp zfEX4*suBse@#lfAvm=WcA@O742K4ymuquSW!z>-+{JGQNa?z9`pV&#a;F7GHwrMVA zhCNz|B^v%0B>n}G#@GVSp|;D~`6bj?OM)XzgXjy91mQp0Qdnll(qo?=d}X~QW#v6z zzzokZWm`1Q6a2kx*xAz)h-xmnVgG?gu0Rn^Ll~3+n{^Yr<(mKNc4=)ZgBIBi!ft;YKiX{o?4D;yYUO)#TI}R+b=uOT8d;LJ%a?A5*h13B zKkp}U;!lMlOoHhja4%H^No7@18K3{OjZyzat+q7wfO2&mcc7~@$y1jM`4COc8nNzy zrj9I%)cCQk*a@tvXy@a(D^_~BIYA;>u%jy>v&ZOigUb^$yA1=}|;Q z7%GL{7cQMwEl%Ga^9)x2i!zf}nw|3@we9e7Ae&WuYgebNYYl?4D_vIa5+PGcxJ1Aq z)2O<{S&ANV$voURs>nJ;5F4hx*=ORY*F_)+A>y=}CNCyoQ{`$lQ@1^Rohg^9zroPQ z1_UeNZoJZ+Igl*@W|7eZvy9LzG@*^%{r2TjdRx{%T65;01tn9vZqvlLnj5s{W$2fd zGJGG>`VE$r!un*W;#E~?nwOCWGZd4Sk3f@)^8&4BpRl^6R^6An=Fjpiq(~)cQQ19B zx-4K~nk#}74Xo`!k1Wj5jtjM+?DPWHtF+>e1_5J$0xz`w_AW&ZdTqzb~^A9G z>2C*|DCpNO<_5%7o;_YDfB1L8vA|u_#lTkXLAjiTlfvi~1<>Ac$cOdp{aYwFw_VNh zH{|XSAQW$Lvtx01vN}>{sH=w~IKxtctbp;DS%jKXR4CD%POBcu3I&mkjNj-HM^LZ+ z?dMO+xO0$Zx(hQDx8ud058g!{fO_sSjIE=02D)10~pncw%r(K*95;2(b_7p6v?XQ>!heBCS4FuH%pj{h8 zWu~EKovLQv`?g4SI&W_LCO%llED+qyEw405qWtdUfJ^KN!QyI1bYp8im3~A}F|##I z-Gko|6_x{#$B6Sg^L>+aM=0?zpQ#mS&r3!@Msl8N{LyR2j7N`A*t_+hlOLqMs&mbq zs551_{o9V!AY82Ji8~&>iOcdjJOlq2I?TaN@ZdN{Rr#t~)UMln8@CmCyzF~DjTw`` znR#p6oSd577^lPy#5&ZsB!kRT36t;6I(PpU0Qf)$zj~bIo=0BRsd?N6G(A6~gGbJA z&}DQY#d4UWz%r)Hse_lGKNR>X(pdrHq5| z#RL&I5pg3n-rn9m7ycjCw`TjM6y7L@MJ21xzgDHlOEJr94MteO!vh0$&8bH*X11Lk z^|?UUDvH|4l7bGQH`Wzk~<_fNxWIy=k$uCsF@l&s z0yyi~_q%+}--~EQz8e?lMbv~FY11qn;J(H*#u#vH=s%NwKce$b*YukW=vjLc4LPq; zeN{$xBI0I;$wcRu4DST9!ijNmNq$L~OHPd~kkn#=_YLQg37*zmmRAPmj5C7zdG(yw zxkZ{b6tn9+b;q2tg&YRf_j<^?3pn07PF9jKg#>eq#8sBF5#b84v_)yTmKE>j%1-H7 z-Zi@4-*`S)Bl?P+Rt0t*^NQ{?@yRHbnh%hlMin*R2N0FpM>KV z6-;XdeQyVsGb)?}dBKsw1G@4&&|rhr10%R}Tn;+{6E<@xXtyvW3saKteCs{$Ds&c4 znjbadXwh+iKAEFMa~8ke-M@?#-%89eNGP5mqTh*cRS`r#>|_ujYK$5okt8CUsB!(^ zkBSn)9NG4ikEt=^<%E(z8q;8|&t^m9`E5rZ^RNZ|T3dZkn&AU`d{0d?I6E%*vBepK z_zv#9^<%6-bqs4M1$JW1@>zq-=7weY)VQD~#!d2xv}VH3MP$jASfu!r>wdXVyOvB6 zj)#PbV@#D0&e>UZtH)O#AbH*&i!&5hzhII_GR*}LVVF9@hv!GybW5msryt|$7dhzw z6~=DRWD2HFxWEj|jNZ<^$b{goBhPA*knZt-?X(DXfeU;pjgV;Ptz;SzkP8`?n#&+9 zC{q|p8GZTy@skr(sd)ghvLzI*C5g;jUh+<5hL}osj!qmUfYSPT869vL3H=lHV9BnMALI&*-lF-S)mE%h22ouAL;v9vFpUK2v;l^Mz zAu~jlPA@@4u4ZC5H#Se#Ss-MS_;qe z&*#tIpC7-j9*wl$>{itVU;SOFnV73z%sKGI-0`Klv(#Mvojv-h;m%u{PxA1fX~&xQ ztmqiiifN(jK_2Dx9?6}_=o<)C$gav4U8??zyb3Up6IRn3i>b6HF!+@RNUuSmBAf{} zb{b)(1!d`+&sjE3H2Mc=O^tCbq%k0Aw9C=xpI~#rmG`q=VMu!>uyTa|m=tUua;i>? zI%a{feRqRp13@tL)%G& zkLjXH%Y%9r8G3olbeg*ZqJ^-AD@%g%@@Sz_N;H)BIJ#Z|pNN?xwVz0ke~|R~O>`bD ziUSTQw@ZyO0PV3PQa`9^MuKO~rjQ@FFi3DU%($JOBQ{j;h^{=()I5_=q?_KR=9!8M z&F`1=WAjZvwy+rQC-}x$?j@+ETxc?B_R=0!VTi8x}r-C6}WHj}W1U(+J(g2rjfAX%Fq-PU&~bp==(rOn`9; zlXq*ZSlfNw0Hp9QEsRVL8eK>G>WEvtZR|aN`6`^|GSsUasdoD-L!rt;% zcL`4noI0hf?1K1L!jdYx6q~I1EyzPm;4!V5{3zLs$E=71m|K}47ZX@vm+^3Uic|0q z-Tu48$Z-hopQreH_e<+ZKRL@ikIHaY_21`WJU&}##IXGL|Ju=lL3xJ@S)A-&Te1P8csp@;#ac{e|LSVJJ+uUyM|JWQtF9oGaN@WjcZ{Ay| zu8eC+m=gY%e1CY||1@*?_-KxM#|hw5b;0e0If^$WTy76-zj@f)9(W_6m~>|P_4)3g zbl4BxnFkLSyqz_-tp9{&`fYa)DyW|}yWMsNT{!gr=H;hZU&q_tVy?_B;QGEiLVEmh zmlfIkoeI~V?(X-$Zkl^sMW)$`iK=h0)y?P7w1~U3$)|7kPY>H4!0z-wT!#*tPYmo` z_4~xW9jDiR`QZcDI7;=ZBuSnMUDUl&cDbw;V_#^N2nW`&b6{|!WsAadrF;_6T^?I$ zM>=$CjOGrg9HBR)>ZDbxpD-!kevQ8th^DK45`v*Dj@1DTYO;s(d_KbKZ(|EDksc&j zSV~#yK5j7OaCoF^f|*TTv8P?ddHc2opaZ~YvJJ!yV9rG!gRQ`}0qcJw%!0L^rQT=n z?*JgYc~WcUe{%PG{wSaBZ~d?H4{-barPu2~GS4?Jfpe{&pPbN4X+$`Zoa=)4U^v}2 z1CG8Srdbz+nUi%JnD!K-apul#^gET(7>J78ZZ_ghqm8lBzjLXzK$M{MNJgWK+l;ce z&FFbDQC{~q8Beb}oL%PL{KL31SJ1Z1ox>ETDgcE>eZS3w{ICo7K{`Oywsn#;D%zb@ z3AE71A$9zosKm+Pg47I?8RM~kiQ*Kamcp}eog z7!i!iWM_Wy?m8IOjZ>^O3MdBKLdk`Ua9|qC-~ax)*}D&v7oRt~oBie%va8BHv@3Y+ z)=kzuplecfZ@`t&X{PhD4Uxm^6dRe_cXLP}f{;136~cvhfPxE-_ZMYIJGYNBcE&Ng z7DO9~&9Ow($xR)c3p3zXa4yz={J5z|o+6`$B$P3sG?hwn8A+evpT~Byj3a&>W_i|? zN>5w_rgR>tc@A=ITg%^G_kWgMFTQDkF(HI8*70W@L4ll=Viuwu=A_zYDUk0Pk*)yZ7w8hA+?XJCZ5=5#Z&V~iat?kbKoO<(E zbEay}Nn!Qm_sVV8b-2mo?Uuu9CWqHzo1Mt^iop-ZrTHMX+4;rh$UY%SVzY9n5x~ZN z*skw_k~B$dmaSO(8#~7}cYcH2Ux7aRZevh$O@m$;(m1LN7X`~{KQ+?a=TIFTfbDT4 zPkE@eTf7`exrhQt6#RR~RpB2;6a~;R4aSar`o7y7tbML2CRBAjdDrIqgVgovDT;+e zq=@*lPU6B{-g&B6`Wh2KoHK^qnr@Bujuo-6F~3OxWnySN0&~08FV3r)5Wny#GA5K^ z@|y9sI9A63Z9HoiwSEq=-1|EChMSgkLmpqlhpm0gx$?ssk9D`(7RhXYD^2QW#+1>B?4)p?p3Q#T z975?dX2g$>9x_M`?~wh%SbrBWcv)ib9m#=#xag&u@CjmY1o@UJlg}@o9J+8!`81AN z`Q8!v%REjlQmu?DkL|z%M{63Q89^FQT+v}fbA}a1c4_FN;z5PPS~&hgM`h-ON>GuT zhB7D1QIn5K5H2Y1mZFD!c{Wdb782FDk&7QW5;0dZbEp0Ma?0W7PGCn_X_{{KuaA%G zTx(SFc9GSx&As_xTF+cp?O)gJCml1M6!3K$&UamTlQ=mz_AkEA`fuCEZ}$+S`1&23~WwDV^aPc+tHBqQB}h`@y{eQ(6^c* z-9hlx{vWUtj*vtsNs+SgkV^PafvM)oDJ|6qRg5S@s__2t=WVVdhPoabhu+n))_iiE zsxBYEqB2v41Y**hC=^SE?d-E5VG3;2b6Ql;ck>P{Dt=4&tvUD!;cL1k=yv`6j$r*= ze>49io%I_ccywIw=-w8U21M5RrG$%}4U`fr$njhpgY({YURaOKI8OR$U1wGahMLb5 z^E9=f({tiT>4}gG5)hmYmK|qbLVUn5+h{H zEt%un?lsXG-*%2V3H28n3%LK|*jO|7l6!BO?tFxp>*qa8h$)=v=dBdv=)He={T9l} zUv79?-jy4x&j0U9KVOs+10Q{JCU5n z=b+M@|AQMF`tE#i&p)4UzCYU@H`}cpa9MldK*58}Ub0h2Rh~GuMo|1X z>X&v^J85Pp=AkSK#9@dDz~rAIcvb6Gnz7n)WmhTR7f;ARw-c=rTNl(qOp!? zOzP>gz?7Fm{o`YNRCgzr6IUev>V5!k<$PNFTajqEe&24pwcd35c=vFBI5f@4xcjpI zx!!HQ9Q*a<+x=7P$JOWC)tAl7ZTpVnKd=9Md{}*cUcdaj{<(eJtiTql8_cQp{r-pD zSatDk{jy#)o&nC~hwYDjb$R>ai*FL$%BL$|+0oVxClV1SJ=&_Bq?kF^z$BRVQ`W_B zae@wBcHHIYH;leg_LZ6Q38DY}>B`f>r`sR9?JJOD?eN95R;(%~@X30AG0o+ks6r9< z59X#X@#mm9FFza4^cbPGg>s&iS6`vz|IS<;USN*%!(?T(WUq;{vc-q!VvVi7gL&Cj zWmW6#%gY0p(5<}T$@65lnoI}^+ z8waC~Z*%jutnbk5=k@I^SkL1W^XxmV>itt5RzzUUF>wwUw;!7w{C%zt8GEbN2&Pie zA)kgP(R;h+nkdE)@~jcC;$Xh~c8j=3QHZ=vW-U9IdGjzd|EPES{Y{ZH($`C0ITO!# zp9)OOtgT{(S60x*)AJ>1`?rw@qnKxzb%W_{*34OFhHqD#T zBscaLc2bER=5W-`{k-4oN=xH*{cv+w)tiU=N1#50^%hMCrIH{j6lbzXn3_5pg_&LY z9>rck1V=>**R%r>N||aknAXGFf+UPJ#f2=&9i{c{{wZT`rFHVKRSq}_Gqc3~8#-yK zl{wbz12Qt0lyX5+2j>6X60;DH68q{w;0C&Q(`<^hg3@&EG$~?%>R}tAdrC z@H2hguj2=`EK|}5K>sK|^uKzZ@3bI<;KJ>byErM!Rqh6OGW%|k+_^~_HaK2z7V~=6 z-Z9b1`sLkt=igaaQ_1YS$kjbbGmN!L-&bSIz5(}j^LEq^sMMP-k=tUSS= zt8;mb$WO+?ygO(YBC-1(tKd@=>}w1sA|+O~0~f5*9#grQg;UI~UB7B!M;PPajw+4i zgOXsk8vj3G$@XRDaWirxdl5`t^Y5&MYwBCD;3um#HbQI<{|1`1_yjhHNf~P92 zoW<`@teut2DccO>g;*sQ94_l5cm4zq|Fnw3m>G8jCqjmLR+s7O0vKkYbx5@Lr1pF-8o+F%&VL>`P*6~nYOqntB@}3x5|1%N zq`c#Jhe)6Y7#!k@6X@jtJEG?r06LHE5Zm@K3b57ouoH4B3Gp3)zb=dRueA6{sFYM0GV|cy>KH$nLb_Ncw);P}; zWa|ye91tuC%=#oDp3ya2B8Z(EE-8XI_`L*zY=;GzVoE75VtB?4GnE|qLsw^^d&c61 zDW+U-N{tFlc-)077C78AXC|9RWJ2qw^xy!3IO}HW4MYcE8_7RWct9+v$FpZBd3h?1 zB(@V1nUsejzS=e7cvw}^UC)F>6-XDLAi-ZbDnP+-qKZhSlUT?FqmpXj6qb*KTyR2| z;%@Y1E98Rm@UZKU3yrWqqT|MQW&dj-Q)Wk|EL6#5P$jL~`lp&aJ=uL#|9v)QXY7y* zo7q{8v3VY2izD!IjE(QJ6Qgp~IjG#`JwKm6e}8^7bJAV)VX7rBPAH^oEHb8AV$HPB zc1%h@1NUi`m@vv2?*w^3rV*Bib?B@P5B&D__PHRJt#9^7f>)FGbyZ~UUzyui1O7|n zmSMBjbi}M+(U(lv>u|6{AMgL-)%(hKwm@rfXf62os)pX;T@HTf0oW@FxS#^nqL>&X z)@IpLcLQo=~ z9Ni)T!gwNDcD@{5bh0j(Fy>fsP6rUinlVnL7-`!rsggSV7+0u|?g5zOwnPP1#tfLi z=ZkWo31<`JCB&i|TJCRlbVokO%@9LMVS=FGZtqway;hm}hYwx=^VRPTtcJkL~2EbaPxXY#NqT&ptpR{bb$ew!Ig60!RP0|0JH+(U39x_Y%o_J_vQEC*x2Tgj0>a~oz@+QL)KtN#8Vkx7n?#VXyrEfxblovjmw2`RvH@?2%uQ`BN2_v1TB_BgxV8$Ci>pP&@0f zUy8sHZ_m%3Ws1;6aaP4gD0vv8)&w}p>oHH6(uMIEmjAUcl9UoD+ZC!#07#U%D3HH` zZysG!Zr5H+P3Xy9uUiH9nF)CnptW9XP;~b%{7l~CtLgcf>2`9o;*U831(KX$ret&l zq7{F#S{ueA5u_;dlRmw8Bxbs=&sg#&3+{7ViGgmE51bsznig`(LoT^Of{8TDFA2Xj zEt-9j2)>ODhgx-!B!M8P6fBf!mO3qM+>3C`G<3$!HIz6tO#PhovCLv9sQLyxo@972 z`G9DlpM-Pm^uz~0P9d-^mpa6nFp1rAo`+$ja9$J(f-xD3`kFsyJtLm*0y*on0A`{H zl++-``)evS#Q7ynvTE6j5&oi}9wO&J}5INQ0=_C+4F`=|R+ zYN|6#z4T^2WSn(kMGC3YSRr*NC^?*HEfQBim5_+q9&53%0%0Bj3I?`86nFQbMo8*!SQWSppG; z3~m9sp#cmFM8E=R#EI?RH8y(8$3>0eoFQL7nV<7LNYZtwN~YXSzS)-SW^|W zG!X7Q8SSs^hO$xT`C`bER3{$?r4CH{IMqvLp37!%weWU}ms0}1UhJ#-?{iTM|7FtZ zC70lXKZs%|T=xf24E?wOqrnP=U6-Ws-N?H#Ce8~KKJe-{g1%z%mC^_=P*45(_3r*9 zyB159t9A2=On2)APIYdWIAwBdrFt*%>U|;q!7np_Mn|2a4`+)u8j_GBct__o7s^}^ z!=ts7Me5`Xh&ur@m(2W64h6bL+|}~J_#aJrhi-{4tsReJPV>O zI6aCI;k6bXPdQ;sK&=0Gxbsj@d&Q3U~hXUR6yO#95U4aHcgdal2VOlF0?j!Sfbxorj>kw;MPTC%TFtnzzWE_|IRo( zKgzy1FQPhEaBDU$w$T|3DR8X>*+M``PCA?urvyx)Jwa%|xM3e@Df}hU6e{vCkOaj- zD$P-UDiCvha*p}rl=(R`H5m~qG-FeQ*N6foNesB^t~%2K5&$_IH08#=PutHaOnJ^M z^`ux&t?mYu$_Nv17M;7%{3O>>gZzJ$9baST$Vs6ABE9P|v0d~bhMX6bdYH1gwHi5R zNGKwao#P;u7=d!CICX18w4ilurO)>cAeJ7ZpTDayeEiA%o!_4{`vr?;zo_USLOXIQ z=H3c&MfFB1siOLahAC>UHv7%b6CEFRXd>%UmnE_;c1fc8Vs|L@AmOXe@a)tSOY=LB zx9}%bCyck#L=H=;zC^&xBm(9`2aOEmT;>%Ca5{7e>rXalZ6~S zJaSTUFzxioWPB68r}@QRr36?RITaA&&YN=5yZMTLL#4eRjX-PF6#2VSQ!-b-n1O#W zcYLYtEH$Zrw*vo53t;L;&MZZUCn-Xl&CyIz(zyTFFV}^1DTX{_%so0;7wo%yQN@sF zvL9wmkp+b2__d2uYp+gK_%^Lv>;KQ*n>9C*WM`u9{1r4l&6stPzAyPEsU@|#HQlnY z8oSr#g@y!?Omva}3m_{yOLqVJ^;i+%e%!-779c=EZI&t`B0M~NJKs6qS*EM7Ja$Fm z)5ccCmw=9~*nFxA%j2g0>Z}?(E&Db~wc!D*YEm`kX{nw|Nn`J)Mt)J>?+GU z2pIwK(vlkPH;b2tUg~M+$zHDuDWzwaT<@Zko^h9{@jhAgd=Fc2)X!jS<$RuV?d;FLV$ zM@F@i0J65!E$&6a+`U(y(G&x0CreNvN>!x({9m@a%du?0hQQb1t1dg z{CqAhm3h4H9xWC=uJR36637M&4nXTM24x(b)uIc+$qt@-isPfRggho-k=>g5)|4ws z?NN^*xxF|$f@|uGIOK#Vhn}lAKQnPc5aa|Tc5r?~2*#Kz6dMtTLbpHM`&D+NTo$F4 z4@mK^WlVmA%`tV6B=?byh(?EXt1r%n?D(@&NdDjT5VAuu(k43~+h=KvzriH$_bvX6 z85hl6%8X3$1SC?bsIn!d`m6d3$#D!&`o0-RA($ zCcyW5cZ1)2SuDS=HjtU*=KJdB{jOL&z^PEpICN|lhkKgsG)Man_fOmH_qP||JT7jy ze_rqR&~bg^>1ln0ySugQrSp6JWx@V_-EB9oy++RSUhkVhrPwTh^>%Z=TbUgUzb49n z?LC)vt6$&DHgeCwT2d%M7?*x`h2?g$Ss673(2WmmP+_)}U0^OVQ{NY(lnGPY*5bS1 zTLHxb*e&wuU&Du06I=t(j>^9LZMR!(;6+z`xpz5+H_4%8znomZtbl1V>*N90HeYuu zU<829v|qA*0Mw*%$zgxjij!;Q_?O!p<+xM;Ah!yHtNM^mqLXhqA%g!a>vd?<~aZqkQaNk>)t=!+U zZ@c$wDE~-pja-6`pW^E>;pTnz?FA$w%;;y-uGE|o8Caz2f+OPxlS)jyuZMIkrFvxO zA%G;{wp{e!I1j`%aC&s-1Pu>Gceoqf)qwf6mCylzX@6+Xa1!S1k%H;$97|I(Eeq+*{{4eH0H#< zWDdkzNJ6x`*SrgB$tjXjY3Y2zc4G#(a)m^2>o5QM*FUy(z3Nlk zQFvHw)*w3g_WBA@12^;^IR@iMQP=a8Qo?p|{u{_^wU%%x%q1zt*2aMB6 z{=48v+i{Yeur{U)sx+MS?S>Fz&- z>!XC(QI9v-u-qrc2WfuPKivAy)A9z;TxGiSu-?BcUNfUzum@ z76am(aBYpmZM3{0Bl)1!6x3LC*3cKq+BU=iSj6M#F)}bVnSToRYTUq;x8M}FJ3bK*Fp3{WT_)36=B-x#8DtB@piHa zGKfSvOIi{Musc+yD0PNNt(CTS)lhZDrvoUR*ezU z%C8zr>>4l&)!52GZhgc-`{%J%s`EucqdWBAV4m1iDlHZ-*p_>unc1N@_Jo@`FX21; z!Uvgi9(JFU{F0+tvF#M@qp4!I|grj{giOcL$l zF~Ji(?##9?9as?}nDUN{2Nk;j7+NxZB7cZ*9~~e&yi6iO4iOXHuV^R$ZT#<-p<%mk zNtbzqTbR+qLb$x$07frPASxX)hdYS1MhX6v;RQ^7O~j){crnSi#?=_b$A5_0C@_q( z|M{Q(c19TQz3{H1SW(YSv z*%PPG@Vu9Sjj#he4?~`e=vM21n;8_?+~|qlaJ*SB{qGE%TdTmQ`yYd&r5hdff8u)g zYmXOhzrOZ*aJ~Jp0K#pc=fbB`kL*PTy=OU#s8O#4W*PLN@!5;OL*x3Azi2=LA8dU* zl)>jq?+iYkC!^)TJ50>96oRk#lBlJDhY#Wl;p~fkkaD$LiZ7hAi}3Xe-?5!sG;auB zNH7|B=tcN|=^R6DHka+ToBSSpCdT;>Y_kgfNqzIE($n zsD2XzKo9z`WP|gz|5*&W)ot70x?3&4=%!Jpew>N!8|74M zCl3o-69m59oTzWPGDooBmZwv-(QuY^-B#ERG4cvgB?CEL;r&)MP8lVp4SS*vnY|fO z1ar)sxvYB55z{Q%5Ay6Q2lj?JF!UQ2DkedxNFm)2n-}oa=)*C05Zix_?TgbwY~gg8O`E+vK!YtNFfivp#qt}*1T*pBf1n8pPDuJzmyhO#%=*pGwl$7?!H90R!H zB))n$f}1r?YCSV6tmzK?=>_Q6E+RU@MWmX)r|se)cvd-vB!-+N3msp1!`7O`&UWL@ zFWCJF_74Fogt)JOUQ)m2vL$D^B?IX1;tBAMU}6ON`=Fi+|2ewnLV`>vbL}Nb1+3lN z8<1E4^Z3D)4tyyYtBi?`WzC!B8%()ro9wEDi(Y`26;R0Y^v|WIj?FQT41pYz_iwwG zr#C3%`1|Sa95i>v(F0m4EN>`c-U>T(lEf4 z>I9d9QAViw*Cw-H7F8Nsa|hEH>1JU7CzgJcUNzonUP>t@c92wExdIu&#JtYy^c(UEsz@4N18|cH)mg(g>Rd2|<1VcrX@EDy_X=7w+msDxQN>yy#f( z2n$3=#Sdz@{a+)Kc?w$&%$M`*a-LnzvyXC~bph4vMSBB}8d&wV%xrbLe|vsjw0WGW zUsdue;FfOaD>>p${~&~0zQtbL)k_`dxO>}dvOn+4y+2Ip&2>MXt)ISKE_TUbr==F_jd^nUH8?22X}}1@)Lh4j9IJz$vKUVsBU=-hx@jyk&m z4#s9>w%_aG3*i6VtHJfANWpslb=}>h)I=*T;#$s2HILfjxAkh5Yq-nBQ&tgn|KmPt z<;At0xm(@m4oYSHC61X>$tYh`f8Xxz+jm2o0XuQZ*%_xc+ZF>zH!4|iO z`yQXgY!plnBSw-zRd)x2s@&_B^ zcK2nyY5aNpX?cCOdR;c}Xbket=cnsW*;L$q+di+Z!4}IKmfOwO^`qTbdGTTKy12gk zZLzz1T7PjbKW!iP<>l?;oo{ZIKk~J6*Zws_yM-C9vRJlPK~c~I@pc)@o0mt=g-i*q zR>^L=wfg|*_ulQ(h@f=qcYu*x_EVkbZDm$1mD;ciy&0c!Q#eIfQ2`}>E_f3vIO?t* z6Q@62d77w9*;v?#NnSj^!yG~V{+uGH|Ed{+!}UW?{ro`Vd50dbueI3$`)ZpUsISIw z18LU!%5+s~Yu+?9w+OlAMPtnQw(=3ylOSuo{Djpn1bs&0GpDY#zHMjpy9hgVN{{3t z3{r9(1WuTb>EP>xqMRY-l)&lW>xecGn4!=LkTN`Z6<>#l5vDD-A~?$Qu&(Q?m+U#0 z>^YZ6sKzIpG7@T@`3~%mlI9S^#HWx-B+Y=_IYr8Y!Q&^KnM$CMe8S5kof>`tZV~fZ zbP=kBCgJRDm2^_ns93@YFe`msFq0SuazEQJGJ}mTKVQFXH}tyx;c>ftd|KTbIko(L zzyH4aasRL|pKYH%Abbmp{s6wQ^B$cN-uSq}4u`K|+&<;w_9+{;PsO;U>QU+KL?}K| zDv%f~lpbkah;ax@?B+Nh>tj^UmV!IoqIpl@UuVlD2lrVg-#W_^r(k1=AdD!*nX^oK zaIq1|GA2i7`QoAj zGr$|wTncHJGRldJmj;&M>_Oz5W2l)lYBvLvo><|6nIh8m&@X!x)z73T>Wll2_m_9! z{!>SMa>Q)|PI*hz5DFrMa;g5PalG>V<)J6r>8QJSpPt;ELH9xC&XI^w%pFd`)*j|g z{({wKB0iHY=I#X^u*wu>nbbxgjLw3dX|*;BiYqYiM<$GpK?t>n!eyuqqj4dOQs(=8 zr2_ry=ym!QQw}Dp!zkolY74)Dm>o#jwbV3E{;gQt2$4C$TS_8S!R?e zNvP#S*G+q47rY-b-w4cUbgs&hZmwJo!B6Z-+*W%j(OS~^*wJ%zgnQKMGtxp>JBQ># zIu7a1B|&QaAiUs%d!&<2J;6Cpq_@mOrcwe^%^gpSWVSS|wPAs)Bnv$82bqE3Q+n`bVK(0GH>*YVh3BIXhjJ7Gv{3fU@=LaF5ZG+~XBK(xF?+$#b3B79hHj}v7p z&D~3|0YAVUQH}$S_ptAM<9bnyzJ5pdTZ#=mPjZw=8SUN&Mi?|U{(=L&DqF*q{m6y2 zI~8kpRsDN1(qz&CHX}r&RA#*_ke*AYR#0Kq!-QmI0)*ux)0rGqGfA}@QQNTl@x(n= zeDOn^J+D^F)|>U~?S8p^i8WglljnUbs_pAb9=3$nUCda%zmx4#gO_c$A<7)+j414+ z66s@xif?O(&%UH%d+cW@;s_4=XKEp0#GGt)Htp(zNVsS`GS)0!1d*#bb5FrjbQSqXhZaLev_} zq(P*~D9RXMbTjkead8BrTTsR|FtjJb3=`9ky(&V_CW0f3Cos$rt&x*_DV_}+jF0+d zGp$272*a2IdGKPz0VY%@V7~;s!TL~wOZECVLn*DB~vca%eQnr732^)9`5_n>ksN9 z+mjRMN3mSUh32KH*K>ESAZgTotr^P*{LYE!&K8u^+%N}NY0fn~vIDHqy0MzPa?2T0 z5K=P%v8%Bbg5r7Lp79BY^WX?hYby$!tOurmXHEwkvRI~-p%>V6GqSw7<=}_4(GH=s zMWg#}jc56fsvd!uj&`MuHA)MjG2?N(%mk^G&VupaJd++!wT#iZq_~_(DVt+-x+AH0 zOUjZRk@o96%%%oYGxYI4xL-<^P0WDk5v(b}f&<)A9~*w>WL;7&d4CzoQjDh~)J}(p zYoaCbmu?|UBHA7D=Gmg{55DrWP@6%j=i4T{sMu{RM4Kk;ojEDjbi77<=l5jtAh-y+ zs-55t8UU_oQ;ln$ioE)xu4q$Vt*6gl&*t#3Q_jY^)UIY@U2GS#fv5c)CqqA!DzesW zM;#Y~ZHQEq+MdT9uEiJ=#gIhq_tehC23UsIW$F2hHR1*)G{64v?H9sm#)Q#@g*i-K zk7P+bGJ%cGz6IucE*XNZs((*L<4jsV#U19sR9n(aKnH9n5tD4@PCQ;BCQx#hf{?0K zLC!98mslL8_Il&U%p7tH#2mtDgcVNXlXwgz-w z@nXmASja9zRrzgqz|9@rAP_R{%GOyTPiq*wczQIr?6goLb;+2ON7xU;LLN`20fs*E zHN6?KI2RP#N!n7{w2O}P<&wwIgN$PGR#HwtKlxdIJHY=SFap7rm7-ysgM%F zUs24fSs{qv$Uw7MaNBl)?)=8IXfKkLXaORDXU8_Dtic549y2X<>;Oy~yE>l3Nx}la znDf}rpTI?=y`CA8IIRq-mjsO{Vt}8ARQ>;6W*3n>V@H@NTlKPGd4RaPW z%uMNxOYl%1+NzrGtLopAu^y9_8#$L~q?nKy*^JM07!l`91IkZ?>cB6S%dOdD`-Cd+ zeQGMCnW`=MQ<=xFJh!A*28fX1%%Et*fOz7A5YOsG#yTXG#TTpL9#+E9*Ghz-PwGd% zUbqHWXbR57xSXQ#o<%YGX_sI;Lvn`kZo&N(ThIN-~K`$%!gsD^l%r>!23%IXAoIC0?RD7O#crd zlwqNO{9S$cq)9hO)L8m?gV}H78LY;Eya6K`=}3cmQU&;gb|JetL`pVMF_69 z1XIrQ_IC04$ST4(3HiXnpANdl_Hs_8Y0jyYDORv7(S+~&o!uoF^*}8U6Baq&Jnr@vWJk_&j9U z;oBU;PC|v$S;E7diF>NUcAEpz0J%eEqYPGs*T?A>^^4@?4OIp5{AG`G{WFI^KFEibL1HWwX+v9y{ zw+g4k_YXmQ8;cU1+Y73+?NuhF006EcvRh}1Z%N*i?O{fVQy=nB=}~CPFtbC-bHiVz zQ*lQ99fDWP;bA5|L0G?fS>*me0<-RcjxE~60qwQ1g zN>gyh{q*qa?^D97u@ZCi6Uj%Bw{`47A9)L(R)-S@*`Y^=lZ*(vvd!Tn%a|pmqcB2=l_++vM+7!ux$lC5Spl1V?{d04DL$Gbu!%t^cm(F? zB2y=i0lMh#bJO4Zn-J%NuYMmJUx{wsD1snD4PE5GGi`UPxL}+7PWy;DI$Lv0?qmRs z)t^%9%PG0F1y98NT%^@GN~>c?qxML+;_)L&s|)wj7M{;zJ6((;JedYY@@Z>S#wgjD z-)ZeQ>>SwK`31W_fv#_EV^DK-gI+08`*U36!5PSdi_UTCQ@n=>vwz{yQ}C9jmj|Q! z0yO0TbXJ2N-Zxn+Kpr~ap1qX=nSIt89b~;@b7gJRwj0|{$F^;!V|UQ8ZQHhO+eXK> zZQEMG&iy=Z?Oku}KQKS6SvA*n9pfCw3DiXCQ5aV+uI#&2O;}mN)vDIHqZ)$|=Y60t>r=wk{B|m4%BO!3CECcOdJsV zoZ~&(M%R--dAgBV_cj|ilM(xb!Vn+xCsP_N1uozw65<4u0N105m$ty_UcXw@EziQz@TDWY{Xfsrp;-kE6k+AQ?cqka< z=jd_J0{)m2J%M(*iUiS|*;?YZFJ}OzbxUALbUcc0M8S~_%|8Zn1 z=tG_(a%HBIOA!j8TVN1aL_#a5Jh_=3h)kweVKP9sg5P!n{i_AKyxoC@bNe5iqb7^*Ko2U{<`l z`nq~^uLnR|f83`4&QmC}jwJoGn)m!t=XE3hs$OM&Rw8zO^mu8z-2aQvD5@kl)BhhnV|dWeoc6 z*kIhi@*=F3z)DG?p662eXXjXh0I}?73_^3s&4_->wkf`H$y{iHRnP=~DF{uD})5tR9P_RSR!9P$igLW+Vp{ zrv3b@$XQnY4Gx2)JwRJjVh}w^@I7e>IWa}cYF=+;ZhGe!4B8)6bykMOfrD8oGrNo} zrCv-=oKH2IVy3o5OzQ|FY7!P%%LNOJ-&xq5v{=P@X8OK;8oE=Z_4aEYVY&AlBaJa; z${jkrIYXKHr^=)jAef__A611k_yu7N%zT9* z&XTYSR@u_8Cy5`-7*Vj<7d)I*0C^+6Mo0{dVLUW~6Um_IxV%1ET6oL8R8I zkxi9nVri_w!0=m&ISho-9hl<2(%YwXMiS9_u@4q{uv}^UElK=6+HP$#0>gl_kz$?R zmCRf$S)m^&Th3lb<}|Q55+`V$pCtC@5(c*4vu-DDHCKo(86J0M(ps;}_%=CYD#~Nj z6mC?J-YiZgaW9AAxQyN51&Vc>L^L- z=4|hd_Xb8|oI@T{--0>I-`WxV15sEoJ2e9cp^)pwQ=v?JvFwwEFd}^x~J& z=fNej{GT=-AaNMfKM87AhyHWM*T5|UAQIVN(`PiBm?XXHC!x81O@{3;Xv+)8<|$bE z%M5A;Vgx!Cq%+K@BV)h=E|*$R3!cTw%J zTsAEf#OOq~Qv;FiRfUC+8}Iy(2iP!$qUVRx;9uiypaJV9;|Pp??YmhhrBd#Yl!O7y zQ`)9I;#vM?q0R3=AjfHr0U(@xHy}3;6!gozK8qoK=^{isLdr3NGJi8TBJjGU~3wL|V`|qgr{L_o|+_0J7 zW7azwoOVz+G1UCv3Go#w`Fu#{#@5^3Gn(yF01rdjKys!f29w%QG_40ZZjw?^{C2yu zo*1!D`BQQ%$*-kFOAa&inwB(Dl#jKbfbW!MdQ_$nkd`pwh%ABH3g#NN@j%6dETi?< zw#Cn1&7bVdD8NTMnX_3Wyg4Yoje6+Jf6ZrMoOq@k2R)GaS>{?(NDmROL|T-jWyX{x zBx7Mk7)XgEbf6T5Qrn+H;A1EODxj-P%q%X@=UXZ7P+C&tSO( zSt1)vY*Z)zZA{V5dg@Rl=9(|7`H6+86E!U?C!G;90gs<88zB`uOv*8ChO1|3Cl>%+ za;eq(rfo?6E0fS)t^Y+%spjmKDvE{(DXq~Kgb6S6J)T$c<=6u#(Z9 zw&CEOjN7U~({5mk=Z~V$y78c_kWV)}?)<;BI6o}_-~e+SNo9s8$5ydit=AA)h59s; z>bCqg+&G=#YL?N$;H1R#3d}v0e(i4b(*7Ttk$qrx28kM_>^!Jzx;Yn>;hrejJR1p@ zhRp>F?c>DUZ~F$uw@-oR%T-c0hw76Nnl`xXqVmtmCO&}?3CN<8^b{<-a7T{ShQBa-mJTZ$QgH;qWsllucfc0m z2Lpww<_4K^GW2AEk4N;z$!iDL5bu*I^NBf>P{z_{ufyOxQ1%}iERZ)b#=64ep};<& z8|gdt9+B&;M@KJ}BlV;K`v9%CFDm9%DRsPDh)2`?vfOep;bJYtRYrq8A{~{a0899VgH@=4 z%vu;s$)xd{4?Z~h>kXP7Qh<(m*&?mESi?+MJEY;%HLF-dU)G;jK2bfx6p8*3zkxQ# zXAj*R34oX%r#=jkpB=ZIHf4}b*Bvh`X$EXG&71JExWcLslOHVLe7JB3ab9fwuDXd9OyiKHRruipm-lJA5>{>ky-F|FM^3r9SE`6zFiTV8CQE;8S` zyj3Bdeg2K7P_q|~it(5|n0Ep}fotIcQW~e=8GKrhCgG1U5Uiv}aAk}pk1YN%H~|$F zAuZK#q)Zfa)f$g90_u8-tCqquKOH(Xz1J{EgO@J0EbjD*tO~(9AJ-3T>b1PRJw4vd zfeuW%zf+)%Us_nsvf^+YW6(BMdd@}+J~OtAii7~-C0Fv3 zWzCn%1vJ}KzMjDD0RuNmjv-cq_KCoBjUbnuUA4ex|K=MaqX!F~L2BT~u%KPtGY6i} z^i4w=t@^Pi&po!Hcp~3y#*t8wqYSUE-hY-fJyEHgHl}?RxwG;~isHPEoZ6vkb%tFS zFaf!lWMELfm-oRy8pij@zBd~0p~1(LK|bq@u;=V3Ls!qKt$a=14c>9JV=;lpp4Hci zpm<=rMsegEkt7^)HUTd#V^csDussI+4lk+oM>Szj>Ah|F4od^c*|4&C%M+UYd|F<- zD$4Tr^wSP+9ywO23P35&yTw?Z1XDr9hC9sE9xnT#{DH3mhA)*bLjO4ZMq7q2KIRNF zpXLQDwoAwNJAV41BWuC!?DmedFB43?2z&YZE`*CCv8K) zTO(KJ`-t3Y{OGHSy-x6b(a$8>QPQ79DYoGwW2;pANsUIIL|)KEY|qlI2E9pf6aYS%^IP!pL&fQ&@tR@|Gn2 z>@Ovtwv~X=&GMN`3|J@uhA;b_uDMOoYR&td?1JqzcjKnp)RhkueYEs%cVm4nGn%|i z@Dr5YQ^D8^Q!9p{OM_|+Z1im_#R&@1F_TBc~Ha)Z*hg-ye`Kk z1@Y{@&|UAfmMKvy7R!vz{mSU$vdPFD{2S?eGLeQf!hR%W3D_#==KcYz?K8bHnC3`$ zlY-XATi-o#OtQA$t_xZ_fl{l5ZZDbAJf+4L`fm+d>%mzFgZk`4G1ez z2VH9Zu4I>LRma?6ZYw7xEt!;*R(grX8k1mb#8k!KN`R&i4%d|pG%fc@Ln)u6*jOHF z(3Mg0*NSPnPG?6+wJZ?9Mgm^$vdDpwVF9=lrA4S<2xMfKlEfDpQ)ZPvFQEBj7C(1L zmuFM`;^oQ!ywqdQV`MnKEWXtiIWon{_zF%s$;(zq+Z}h2>!jZ1q2ZX>6XpDPEw10ULq;;4X+(*4FYHm{yMAx1+_W98=$v7#+i zf)-Qbfv20jLw8yfgoKr^fDAzwRFlRvZ2=5#uqP2@6@3~RAA55{l!!t%etQG(TWQ9l z@&vumMt3?m)h!)<2pE!$RfBecTcFl3MQOM~bv8O|!qrB$cM5)Pi4Kp;32@ct9M_H6 zdB^7}P-+NThW9J93zNT$4M=;LC8qP$R;J+a@r33*YJ#<2B-^PTe1}@<^pZ6&aB&Lu zifN|{E^O`wQB|C;OF_q$8oQQO(K}R3q*dE!$o_St6{XR@>NEmX#~=Wn zh~#B@HWg#w;J;04=Q4r7mpIN1ZsV*(85`)NmQzB_iL9C$lP;B)1DyF$L=!_)jtm}w zPS|xK(HsV1Tl=ogUCit!%nP(u>@)ze`q2a0cHIFmR1}pNKvwGI4o}Z0fT^AdLqpt; z_np_B(NGsYHup0dLdGbcFHU#m%lhU15yA+BX+#nqS$B;Wnz>+U8qx`C?HDUaXaZcJ z?IjmTL2I|ay*GH+`;#PL1PG@5_4v?lU*7QH3S~rG92!1KRYRH$in#ztY$?vV!MU+> zGfm^I$Ab=r<42XO|BT)9AB9o?`JqtwzjmdvX(7yqgSkkd%}a32rTd84=6w-;%nzhV zRh39GTdbTSp{454U;tC4OGQ=eo*3NR49|1ztG`Q~^0-6nEMtRctOXKoJHu#WM}KAO zMj>fzWz+=i2UAnAwv7HFjEnj^nO-Ep-Gc&o=FcUrZg?Ksjje02baQ#_TH5Qe9z$3& zy+XB{8qE*dHgU5ifnXEw`x2ed=2T?VW+}(7lvv4BU2n zB)x$s$8s#MB5|_qn0GsEfvfD<`o|~0uplDUa`lkP_Bgt63@`zZ%qTC57F?U#d#tfAYfIEemBJcU2y?-* zl3d-!9XS!wRPI?4{Ms9r*Dk({P6+TnY{5IT<~4NZ#VX2 zBkcSc%>Q62#{2m{p#rr6bhS6CwG+p9q2FDfZy!#dR1>CN0Bb;32ZScAE#t}i|Bb2s ze?g+-aopjIik5F=729!5^$JDa@$_i%x$<43q@gOiUam1^J8A{~($%`?dihBPyayvS zbG(RT6)fz#>iD8%Sv?hzx;D8j+&_y{{JZQNbzKM~L4-^;!Fc6V@J;5vN_I=HmPfdT z=iNs#`%+tk`Di0X5`UcO6fs!u@ueKVsL%cj>rgi>aH)SuasSSo?I{e6P6M*M6=(1$ ziNBgv{;3a>c(**8^kFrv!w^~W)&!>qJCG3^*$S6x#}N`G4X@f|vBpacav=Yl*z!xB zP^K;?g?kIrCJ!2%z8-k7odReP$~?}zN4u0&kiBrBw*NDuD1#8?Zm z@?Bj&6oa)KMVvQ9YIatg;Al`xY%N=lt#N zPqEvG!=mCB3@wlD%3y_W*Xw|{jBgt(l`GNFvEcp3$SD1$BB?xF;y}DC+cv8iktsK- z1b*7l=wpAzLD^RscFeoQ69KTx!EN1uwR-CMWQcS9l%)!0wJaV@`VmEy578-$YHs}{ zReE^;F%+Vt3B}Z(BqNvmzTtk9x?UqHm*}qes~rM9%!*?0Si7{l2Sv7_?TQttgp#?Z zq~9}P9>zPVA$B)#c63IXW(9Y0Lwf~9#e6w=Ma>+IohjZ)COgjSlFG*;X~UaUu=vRl z+%n1~Y#ebVlbnpj;>A?Z2BeiDn9|A~Nj9bi0T0)uEHi00iWx9Mq`VeEgrw_Ys$pM8rH`?L+jjp2JO3$qMZeX(a)hpA;klr`opv3mIG784-9@S#v0(7 z3;AazoN|hV=}{)|VrLs<`^DhM+~Q`pTBGPk6L*wGxBQB@w1O1WCSgh)D2oyV}mE2Kwx*|{^Sf8V}*)G)?WnYnUbFCv#uY+ z+6&k)^f&@c5YrIO=LeSEdeEin45*uKhH6fB*jXHdn8$=)Aze6H)Kv4M@jyyESoMyM zBjdeWjE1&4H8y)!ch_{ozi5~0!nf-B#@1YZpA#^1i)fmsqrdF~B@mzHoC`sGz&fO7RX(yj5e4xifjEE@V&N|Z zsWk^>*FYl?3DKa%nt&Pds77CGR&lEmaIvicL3GEjw>f`U;y(%Z8}eo@z-{=(%Q)w% zia)NJ9--gH7wKS0X#H&$3#LT@QrW(M=Lbv6DRsvfcB{DyaarF-520NBL?4SR167)# zM;ZrQlbwBaj|I(vndSIzV-P!WMKsgo4Cpz-Jc_9|LHqRL{aowxf|4H5ag3_ZrFU4S zt&5aWBB1A9{M1Odn&H}d`>SIo&Y(L3vMse#YyL6jH= z%X)Xn>ZN+R2%8cdaQri7=tz)`DExBr4a3B^_G)9i*jc9{i$<1AdrPf=_rGZ>=n0P# zjy*#jMaNWlUHz55`i4Ez6@z~@1rbQr8+Qw47^M8DIk*Sh9(hrz0r^^u>H*~>me~dY z29s70#Wa@Ldg4RKLd0d&fYlDUp?<}JN$fp_=B2%@`63|SpR+I(Yviwy-n?XlboPYGKe9t=E<8tN9t@2 zGDfnkP|wuZ-&ERGYmP|XqSQ%gb${#zvuJCD=1$OU##Cm1F!4-9w3Ai3!wFntpSmg8D)olNyV_om2^S`(m}Gu%39AH$TBRtQ+`0j*Nh*G6tQ#%YM8NxiLh$Cy+k~r zRg95Smk6_nRAnF#w6WxbI{$VLPxcWHv9bgIC78@=R>&@NROdvJmRr;dYOV7B{3hjT z2?FvNMyzBCO}~A>UV-4z&Ol;6)=thI2)9yg8BEp%yuID!z&n}bdniz=AM8*1Nx^`X zds{ZmKgIsy1dE_fV=rY7ESZ1GTH2&NrJ4(+@2G4{yicU-Ihi31mI0VJAG~QN2doRy zU}Rb2Ov)x$$IVr+zLr*ufyj zd*Pc1mGsfD3jGEpGb9Z8*nc6LtEIs^FSE69v-@47oGrsu2#cSbvj(s@;!2E_L{ng8 z6NecvO%9fyT7?y^XhxPh2Nx9}#dE~*5x$)pI5G;C+H(a6Z&+afd8r$#>Bo%8sJ~#M zV9miT4XL(gHPil6&+7gMS0Tu8g#cy76g={aG~v9duqB;+I=i}2x0{eRtr`keY~3HX zdE&S=wTf&Z&v=b9&2K`JUsr%ZhQVc}_|MV1@8OWlLcKywo z;RG5!>efvA1)0InXVKcU-9gC8)2U4~_b#CH>H6G+=@c2qcsUbK{LI!*Kmu3oQf$1K zcHrL<87PD$fHV!_NI4hSNL3%1T}jvAaK~Wspp?OS5p$*CpplEDp%dw_eHXRU0rDP| z4J2(NT&yNJ!!}nT^3qW7942pT@-{@0xhT@1Ra_G}lej}k@L7mEBQ61C?4a(5;sTa3 zSx}<{1OcxmskH3o;9uNpqjh;xVz9Rv>^X5-`$6vLKsdU zo{X=fA<^N$k|zD*_8~PqABD^DUR%1Kw6-)K7Kc$|9$SdolHBa6p6u$5ruMY*RC?qr zw@Xk%uzd5s(RSj0pDo@x+9K7-D=ZbhpJvS}Iuj^N+B=^ut6O~4|2WlhTVetC=g)W3 zEQW^S>(LrZcNOn1MorU2;D71aP;o>)uQ`(~kReZl^B+xNK=+(V3-MzYu}+5FYF>~x+}{KT1yGlXTCD98@$Lar`$ze&m@sU^X|0wl0R{gWF_;V| z*}PR863n8((Ou5F>6zr(fO8g~46MWKkuMa`^|Jb@I_~|Y|HN_QpR?{~vZcK(NDp=h zIhR5U6xZuRc+s}wE_ulZA%J<3Sy$)D;(zV0{S`l$cabpAndoc66QWCZh>1d3EY17) zIE%){PCiLPtU*|3k?Pjw?&%`4h-!=1j)8R9E-d4ZNrSg($#fH^xieea{c8kWYJI4< z&2rN(REXKsC(dcQ{Xlgk4$fihV@twJPqme0Pr74e@v2u692c*jgG5!DcTgpiz*y0A zEsdR#9VBWcq1&meqRhkO>Z69DF9BsDD(%;B$vY_?cqPPn);!=EN{0+CD=oWhF^=rA ze=YZvy=8lr5Ayc$;X$RG8d3IR0~C&@59`duUgA~AK6~ppXLSu>iLEeLc4DJZ`>MjC#Xs|;c<5$;K70~y5r!l3|r0n zz4`r)X1X2nBZRGuEzmvZ5ab~_%*oA8vBej0-!A)fe>*32Pqn=}fval227nn}x{%sd zFNNP9Et5|nfPor2o@)1|Ebl2Dpl7CQ|M;~J(N#J|=Y@$(jJtZ)GPhFKps-d%VZ<|i zhOR_L%=%uA^Ss)0Z8&fmEhkmb3mUhQpN`D|r_V#7PPX{VfE$g@IJkBy-&o$a=(fLf z_HJC=ncoHq!5rT0Ii>u6Scsh;U@&bAW|B zl;u4pN(T}kH%?3)2|H^&J>4nIusfGRmlj~U^yKE25c1R}h28(s!OoFSzR@+ca_Hu6 zKkr;m@NffAfW#GeJ$>q9T+x55RtvFAOJ zHAUXC@ps-ziuHBi#cti8)$;}R`~>1dHu|!i(gWH?anHyW(-X+UO*%FV!!=B;03wP` zL`xxKKIlK5Q<#Nee?{0Z8GVOohcIeqHkw8wso=t9ab736K+S{gr{?X?bMILIlEgD> zIq&xcK2V_0XOZfcq5gmSmyC|4x*Qk9-_hHplYSr-zAuIlJukl$R~Kg`CT6*bHtAk{ z>;RncV;Jw4=?AHTGQ>etDR3LtghY@3+_h}K=KKO?>tYiR+e1xdFW#|g_(Nl@oSJz} zQiB-&)u0i131NcKVd@e7#iH~h|>07E9;81PZonT&mfpws^M+;3Y!9(1dL4$=v z1|T}PX^x+!llG@?Xsotfk-)S?QUZzf-55rKU@*Y2SFR9jY`w6W=lwh;jy}NRBJMbhQrxO?I#L6`z)nzo{=XaRm^s07IDoubJzijN{l{vQj(cv{PmRmhTCyV zR7TtXuml%@e8Kqtjl2M#L=IDK*iq$YwA;ab2kXaj>x0(vhu;I9-zI+TBW<(qaBL9Z z>`EDvC9eBOqq7;Hbz^|DXXDEbBi86Bk?@aB;V7- zN6@O#+~v(hC_W`iSA#P%doU%e#%~$?e#YR*p&)_2jHPxVKmL@bcNrW#j~6T|WY!$M z=c12>L<|lMZk}NoUgWz>-Ds8F^CGk+zbkQK9ROqL{20$CZ(Orqwfad*oi2MiiZ6TH zuW|lSw=*7zV(Yen{sTty^Cw&5Nsl$6qI?4YZk>6bm}HXLAmVs#Om7SZ@P5d?5q`h7 ztar*EV&_Sp4tG7epYChuk}1K$&|Q%q6ILxUksgwB?A{oAWCY_59Pn0b7$QL2xZp zF?k`n*VN?u6mopKlTPr<-bx`wP}k&AJEJed()5>5YW~$UM$6DkOZnKr`~2g}8}|O{ z;zD3)>WiFhYcA>UiaIAbYP4IXs2z$rW39nsF{>WSdaj1jYC(@p4+?@~b*UxHgqZr5 z_TmBZwHJ4}nR~3rp)vN-WUzE})AFXjXv18v+iuvF#k(Nx%ID2KG4f#){Em0&E@XqSzco_Juh-vv zDmVV6!mJNuXM@k@0zDNi30JfF#QGuZu;kjzw9`0(dL*20~B-aZGTa zt;`hdCuw{xjKV`0SCc`Fzwzqy?>5prbJ_%4Es}Ps*N=`_$rsvbRXt?J zz{|Fo2s666ME)=t9^>9P&|+IftmGlokud6YQu{^IJ&v7pkb{Mami!nIUhohnE$tK; z3S7dsGI9hHsyL&*I@fQ6O&hdS3)QOerpzERg*y5Gi9(jU%9zp^2d&&((*Ysb!F2ga zpirQpI6^SIzG4&dp#earq+cNJsm6(3cE0pfeoNc_W{KapXMwmn%P@_l6fDD7Sm%*i0uEr{YIju*lHKsU_K=WOyF|!BnYE;eT1_LyQT%z504`JwXgGMWOcYVo4*@{Zs>|=eG#5oH@RBQ1B$>`S zqr4CX&Krt6r5;bx&rF9&i-xI3MZh%tEcvb$&X;;pQ zZM(-Yno;jG%!1|@Y&YbcnA((QkzBlz6Hup!9X`eF17fptVmUiKp21qN`%jhRk7kPL zHOtPcJVofJw{fs#WlI@ALKZ@5EU_T0!wS(~?}1as0;yq83iZ;=X@fiBW+bje8&IP0 z{5tBQEj0-axg5?Z$cp(fj25ZC^XxdX*GcWv*6*CGJ1wsx6x3^(tf@!yQviE8Jo zMe)y9D)f@9uN(RH>Rg5+eoZ%sYb^Odbl*qTv?VTS7~(xVp1N~H{Y{v2I&RWHx>%Y&n8UVUl4JV& zYe6jrNB<8D3|9U5t7?Ez;)!|>J6uVmX9V0 z-gm*CCqe#s;B&zR@Od>9!u?Iq6n4X5J2TC!W5bb|tat`&IIB;zQ1y|4_nxG&aubOt>@1cd2TS@(;8!>LQhx&|cU9~ccXE|pm=YtQsb6##JmpJ=HAliy3%Q%(mHaML~y z9;XavZ!A0iqeD7+Y&d!aVHOAmpZyH5y1n^4NYC`CvV9;pa_4!;yf2H`uh;Y5EK~#N zYUkkF0Dh}$IsSH)W1G)EMSu(pLG4?-+|7sF5(DL=#eziA(&25o>x{%W*u_%_dK}II zOxyqkF}EIDyhmFzzP0@2?e^)M`f$mcfRM7*K~($ftnumF`MS{k_CReViPRSL)=zCj zLSj03@^I9|*&$2NG8+$bmT;9;B0?tze&1BneKcwQX%$_Y@QbW@3J?D{4AKlN_XKZdtnKC=1%;=Dq(j zw{gz;-unI7`tR$$*7vjUO8-w@1l?_b$w^j5yMQi+_>kM}wt{TeOUSUvy|3tU_to&_ z#5hTVHer4Z?t^kA!4b+TZ~xhmf&w$zKfoKzfBG2k-jL8T>A%IU$UfTw?U zLAQhBIYcQ8da}HUz4iAZ`yf_Xl)lZ)0)pg)hYC8phDMACXSX*(AOE!-{9Tt4;A)?v z)KBqZ4X%0fe>^{2VT?qq4z!%J{&6=HotK|`No9*4PLke!z^%=*&qBDGhsPv$b{Dy$ z_YkYo&6<2wFAR|@lk`X!h-`5Hf$yV;pyhN+p{!D82y{%{md=$Ayd;a0w?K({%z;E~ z%mo09`YkP`Y*TJ%zV$JzmY*0-a94UhEqfp+*?QiKt?ymlepERGeyd=;^*S@+5vU%H z7=8qZj_RPj;o!G&Mvj~5@rcFe>(!D!4AX3agA7K5w=enksdVJW@D21bGPfUp-+`?o9l(P&-VFHX=MP*zOB*s__KqV{1 zl;MEEvhd39R?&|f5=k>ku9AK6ZBGNVae=c&x`D0FPKPNL^l#D$Q%pT zSiieZM#6~8cq$m>Qep-qre`hEb3kPD;zW<^Q01KmYR7hjWhh0H@5VExC9O+{Von7v zp^`(Ugf|zYBHb=3f;^-}by>tzKFDaWF6*ZqsUNOQqC^z30X+G9i;onBXSyUzNLyF) z5ypgox}Hj%CRwyRE^pC_To{S7om;>6C}HLlnzKMcq;W!h<{xCG_%QSR$lz;VmD}=` zY&KqQY+(*NKF&b=Tf}y-)U+To7rV#oGMB>j`pMLLG zvgzFcT^??i)HCdl%`m!gVFZ8{yopQaVG5t1Zf-5w|&nygdW|LosHfKa|2 z?K*r$v~;S&+JK|vOd&Xea*r{+3CJ!FVisw$2Qv8~nmeko48A0~e!35QJ=39(wkRUxArxhm_$J*&(EX)?aeJUW=L<-2b&AP ztOj|BV9y5JN6u7gr=afr-0K*GlX|2r;|Wl(?4N7UCCr#RU|J9TNWAr6>?skOn`m=(JO_kLZm6A zY=bEJ#}@>dgU$p_y+byv)v2OwHRy>%qD1FwPN=JH(9%@qI}W6_e$EuUsP1TDH0}{z z66qqj{Un< zI4~UxMI#@(|C1J*XYS_gr)582dK|S!Y$`f9D6pFTR*_HznNigqPdj5ZK8yQq4TRXa zwo2m&yTc#6s=>odCn|E`-PjoR=;j0%Dxc2LgIt%pdJu89h=kLLifEphce+VzNHt5L zZcG07kL3ENJ&ym!e?*J2&kn(+#&N36-JB{dh_CaQwsy*dN$3DfOwc>Bm-~a79eC3f zOw6PcV8BLzX&C_J{7lQCwTz3?(0ZDlg5QsvW=It5o( zos1`NV6+vXP-LR0WLAM}t9#<9;36t8;DdT9-opVS!_WbL$i1lGcsh@(!IrM42zr6< zBG;)oqB4wHI*+Fp3Og=$U_E4$3ZjZ4W!N2RypDJaoZya*!)(`HGb zRlJy40Szrk>|I;F)=8X@x~eXa(qQ}S8!3hBj|G0%BxR^~ z^I9Wpp({qltr!^FJ0k;fQqBHvsOs1XXdbkKQDK@hUcl;!a)p#V*G!FPj_HX_L)Mi$ zh9zhvp>YCo)il{QYz;mowr63xUp*vl6^(5}6?0!uGl0xvHGjXZy_Wer~=j6 z%S)$5`RgBrs{K)%`@mpwKkv4krZMR1e*qLFy0!#1md!)!>!}acoOZg6f7R=;f3J>2 zo-JzE?NSsa@jBO#ydqEkzw`-&T(uqLfYHAr^JWhXTl{>>&eo}tHmC6D9ME5q!kCz- zJNow?yYYs*(e%M|j63ulSXRx_AcT#`0^hvcwq*fiKK#Tj-mRvCR;_<9zo_sM*VC)5 zRnSC5MB*mz-}Zhy9D*b#F0Sr$r=0^fJ%EO7)~~Lwrmh~%Zu(4D+^>h{lZS<;(yF@4 ztJbTB^Iul=U42zOwHLoT>+kmm_MPp$Up5R}Uz)!5b$r(OuO}upMuv?oPd-Ll2eY4O z6j(SXRGU4k3uGc1!OkveiC$Soa;K0(klz1QhtznVS^f$o70Xfx>DH<>Uy|*B;Er08 z*TAfPC8#}rxK}526z|H0oz+~aAq^$dPfrYRQ6N+3s9jT>-27-rRvqM;Q!lhLQ|NJP zz^9pFrhvXl^#=E%ZDFYVDTQYe`4hrhx}mW*Vnss?;HibxUCk^I_Bd2$AaLE_=xyDb zNW_^-)AfU8=5R@EO>)euX<6CX<&K5!s^>$Xoq%YLEy9ew?@wkwX$8ZlAZ z1GBqEyqVgF7-cA0?SZR{`?1nmUF^0N{X_-b^8m@~^2ArOA>Ic@Lx_0gmdETl=el$5 z^Vzb|)5Gs?!?_i!o0_}|NY$0!Vld%jNRhtP%Q!R|6{t;8kg^{yI{#p1F}iK(q}R$o z&4it-rm)FhbImekr*~03+y)^*`fDvUhD^52PLbgm`$|`H>Dw!Em}vMWraRkYtCiPq z;G(=s?@zPi^4yOn-Dav$AKi+F`+WuX^q?F=s}@$?=*Z2TMszb?}7jm$wTxutF8x45AiD30L}02XPnLaFqUo@%dF2xlp- zsFi7(nHAT%LNi zTmakwn#Z(eJZa-uEKfiFx&P+yZaMB94lFfXhf~@b)7in9dL|6;wQ%;}R@5ga$Itc? z@Y)1c8_D6gU1!BMTh!tg^)mgXu4_&O*z`cY6fBc&vW`?H)3+zjxWyNK&h`+?B6-;< zQ;m+N(?cDrDM@z_ZTcb9pu7!H^M&i>jHVWK=@u2u+vd(_GG@WW`%2=*Y6v)ZBGurg zo3<_wnh7Sczrjyb;28bTW?n=JFnQ*gt|Y9Fuxa+cGlkYLxEXd1cN!=)xHdzEs zx8p};4_OLC>A&>KiQrl$o{03xlijix&4C9Bt!1x>C=J@dKL*NYjc8 z)~>+Q&rDs~U!MKARt&NT?dJ|Hd(DtNKL1BripCbp!8{Vl1Ar`@;pV|&WJgt+xta6d3uC0qYE{3H!z4L*FGWdz zVp(@k%R?@#!p?K+C_WlCYAC!3o*rWo`i?d&Knj=!7riQ3jtNI(5m9KIai^k8r11yg z_Hi$wBYo6WimC;3x-cWCmaVz-ZGbX{hAL$;*Fo<+K^jM7R3g=|MhS zyJ((e?Tz+Eb1`SSwRr&~9iR4mfItALAf{Y*PUkC|aFMup;H*03b(!QCn5Kc_z^D=x z*N}l$Ly}~8^1rDfbHtAG0bRTk@f7biu-NXeLdBFi2(ew*Qf;k$m-m7f}ulG53pQ6RTjSbYp3BoVwC3NjhPwEm*K=p&e5#aXP_ zLKceM^N}cWq}8fmi5tM1C$zc^vASabQFPNDRe!q)M9gGntb9gENh0hC_8@Ql^42R& zfYDtY<~e2nKgnJCfe$pbl##EK%`o6jk5R~2IY`!$0iS0Xj0g&I_*jXgTpcg9Nao1e zG$ZNkzjxy_JzCCQc$$?|q(r|!0yQ@sR5IAx1;j?=?If&bLKH+t5C*|G+6%j6O%oPN zrw1WocV;wCI|?Twf#JaLQ4E=Z_UF2@VY}*JUcvn|{^RTQ_{BK;2amyz@*qGat@WA9rpO&(;msVB%r3ae{J z?L&r0TeAtQK0{cDqhb#aAq*>rwyG1g46<@U=Ab$F8}plE;5QR^8g-+RL3jXX1hKIa zizp8E{Zid^FC-Yo=^Apu8wKe(JAa%m{=usHC|+#015{zpL!dFQX7ZaPf?ak5Q+ z*}dTBN4+&Pj}TM6V=|!m=x@mkaZ1X-uo;O?A#7{Z(w%D6Ree5fpXSx9xEQk2j=jH` zx;DNst%k}8hyU`6iX2(SjMXtzq zBE6s_U^;u2>p>XDgFHyW?DDysm0@$k;cf(lVo1U7W?!s6RyuVFt`(HpBKThP*T*I} z^KYS&wGssuTh(D2J~e@{5fQbSDRQ_S4S={NyU$nKp{`0)II*!h2_YFA(pa5KJFEE> zP9Fd}`N$gC{05M^KDuJ;t0Goxtqo-a{4q z;<)kc`Tc2?ha*PwLzV`aTZlsn+L(99P2yfjt~)&Jd?*qW<<<#86h~Ng2V!?7C`xN? zSX7GAS`$5Pf+A#e4&kp5Gt$IgLH~X6N6Onep+C}9_3z0@ok>%RCRn;_@5asI#qw=T zGiztYU}Z-pTARft>?)9*c4UssXt_|SVMi9+ zzl%G~oRu@A)vIx>pWYtzG+j%^=IYHtaF^jaskUCeIul{$1yH3uJ{(YmW~tZIzBA0< z7hX;`x}Esb95GaA0}-5B+C9)`N@K&YCpPENsK}ET6@2o zSKhR;s@fDrD|!SOl}}BN&HrZ^f9I-V?XW+7lcRRZQyfe2D93aPCOBPggjTaB9Tq&X>?jv}u# z&fH}#(PHn5IO`m&GcH9(D3)2a!TyV$P=3CBtfB+Q<~$hHfr%@u z{m%Gv8u66Vvx*APl5mz6q3QgRE-$rUYgfL%Ec)rOHXvTvclVDUxbQ-g6;pes^hx8% z50oIvneVxfMpxCpr=oKH-O6YBcY*((-c%07w`Q9Jvyw$D*Jbo_T|TYN8S(B`t3%?V z)dR<3#kuBOYP?Wl$>f95YRNf94~wx*A<}&cEeBJv;G}sr6?pGZBDP=z2_?Yd%5Xr4 zSajY2QHU;>F#6h$1)!rhxH~`L1_HUpll~HW>j%JAT0g0^KgrU1_pA3o??cONsT{T0 z&?3ETdUG(yYo-bFKI*~Ko+`W6v#+bbYrT(c)=U3bH=h~~|7HQEV1QXP!zgEY9Z7}} zWzxV>5f4bAJwFB>b;tem!uOYvg)c|leiX&=N3{fwzlZfcvy}}#0n2urLoic;-A(di zw|<3;7&p7suWzfp$BOd2+GUiCQQq$Nt7X2e6(S5tLa-1_YcMNIeK)@4nUy_DVJHYz zf^+L`P){r$4mnUVrf)IJ0x>BOT6L83w#*0Sd*8sJSp4>QUnSl)$CnmFDP@!sqnT>W zf^GUovDvC=5Z!WG|6jPxMJdkYtz9dm)Y&VC2Qw+QIreS;Grxc{V>CvJ5~d~7wrhgv z_X4sbg;zymIY4Zmvu4Jb^bU^@ztE_nwp$p^_w6^ibtJmLRy@3zNsW{}qvfj!CWKJ$%gt7hNOLPakOezjJAK`{c{6PpUB^tsFk`v( zF6<~X)nL->C?8%ib*6hB3g78*+}}@z;~3%4QalNcJF)0@g?kVH9!K9)o@gqw_@#&-Yh|X zcH{&k!4Mj#*XRsjfF5iFeN2ku?AeBs2>T>?evy;qBLO+t1S@lfKeG{_e;V7Jq$NN* zB7>i{i-(|eYFsO=C)N2E7Fc=1)2i?z^?u$ZI$b->697IQcY%sq3=Id^i8_fvjOi|s=Et!RuzCm!_ z=oX+Ey28(P-k@UUE889wL?D5}IT^~1QEKj11Yd*CrAL-u z0%g(Nd8n-0)B52*obU^bd|d5*TRFN-HokAWm!~)2jb<0-5v-N@m>?qsxPPLm52Y#( z8j$UT-0=4v;@||Ahy&KwYRw5HT59QVQUB3|^a*UIb0>B$qJC6SKZXd8?J%_KLrPL9 zACuH1iszGi>QAF{?OljsvwHop-F>%raFI*JI>sM%+bo9&AVglww5?tt@!}D5H>=%l zyR#`~n0I{I+DEk8wL^2Zc=Ptz*R#gA#ET-otyyYdu~(y>WNp4kytzocd0H1Q3id>C zKBtg)rx!(&vW3ATQ$g%puOl--;#KciZT4(ZdBZeO0&%K@mGHVDd5EHzP_F%YSZ@JM zj3m&E3GV40m4s2HDHpbq28-;lT)YUZSqQ8P6?IY3-n+p1kI~sV*)6cT)l0#Yu*Pz4 zPUFTiw`Eq|+x^?~^P;W3T6ux*t6QQZohRFG)rMt{?5j%8L(+*TwbSZ;PU8uXFin`?xPJZy)cxpVlj- zx;ZAfGRM*%>>C=Mm(I1$#Ojv6=3(X5e>vjNO|Gu9bwcoGPCgUVBf0vxS=6l#mzmrB zkrUGt58whZ%-jT>hk?h8hex_B9zaw^YT9L&>*@i-2rrFTz()xzA5iQ`Vnm-qmWIj- zB49!N_zA#THJqw=guAzP!LQ$+Zs*_Cy(rI|u8G z^8#Z+i5jx-FhztDHc2%uq1C^SH{QjB5u(1AuUDpkG| z0&~-^s21m4zcT4lMz3s<(9t8alkRiMOm0SmvotQ=vsh1OU?+ajWJ zMACK`y*SEvg*+yxUIJC|=#K9%6jK2F1%a?PoqT_68IcU$p9FrY@AN+9@MgU}+m{hO z^0kA;`;v8jNOwMN*7@Lm31oinN>^SOQwT$XF-M|<$vJ}g$`hL#mX{tgft7*jV`io& z5=$=q+3x$Fc>NEN_S`rAYMVF8Jny+BR@kdJnDTO@z=rt9o zvC#HFo7%xzsuXuhOU4ug^Y$sC+n3s2Y2S9yvJ$)8Z*K)xeLz{8ekT_?4i^U0NQRW| z9Dpu`FQu)4RmczZg1IA3XmG(oIsu=<`AW_av2W=4O%1l>QjEI(QP9 zLNwDr!QBpXKEu=wP{?l?&r}ZDwfmA^m@%zYT;XY}ZZjfMK~=F6h8QDF1yJAh_+(I2 zk#0;enSjn9$hF8#Cjy10y{@50=Q1 z>XJDLG0Jx7(4ZJ3dc&Sgc4RN8LupBrZ9EQB!^wWsZuI(gqj}E`^?)plQSVx`z5?2 zzc_>Nk_)Bqeqw5z>7ED0aaH|$GU8$ESo{|8Fpv1rUhG8aSq}=a?^%@pYIkSW*q_=9 zxaKdafX6sVR#xqZ6H>zxyj4=uA8Bx^*baY>in(a#9xUmjq_Br1_GmPI$Z4V4&m9w$ z&K!kNMIdRtB0-uoL=5)DFBg}KK9DB~zsy4L#vaxeJauR};G%JI!0_j>b0JLbsXz&> zUCw)9fpNsPPoBVv`Z!{{lB`x^<4W@mu`SxaLAa`)TgSP&bb!bu3>?F_rVhe>zAqTh z`yanvEDYBph}(;WVZIXaVqvhSah?{2KTn##!rfDsy)ys3(%XV_z6PZk!ZQepf#9UL zvE{PSH{Zs*OkF*5xM0l0xuVb7hFMk)e7Hj$STl?y`#I)kI++5to$Z+4+p2U4{23JZ zb9&U^21NY7Q=*0oCO8*N(5)6lpoTdXkR58|5`)5V`iVlU?bK7nJLVt?F^?35`_1CT z@<>UGZV7nBhrFn}oV+n-LZ-NlM}-|TJv2TzAFtHV;Esp7-2StLCa@q%5!~6$F2Da! zW5E^Y_m)3D57F97kTcG-8x~f4R*Z|8>6#hLV^Tj+3VhHnw374#V~;V761r6SkNw81ke!DcDF z9z7HTlJHq0R476(pcP%wn%%3_9n^QRn zH+O$dkB{-i&!26i_7v0YO(rl&_&;=%_fJ~TIc(>WOyJ7*SKA&jO$u`&DAU}HfNli4 zh;Xg#ibug5b8ax0eYv1?Fc+Lt(#o^x4~5B6_h-rX^W}R7SYQHtnO!~XsP0UdSVhpm zx(HQr8~f%&a^*sKd?d=l4aJz0^0@E_^@==uml5ain1}OG7v&MdYcLMg?DP`F36w|A zu+y?)2c?Q?YRjT7VN8)WpA;0vQLCb5+uhGpQT6?yzLPT5>Fk}4#5Sr zV|__?COD?#@jN%YLs2cd$L;p<$q3@2Z0x-!l+2R~FS&-x`B{ogiX#3Uyo zF0<5l$+5;%L^5+#(un(^)WDbqbI8!>vmy|^kuQaKqyqBhh3((JM$S|A-IgOM~j_{q~>My4lb}zv&Au#~7){D;Q+-&DUFr*-z$yhG$ z9D@g2aBuZfTnw8=Sok3msX$$mc~b< zco-671{6u^_7+y+} zX>%m{DajN}Rt*dY%EoXFYVen?@^s)mBWJrK@1TdO3&Qwn1p3(ne2QyNeY2nXKCd!6 z8^1>DS5uQ!xVUK>XYxbVmos$l3?4F*Sp;b2vN)^J^aSbhz zBp#9|p(2NK^a@F%Q;(;NfRf7Wxwt^3$z$m>!I%ooVa9*dMR5{(wq#wiJ;0a~8ayvK zdcLl96k*DU1X%4@DQJ{XLu1d^ZHls0j}kWWT2{*C({}m&e*e8APvCGnaZ=@xUKTuSEtgiqrsI!gvrNzU z6x?z7P=4BfU;P-Yi(`Q(Qxpm1q^{_Z5hC%BHn z7Kt;J$VCdC{_1t!Hpq+^RDk8XfSGQHp|DNmfm;OJU5m>6iN z=}uvtQXsrEbWskycyv?G$ZqSC+jtZO{mqYIfh;PwD+0|+WMy!8<&Pzx(^Q{?cFs?N zN2<$aYf>QX8Tdj=&u)}dYCP6CmGd{|9Iwu}Jy=12Im7@Fj(Tu{9!|agg5%JuFXNm9 zQK1(nIG!#67}2kTMAz{HFlOS%a^?HWvVbJz1s|_CYG#q3J?nnNc^3LVIl)n_vW=~N zfUattE_+yHtef=#oi2Mqa>iY=SGvm{=cH{h_vGx5hkSp-6IFfa#8ZC&hvZW6^~@76 zHM%--#n*be=aJIs|7Y)Anj6QpHPN|$g~Oxnh?7pdLFBBv&+P6&-_yIt3R#k!s+1*_ zWK~wy{qq;#OC+!Wf)puHPS)PxNSh=G;oT6vh za2nx742x?IRo*bx8=3lj%nz$SPkOqKrV#4vxH9J!)~kwJUwGPsO5c-Fvh{=IWvMtr zPL418vR{$dZMXVR)7uG{!$OC$2V#EwwOv5s|Ho>zpUpSxzgCa}Xk_lu@NCevpNI8F zel1e%OLdLvD53;C*E29x?#YMUtS7AW{M1Lgdi-d0X}(DXSDh|g><+7!T}J6y19e!< zm%8(nmpB#ZY6rR82ajo*{jDJIoiW*VAV6YxcU{u8-fr(JjV(cAji- zb-%sAkN=#fQ!~?|tlk7u!0y)i=4!r88A-b#!)4Bnn_WhHIzwc1V)GvG+2!^)+w68f zvWpF;$Bz=)rCPRC@^nYnhbs&3WCv?i)hLPZ{2;cZm~RQ?EIHA7Q#ZMpy)I5}g7-$J zLX4^ce164vFCl^p0C(3H^j|!Hhq3-{*hNHft?| zwljU2q=RM4vh?px5lnM3Yq7ciNG}ma5mELzQ*C&*NnHyt30PN|r^d?D&5TQUvI=kJ z7fXSvPe;8{pzao@9(O(?Z`Y?jcspDy)So|pI!2E9lG*!wJAcb;o#iim_j+L+^PAnz z;v9EijJn;9IhB-3CeO-D>+>aDKj7(7EVq`&3t@aZUWPede*9oM3Tr-Byw{hzk$g}<}jr`9{8)r8(i z{k_e~(sp|o^cAW+=|77@uMF!$f%ny_%h{$uj?ITpxBJcoVZmEiaVZg_g6qd=V$vta zXK{c|#m8O~zz2@dOENoH<&`1aZQdDo^E??VRl4AA9TGA0j?0}V&%xa!T3~~pu2!$f zf-P_&(92@+D$y&EubeMqs>9wwfZtvK|GQ@aEL5=kz>sTn4DH8*me9m!T0}FR|~^iy^_!QczAL;tV$@7;HCS>RAgU zWEQ2_5MUL|^Ud@*K~i8&C}ILB(lQTh0V6phG5_mrmh=3n)nYA`aGekT_g34*MiYOo ztW;ia^a1+!C{h@X*)*tK{ER6KfAmeE)>OTCDHuBQxgsdxes0Zo=0|QEZilAW8?cZa zHb`oT3j6XT8N8BV&?DR$?Pjmme&p0OB!hPgRFp^@qeYgQAa;r%oi$8T4cn*3X>pSX zh5d?HgBD4o(jO>oVzbmDG2_b7Uu`Xtle)uNSgwUo-v|}o0e)$jzqq^q+ouGkDo{dDH_Z;9+V(>)GM;r7Z~-#olT%|uzwdNB?xMMGs=j+3OVSPQZ{opTB2)rkta zh_>oZ30}gqb>sFrl91`zJzt(|&>P#JHv;B+&+*+s0G$V80_J~LA-d_?+oUE$CjvQi z2HZP27qO?h6$t3I?I20ot=2Y!3T>x;`B54i5D)=|Lx8~$c_>6(L4kq^`;D;Z(G6!L zqP|bt`wH5UJMOoa4ShR8#28q`Amst0tuQI9n6qf14GIRM8Y2t93JU`w5l$RJndp-; zMTN<1=-pnghn49$CzK+Etjb+;Ej1uhB7caQy3Zyrh7DDM9j^3CVl0I~*dHH@6IxGu z;m26PWJX07eID0sdmI_&?Cqq<-IQi&iSDUB^-QP}BC&gsw-z*UiL4>eIL@$tIMV0NW{#Y*=en$;_nF2-nTj)(e5IuFtgwpKVYH^APvMGDfvWC~UE(bYRVn=RANI9M!Km7$ z<^YTHI3um;SW+2C?~7?Y5XG0?mn2FA<2CF|$LWJ#&!3xS zIzIpU_+|0onBSleuGjUO-B^BcIsceHe*J5H z__|rYxR*D(w_|>J_x9B{H+#<-^;PupmvEYj7M$<5{^EvJ-EqAutWO3oQ-16SW2TV0 zQpKy$j^>EgVju@URO$#C$KERr4O^-wwvZRYicxfLN!Lky4aM5?P|GMR~2bAs?tPRbCZ}3aybKsPOpJOPIAPP1b5os^!Tjmx8+r z+GFS1ca29`Zfl%%t(IkFVxGJ|$sH$^l|&}sxxLK6NF)izBx1sX>i8waoBUOyn}hoY zSTw=!jC^0$CF(1{6cF=`#dLzTcpi&lJ8=huxA@L&wzIb`RHsT!&{;QJeW}I)yqCIA z!Tk~_B7Kbo(o|rY;zUZNxMYf{<_t|uC8o>fq+rOFxviA<=8DipvMbf5%5+TOYDNe_ zIJ(mGgYP#Bg8@sSw=26<0G!zv+aB|e)p%eRR%)!-Wu9uau%QB6%AlMCf8*#IYAV20 z6s0f!Hb~8>aeKbql3fan`;>FzGm}xybdSU9?xFa3Gm@ug5AHh2(}uqfGb}w9Yc#c( z8U=MJdpK1g!BcN3LS$rPhQv3*n?**5J+cdYG_gmfWVw$$a>|+e1$$1D5rOJ;ENeX2 z&!48k>xY#E)}s^HY>i=OvJFKZzx;Si$Iy~ddru#{)KyL$QIaU+WCF{HEiGqELRcpi zZ3D3-IARVPR$C)h>dj_mF8_LKoIDgywwLoq+8L(}4+TpDho9~E%8-FKg2KK{=3?Wi zaxVs68@uJg!oOXyidL$7qfI*0YHqSdF(I5LiW&P6MWuHPTB9wS3(RVS<;b;q%}5(_ zw9&*hVNA?#;kKG{KlOdbY%Wo{SqktqkCC`BQy61_Bm1q`+yD$6JB}dk-tWO0!6!jz%)8tyntD8P|tr64i1P z7mK;%l;F6<0C@^PEO0A|)$u{|zdf3KCp9tH+c|Alfox*Qwy)FRlD$!9E${f=HzpNBhd9-5k3)QqY^G`~;)O zPcShM>DAvQ9On0AN_tKlP-jZU5$-zlA&xH!@eD`Vz|2B`J+U!s7VIHbM6#W(@F*vfE(_8#jL8)p`UTPK91rRbvG zTp=+M#*x-W2E|k(C>V?c5rmVtsi=<`W>QFqUTH-o=m8WAMUoV~qr@#x_jW^dyC|!U z;bhlVRD+sj14elhZMmW$GQuU}u0z^mfmAA@Z($8+rS;8GpVsZe!oE<$jph{Ya>>U{ z-cZhO5UP(E74=#sMW{j@ya3Z`6l*w5s!{w>rqn2}mP_5APUHNrlT5?9R8OU0U92b4 zC@xy?`J3m%yLci)aUt>xPX0~MH=KOKGIR2^4ivBda>cjUS$IABHmAS^N0E!AfZyOD zZO9tKg;v%uu~D=p=UT1gV&oR~t$r}YR(W{q4TbM7Rwivqz4rEl{jb&p(_Kfz+>EXY zj5`pDGX>6+*YBOSDyI9P_<1WvXWMgb&1)n$ldSN*=|rJ)3%niZLp&JDlf1i$cL3zrE9`brUyh5>b<^tmC`X%M80n3R%e?Ic|Db-*j zPmi)brOZHorX(e0^pkFzD9A_nF_!E>R4Gb(%P=;%wRzwDDafAEhnJdcMHkE#rb3ye z+ta$cQ@-auVjUccUYf4H6aSBz!Nn5c}k39sJ^$xE`Q7Ba4B$@%} zj~%IyF?vW6q|MR`NVs&`>SA!rht70@NNFnC`yqo(IZP#*dI-c#fao|v(5 zHzJu(DB$e=C?CqTyx@SI63hGmnqW{xZQyWX6wB@^X#|f0WfXWU2%L6~P?2BM^?Snf z&9DPG1+-t%or%JMJ|O5YI>eUGJT;Lq)FeX*=S(#YabvK0yXG$OT-7fStZ&CvrUYf^ zQoq$kq43~o{ZjQZ0dT@29xgRLXOlgpf1cXYyxq1M7cR#b>%=@{Bz{C%WHN?88 z$Kfpl+2;KrX}2vJ-wMC%8wHBSLx%#*`iG%<$3+JLtgeoY4h3jKsNX0g!2NPvcNOnC z5SQ6?>_!k`=x14PzqGDQqh8AHhgsH?Ns~)tk`i`&pooSl1|NaR6cZr8?qo-}-`EX7kqliC$S9pMd%xdZjR;GM1#@}!f z<(!)Wd*z=eerLS=&hM8GYiz7cEM3w}wmH*1#l2*#%b=xXJgiH>tRz*}gH~LYGo5V` zkAXxV+%#}TitnB0;WQ&P;J=}6y#Mp))Kgk36TlLNRAZjzKjEC zJkRnPtcC8-x(aLagZB$wE6F6`t_x-MSy2!p#xxPa3C>Kr)nT@#5TWy%?7^xlpY8C% zA=iIQg%5$W1Qpcp=u8!tT~b6f^{?Y+g%d;#Ihs?1_9fk!(nCQX5b{{M>G_bA5ygoj z6f=?fD6P)xF<2;_W}z~eC0Pdej|!1DVPj`FelVb%26;G zS|yQMtrV7Z(?qmT-6#^=P1Su4+>lA+SHU%C%0-zLp(%eWtI(XUpO>${4o&5Grx1;O ztzL=7zFIFuYAkk zH0Kgi%SX-|D9jjh>4`!eCQ4~}EttR7POG9eohV7GXE_flygl+Ul^*y5wgJ96W@nJPmE8EK9G&acGQqWxwPofMxsqUuF^M%)4E}C z{)!%*McTx_8h9?!Dd+|oe5K z`HT?Eh>~%KYa7q4Hd}iD2d4Vkq>4IDWCQA^L3OfaBDn5aZ|UZzC`YiHU>*RrbM(r1$)Lcvy9CTQYu!&3Yr0T3#dJRuKX1i&{BNs(%gg`s@qarr z9)vt=wWq>(WUH*cjE!b{a+Xngrq1@O!|bs7^R!CWzQXF6vRe6;r~GPm>v3gv1lAwQ zg_YiN55jLx=J3-GmY1dC3=unrrG2@2RMuXT3W?c|QXo*pIjyN{HR@)w(|Sp|v70#u zy%RUf!)iOru_)V{qr6@sOHN+0-P}yEfzq|U%a~mUCvO<*JxlG7o3c@i^rpt%0m$EB z^&MxgwL@un_GcT2$NAs=Z_yibt4}3;%(#|MDX8twpC5m17mzyeW3}4P<{PaRL8hJ& zZ%0EGLDzmB)*tz`x`=LAA@hadx-!dva(y7x%gp@T9e(Iz)cv;gGF3F0rQScioQ~%F z^pDtiJLP)>CFnV+zxBA-9ab;9jFfQp$#$tfRBy(8dQw}VNMApWY7h z#p?C6+5FNf^mcvx4&P?JdbZfC=G&CyurC{WWOm%_GM>f0dRWc#o)^c6vvaZuo}E_} zaMN;ooNacyA7BrD&eLTu(_*OJiZf9ub7*b_+bNbV=GEoYppAv{S>|VJMP{AJ+59Z7 zT+3Aq@L0-eV4NW8bYf&VK3lq~j7RkT(YNRo71296@KlC+q*`EgpZ4y+bBnm_*mKHg zJm4YaODBs<(j@Fv;;K?lM#?$aPdw&*C2L6H7p@>XSaDqNyApU09-7saczF+B@cZ?A#rRoylmGma4Lm5oHNFJ z$?Sc;oxf#A&GMJNd%dXNr>&)*g+)|{`rUJIWSYdiYWM%|fA)O52o==sC!PG(I(dif z&^_zYn5$|m*GI#|wNmg|q=KKfZL?21gM7HhdCqkeq76NBg|sT9C}TtrqU^Ic$JNj? z6-0|cDH!F5af=jvHur4>fR36(v6Ddx}IB!E}NE1*Q$=i9|IHd*vBLRy8@lg?WWMWLrS zLoxsBZI*kF8{5fVD>B%s|AVXTVk!lHChWXkgN@E}`_5h9jXK3~Y1RD#m$p8EwE!^+ z7!X)mD2|vi2lFph1~bLg31)sn6JB}ciz$(bkhWKS@opydYLIqx>iO+T3j@aW>ZAb! z+jSl&nkNFAT+cn5lE0e~XsfP$<)Xa3uGcq-TGRFJBW&y<;V)d0VF2MT5l<3AIZ+H_ zeZKZB{0EiVj^ym7YIGC+gGy=sj44+f3sV#UM+9#4ql%1I_6sK1Gu0{p;Y^G3hG?;~ z?6=oaMN9&q>+&OGiZSYP zRt3iWUSg6aMaO9dvg~= z)o6P?tX4r4(1hxzG3Rbii)S6MGYz(aT%nGq!+vuDdaE~A8d_XHp#^$E7fN&@m|u&|$CwjlU~O7|@mwE{kXoNVM6n=< z5o(tj@{U*0Bb-p~3|U#70wY1BlY{L6`uC*tj~68Uo$#a29;@t3_c-vS+ba}(^Yb-@ z0+RIG)rSe{v=?A8qO0wZ+2@0Mey%GvSNAJRKCi_#q@ZafOD3-3 z+=Y9WH6xWJv1VLx0JpN^aEa27KxPffGY&I)(wU_evJsRuXNiJ2)?dZBEiNkd6*um( ziL{+SW5lRe0-j;nLFKi-_rM7BD;GbJu(~2b+e$7@5-OXK&y=}oWODKL@@i08uSErk z3s)`{O}#l|Loph*3cuT?T_v5CzLj(fC$}c14RuA;M(D|-MU$Yrlb8H zj`r!`{X7=mNRRd=rM=L;F{aj+9`)-gD*JPOVm=o~Brq^VL^*Ja*AwC9vgiNwOc+wk zZnLj-^gH0n)m)(6L(7&hl2lDh>o{kYZ&Al|I&7 zHl1sYCA2I@&-6=czuOErRO3sTQ-R=bT(23N)%bewwBW7D1gBy?pL(52SvNl3{l$-g z(ocgFYXYucP-4oSbLZneW9g?mFJ|3+r8bo&%FY(8@>48Pb1L?x@=|4UT(HEcd*5cp zV#+}=La^$&O10^|5|>t)0;VQ7_ZPckX zC1xV$QCvl!{tEaEP_X9eHJqaAX&FIGF^ww^1XYECHd91pFd{HZlF0H`^*UZsaGRY> z?;5t~QvIuip-EX1S~)RWrPb*7Uhk?!N88j}ODSn85Z2q)|JIm|zZ$%TUm^xHpy=9T^vVJ5|SW@>?sN~V6IQU&f zk#3SG0b~!!;{YV)*i_93WY%sd_HGq3PhVS^otB*zXj>_2odfz;L zG0W!p`|f@92)3Btu-I*1*Kc-X`Nie@WB&N{uX$En-MPHky&dz*ySK{a`lp=(SK#Z$ zC@k(d>~_{wsJMAve;m7McKa-P?q9fX=au_l-`>UTa}11tPxr8qf>|f!7-~wh0h#_xNKxAnwtQ8&+Zb>J9F{ z0N~yTo2MrTOOXB_ZC*i*uz9=YE`-eunw$6`?k=#o37=G)Tnd|CXWso_`xvX+m+2ab zq_$&R@j)>_UG_Y1PkR))aW*HwGyKG5NB0@aNSL-S?WB*Dn=)W3VTdaV6+o{;N0><= zA>?RS{Hk{Vw@s~ZB#0oK*cG}*0+bE__V$NFN1?b0AyQBtSB$-P95Dj!ZMOo3;09XZ zvU)rPLy_ooi*_*~N!$>CQ2VvzJH+h5r)3;pm?$a)kr#+ptSC(ow9-EnO+FAA-Bl?X zo{+Z(E2vpEVC};#|A4(xS>udwju3_@stk=+rb-&6;cu?|2E&q!ikeDNB0j};)bX|k zU>Zc@!;mfPeCb2*a|E3Wq&OzZ4lir~`1QewQ~wx0m_#uTu9^bj$I2kOJdoqY4@KLV zYp#Su!>mCu&nah6{8BOo<<)Xo``Lo?!wy$qU8*w$*2Owc058M+dGS8jA3i148((6* zDec|(Lk9rVziV94EkX<)ik~-Qbb3y45XIKpQ*!bc zhBc&a`4$VM$e(y3pbg!Mm(Nz>*#w-@`i(cO-=rPfi*``C@4m{x-d=y`IpsuMf4Gm} z?+eu#c3B)~Rdf0I^XC_1ruGpNii6>x*tyn8eQB$MoL39_Mo@zelFLewP}uuYB&43i zx17lD`!BEicfAK)B=wmcNpAKY$KF7@Ig+w(~Isyg0!s)ep0k62{pBJdF1Mda&^!xCehS``1ZfX>#-;`kJl8@^to+7wkE(jjL z$eiw4MsOx*GiTHkJkYYa%Yp}(62{N1&)5O3`_1sBp##0{$NJ1yerp#}Teu-T*iB7* z(D?YEsodh{VU~*Nekgw4ih%j|mGiECzKZbow)Cz_YJNVxO^Pxg_Y(IZB2YcNyY$U) zE;uf%#%VPh8S?n$$79NK#rPM4M4p!=L*g6ZWztkjxxA7W66MNHVG(F4z!POdi!A5q zmKk63G5=i*$nfWO9Ho%yIECUzbmzvV1(?o~_VU%2+47O!+ml>v9+Z+Ka zvXfyduwZ^$x7C~vmEe^yilwp(Ko?EN;HFfegdsY`t$l8s8zlIL8>>MX7NT^s^nx|d z6vhyP{ad+8jA$(ej{aDpbO`SO&N#x6-0QIPcZ*)@H4@1|Lk<8CofP2{!nsUjWR!n} z%9oTSoD=A!SND8rL7nqNHy+t+3zr1K6U5?z@S_|OFqitEBLk$GaC``Tt@iG;Qguc# ztH%V_LRLj@Za4MqA@$NqkmL^y5B96b2Q^DCN8P`XaL$g-lu97lFk_yn=sG~bFKv9J zj!HDUUN`VJ#l!g<@E{~DSp zp~`tv3#P;yE|Uuw&J`jAc_a)s6;cvx2P`y-KO#Z6s*(;}SaQTG!kXfN`Y6HI$hS1= zIc30>RK%YoCM@#d!h6baNEm<9XKc4T!9h%N0@C2Wv;op?kL_GJs;B`Sjv7iok~WeB zF=`0BpF&Bkf+M1XnR*8Uu8t8!hQjm|hY<R0{ZulkO!`JHK^*#GVhRN8PO4|413Zl0to-fS!lG?tS* zvAj5?x4m(C+lS)k%~+Q~6O6j7%cyCDD*ir7cIX;mVoh{Y;P4nn(%zw27j{uTI1ecS zrcs}tmg|o)k9zrAnMnP7z5G`om3rlQCzrZ?t)5KXzFN|D@IHvdfH>-5n9!4d(9aoJ3X^uE=CUmW+gF7LAN_%{!f z(U5RnZ&;~y4PkKtO)jz&VU9#FL_{XRfhjzAiEfF|TKpI6LF<8Vn$nxy$dfj=DEsrJ zm0xi3Z-Tzzq}i7?#1~mUZ&$85bl#qwX`N3L;c`Vv$sPBH;^)n1ovH3i449u_RN1o* zGvK_beI6=|xojgdh*EmV31&xKcx1*|BnVetoWqK>?4~46W@stLjG65{ZDO-rRqN3a z)-KCc{#ni!^(aFm*HSj}fGyU=aXa5HEg1;XIeU2SedI=icU=0~wz^cqLjk2QcX}g< z0<^)>C{&aq!1{_%*g`$)@G(AWsME0gmT8wea$Mbd|2aL}JeE*>wFUP^fD*cl62X$o zUI`H*6pN=rqDE%$GcD`5KJ!I_Xo6I;plGDE0*wVHdJ4L8{`<|cSLua=6aX2=4k6e2 zm5NN)7B!B3zHHe+emI^SYUsQWzO{I zBqnG(s=XE*AZAJk*?(EGR{d>7;t_%wQ8JDJ>X){RVyN^IK;rrZ*#=I4^6)K0&U z-USiU2_)-k^f{+oTDM$NJG)d%@k}7rwz?&WL^Q$6`O*?^0mj%#L;SZT&Gj znq8+`DiB+TJxQa03N!F2jRs1mDf^j53E9t>c9-kJM=Cs>7E|H<^sn{y^!Fos#(F07 z(!}b^+hYIdi2AI(#bQ>OJN`_cv3<{JpK}ya38d_d(NFK%3|j9utG~70JDcy7&=+LlY6+Q=Pbm}^G5(9)`@7!V$60>dq>oUnw->RKJ>}Z5{{L!s0z0(Z z>vmR$*>SaaawE!%F`xZ-*{3r0S-OT#Hjc$D^qGf=e61*J!7$Ux@{idmdo4+93+#RU zcF_0DQg~%KJL)rW1^Kr>9e-^X(09F_HjZMEUf9nMA8Q{Cv-{yO@>hogfRTjP!2a}d zJiS1j+s{8fw5bXr3QvpgbG?-}E+*r*tQVWLwx;~2LbmVidDv~=%tYkVw^<(npN6NG z^;>#ZwhUfQuh2b4WH}4h?&8U0MsT~RjhL6s+0O7c0J(LXjv#evXvdkh;Wo=dYTpy| z%-jRdzy;O2n0ls8RyfntQ<}X9Kf6gmb1sr5f<9Yr$o|>#dDzT1dK~8;yVPR;WA&c? z{)Ik^XGetjzPr%>5|iZ4U0NBaOcR5Z0y|?h|B;>DZrW6{UQPy{aEmuM{9y(-1>6CR zB-M*y3y2WCD(6cB4LN3K_5n+9KV-cFb7c*DbBL{hsf;b*k=P*t=@gTH_gWP8?)2kDMjr?Zv zt?bze%V$#CjNXYc}oW=gqwO2gTu0GlsSX28CIBWG zUG9cg(R(j8^Z^3Io}71H5?EFbVg9ssyj+g$!06ulZrQ7%>Ab*MbFAa7{8T_lUWoBa zFbg}Hnt`}?nO6p}nrCNMX{AS+me2d~;v*60{WYm-o*>i$ipv+eWz_{-&s<GRM$4;v^Ye@!@HWQKQRhh zu$qf$3wZ_RMb(R9Ae-s)tJqIT`kCIoKOjr#6XZ+k>z}9FihJ%W3s8PkrAppcrUXwA zcxswGnS2LiUa%1JwQ2&qJ$|XM9g(D5jH@g5PgUZRcQ{<97XyI!AoFbdSv2 zG(@Mu(ErA36T4s5o%O3bCco_tI4l9jm+% zer3h5?ObCmhRYw=r;hdLVC`!`oP%j!Ru>|Fv+qte#TPM680RG&J)=8ovj$9e zV3%jvtAB!;N;^$Ib{)3LXBA44>zMuZjfLMUo^VqM)RMNPPqE`qE^?WvZbDx?9&TJc zpJx@Wk%ues(=;X42}gXJ1z6vpodM&A#+EJr1xP(Zwm)?9V&~CNJQ0MW> zzYB}IzxY;=l|P=hKxfyF2NW`@LMhQvvXz8d?FM;W_iSvvBN5Iy^M_>N#UI0=r@p|Fdlhy_*#TNg=N)#u)*Dc`c z!yKW#CZ|QHr88eRIBD*Xya7T!(+jW7gWJA!m7=pf2iob~L{L^lGgXo-h4*W)u+Jai z0%14PjBnIS$Nv2M1+BNIrZv@&sF$8_J~Ta*Z~Dvk^P$J<-Na>6C}6w0p0FSD4(~U8 z*8gUKX|Df^1)9qll!$##P-*(~q*nFmoTwR|V{Sk}U2outZ>9~IZXQYUJ)$``;l}+| zMNu*JO8ktMye%&}YZSKRl=a$}U2K`N%@4MjU?8N1wY0UWSp~P=u|cf2T=<);BV`MA zA!b4jfpe6|d=!2raYyu4@NfkoS8!eP$Bd>$y{?vrzrghcZ zfD_=?wC%bs+HJ57aIOML#rXGPKc60qC@FYp$ue!I7Id=z-W+e}AY*P>RA~Fqa7Na~ zK&-w)l??D9%Kh|N6}s8``APdJj&V0DCfAORUULLS=x>h9LJBUEMoy4sTfluFEz9{W zL_leEVx+%ge=ouNj?_cOU0PnA0=HEIkK0n2?34+K=XDleq;O8@W>40O^C$BD*m(R0 zw)Qtgm42K==ix8XC?eGH2nWWF3=_3+p`RGVaYn)GcFK9bQV~jpl`|1%l{`_LSDpX%S+p|6sLDWOQB=*pjO=f7IJ_a63@5t` z=Z*H!nWa+{uqK~Snl*aJ24`D5lUgD*{P#FQ_1$7Xq3 z^-{${Y{c-y66>9n9IoT$XBLfO!88Fmj~#aMWZit*!<+pYMcBxV|2>gr%DJlTKIUPj zFqKTmOZB>#-t~UtItxEN>L;l{FYSdenz5>ncr^-AIxkLX6beBWfx`d$1svI^1r&+g4yLCUcB!`ZyHqPi);5zB(L)@~do!0Lw+H3Ub6vbVmJQ~?7PSw6WaY!w76 zdl(J46!-|jm2&F#8MMR|(Uj6=b?cS8o#61mCOyDyKf>U{B&0Uu%MVSh>dy2*bI|c8 ze|$IL2nLghCbh-ZXkB!B3_4E}YT51FSY>`0s;T z2vVBtcFMp(N&Zp}o@V4_pz-=f5{OwI!v79R#sfx{k|B6IK+Z6Wke1W36|)?Z{xZfrGzgpIz5q zsKY_r*1%V-Q5ewYz6Eh7DqbCM_WiP7>wpj8I5NlwsTuGW=2B_rm^^uDn@Pr=A*JJj zNEd}-XNR4ZW|r94Y|)-nChU}K5g8fa*sLjzIUTWv>nj9%2}b&M(mZS zAPvS2wVg3V989Gvf)cwRXJb{S(qrr(#snM@Sz;?~#J~@UT0~V{W|z!Sk=cEZc`8{F z^i~`bQN-LAU{}FaFf*iNRK}ZjIz9+7=_GLxXttM9{`0*q?ZbuuDn!_g9+%8ArsT|g5N2(tBDbJNy^$k0Ker3p52X94nG8cb8VWg|ZM<~0i! z$N9ga_r#>aUida9QEUiuBX7#>5o<)xU&4=@zFFC!ww@mSEG-J(Odb4oVZ$I6 zn>|xpOu82xoqG)u=@e={3D2TdUe*9;`;s%&V}3!GkO>K0kdw7CE~+N#Vx32hMMo?C zorr2iYS1@5l!Y|8nxIh=uuWgyL_(CMhU(Ry2EOujl<=XAs|#ijWFk~E`#(S)0wCJI zK@X?6FhXN?X|&;fRz-iPv0N{!V>E`cxjX+3+&UWfsvF5TQUVungS@|_^5jde`3&~cWnZz$hd;lC=KZtz9?>(EiRbzg zS^<@K_`=iJS4toF`%|D4XL0|hz>605BsagJLK+cQt~iT#4}YHd$RMygspc~Xw&JoTy3i5P6<(-#v&Dw z9$dLLI=o|VN)TwFCACrMNuB|5@~YW6Gslpo zO(^PFGRPHfEi8+R1Qo>#2(UDPfO+NYTlWocYgb8T@xpCK=e`Wz5os$Nj7)>wmK5#k zIt>_mSu}|GK89+95sIosw&A_sTxu0I6HPs!NuSCa_C=!*%W{`thCZJL0^IaLzy0o~ zMYmOH|8Bipdi3C}1;)r(5UE*o=ZMH>!7DH?r{Nz!C7Hg)BpvBUcURZPIM@V#7|E>2ir0C z*hThz(|q8l_JSNjjhl*_tF|PaRZ&lL-Rvv zbPRD_LW4$dGz{H~(yeUhLDGc}L__?##5HD(T*#H`jirS#2h6dV3CH~sg+#SW!ho3g zk~16Wdp}sSmLMK!7_yYPqn!%L$%5~u>8lVKzy0@XpqE82=BTSN!wd3D?%8-+Es1{U za2N7H^f&zCnC+5M_OsKUyF-*yj;nwbHi|~fWXmS`7JO1G`v${!E?fC^IcRdah|QZO ztq8tZK;#zoJ9YLR(jqErfJOPT1;%CwzjCZ28d)7;(Y}YpRV1RNHX(+rsHlR$p1ulP zg4HHO{qIz!xCjlh%2F!X6?x$s3%DeGJ&mO(s_imoXw6ebA)K}WW3y-~vvm++%NESA-|i$2*2$t+=Q#-i7q5b|o8fI$Y-i#?eUl`E zlKCQ;$Rpo>r8c+hT&@L+>8j5xz8~qoyut7N0EDa_H+V6A?z<#z$1{fJy_E?4EF(8< z4N(O=>?jZh>&go+}6!2`{L4zv;E_%zowWPKJZ*UUk^8at)=mYL^YUct^!dlfgq{BgpGBq z+Jwk5nX&bEC}Q^LE98sJ*xo4eSD99)S~z@kIazspHeK$sBM9SAYp+aWO5LJW2zKA()3(Hz*bOaz#7Nejn?M~0?1)@>DQB!4I9wSd#oc_R^a;B?xjJ1rmQ+LVAP zKuWc=h|-0w`;V9dM)C*n^$A1f&H^L+<)!}XeLGhMS27G zj_s4OLXDA6w13D??=~c;d*O?_v(`wzE#M;uxZMVTBH+9QqDzmlC%4E@i{DGxU?40GfMH?Lr8^ zmAz^5*&v6}Af$19dTn^psKM}!w@iCmM}3o5s`m8e76Kov7Ir%BuGgsg%=*T!hvR6~ zIhP}fr6lqA0Ov@JA_8u&;)qe^^(eq{trVHaQ;z|7NSGI4D#>{4Sy2NA(nBMnyZ973 z@3jvnyKJ}OKTVWx9%DHWDiGDF&8*wqqRH-BAN(~!{DY8PXriE)+nPsKpy<7?RF9lS z>3@WWWMSi?`1E5L9@n!p_6%tU3349)IP|dh0Hc}@vHn_@%?!L>T3{=~^Tz2gah{u+ zesgOF`wpFpvbQ!od=B@B;K+6F{i|0G9B9Um4_FKzoSj@&LBK2L+mz|)WFU%Mo7<*{ z;WCs!)5!f(&&rsfUzdH3PLjwdl6?kP=+?Y-e!WyBxXRRH7k5reJ45^bi}x3Pn9H?m zO&QL>Y15|&%s8IMue$g>OC#_f=;_m2V7P}00Z*XYcm8X>HBZ@#+ukx$M{n*n9oL@O zv3{ndBxl&x7TN>~jbUj-mGVW>wB#jzJ67k`kG~aA0OeVVM&3Mfrb>Oeiq^a#YQ1Cr zW!8xJ&*ZLY6F(D4?3judM*Lrwy?tKa5(P{*U29299uDmr0^In~CP@Tv!~Vorede=S zt=Vxdvn?2#8bO@LU4NBK&KN9E)w&$0GNSTOxkh1-o&awUn*;xIgQ!O@_I_C=lr}yv z3j2@5Z$>Yzf1H{=?wcd+0TesurJi3ut*SNv#4M*d+;>Q|r2vE2uW1^eKyrn$MZ1D{1hfsm#l#CZQh)H*lh+!|mJ=K&7sc^ovcVa#9%BOYbHv-1r z4WWGAhzO!;MWIIMC{sQ5c5y~!_8?Q{olJjf^^W0K$<}C6vh~>#ygX_f?E8cj>$~gY zNA0i!=by5A*25QbBcY=O0s5tGOO#Z zmQC03+C7I{=Va6g%Z{h|tL--~-eFfP$G!8$ozdlL=1v_a%f=%aZ-ws% zuDDJ6ep{n$@`)&q0v?z5ar7j{>eoX_;kr?X~oOv6Rf| zC-eRN7@Ri^GWKK{QXYAd@6v!Wm;{o`zi?dXo!eiHhV9iqzz5aire3Xl@pU2%CPLYg z6HflDw|Gn&b3hH~Ve)l{=gsZ-nB%QN$X78qNgXrfHlh|`*O$lF!9if>(Hc%Y3~H^N zZrp0BN+PR|Ar8)grV-psIb@HdnqK%6pxU55PjV>@dk~A8-H`%p-!Cv zhbi-<-wig6iop0VHRYz;yh34rqrIeDkzKqrYG{9NnP(C@6eNQ9b*dM@Ll96((AxPY zH|`r9%`@n!KR32fkI4xbWit}wU+zmFUyfP!;H*ZH`Nx;VZDlC8yV4#{jYOxz`rqDO zylcvDw8>LoNh$>eaP<=2d0kN)dvczTg$1o0#B3dsKRFmbs%a0`X%s8dJC2aEtCzg1|;ZcW5cwGW}^l%0T7z=zfMnVrZQyKQZuIKNl=c^zZ#Z>If z<#Z@yb*ObyW&`t1R9h(hEaogbPT7{MV&rTC0zVPX)Vi}1Hzb_)UB7%)JkLQNIy9=* zkJU`;LJ$n7Iu*4%5#%3BI&cKVAH}%(0bz%tGGq=wp+y7%oyrKN zQT9dGVf~xiwSJNINBoxEv9k0%x|7}_E}E;qnv)%iSMgRDo3=DwGKme>V{Kt29Lo&p z=w_U4+?TH|k{JOGylzV5!UW%^HW}MGn&>hLI3F{ue4t(Mft4M(8iID0_Tr!q`D>;x>)ZAnS4)4sBMZqlba+KWeiz5wS<^RlDOL25{W5AJ$thtDQafuIT*zTP2953c;ojE(vL^!FPEwx z=BDNQrD|W%O9-hMePaM5Nq>)1Hr7Ggl!3pGDrXv9YKiD1LKyjX8xVle`M0;O>3eOA z3X47ll!l!glY^Qd%+!jgR^HoFr!|MhDbbdc@f*cax&1+^*3Z@M-kL%wg>~TSGl0RV z)ah9I;#bpe+~jslrcKHQw#ZzW3wivNUna-#x=uzYhp;$g7!em^4L$Kb|MO4JZ0 zY^(B@l|W}{Dbv%YU%m5+nld(C{!>fY2el64?u7CKx*Z97Gd3;&+n(3eQon}Zf707$ z{;z6+yv2KWMn@0F(f8Y{T9?(ey*XqeC5U85YhN(lA#I;E$lQ z93Fs98{n#2Cm9X=0&)0O^#`=ky&2ax)|Gb=w&tPuxVTLvQz3gghODAPt2)>r33mF7 zL_9A};8EMXR-&Jk6lazIUu?16o8=!gmj7u{(3=#|V1AZ?NrgVF0e#UPY-~5)U%gxr zLsz?EL3eL3z*K~2Rh_F;DL#fQ!|ZwHpVMkQis1wYdd=_E%i-VbCz@ae!_3ma8cr

hRl=mg(|Cj+kKWUl#g(dQ-AxD@hX;{w;-f{|;4a+D!31Zr2mieId_RWAyjy zTe+iDdwy1iL^f3oV-faT;_xEPU$3%I81ZaU_822hXl+m`vE+=e(q=?Jyo9TB%YI~f zboF0*#;JrGx7v2@&SzyGNXVs!YA`pH#w2o4+o7Ci9L!pAage&z$8Vhv$Uj)`_0Xx% z?n=T_Guu+-1ReG?CZLL!ojTR=H@HA8D4By%_#qUzm1_`QW~D2XM8cHPS&6#i9kcgY zi=B`$W0V+wEx?MIwq{e;I=S|*KDn}``+gCGh(#Khj6+aEQ3N~lgNk{5)sOEyuMW*J z@l|0VfRX!LAhU+?fGBwqjYi7Rzs=U4p-e6=a7!tmSyK@yUPl=*{YpcGi8L+qw$#*d zF0w{>@V9OUj`?7|SLI>Vk;;^A;S5%@1*z-AsD@n*{XPB8umo$Y*Wr)1TwVrMkaKP+ zrgNUPetI*HSG=NLMGmo$80~i0A^EanT{^CvL5VGAlYaB~0;_4OD}&;aUyBv^>)I_02@cRd zfw7E1UKZGxPMvPDD|ScjdJL5mG!SSe0H^4ndT%tEZvD)Vz$={fKxhg4ywaa-j|&k@ zL^HQU)~<@@Qg}w%e;f}SGndF?AgV_0p@8()6wVzIH^QEFxzFK-gffP;` zOCO_{oBbcDn?>FOn`}DR2FJ;ilo^dk1^I*#Gdk4s{P}fzjgf>xufEUB(I3E&-8ojQ zPgg8YA>h+wyN~JWPg8R~CFjKR5(I$ro8u7!r%L~kZcGv>fa_ue>)!og7qJ8dH4q3lE_xseypQW&7E+@14%FFI}+;Yyldj)2q<{^D= ziSvFu?g%{lSCgS2L^|}Dk&!TOLU>0l$^EDRnuwx!_Owmg0EnKoJ57 zWY2PkSnT9H&O3JJk7&-YP$5Iqy*}v23SZFhn!Pn#n`N45K!N!!P1m)^uMaigS~XLl zJVx~H*Y-BKFN_k{)J+!zNTS(pC=>P9E_GRi`0NE==*F-zR+vc_OoCwmzx!bnX z-JLsXNy@p#%oT3H{u-{$I64cySC*SU0d_)x5AnA&W!E0nci~#157>s4=OD~`a78t{ zKw-MNX=h$rJC3r}+1f`1H4W={@*wWAPp#k7nAH8WjJ8XQJY&0=%Q@Hc6Z9!Y)!WYr zTQE(Nw*ee3vl%K#B+C!fZE;Ea{4TwqezMN6wNqL$!7%&SJ4eL_<003rW6v=gyBgWo zkkYLwe+ITO(V}wPmktnWbk&5TBC3|DV=w&Zuudal@Z+>EToXsO7%_a|k6@-oPlkJ9 zcHD9KQ=jr$)x0P^${?RC_Gj!~@1D)`U(jr$`9B659lmZRbgq%dc9*e zy+==a$!B&=Edqo)xv566xrZpH$w;9x`f|V~>*5E*T4A$p)4l9rd2A>!-co%!BA4Y>s}Yo-`1MEfq9-htu$j zx8q(K62_6u97YXB47>UTkCg1hC_A^g7|d=@S!keU!+QyB>d_tJSyptGfd5S!vRS>VLUA~Pd5Une z)%0uyxT_!fdQ2ozAA@BzL(I7#ww{o)W3+$zL&m6a`IDj>VUAuf{JD# z6vG%7<^OQlx#ea>muFOYG}<(dT5P)jS7ADSOnk~4rNpZ2D;B67>YF7>M#q4OL{2b1 z6m>+Pz0Y70_j^>O#cMo?F&y6?gd7g7OtIKCE&llAXp}v-F)$c`- zlP{a?Il2c-u|a=mYA@CdDxaet1N`TZY4;V0-;N-q^Ob^|u2NPgx^ap9ND~fL-0NzE zUqzSdUWoms$d$pNZWVRI3wXTa)?fTHKbjQek$%C;#WV$_t(`Fftp&2>{>!v?Z40mS$iTZB0BgDT)ET>Jbj47a{s$gg_3s8LoEhz zY5@zG`f`aE^7z2Y@cj_iIN-s{Rp1Grs+k+i=g}1KuXp4E zn|<<_c^9myMwpWzqnM9b%FE+B$)9}2l6HtroH8apOj+_ZWGqCo7p+4~FTFOU;P35D zCWe196e~4B>XvhVlDe{_KOB%k%-Vc)V~76-agpK|M**9=qx2WE#{Army@Ea0E%y!Y zA&Ubpb)&Oe5c+cw++b_@IHEuyJ(Yp}55k&}1N&ickhHTRA|{f|MY+=NLGtW$rk5_? z@uO0PpG&_J--Z{MM`fc|;Qo?Kq18cjM~6JdRmOs!;zod*iCM*c9jCCdEOuYQfw%oyg1Zw zD7P3{SYk`Qu(UL*Cb9Y|74SX2R+Dffzu6!RzQUB-IIq^ZgAG$ST7Uc9vZhOt4hRB7 zxoKM!j-vf!N&C$Mr<;ssQ$51yDoT-K)C-`tie>jMR4HS85Jdne_)+lx$O6+|&Eamw z|K_8B{tWWr!;eDqrDZMC{=VG7CNp^IN~)Y4k%C^{e52ai7QL1 zOnAHySZz4^@!mx{o#F6Uq{B3k%^>gjkMLsqE8g{PS?E}B2LK>lUQEo%*#BfN?kRW& z?pdXZ*uodQTw?w04cF_#noh9%0Oob$3WJ@`FV7K=I2t7g8z1L6YutNRa+)HXknYPD zmq6et$PNTdMdS@8p{0ROxl#Fb=j=lgfv`;PvbcWBlBMKIIE9Eq$W^U-(au^8gk(&rz`nhM1kpg z6NSZe*DknXxT?a4d53i`iV0`l>a=!jYe*ZEGI*4|OcX0?v6c5_$yKNx8pET|9m_eA zJJvxq{44LXc`NVJ-wcppV-8PN)6>Q97$1ixzjS1M*RbWN5n!v#40N%NUKagZS68_F z=^q6@rvP|=Z!-t=MnmLDV{zhw8PSg7|loGj%!Vx;1_{@0@3Ka3AFZ=IKoPkFh zA6+13_Dcg|W_bFuKAGydn3ONxFY6O(1z~fK+qr4{6wMq%h<4#%-0DFJUd|48RXAGKPpiv9SK=6a~t#nJlHn2Q`KHPmu%c_-TN_d{RUQiPf{OZp&%)62Wj{+HQU3fnyz$w_;6(2wqVNl`M)oq$!*r90R2hRZWXD2KdTbfW{ za!?m3*FVjyOp;6RuB+J$8KXmg`1+|bdq;cu8$p28f zEsV0&aG}V=o`kB9ti2SUG6@ES7;9Y@Y2?8uHE7EHQvZ_HSU1nvx72%KS~=ohuAOCT z{A_fX5)g+y>g(RFSHZGIOuKu<0lNxIst{3GJ;j^e8iP@ekux_myttozPAThBo?9pR zQK=ytDpwK%$0_khjDG3*;b7;pfGJQOLtN!FR&e9rJU2lhW3wcxwTvinc_gK!-olX; z(=-&*QE{JKw#AvZoV%HA>s4V%Ro0QVj5AfRSXK3iOC((K6=&HdhNWMz=r+#=vhhRs z&8X&+?@<=7Fc zY)~x5tk|BHR~^z$D7aBqfqZ#P6;0tx?&0XOFNWPU{Novdwlk#<=}b)4a$|M<9=Bkj z(iO_uG&@Z(;eZX{iM@^rJA0xyv@7Xi8p}zPj?779lRjms{`&QlAw)*~@*r(0E2)Ui z%mP{>_Gk^7_{y`MX*8C}RTZkaC&ZEbHt+~+HOn+WvCA&=K7bHoLNB#|dD2to12$7U z2Y1x{psGcQ$R6wM{tpwQ42F4pPe`+jt8>l`E&Pn)qhiEH7I`7q;6cyz5)cm zVWzqiKlY}9V^vhlRN3p;3wo;snuoN0>68@UZC{wOW0w*l*Nmi#?9DS4<7B|iTJ@OE ze`T}aF9-s0Xm)3##@4gbif>-KAquH8a8m2YO9cPX+nj}TV28s7`i3lDUuEZOK`$4K zScWp++Fgz%glei&VZ!fg?kCURRFZ9}V6Ol(3|~wMTG6j|x57 ze$rFzMS*O#G7-e`OU}vf7PgA* zL(Vzqg1!-lLY+_P9QR|^Z>F7Z?GSb7gg73Td9LG_uC<1yV3*4%wCfZyE`E{vdg5Iwk%4+&i`(jS93>ud!F7H@X+yH8Gn+U6!6AQKywH8 zvb-R0En0`#GFmL+z^J&_Ln^LHDh5d^eqgp$Ntin~)x)p`XAueWHOo>wmhcjBr8ZkX zJ?{^j+Xqr$ZP*0KGNh-n_5&&HN2yd`gDt&9Fc99Br>C(+uBL5rxvAP`y~mVh$n8PS zcMw=tD4_l437a$q@s@(AgF&PZmZk#tXOnk;8RxTcqrW*TV8pA#` ztq_iKak8{z1bHIt_g0%|VL4}a+RB}nv9{oxZme{B+L?yjOiICbfWxLfa z4GLpjhO{lZ4@BJ)cl3@m0yzh9=p=ej#2c+hapYn>*aB{+lzYUgG=v9p$Fd+O*sNo9 zGu6Sl)WLPr#wwz1>i84eId*U$NP#m z-x^nv#8D&PalT@1G(l3rH>ZOe9~}w*9_8Q{4fRh^PJ*W+R#Ht%Q1>cb1CNST}`N(SAPFnhw3~Z zF@TA6itnU4h+#$c)RH|?^F_ZH?007P;(<_zHg>en5N?P-wn;Y_=tm)8tp?}d+%Rl5 z3t0@reg*@dN`Z*`n`G|RvN;GNSG6>lO0CJRtfp4U^Up1hekqlGY{}C zr%5zr6g|e)%(V-ple`eP1WQdCV@U~}S*kFU6Z*Asj%Bk_37hUO{8=4@8iqa`?V z!;QK609!Q5xhUG+i6J~>Sqg_BSyaLl2YaRfk}4PBE=WJ+>ZLhnKLJ&O*D56hbq+az zcqofy7bGVH=n8$Ar@u~}&;;@BZ7Zwf^M6Tf(Ket-M{H+UJqoq1dA{3!xF}~=r%;y6 z#uJ85@fsne0#V!A;*lPdlpKIodmrtX!m*-HjA&4Bjau08G9MV|>2Ac&6qVLxJQVWX zA?gL5c_M7fCl+n_pkf7Bm7s@#Au+<%yj-DTrvM_@)VlZg&cAmSzQehWs(+XDHz4XZ zO?y|_ zV=~dW*cday{K1{3jRP1B%X{rhB%Pu*tj(-j^yKSp_oq5Su2J} zVJYF>6Q^kFc}dtq0n2o|)XgMV{C50mwJ6b0VV|9jRnibyQ?d8Ygb4?pc63|&<$QCc zCO8i36YiBuC`H%OYE?Y=nd7156d@&=?rVL!`n|K^5F!KaQ{jWDHaJB9Wl zhCK)XC*hx4nT4?N6-V$TdCcA99_ zRzc?Sij+dR#qWi7`G*Iw+{}(zRdopYndh~li*lOxsG3`N-;bM=Mg)}XT)MSE|FlT1 zBd-g03~@H8ZOI+xC{d;Et=fpm>eeH8>A_y==li}QH;>PX`dNyqlp#>=ebH_Yg(UKf zJTrp1Mj1}D<=oob#0#rUzZg?dk9Md5pG%BOVlGk9&g3=uAVCDC6ZIYC@X?lr96-gI zk;W!4j9d){qzxB*G=BiRE8s<~BwS5iZ@|k8@WdU5cBuSVJO~X*9k0c&g&cOST%4CK zfGF$+j|@@pJ%^kT<}$al0E=VBDR?&_5Smkr5?Hl{+C@ZcVNx+*#3Eq#aM_&Y;N7eA z?X|G=w$f6xpAi;?uEy|NV-IL@C^R!9bsaN)vUH&J0G?vwl!H5aZ-I@!jC9aJu(c1i z$aYpZID?nnt;qnhr+w;qZa+DNrrph$?v1FWiM6HZdn{<_0^ ze`0+%;oH{j$4XCiC)Yt*hEy`KPZ?R*{dSrh*OAC&*$ZEt(uK8ZUM5TsrhvOHW8Ic}C<4#Lx{Gw*|O7n?u!^9-@lmEO*r z_gXoefSm=c8JOjnTMK;2Aj8nMan_1(Lwr}JGBt_7Y=;=7e~=WZNq70FtYNTU0XbAAvpaCy50B1g#C00#_u zBS$2>6laOBv(E!}Jq+bYv~f_v78$Cd92l9vi}Y^EX+3QYM$;r9EpAVpCWPyNK^q?2 z)_$ptQw+V$9Qu})YtzUt{MDmT6Gb~}>(ZU4S5LKkzTR%|71ux;f+=7v;^8Lin}X%D zStlr8S~(ddG|I_}@-bWghA#f~$Ccut!77_sF%FesnPo(U6D!_Iv{n}=)!KXqO0@~? zcy`}2JJ4GY0SZnO&msqKXq~nKss>35hBg=qZCbDqH5|fyA#1_0s^}vU*I?qkm(VTJ zDr{|7H@W7+k*-1<9Oy+^)h4A{)uy4SW2}x~i>!XWWVqqY4{=V2fdh|l-bm4SqHi7k z;q0Xd|G`655@EdfWcln+ z=5>Id@3#G^=?j!?Xd_I=kaLR=ly=sRaM|r&baw9PIm*#ht{*vkovDU^>i7OnP1~~r z2UYvcq~9>`opQNuyW(XkQ>OCZNAi!@70LbDtD>Kqc_lAQbcHK#dY|#rtNRiSHVi>^aq?v#LM7x=7r}_7T zi(JU}Q#B@=TZ%WC2zP%hS~CJJR5lOe7lE25)@zM!-nn?s*2_q}J_ag7e*@0!a2W-ecUv z-kYy&-{3wko@ETly11hkRz| z+!}pCmNb8Qb^`eG(2RXxtGa>wb_xL*$Zt{ZU)|P9M!m7YxGz{2sov130$o~x#fWyz zIRsqZ>1))57&+a%?+}rrdO_1uqCbDJ$x<-{yA&(`FNWGFRyq9ie=9W9s?o5G|3{y_ z7`%t6-89egwgGjFiL~9kY5B}xSPqY07;zn1cnX+n{}q1O^v9>`|CNDby#ALAyjj=a zV99izlH%pknOjOl|C~_H{@u8$+)QZxJ}gdr^B7MmYYwv|+FpIJEH2S%#JC|t{c0C* zkHc5&_5a(#*Z*wcD6@-yw($P{D7v1+#jIdr{_HkAI5+P?{|C!JG{3ur&EYg#Xzd}D z=M+hWxb&|*kWqfxpI(k9P#7E0vR!RJ+})tGdNTlyISzvMYrBA2e?4s+tvzq~@UixR z)Vm+hGv=^A901`TKHxmIMtbdgw(PW)gop$b!}s;^xT>2H&?`3c53Od;UJWFA%Fbny z*pAlk>$iixZ{x`MdM96r+jU+qpH_PpNiPam@%FMD{>cBhZ<_5E?C)wUU= zNjdIR*}1280@#zoYO&I%x7q(PVUoFSG5VH2(t|VNRqyZmWIE3BV={e&V!dZ5vGLID z3PeNGfq|D)iPvMsgjS#2QWc(Y3^#`{q7o%YA9}49CG-WE0qm5z%&r*^0carocGhOC zwFuxi(5L^KS+V(2*{qMC)Ly@(cV+AC<@5^OV-6;$!)K9cOqgmHAMAgH;IJDeaqb2Y zGyyO@fGoV~wNQ2{wbYAVJQP1~22}jfGf<&;eCmFKFSJ4_u|&@NK`z%WaG?e63J_xe z?Nr~IFdrmM4=N#aO8ao2|aaQ`lyia<(N-NL$b6;=Q5MI#K*Yy%` ziYecx6!rIY_xiCu{2A&j_P;jpVC2CT$)$Z>!VA8?7s@a&?CueMM`Tguwuu3B8Ng90 z54V@Q|MV+&6|WKmR}JgyJw~s?@*i>mS6dvxsT8rFdfF_NTYWpUy*BMr?I@Dac3&Tj z*Ity;m)~ob$mts35OVKoC1kuDM1I};^ zkw_Vr%(_p$rOvzFx<&I!tGk5Px_-G*Kk4ngJ2w-4L$co33zKORiXhT^{C0V_i7q(RQ{fa-1!Esh7uXz*l# zb%IYXe5?YBpAkC4yi4meO>cLzD9+w_2#%-2eshA{ zWR|NmmcP)L2-5O)GTld@a7CXJ z$M&)K#GSuj_fKHVwc8lfT-l&k)|B2Um!G~PKI1-#Sve(T{cNXiz~;F=dwY9P(7QK8 zgeb_4`)W#%a_IBC8JAmfMMKu6E8er(9+`bMx+nhXaM&F{)%vhA+1h|B=lUuMCdxR? z+Yt@>dEwVimC%P268MLpfq_M}SwfA-$3IdWt<6MW~dpw-i^ z*(p}sFZDLkkwzNLN*YaT$829{S!7lfPm`JKB-uQD^yfE#1du?4#|@WEWD@K$HZuVP z;_e>)eeTW_!_0;#4{aXzq;P?fWcu?)maMwWefuLCO&3`O$*NyQhnI0AfOtfRJZ|G6 zQ9mym!AUBmmF^2SBL)2&CrnYWGr_aMMxCsNDx(s49^~yS=_MvahM1}DH}C|92TNL z@se}Mbv`?hOugyg0u7%e@q9a{I!BB;VaKk=%#M_i28u{Vh$Ly{rsdzFf-{nsZ+?Q5 zRqd=^W^OW$pp;8l`JS?x)Jplp5K))|>3~v_Gi8lTMq~PAhCB0Abg6mF7}kuUv;nnm~UV@R<%=iEZXXkN?>mc6fdN&+cTY{*godC**e1K0H2vTn^L6=$@w{CQiC zmeI5K%*19V(M}BG@}9J0a0C;EMcS-P>Pdg**3);_MP-0H*`XrPn^m5-ymlrwr*C6? z8S1@x;%ATt9#Y-g+3TY#amf>(_jr9a?4MG6)aBS+FRf2q^kScHk09M;tip--4ql)2 z>nv-tC*??;Do|^|v>Uj`lgO~aPcU^;$Tf6df)o-g5(B(SWJr{fLFvU*i}$P7 z)%BO(SGzBd58vF&kJ}$F)#dGvFTUXpqzQDQ@q6-dO}mNVE3Z`^$IpQH1}6Y!lR5QiyXme!DsGng6pPNOE=z1^0{nXE~cm4Ub(8*`i` z+MhtUAei)$GY;|+R-(eGh^daGBJP>xx(+*)r89cf#WX$9&sPelJjoi*;LON?0uN@< zCfzT8c*s^A)poevu=qO9G3)Yif>MX&?V*uvmE|KVK?!=p2MoFOpOZ5A=b)O!l$fC; zl_uIyFC`{y?}!L$p(tmFIgw610=tRUg^(25PN&sTSETA(^BQ>&#+-4#Z+B(ck_cG> z5;A%9vhJ+j?jK$o<4*IbvF#kLH-7~zJFVv(!;XEeYuB-_cFj7?RjWxJic&9{%6M#% zNeC|$1A;O$Wn3epch+{^Rs;=3NR5l|_u=eNrJ2&eZ5gx+DySq(CA~e5oMQAP##t(7 z0iYNF_f5;jI6Ao`gJhI7=|-o3w8=}x+${4+QR;+<&XPq%cMM^Vk26W;6`4Rik zPf(d{UmlN3W%poEY4;LTdT+1+*2$h(LK!6x*S6WEIKdnthtZTSErKmh6EQv8zYta0 z-}mE}K>AKE%1gB3(-BoRexcJUc@7FvaIFNqVutyIXo?uu3CS$zA8dHIBkyYhWXAaukLv;C`Q3Yn>22>MFISIQ!gS%_d`2N*mS-1Ng^ zJ*y3dKC4pAtZKeoLZ8nz^!XVfD6QL;kS~7E=&Sno$uONsLrhEqqfnNXrOpGRM1T^i zFqYIw7#SnO0)nfZ7*mQwDy$?@Q$I-3Pwtwtf@aK4uQwODTT)ew+$A_7cN_4l+-1rP zAiFT`Q{X)9yNgN}|9ury>ceB8NUYJC^7(XzZLR_UGHmk|fF2&~F-6g6&Vmub3DeTS z9>#VD=ZX`f{*S5pQ$dCBpC%GD|Mv9BRsPeSjp_g4aR{zBKRCD;X}#ZEgpoF>f0)J` z@DYz$7pVs_OzOwQi_j_|%cC{0$!4IwgmLM5hMpqC0;fv4ddanop<~1p=VaQz7vquu zMn`u?XIdly!Bm?=O&Sb*bYMP<>0k=C{n32o<^cW}ah(`uqaE9WQ;jj;-90gPB9+0B z!mlxEiE?0oIq6kip`GS{uZ;TWnkx4tr$_`!jF<$LP9M22scMm>QF@WV1h;afgcQ_h z9MD=WjX*?T97mQWnn1yJC%?1*l=Y#63y_xg`1N3q@9FoZOG19He4i|c0^;%Rzhejo z{9j!AONDkgkGZVi=IR1#%of&IaD+>7uW<%@4gp`U>fa~BSk5q>Djnvk(ze6D6h`=m z&4Z0RXCWC;Fd{11>k&5d-tV&;Q~`&2+6GVqVZkraxE!TH#0IIZTdacea;jwh0ZHa( zz%R9)Rr{%6c~OV`lX`gZM36d62&Y`rM5wL_O{2Bo%q3m4P%R#w2NhPwusPpxe+B|L zYK;%5+3yv_I=OkdGtXKmhCj|Tmpdw*HQ?cOc~)Ac4m$U zLL*5e8BUzbDJv8rI)+3Q7zflks_`-tb3AYSb`r;soV_dy9wdePc~Z|DCpdN(qA|NLXsAv?%`ih| z0ZrhqOSDEPt=z0Q{#4+^>UKMkAT1E&+}uWaH6nJ__jV0a+HJHk3Q-kOaL6-vKOPmRgohZ(a2-JXYm?G|4KK89jauY5r(-4H7#Hk7@jgffRgGVg^ zo5U0w)!vUxiU`&93i^8q)-~H;UFTp;-f%-~7L)2=X}?bl}clW`GVL zzp6m9(3)A~UH z)R>Tz87(0(N`9l$A#DyWK(iXSfzUL#!H79!`4L%o0~qwI9_rE;rvA``JZrAje*^-a z9UgY#omrQ<;m)j!-DqdyL)d4M3ueTI8~nY|@u)Ckm6|iF>99z{@RQz^ z`ld9vs8?av0kEY5Ye1%g(}OY5F+UfuCC7L-Z}2Z~odj^CXn2KEQk#>6#EjW=-5%i; z@`@YgHK!yG1-Afg1+jn`OmU{ubEuwldz?p()&vunRGc81;V5u0u_{Fb7zDH9NP`)t z1ac@ywe|_3aW_1xzk<_RSlfOQSm6Ot45bnGLMKMI%&?bdjpoq}#;IUOUZ7AWbYVYC zs=;_ZS)(ICIhcc>DsAcfa}WZzj#PvcRGB9Ul@7J$~+@7;u<^4sy(a3XYK-u!hSBl{t7=1TZ3$ zAfqTLOGAuDk`wYz_QeB}3Q3Ns<=Eo`jF=<^i}%WNYmJlH&F&FOY?u`jQ#P&*lW^1S zp%%=S&Fc9+_oy9tC~Au?!v7Iw6m6=b)r?xA1BC@Akl(60UC(%rfipKTP>Ge~fSo92 zVW6A|Nr0pqgM9}A_J^6A#Ud>n(J~V4tTVJfB#i_&hdJ$9^JBA;6nrbN;gS% zz{46~h=7^(lERk>E=gjabrP!yN}Y6=*O@`%GTxo%9z=}Nk7QcBz5#w9S?Xkj-G5{~ zdr$SkL_@(O8)pek1!2^oZv@*JZ%&WK2uWTIb|4{Xih1hg%uNzf0NUC5bML}y zqxC5zDn=7nr0B1#up+}r-wkEEI4^q%+s^mdT=C%M5eY8CQIFs<Vj80;8`CHR12cngtOXtvN{1_MPU~lw8)P9H zOhYzEi|VM0Nz=c>B-32D!0hZNT~N>TqDxaB9V#HnA?ro7jxi2hSDxa){HM=ln{M}Snn!SUs_;b7**T5HOaXxe5UhBH&1Hc|C>CIRtgP_0S($nRX@ft|dz$lfVOX=izFR+6EIuSP z?od(8KEJu&8-Jmz_q%OzTC|n0PrLPRZ>GmfC5tPGQTOuQ+iqtzpF+mk&#mr@P2Vo> zefRLX|Gp~{-&f7|fh{S?iL31GG(-)$HRi+>*dIf0n9Yjge?H-gd){sz;kEYs^ZEAs z^Aoh%9=CU^$MS=-+9b!$xYQ+eG0Nh_)=KN>c9>I1sZyxBF824lJZ#EtA*@LK&bmur zyV)3#Xr_#7jQV62&zrldnzdS9A{--%EZ&&W<;?M7b6Xa0`?wE$M{I@9oX>9CHx{M& zRna|6y9TQHa9<9B?Nd|~-|RKeyNx>VcyBgtoj)&+C?y0prPd)5@a~INqi{M{}58Fc6g`V{euT4bpxfOIG;lbR-C9A1Guiua z=6N!0+%EFO{hdnrok&IQ)@yOE(V9{9olC7n5&UcwJ#qIJ-B1tr6WvWo^O3#oL3)tv z71WZw7ZssqP8)3AHa5;0O0!xm8{>o+BXycGCYNVj&*>J(Au zHITktm2C}PVK@S`#=Gs?-u%Q7X3p7jf3znQb1m%i>%naf6?`{}Q5#dURd)ByRpFFi zD*f&X58J}Z=RW=I?d1>Pv|O0YoSUy3GaPW~y5tVtzO3)u;>xQ}>s>+HXx(Jp1CkM| zdx5w4km@j=3J+iEyNK)g3ov>U`{)KDt+>5(L$exK+h3dpu73Y*5I$qjys{(y%gO~sG)0oHaSC)(er{`e}YNYIp)AbTmh&y>34tO?|#GFz)M`m}U zJh_U6UCZf+D%Kpd*x2@;u*qWzy>q{%57_>F`{=P3jXi}&+{WE42-v6Qx{YVH>;@t% zcJ}CTS_cV^vA6M*eKcGZGo-iooHpf+eHAR z?atnH`(hviprZ&#q`VKtfF3{6l?kJCpB)6TxkQ$U;iE-h&0kgh$n)NFtN6HhXrx2m`eq2pE31`Ni3`1F0Z z-W#d7(j03ly1Rv0S&$lEJylq?%#Rxp$Q*n?D{fILrBgej8*yTaK@ypxp`SA_t1G8XD zr~2B8OOTNg&X_kH?(Kv64yq*K5>wrE!T|fB?c_}b){NU&SUqE?Mjf{1aQVHQE2lnJ zF4Fltq;veF?hN)E4m~GVCdlZxw@g(gICNaA9FFspiG{&969(gAg}c6x4SSZmW$^S+ z?;JK5)7XLRCFE*y&!%GQ(whux%&^TWT<><<9jJZ64z?}bP%x&j!qSh#>_ad8S8BnL zsygrWHYKc(o?bqUjv6M*r*>44Ve%1_ztTHC6^VN*7HauI9G@wP}2Pvh%7LTW)xy=@tBXcCiz zNh4(t^;URXF*1&^%--^gtgr$VEx{B^X2u|W%Lf7)%uU>7iIKBA-SIoZ?~Dv1gsNybFk8?!(dH?Wlo|2qrGCB|?$~t+*QD(^*<_g)GQLOKUmgap*IoTmwD06oh zMpsxCJp?*-hcvk?g=LtKJm-VvrD;A13d`}Mik)7QaCxbNGzo#iiP%mUxNQJ06+`bF z>^B>6`7^>rBkqZtKowSu+k&T^ADU3Jbcteq$RgnNhmkB8G@(Fgu+Q(}liPV}SZD=I zD7`U?kEU93ji_+K9yo1C543>F+$&}i=9nQa5(6(_go?c5NH8-!kXad7-Epiy3<5J2 zET(ZO_fGJh4#H;1+0pEqHDxYQTkAhyDxypg5{a{rs~|2q;0b||^E2uM_0>za)XhdG zBO?>UrR)(d?tJ*5!9(wH@z$)JW0vUW%oq9DlC6#psg7{&p;&XEf^|;mq@zzH0kv7z z-RS_OAp#Qp6k8nn1*5N&ePv>w=*MGFbri*V@5WjyCH)>E$j!VJPkdxK-IpD7<@*Gy zoaIp7TRW~NF?XFe8!NL#N@Rnnb&Mr$bWhHSqkhKndgJ0CsYD>LH)pA-iP~v}$|hQi z4A82*Nt0TMk({cv5-J7H09B$U>OUZd(}|aD$V(p{e8iJ3{A_bdhZ@_fhpsHHptt za=9z4)AFu^+#9Q~v@x}FkH5U9r5;aDfPTo#&atrFxXZiVHftksUsvD8%DbMCYhI#~ z5tBETDFsteO766h;S*n{yut@w3aZkk-Lxs?JtJMGx+e%6=8T1q*Vw03!D~($6)Z58 zQlz!XjLL06ARA{=KCS+;-Q9Lq1eV&{mnE}Ym?Mg|?wC;L4eFKN4Br98xY^mHCI|@p zab4%{miT1NY<;pU4OSNKmm+I7WCyC#Q~$o&eR+KN_60DcJj0eXFx$183A(vDA0I+F zHb*5tcG`(~%So}_3B*zv!&d7|&cdqk(6)BU)Ha8?K=*C-u&_Oc>TFp zIyXPJPwQ*2#Oj8-?dJQ#54*7H;{ED%b$wU|_T|UzkC*E5_DAb7v{p!A#f+>AuPL+4 zke+6%t;h*RtD{;lo4XUS#d1QJGNLMAuBP47yS=N{wqm093=aQpRBbZW)&rU5y+-x~ zLph3@F6wQ?Om8lj?F1Vr%xSv|As}7s3Iu=U=quBE2*KMWkafB;AUm$PUaNJ>GVL^^ zWzkNR86NAjM=TvyV4nTCXK~j7W9=m7)qdtqpHVnEGkwO|ekN8(CG2PQjaGa*JYnNM zl($OmQRPY-bEjNz$pv_mK-o;bSrwCSXvJuk%$1Ainpu;BRa&x_lgOh#X3kMT$pe0 zyGLifVa+hNJqW6M67^UmI6!!~H0Il4+8SiqN;;5oAte)u){|4Rx`-me;r92ZUNMCv zVly?QSR6Z1u;&x)ErddrzX{A8SvEQ@m^R&z#)KT-gj$%cH0D#=380n#eJ_^Fw<7ePBY#SPrVe^%9_o#3&r)d73J-pGpG@A^ykWJyuu)p{n~egh5;|br~k<)^RmRE3Cor z=wTl@-DD8c0m2Ify8R=kRk`%QLe5|($3D%;q?R~Vb!D#V-zRh3aYLDn=(;n)HuhnH z8s^H{#+t>+1I1fT}DW()VZ^}V*K}9TbYRH3u4*;!W^-O|@ohZFt zh?s`M?|Km6{SM8)5)wgxYxPv3Zmx&J5dM7r{QddK%oeM^4vKtr%h&7Y?e_8d{r%l; zc+QXYmOcPA-1)P&+M0tYHDYG~R;Y?VIs_%s7Nb)zfc0M<@h}2^M?1@p^`CxbajZC} z1N>ApW1LDC`<<*O&k*bHKN-Ps8G?=t#rmnhO5wyv8DMOSp*S#34gk^)m{CCgiUK#y z*qdWo=y!A?#?dJbDSlT-ie%158|D|JumeLte|I`-E|Fl6Lvscppa^g$1rUd92(g4jE8b3F9J1N-I#IEhz@-Rj{>WHRe)Ds3P7z@LWj`o64=RJNsJw`p$k)I)o z#|45pQ7YYy{}|hD&c3*h&44)9x(Lj`6JjYuLo8ouZ!wHrs61Y#k4qhu52zJ2U6b%IlaTW=<1;;+AR|keY#kWhXJQEM7d`caQGH zLz&VNQt4BBtZ-(BtRctjw-4>ba~_txya>fa0?`fn`p8hKX=3#1^ABD!ebnsAoT;ex znWkz3mO>c1Wn9OY(T%4`jwl&(%CbExt>zYK94ki2yaUb|s>_KL%Ok7R z#w~`a*L}tLKFVSXPaS(i!+}a@EKo^h1ngAvkP*II0{2;Tzp#%@+e@X){7~#b9&eB4 z%idlcm+N`~-+%nf&U4OH+_uavej?Yy>ChvkZEoEf%NBA~|2`GOpxm%sBYJhX>uEyv z{V}G~pCa@7Fx}cK{vur}`mLv9W#7rkUk-Yk2J=O)-tHe>^CL1uA6w4pS?`?fIejv! ziFa&rENQW6m@$8Ys{4>|3|I<qML+7&bOSqGA!kB;%nH<>AJCTpSyE+dJ zj0TG^MPv}i2xB8T6%@qt{J10wg~|Kw^Kwp9)U4PcPOs(jqYOz>KQ08OjF}kJFe8y5 zr`(ED;y^MeK<>do5piZV;|L7W`ULykb1FI;x+i!+zx=ilq>Lg&D6sZgP?=Q05o|)5 zA%ZZoMN<=TO>t>7worasFe+Fxj%84==2H_B>~Q@s;{J$Wt>>M9VD`0cJTUueHyl`V zb;58H-zJrB$+E5IK#xOD zIhbyGb3qomM-K@T=yn&ozCcj=gA!Yu!CoSK7L&n^@OcKhf_4To2m237;iDYDk_8lH zfs@y?LaOW}+5N5(T%dISwNNDkCUn@Tnt$&z%vu zXalJ<*93jxBXURG@D!7BN0*q-*V#*Yo~+Y;>*-kBQIDpYVsY){M|X7FA)0DLH^PJn zGp;rR!>1#)U78#PIe}+`*-o6+VU`k!C!8?<|C@iGXJP{)q8lWjlsf<_(PogGQ z210Y*f;Q7eZVl{`n4&XXLGuayd;8)(>NdDswYnh+G~1Iw}vPTGYM^Y z<@*G>S9a-x5tiOFY-Ou0Y#z%FNM3}9isSl(SgW{>h0yU{xw8N2V>JKho*&6}f7`DQ z>h^JbOJ`0!|DfI^&R{RTA_ZJCX)05h^M7@GUcqCCf z8&(=JFmCMZv*nIY8N_S}C_bcdBe^*Qm(OHr;w8yKw4xYUnQCc1fvK|rEsBvjsta0> zNu$+`=J^T~798#vI(CxavZuG56Dg$TbVv?lV(LVx5T{4TW`Y((S~wzh7wxPwM97jx zf?`ZG5GFoGob)|66eGLrnKuqwHy~9ZqdIZL!%Pa#+36=VhsL*!RFOi`4+C~IQAOO)qzYzqZ_c<~SQ7LsRF7~@ z%>X0)f7Kovp#Y!EG`tOv`1UfUPC~G&#Wu@}8u$yom zVl2C%&fG}O3DD0oT-Ig8D{opfJo?!DVuH>WvkG*3Ql`zZ61$Ebp|l5Vb?A$W2cGJ| zzN&wpEZ~|EH#(lPSTb;v(UO5Lo-6xq&h=cOMl=XAn(s;{+XU|EyW+Rj zE(Ce+Hy2_4Yy8|Xc6{QhThdZbmCujZj|)M*sYj0<3>g1XPw5P6<{oILW|g;WWK3#F zG!)Jv#ne}5-w4k%Y{vw~#UzWWWE>Z9Zt^OblKKX`g*qo_0{>h zGe{(r-~o%S*(VD}7wMXGgDpORN5kT&aK@ae9L;SYy>H{!P5pie>6|BL!Ufk!C|bf) zp8orjw>Cec1Xj%}ZWzf;Ype(#mFI>9!3vSlBR6!1{mN593}iCOj*yhva8V3o!k8jV zq$>{(C==1CC=-&r3rSg!OPwbZTZl-q=S)Q@wnNbzE7#o*PXjYtL!C5Pu!5+&)q)!ftx-wVw?^EG7e`h)2 zVEGUK(i^{F`bKJ+j^7kJp$pR_KsYEZ8*Hn58?G#_6gxCgh3xLm%H4W@X0OzAO}lQ} zg<=4RqFOvsZl8);F#{B0LTT+6iPaulwqFQyG*#SkmniG^X&;+|3PM=7_VrM&|N6?h ztL?rp86CF9FXr=?m;03^1Zo`+Bg&AX*lf97tz&DJ{_XSjVe`6|(Zi+K{N>L0RD=l< zO9!Obsgh&`1NARb{xsH)G?#xJufX<`uWw zPcL@=GNsr(hXj!IYaX|&cJ98EGb~Tqipzqn%`l$1$~v9%jl04je=+^I+;=alD2+N=zwM_ZdT9t zmJVSB1}L2J%iF#HH%CGc_?*=D{a%)r=T{SatN2S*)gGRhj}MPrn`QC(;VqI#(ROm`rHgB**gJjK%Yy2g$WRMwp7DJ5Xg z2yka?9%Mo=#@q*?L7Y!O)+LmR_nV6frNWE`J0#aAV}yz&l*(LYVp^`zB9sAiA_PM% zBMIC&Z77MHRF_C|p>iXcB*mvC7%P@KKgJFc(j5e0j+vqM962%zp+xA+yroG|xiLpN zvDlPcvpI7kCwMrMTB$^le)MoX?KmuEoS?08+?>Ka<0)kw86vScrcfrMQ8}1^GP^cw zL@7yt(D%k|5)IV9sII`q~v5`r-+ZebI3(A3S#=O{?*&b4U7LyP)ux5=Gw zu@J{17UH-{W64za>rmul`{qd00YV5@$O#|di#l-V3E@ceR#0|@%)||+xom7qDuBzbXBghpbXE{gv&vaf`oYU)7Ah4Z;Hm;)0`R*HcQZXHQ6 z*b6#Ji0o2gW9gsw&vhN)>%RTW|I&wMx`R%tbYDxw~$w1_74a(7%wM94tA;;mx4MN#Y}*#97IkOss5nc z&6A^FQzRxGci^&6Vuce^*FszYETOrbg}PHA5hJ``DwOdPS{&NOvETy}4og&eh-d5> zRjy;?^v5x^tMel_C5bV@kPu41sU$$@*nW~w0c9qM4pV?vciD2gkCZ-RUL7HVBQ+pL z86lDq)sq(%)GNJQioj{05f8FRXUw2JuTqs@eY~xz+sxJ{(87!<=|l_m+sA8sTM1g^ zRIyFkl`|eM#+X|{d%XhuFtE6A98w~XTbi?EBMJn3Bytz5Y99$MDG!0R$5o)LK-=y7 zo<&Aa$TrqSNy_UM8UW9Znt@ZN?c6`v+;L)*VpbSJ5I-4(zY*y64}nt5lYWqgQuN@I zID(7N%_2%dHX?+cpR9!av$M=UH-D0Xs_p8^{bz>2;EWCpi=Wbm3J_la?7zwp7p@d?S#Sp7oKS4_TA9HDQADR4*4%N-y@ zOvV@kKm>noXCI6(U0U`fkkF9o%rcPBSb4dr#1yLp)FUk~cXDxoRXR9@HZ-LYbA9^* z74==j!C~)9jGH}ZJnsM^6GWS6G2@ujl4vN(MFzvhQ6@t#Zt<21{+R1lex1%0V^}ka z()d{8as40;76{GfFt8-!7*U$mk4a?7qD01M8n0|xPFDt}@PvV1YT_3wESU<3&XhtD zEMRt{l4b>INm{RrfCK>ssg)GQq$KJELEpB~^p~qMD zL;WMUoTq2>I7na+u>^d}-EP0Cf1e7!`SYY+vC{zF0yAgYW?0c9ln)^}ql)WX>ZjD^ zm|@$JuiNBDOPYE^FBLT0uK!U={IGuUxF|-Z-o8pZ-w)(-#BHn{GAmCD#D%4d>~{$! z_to3|!)s%6Z$33f_rvw(uYlRT^}J(ux36^#@AlQM<-NI@jOSoG_ri%?z$4NA4xO7R z91|Xlih9f_g)9Zl8rK||^Rp}HgR?xXVLh9*IKS6dPwo6Z<;=Y#xFWb#LRSBXxxJ8N z1TiM~T~H)O=5skVDPvC)zmo^$&D?aJc=}{`0lI5GkbQ)Yc#Cb|v|TnL1G_ zglltNtS=e07~A?XLZ%6fi3VKR!5&L^Zr*_y!ie4JSL(_AZHI`d4Ae&xg?S?A(*>L; z)f`fY(;~?WCWKLz$BzghwU)}!EZ}k{KsHkV8iX}XjJA-Mxqx$OMl%tP95)`5 z{^=tJDym)Gvh~R_6NLh^+s30X;k3ST zu){Q0dz;edYZzaga26+=vva~ZzSHnk{rhAfj_ZUo2*gnc$3dI~q=qt})4#uz$+w-6 zgb6Pwq;&6+jkk8TqwkZ(hiDKn=&w>3@M7;5Fg)n>k?0MlIEKQF;fIP|a0f_Q=s(4Wc!e^I1h4Db@We|Y)z zwzUW@otM7%ys+q9E)sYGxlkQCI(fc9y(zFR;1zMmO|I|I)?WSbVO20d&Zw?8}!0P66vM~#LCc4zf{VrQCZw)z7a>-BE8-9b}mKhAB_ZgahCI^?nREY#>^QcQ%Ex^xMj<9HI*gKKq0(- z8C!U@d1`a$;^0BZMZSGFH9*Ab&f$mc`wFo5d4lv=&+dN9e_<8YsmFt_YXEkRJ_f?= z?G%ar=G_AZ;O0rKsbBPLE5bw9TKI71FV9;RjJCIVgzZNI8%IQ^D&`cZQ2EaDm}%%8 ziGdN9c!#+L(7@1sh`=ZxJTT(vW$s_bmAQf@aKjVAsDQB-3*GWznVJSX zTUq%iM-D#ssiHs-dIeHPO8L4Q%4-_aC+4+bn8K!yX0xMzjm!Sg9K#4nM&%SC#gtZ%-Y62%qqY5qu(sI zu~b7*bzI7_6;Vo^*Q6iCT8dtZo_EmKn8Fy_kr`WhAVyXev$h_n{5Cny*|2r|lMb{3 z9RGav5~gO-`|{w~5TPDt!y_p1&QYYtX*7Hcbx&dT8SA8{(aBGc{aOc~e}he&(`oby z`g=a%6mCc6SacOL5E%A!n-(dGEFeZ*$7*t$SpjTWp#De~!ploWEC?E=Y$70%^gK7I5tR0J}ND&nYqF{tQ zK5;DOBMK%Z9n8TIAa&oaf}>>Z+*r6&j4DaE#8wQG+PBJMe8U_QCWUaa zt<+~5ssq%!%Ik_yfskgh%cUqh&)=YP9ay7Qog^|vF~R!Ww4|!7zmi2TfYLeLt*Oy7*1J8=+;IkY+dV(NL7eIPb?Llb8*d0Q zBANSq?oQVSVdZJb>^ukeyIJZO3ryBSah#7XF*-~x;{?XNAm$X9pqusU`*!zhP^2e` z@46rlZ1%Xd7puG7d;MhYciSQo4{)X4mj&ZUV?<+OjCv+SkI8E3GUv#$B(zd2~(+qm*+G1<+*WVdVxmtwI@*v95-PfF1~ z9fJ}V&TD!or0dNKv)8Jt0Up#jDkM<~*@lDxIx8buaH^OJxXwdbX{%0L3Bnw1SrZ~p z5Je>yc7Va8N{1EG)5|Fbo*P+C^>YLhNMdVQy_oT8J#$l~0J(X2dwN=Rjj2`=lH2;0 zr1|biEmD`^H3KTgv{t96C^EuX*A9U{oLB~XRt~juJG{L5*1_MlPv0Kaz=gNXubb`r zCO!)ni`m>PW@jWgm*df)W`nOb)o{tP5$Y8T;TW^yieQ!_c2ySbTs-PAJ^ zQmZ+cfs#|645ajEk`5qZgc<{r4wqXrm3dV8#CG*>3-jS7tgA0zBQSFmDCnvp!A|f%dNk+mHVrr`? zPD{tp%3Wa&!WeW*>twCq0&xkY)tEN1$LL8rl9JkRAyuIjrAfe1)2}3?oxw~YnVNBD zyu2dq94pMsG$>m(nD2zjglRKwmJ&#t9X~}-MuGk@n}yUo-$ZsmTiS31+(+;ea8ToPYyiK}1!n$SaljT@6ViNIE z*L4jAEw5HbBE&O^7f)sB&9Q9aB9cu!kVM;NmK`aFb}Ump!9+@|tXIV{)ia8SV(z|p z=y;5AxTmX3^+sD|A{5o|88-GgIkuXMz0sz{2YGTII+qP{RE4FQW#oBq^uj;Q|bsx`@yC$waT5n?)_Xwggv#db8#YTI`EqT!E z#~ecNL)FXp0`S_^aMi zA~@;=Ti)?!dNQXX2c7k4_W)3W9uYDd<}zq1FRZXoH8$F4fkRIpjR{vL6cC0bv|llp zG%<6Z1C0+x?$}C&Cgpdif3bIt8YK0li;W}0-+0dYoU;=>g@`;1XQiOdJsw$&IRId^ zG?s{w0}vIn{vjJ1<9TAhITRubo2_I}$Cgaz9C%gAe7DMEy^%x7Y$)c;NDw$0k`M=1 z*9rj|X$66OQ#hz$2|5qi2!WOSmkdR&-3x&Mc6#A{?}4NckP%6(q{YC6Y&ZhYQHoV| zt5}Hx5p%@U!Ah*`+aN`TA~RKE(af15_|UQJgEB`@c78Gj&Z5*?iK$E=DKN?^6Rd?# zGkuL2A-AJ+nREVQa@x(17QY_lF}`Ydg1MlVgFzoP+0pM+9 z$oKb+2sp;wQ_J9#9<^Z~uLw zSZf?ZOH|s~;aUMahFH3a?OfmGyGF>ts$rB3!7yD9h`S5-fKW7!bNSCBi1v#?iT-aP9}Y9zfx(eR6>5g^LQC7B0!GeyFp zK$riZK%&D;2Pzzb1!GyA1ChzTXavMDyxsBSGsSZL8D;_y4I|4nFZQ6#$i)BEpTJ`&Hl5(9qZBpr8$ z@N*7kJPuYqh)}Q`I2e&*rP&U_YyRFsDFc+Py{ z7aJt~#ReHMr=V|JE5y6Ox%0*ha#*311w)bkSY#lL1x>`Xu7hV``b)$AIdG=SlJnC| zgil^c|^7X_a9jh5F!j_*<^?Nj zG%JUnN<_kH5YiKeZM*xFuhqe3|@b!ko^#V1WXr$j&VylFUGoygp_dhMPyi>2Yr{27h7T%Bo!`;rht{X-x#<|ni3lbOlbIC@?LH(R$GbfPdDH&P(q;#-xCU5?P!)A zR;>19oisaDj{zL2Vh%aCxW)Yt2~(RC(6AqjJ;aA8hWNH&F_R9Boio{HYJ!RucxU{Z zZxr8|6aHB-+~Np~Lg*S#jo$P4@Pt-|e|ZC>lOzB@*D{72TLEN`IT5UdAX4xNIs4R! z=ezBqhdM`&E+jO}d!8+e(NN-lckInD+0C%nd5R3oBUWpq;83!RU7#Se#fpsYriT?J z90!$#22C11EkGhBj+95yAq&GBmZai5LrNTNu5igl3O6;F?@VVin%W(c#2L&!Pm#Vc z8rLivjjCm#)wS25BbKl{gp=Q!c%h{B08ck;QNx}5tb7V1>#}lgnP>RQP=$x*_EfEr z-mb1(8L^X7T{B~A;~+VHGmEc7OwK-<_@>6L)l4*!$w4u`N7mfSj0&|TgNSe}S)yS+e6}HTrPqd7~z1*Pi80-0WRJ-Tpo5U)j~pXnQC} zUtdLa3}%VrgbWdW!5b%oCX3)hBQY7vzxZ9d0z{qXRz-Chx9dRhr;e(7**+4)DrTmqWh!6N9Ar$7sxxEho=gy!SF#GN2 zNq9v}wrsHrKUHXTLc{p(^JAt48ojW#xDhwIw0PpN@T}G!r!@i|Aj@Q=%nMvDPRn_5KIZQ8) z09v%d2{c7(wg&55{}Ejd^8E#hFvFQGs~2!sfRmZN4&0HO_Gef^*+EXm*x$$~|Cv2y zXCQ3=ML=1U(i}r8s9nnp{f622cQ1&T^5N^b2{N)mE(rTK_jRtd$`Tdf^m4?99dGbO zdQ3aD{}M!e{8YL)Pbzpoz?Fj zU_=Y9G=M4rVg8*BorBmwLo~_e4r5931QQ8tFv2uz6NZNrC2+fG4{gIiqhI)~vK6Kc zaannCO42ckYn5s~E(icNeX@i|Mcf*9Kf_;6dvT_pp( z3i1DGI%0nDTU`9RZY@@}MjJCDH|=-9s?C&u1yHA*VZeMC)h-^?lru%2v9^>Hw^WCI zg6ddHe|_#zNZ!uYNU8kA{-@`KRV-O?oFru)FT69_Jeif|6}R*-w3oR2SpeVK%mw^y z;;}vIH$a*-$@)NdkH^aw%-`g9+DVd@zrTQa_Vi>|FhD!%pzTKOnt=J=RV#h3{GdU$`XiPyHz-P!*1So>VY9sOF(p=y?DRNMNv*lz)V zwka;)?aPnM(*8Y|47QtD^X0i+?(WF6rJO3%lAvyNc6aXfHGHHi3a`u_D?<^6M4YXR z+5GdSh3WKqY2D1Y{z%Hfx$*^Xv$KzRMVZmdZDyOCk<-qas~NXu9%%G*}( zTcrQJ_{MKVF6Ht6DsoA@79%BN*V`8jpL^9xlG`SYu9CVIO&$#`b6g$-Cn`#nC>L}w zU%d42S&iBfzuP#fx#!!mVh}6LCfX-#S^_6Tg*^5p_8yd{+`2nhCm(HnKiW_0*VrZo zu^cyh?~_t`>UnfBZ@VlXabBJ1(N+XlqtIEP5xlzQvGH!Fy?R--N4DkN!z^)`U-Pc$ z$|qVV;>@^GiEqaME+rqozi-NGM5XQW)UuZ2dY-+0!a6?oYrS_T51+qUTV6txpy+;! za@tXsZd?x5hUeOoW?%2U+h3XJq$tKmE_}n$<WMW4zxcfSAH*-?=2^z zMAy|1|Ajb!YS4Kq^klZi!@`-;BrX5we|WE+^eaTgtDw6#H}l;}fUF&YUm^M%vz`>) zvWq%>3CK>)h!K)bmLy}knVNWRJ-q*bi~5Pb=5YEV530L}&TU_O@D99peVcugwC5DK zL9EM+$^Ue|obNuGMB1dMWOMiAJ5{(gp{w}72)68W*SD8r5kxqgbCyrd2-}L@5hz9@ z#W12Kw%JJ_sD-&RNJbAEZp;wul$~5#SsKa#*UP)@yuay zKb{E%gS?Pt3KA?nLSqPA z!tm1gibZCSIwvt5If?Ze=f1+`9g)x+`@FVlvwdMU$y4RG-oU!_2Nn=q%AEdNI_fF= z&V~z6%gVq!xe_)r97T~{MZrNrpA@y-9lCS$FlN{gNk<{bam-+3gBJx!^+CnmL>e@ z#(mE0{h`&{&jOpL(sM_?JYL<)&8vRvW$9`_E|&PR;`IWy~PnoM}f zSq`!lhk8~v?e#BtL)3yCnl8{1saPl;XkkaedfbRnMAsmC+@|UlMQWv|%r` zWUOI~UO#PZY5Y>-5(pQc&LVxr5#cPYI5)ccdOzJe+rPy{0^6fb7lO(~?T!=GuJJ#fD-?3MYLF?*{r!Kc)jXnaUVi^IqYu1Ps3wrcrQBANo)p+vEY>^)rdY+H z&R`3(R477clJ+uRNw6G8HdKoLAf~vYiyQ|2+1k=A!C^Ke8LzLbgN+mic*x}$POF^b zul%VXFC@^%PR;rkny5YeI{bSTUmJ^_&a595(Cm4*nbwBH`X)p5R$^ zO91KJ)pYz0F!K-L`}ux-%GYw$Q^l+*q1A|uan>g`(bchkHzvf7V6Py}M;*s!WY5Li!t`%YSWoWw#bdm^N`NEh^7;|%bBnh9M z)<Z1Z|~1>(AG{kDHC-2Ew;{UzMJ{LU!c#*e=bL zgoNpqm_(JTM(Vhz!R}H<4!@ySw?yMPJwOFaWPfPwra89gRqz}>HTIl)a`TCO`Y&YC+g&x zHg_UZL%>hJ7`g~|K%et{!iA>qmM?=&Fq_k^{7>-pY;IY<%YfU$t`k(7+F6=CeAdeU zukWNqefqx{=SX4STZgZfeh{e|`<5;HF23Jdh${N6dR^5eeP7+PWO&a16HBceJ1Q+_ zv$CF(Q0V4w>Jr=p#+R?y;xl>_{${!PY5#p&fL%pj+s*^Joy?6O7s*uM_`pvzr#Z=J zN1RjdlPj_xizYSfbj&42&+_N-`}_O7d+C~7xBL0~_u<_cQ*z{Q9I7%^t z6JwFAh>`EPxkSbW4t1uwh!<6$=tQ@$4IRC3hYNVxf{wbJo(k<~W25F5s7V#$j(O^g zEZ60mRTPHNjm&f@v&e>l+$1aA8dBlNfGP-O!G_+~rHdph;9qp^UQJCfWXUyfJS>!s z<~`;&r9l|Tfhl?kUaC#f&W#zHWjG0(5bsU>g^z5b_pG%BH9Z zGsDkuI}q778wMSSMh6@^$g)JSg-b!hdBOX8b#>3Uh$`y$449v2B!LjfC+GFj1Yjo5 z-^8Joy$JZX$}CzrOiyWrvLf~RJaH+>&%o_@(!)!^BV3Jz3nmTp)4=&kPT03oLLv zpoM&K7~6F=BBHZS*AjX5&iz({42$`2hs*q;V~^iF;AaXcQu8y-d(ZmGK>zoD2JQHK zX$ZnEeqA6D#Ke%2R0T$#F&cNAmSV5(f&s+u-W!02Q?snd-tJ5I2Z3l+#l`m-fKtpt zcJ0B+Dkz5f<{be+vI?XLUDfsxwi?&4x=^0jUpnv&*dR3*{Ddfxw z3UM*!Pq;>r6X0v+qe8^90q`U0H+q2{*lYBVvVideN>sh%fm>F{?3=lKe7;LFp$v`d z6ju$dLb>*y`5^Lj{n$(b(}8nhhjxJEI|bbSkNWz(k>*40kPb04vkgCo`!KMI{sJbA zA;??)3xiGZdN%kGNFvTn04Dn{jUC1oNyeLeEEKyXWe0*X_aJCyj)|wDQW{{|Vyb=N z@yN9J0X=hAYwhB+rtJsVF$5zV?y|Dx4=py_aWErb2Lg%45rd)V-Q_$kQR4*eHVAL- z{o|QgeUmfH1mmI-jcK7QE3_y@w>K%6kN%+mP>GJUH)t93*nRMN^t@0sgXkd2HvZp1 z4Ch*qfEJlR3_5|Q{qJA6M2@88f;*==c11q|6=KrZ?o$_SZ{W9{Q|J_1>o!pI6f}k<>ISp9#P5w8ZtMQvsjQdTEqsP} zSn4pQ!3WC69OfllPwb}EA|QIbU3%jTlGRg@tf(4#g;(y4fvl+Vm8YK5G}~pViX{&` zF2aW^>teJH?=9lHw?%;$lb1(Wm%UUe%)E_byB9~p*Zm+a{f(~E8DuLmcForwyN z9}OfP1XiJ}JWzdmJi)&UG!hC<7h$k`p_tdnyUB7#S#oJRPjM(1$%@j5bbGM9Vb1vo z4`sO42t@hn%aXycL(hR|@a0%+2zuZowvG0Mx!}J__+e{Z&^!DO*j;AO;qgMejBkINNUXbzO%xiS@j6g;S9Do-S|9h6&WE&!3?2t@fg4%$@LmQSMMGB&0 zFpg{=fq?%j?A}7f(R;g!+?o!;)qDge7&O+jCMdu{R8PJhNm<5q?1LXgeD?A^l0L7` zJ-Z#(D9kN1x7WLwswd|nRN2V5Z76Q6OIzZ@tP7f9G(SybK=VOU;RQC3N^YO!IMkss zG|ohxdoICCYmUQA`3~loUx{umEXqaug9jIDMb95-8G}RVNJC`9lZcAMTueCR zyagjkVg^ERVm2bEh@zNj27-&`^w`2O-m+*pCByz z*KD6utFFn$-Hgw`rH}Qg)`k=S>VKExT6;fyU-eNkjfI5aw}C7h5h`Jc1mr@}nT88HVd;w*U}z z@VbkchB5zUUgrZsDprGKFAf}^j|l@{sQRaa%^K`4IcO_$EI~iq_Zc$Fov17SO4-i z%F(N+fKv=%B4??_btGvjG?OYK1!v3y1vm383)OshonQDi0eEr6<{h~7`1`GyGh->v z{EU~082Dve-~@(dW<2MVnwi+x$L06tnKjQ#JI_JwFh|;7NFpJ$Fzx6EGQJvjO#s1U zDyp6nA#mj(=ni3Gt{`ne)<|VH4VcnwGIZhLh!8L=Ma>{;`a3>&(IN>Y<5cUK-O2Kx zNm;J$MVJl=hYX$yLv0jyU(+94$86B3yzF8){<~x#)`6C+$bqH8GRp&?^n&N}6Op#@4t-~!uTD5B zcV4M4@63muZ!!-YE}t<_`R+8H%>Vq&7RmgbTQd5-!#~5qasobAO6++2E{)i6_<3&f zo7B`G-t@-9Y7DDA?sHfs)t~j(|L$uNx!-+_4e|Xy4yjDCDHp)wEE+Ka)Noo*BPYig zZbk$7kUh}hR2K7fnn4tRIVQ5&*D|u7aJrT$vP8O&&jL!rWjdUXHvqaw#o$=JTseX} zLSq#k^KZk7GI6=otJjx_$*`BZ?$hJbkLrZI^HUV%XH>_bw5vJg?$53Doq71~gGXj5 zroz5^8x%ZDzUt+y#!uj|x>O(14moSAc*e&*=4JqS?sjFuGEN^?W=Nt~60)97f3GDn zrykPL*{=z2>o9Or41hYuFn0jvc|G1-&vHm-mBF+ej+!I&5sO^vvLN8}{-NuAVBwF< ztLCwG9tuok?72?S5k5RVZX_!_tY>P<=KH_iR8G#JS+X~8E4GjG#(=okMVUlU+`mwK zlrC;A!;H{8BY|XM$CKj|B=zwMXvr$km_QQSIFC&VJzyfJUfM38DfI-j__&swL!ZQj1x!zk z?(h@z{#5xa7h94dK!=2QX4065uFVYEkg11m#nRhjPB;Vf(K={@7T_7Lpok||{W?lA zlkVzg4#w7az~mz5aGdaFj@>qDvu?>MQ7H-xKogt20_;I#E_s?>3KlxD9fk4dC1@VQ z;|zO?vXh}lQpY#KkOxfvQj6V-F;CH{|HWTq6G&{DxmO_Y zWh;r`yxYOgmShitY28QQt%mBCcHvtM&SIS94<+6Xb0#_OiGV-DpBN8u023u7w~@f2 z9ZHpg!Af0>aSoz3Wh@ClH(3sZv|guYaI7yJ2;0=KNXsxX?@53H2BnnJuJoB` z`JB0pS#YvbdU{zsDa_ZSVY}?ql-HTVLPCJz-Wr?Qc?SMCL~!4N(sGIGCnV>>KYU<4 zU7JE__I?&7Rh9Uei@z%eaRxDT|ND}6)8Lf!`)FJB#|LstmnDaD!$FA2qi*8*c@Nv} zI$j_&EwZ~)pK6b%yZ93$1RCvIaMl&1+gGj}_n>Bdk9GZgqb{!I!vtjU=%sAKG{S9j zXr`!OY2#e`sZ)msP2c=3Sf|sz$;XR*|K8|&O^`SBGP^nbYe9A1Vp1OT9>?M7UhVz5 z@AmT4+}#z}&~NjqVK;~<76^8;JTwKK%I)#2F%^Az_+{h2NN!R$Yw=bRl}lqPr>hg$ zv73PT0mw5(1IUU8Sx{~lF~1%zy%s)oe0MWy?0P!d!0UC${L&_d{{C$C{S5VK-5{B9 z3`pHRTV$a-IWZ<{^*GgCv0_&b#;^aU_6h|{2mUy%m<8=$n9r7@og3Dske|^TutACO z|BUnhSk?dD*Z#)uJh1RX=NfjreM@0cRu!EQ|B-lvQ4xcl&s6 zQi0K_!`9(Dd}gQYL&vd{$_f9d-3 zw{|T+Zii-dKh|al%Xw#FVrJ`xiI!7}qp{YqCSQ+&G}n_1=-8fF7Gm~ta*pO#p@r@; z;-7!FQI>e`+C@}=V`2f=(r(p)&8?8*x)$|$A*?-ML7LOTEmp8s?fQeLH;G@CH-{Zu z!P$tfI1b$q9jMn;yCw|Gl+5a5$x1B&VqJz6x+MB7b*Abal-CXdM&h?YM zT99q}i71FgzCr-fPOQ`)Sb-dyEpQGxs81;?V3ESw%>%Z%^Q&hq zgbSv}Yq({dqy^QWuRV|XV0NSh#R7IF1lBe~OAA`Ld6Vg^cccZH%~Rb#9romp>S&)B zYL~M(MKj*yu}>F&&HA^^OvS;ET>KBSo0KbT=2nd~Rrqtdo$JcFesi2kRgGc7^ensUqg~vO<@XUY0VlVrz}RYIhZ$->+B9 z)oQbu(Omc9sB(_~$5TnwBHz=HDZ?i1Y{KL<)Q}4NNzT?>`$jCp*|fw+tBfWVF)k6Y zAgn`a@cySF1kXt8EhKliws}k1l)c7_I0box1fGI?4IgGuwWofioSVuvL7arm3f=js zHsJ3+$>AUp;2Jt!k&?Cy+v^0z5>{1-jTi|9gb1PXDoGf1gr0>?YQ~&2JjLXf`F@~I zk0l)SC}#`3SNF6CIdi>bLb^j_S_Z#K{gM!kPN)1zU0lN_ojX<>jk=moybaicctZP- zSINx1T^CDe6Up%WNin{K}6y|9ID$f zGn`gV()A!Id|eCY21**7(nuksCq@_2@yn$EILCuxu_joMbq{O>ia=dMu09P16ny){ zo4a3aeLv{np!ZR8$~cET7Y`bz-gPXthH?=`&J+%aVI$o&7Lp3^bL+zMXSsgGC&|d( zy`U~jE7Ufu{{nuQP+Mv#X>Pkc1(j_V!I21kPPSDNAi@Yy9G?-bt~x(qobM z=XH|72o06W`QM)=3(2D&w1Kbl z4?EcG7`}nBgSNE4VrUzJ(C|l_z8#?VfIfr{`>#H+Y3Ot2>(sMaMEx%ly@`!<>Zpi1 z;dy_Qt&;=z-e9=UZgt7FF3@^>FK_!3YxA(+zfGr?;hP#n@Rh9BY+ zK-r((7w66I9^S}TR^?F&)U>-9#G)5W4D)|Y3bwT^PxVw zZDSDLY!V^duGSuFbMmlfUq;Z#8s?J#xW&`RM{RId>+tm|?__k{9#t#*@XhR8cbE!r z|L*)gTv5)OlRMDt%?DrlB{8;Zb^%yxyG!K51K%ZFquD~*%8lx8?eW_-^>=fJ#>Osm zK&wB@*pY)JOM6I7iXtGn{VuAdR9KRRd`>NG1H3XMUO4ri>|C%?Y%1Ipve8!KJ{E_b zeL>sTng^|4MNzNJcD$DO=LKi4R(?~CbHkUc7r|TMtT67n0}KYre!TM z7tm?NdK|&ow2aYC(BM2&+WcNJo9Rsf0|;b%z<=CzhYtYSg6f)#C)%)BZM|-z%#$3@ z#g> zrFemCrhfD3eD&C`q4%+0@Nlr`r7lA6p?7Qd5(;>hz1(S~3o-<)`T}JCI06rWzrHt) zWc@3ve;uv9nc+X9Id>V3$Z&&r#M-+~rl2D0o(EQT#e_c9dm@Wd!CvUL{sHs+u-=om^!IG@LK)vWAd!yQf@2JQ^L}^X9#3^ zTrE2rZ$;6iXnnKQDkN^$_LubXN)jIyPIVcs3+(`{e@+k_c{y^?6T*ZDVWkNHc(%Aa zce!S;Be!u|(Fmm7X_d9r4B{e>K_b+J<${G3;83Ety!KMD#3W7+`I?G)ht^VYK&DBG z=cjOxdrvc51R-Ew`jeUQN>;_F(>YkXC5xhY_bJd+j@~kM7F&sFXJwmaU$4D;-^sbx z#<7TCrJioa?t3GU@;%u3llK265K*iW#MWipP zjog4o{h-}-t8hz6LAEwi17w1^a7H2%M67ziEgr_w+^1_Thh|nRT5y2K zm@#rPN|6?oahs}}(_DhG$6KD@#U-hr+RiYW6WiqfD^B+7#Ml`sILiLf({0{I?TUK+ z$7JXdtqOJ+NLPBKd?`N03OnU(U5WG3$VM)_jL8bajBYD8#jC*D+t=< z^nn`(?Jaa7TD%|8OV@0pB0(WAx^>w0`(*g(TUqHegSRc58aU@!f5&Y$PEJZ@O)-?p za*4tA`%(ui%jphkV7L_?Cvj0BQZeCv^y8vZFxiR@qDiltDGK3%>i)@Amz3tp&`MQG zp$0@bx!8q;RP>Cww6i-pAkd3abMe%YHKRz0kunq9YuwhI4V`2%u97=?CfD(;*Z!+# zE7XIy)cY^&uHKA)N#1ZI;@K-Pwo+QqppnG28b#rDnh>FMn>_^rb9@1DP!v=ZCwC`k zPYP)PZQfO5<^QG{3Ogzdl6HDKxw&fF#JalcTt1Kv(p!s|N?esdxIINwyNK5Qn|!|B z0kKr}S^De_Ab*7spgtfT+x7VQZTtjQ-R!fbzZ0=R9}&HNCar^_=$Kx%Ol|@tXY`ZF zHn+@({k~7nGzub}wW)xymkpT8yt;C%c55H*k%l$H^xn>I&cE*s`_`r-cYHnHIyP$h zaJ=3o+rnfof0sFQUD98!c0J>U@!NlUcy)j4n3(kbzZ5>bgD);Kg;{g@#C^?MZtbxDT7l7F@DGtBuTGs?irnB51MhWQJ1A#1S1jE#Ke^{ca8 zcwYAEv%lm0#qFGgF8U6uw)9{d9arh%SKJ|}N}LL$A7R#IS6%0Ndt3be!yQqyLf_UI zci*bVRgPs0b0ivuKfRJt^T9~vzv#){o8GO$H8PW38p^|E(|hh1JM7x;1SHx&@r^*zG`*dWmt}}RQV;7P*`-` zCXy44g}P16VtT}lV6f)M<;#*aLwDR5TwHu1n!(w699am0l_U{RBbx@d2|Bb3IMUSi zMg4FHQG?L2aqyPtgq&+i=78F#@iLQpMqExNKU}ssg-%IbqdxHNWcM>gxi8gkm!xt0 zhI7t1mw7FN;yA?@o?AmM;9ef*(Ik}QcY1dO_xEQF3E?q>9ZF-XP(FP$Zl##}w=eEn zb@tkb=~e9HFEO@}u$6qS@oNZi|i+avwgZ|u5^!NFK4Jn-5|z`===6^}?lZ0$BaR2TwLntWF$ z|EJ#T|4+Slf$FV?Jxye5^s)_&$A+m)Z_P0U(@kr^+8~6vVg{q3XRD4)@LjL!ureV{ zIoD@UsGaeGf}ld%$J;5WJUD`Ts(=`eC>ns2e@lzn`2-2Ky4SRWQt9hEYuD9MyVH~Q z^)T{|#xd!ky_$~k5{AS5cghv}*!|HUuvqJ(qIxkT;ZN5p7vJd4Ot_1oIms*an0^Bj zY2nXo-t7f<|M~`BT~vpic-{RqGilAR@hnA?7)lg|=7pEoQ8Ve?C=ZZ5&1X;(psW@< z9p6+3$L!gsKWf2+=UiGnP1GKWrx2|u-3YAbQ#r(Rh4tP&S_;vE$$H5JHKKmP4gG>m zx<6M!Dlir&&ozU_QXH}#u!vvd5gx!rX>WxBA$8Ibd;q-G?2i~|Vi4y7&AEss-kT>a!VaQ;!38e)fpG9Ka|su0 zT+;uM^mnNtDW@f~V5pL65hsTZx)0bgFQ=FG+g3<;Ac4hIFgHjyrfZ4P6p&qKOiFw4CXd?UwVp)O_?3VE<_Kew6H#YhMmBF~YrMZ|}cDOtH4j!UaC zFk!M^<7e96$}|SPk2c2*REpf}W2^_opI#`8+@B$`HgwUuwk`~@K zmIoX^@Xg@8dtC(4iwfWwjO#-l`@nEKwQ>n|Rzdfn?PdDYGKX#^p|3&2sDpra5d9*g zUp^2vFI+DV$CsW%M;o9+UpV}E2Eb6R=eHVT0|s{!HH)`3UlPe;xkva z*>n8${MAMiwk>iKQkS>KEQR!9)V^}}2Ljgk0`GAiEA?)+X%P#I8mI>Q5bLi^bLfxx z!X6qYAvwW1hcF^uaX)H?(MlJ++4C2&iRhUM!Aav?!SI_W0;w*n4T@%O_*ulE(6kWP z6Cz2J=-@IflF1uSM64ya5#Usk*00UYI(adJ)Kc*=__@9bBmtxW<+ zXX26!LYf^=FWvW=!pW*5RM;dykb1sTtb@ppRp9g=a4C(v08dOF&cqu_v&IO8`v^lbjvS zZS)+%XXIRf7Lvr=4Q5=hq=@M*DVB}HLgUTqdwH0#nL3?Z-1+V0Dm4DYIb)+-Ef1+j zLncGe0T^b;WW_jPC%GbwWHQ<%j`eT?wsj9sR5XxuaUpITOgfL!i@@qb$}l*Z8r(pr z)|F0x@X2Z&9q`F2ex}3Q^s-s>XTifSRQl)P7b<0V`-Mv5ecH_pcANo(+8>f^d2>ivxjRk_5&hKjF})JUIQ zZdXHNX_z?@0gheZlzQT5q?J;xfMaxz_pD-wa+PP!C{7|skt7g{z#zvcyTMN~)VCO> zlr3w32lTuQb0w%L*O$^y{~hko=Zj_DBQw&l1Pz&jG|1AHV>XB=fBQHLU}~7hrD>8b zazPKyIp|NLVMqi&rjWexUU}Lmarm<(nYKFkfu)P5AP^89VsM<#Cp=k3039|^Xk9@} zbO^1beH5pBhcb)=teIHm_a2Bq=3q>gOv~qIGZ7YC#9*tN0JREJsggpDm!1?$EffNq z{&|H$pYO}&@Deu?GeN}k(Ty)r@j{$UmY~fhs-DW-6Q!%zlY=0~Ctxmo$Fga-wN=j* z*IElTovnbyz?)R*1EKyPj^oj~N|eds(zUq|wPbFoV8^}XLd*u`?0q^amV-adecr*m z?chNC-{9;bn+WbNU`~NR94@79&pLfq#WZsU6l`vPf~5-uB{!1VFe7}f!L!|HLnCmm zsss4^##KUK%M&oP-Pz^ieWNDt?r9}rLRev{{5S?P6(-??q-m=C%M_)J0g+|!Q#qTw z5sFaXsYEK%L7Ru1MI4J1D{0^{HVcKhNO7r6cAPG;K`ak^sQK;_=87T-eq^Sab?>bUrPzR)H-B`0d z**eKI1;L^;d84d65*nwenZcCj#qgPiQAjevHqTgST2n7s!(XyZ`rlddsp}$N3P%}k zDaz|#4=Znloamz%zK4o}_3!vXp)SPSI%{I8QVsKp>HCv^7Bacq;>Fs0#q?uB(GON~ z6~pDlF-2W$wLEb{%_EFOiL7W}2Mqko-hQ~5(EvDawd+g>4qIN!30v5icjqJd?qlR9 zM+Oaf&@+yj6X^NX=4<6E3IcXC4I4>!x6cTxfDkb$bdk9`xnn ztOGx;3ml~pAM1_mPeK(<&rOp-O#F8%S@n6-%&CV4CFcCXe5=eyk6#nj>9V!w^sskHZXypipqf_H z17ew?GY1%xJXGw!)HxA3%vp1cKCz>lQ-v7Grob?5C8Gn7X=pjHy&Tlc;N6u)BM6)X z$lNL&2SB-n0-8v%JGV7~IjMt(l<;MyMiEiG}amu~2p{gZ~ifmQd!VRB3e_5dGP(5~i4Yq+z-=7&qs`a17 z{Os+`N&e?xr!)0ndx(i}DYfi~#^{dV6>CPD30HV+Gqu`3z_j=Oox%F{mHT3ptP<+Z=QA(`*mSL)A1m#r!CxmvNj;$1`+uG*Bo z?^^r*rIkD8iBTM3_4UoYVUOq6nF^E`r*WdyAVZ-H5}^n_6{yy3*3e$2^K{3ON69d5 z(u-6T_Y7mFeoV+|0!OaoOA6ODm3o}nYv4=g3J5SHum#NAAq+;U>#qykr zj|XLZb-avRVxKDKb8QE$im-duPL02}c3%M6_3|yh-K9rLYh8dXl&z316CNcCIA<+I(4J?Bv@kXA77&F7`~R(jhz5_=&9eU2XU}SM=rb ztxeBVV{3vUST-`{SD~&KH2%(k-6}7lg;1%%TZR6 zl)bG5_&lS})6)me3DB3H&g4U(-thWyZ^5(EZeL$H>JIo z+K#F&kv%GVH#}3Ve<4v3DJZ}_KNAJ6=euxezgcDvA7659`*>;g(F<6+6e>`0-L~`x zGV(6Jb^pe;X~>GUd?nB@9OXV_ zd)xhQf%0SFBrl12XoD zbTne*hu_XZK6M-m-)(KlD`^`M^I?oq5 z``EG)d)EJQf9ryqppTLW)2xBhs>tjilf3nOtiAf{Xq=KbF~F!6VrYU)`^KacH26=r z0u&_BR!Teq^Z7M$@rKLcGHp_wK zBOrP8;u&l3*z|_Z8`fxraM1}N-;KzWD4B#!<(eX^N}U5{xj%DF<&~nq1Qy%eK(q|X z{QF9XUR9w&I^~Kh!cEp^tCW3Iikdysq%&vou38d-wO;JbP{!c!TE_|0%D8*O)K?Aj zIgUr)f@;YMSvFp)yQbNyITTv`MBYPPUI^WqXtjzR><~qrNO;rtvgNdm)=Z>IO{H=x zf>X5`Y8O22CPFQ@o6A{Uoa#$wA0E2K;G|5Lj!p4O2kinOeji;g4^40F4*rIFGu+$l zYT8IzHpI0lYic>kbBnD)bibZug zirk*{mk1U!ql!39gK>vZFebIWRVBkB4VUQqRv492>Q?rBEwqSpy5Gq+N7eRf5E+Q0 zP_@34D^&USYo!*`Zw?*b41+Qs#~#4b!@e<|G&f`Y9olh}(&y#ngTr}5#mi9~)_{9q z>?0DJj5tAquiUk%HN)owW#j$_BqcsFcPMIVYJVF|BXUyjM0H$9hO;AivTfvd;Wxz! zGx64Z&=ZO3wlPbSl`*%OnGMd~QMwAWaACMZIffpM8&ZfNfmBMOqv*{{D5Q*nHJo+j zLe-8=Xvn{QFUF)GCedb>Rcqi_Xl&6GK@pIBiI--{3!#N*VN;h>OZ1|5hyB|1If$0 zibY57S44>CPoPte>rx`#BfliV<$y#SoTQTb5Yqsy70U8~lyL&dZ8(su*c?Y6`isH) zxy#Z`yNGc1(P!+|0O(hE>_$?D5%(&`;B5a+qoBC$ZYj*0iSa1r42khzC6QrXV1Tfj zl=e_}gQl4H)3BLEJ$h?W^fpIsPYA=m0A+{-9VbK7LI;h_IGk9^NV_y%y8&3gO;KBq zG6|=n3UIJ4EENu!Rq6t!ad+`ulp6}S{vyLYn-26VXZ1jzQRQs3h5j4@Dda75Se{|d z^E3rGC#3{^gfHNI`)L2k@R-Z3bbnpuw<-Fh*%ptDPrwijm42-o&*H(J3jSG8o=-+M zqhPo@2U?`B1Zn1(e=?$jdYNek2J5AvJy>xws~<`VeLqiSjHe@*=jl>Fa=d_!EQ)Z~ zlpxD`_;L-4^v}BC#!A;kOadk~;~mbqHM>b6TW=9n>Jcv4Os=Qs7-Z9Cjy<| z8;7eBr#ns3{^}L`RIE!%L&fumtJ^GTO5^J1XNPOeM8z%6uU6t&?!h3Pj4hsH(Y4b> znlD+$o5pXDnqCMup-M08$>|*v@+AH3JcYoLV3ClL)AR@)6oa;*)CDZ#!Px;)eVD=5 z!LWM!bQp`z)F(|olL$-qg zxMh`$g`2RISSy8Ljgq4*(y(rYx`y;iwav?O;h@Tr&76%U3ha(V+bR;Ke6OcMFlx&w43{?{=Pq zjBc;7<^P+sc1kmK!!V#$r5cy6!7S;*^#C^tXS6XxswqGp=J@{rqd;80V+42Hwqsne z`}va;ipWfzN)QX>wt?L2YwvT@KxQLm&D9w}9+ReY_!P)FYeLw1*<$^6)cVTvcKiIY zy06Na-QNawTEy{9N?p;*XU#Z#bw*1!ndxVtEvM#7H8o!zmwLNwQg!&mMj|Y@LP#(` zuQK0SB`dshmp;-F#_2NdPG=F^xK(F&%v-!g@EkkkQyR5<+M*%pw3m52>1+j!zcV8+ z#UUXi?QS;8B$o&( zmDILqamuC003@Mf%hh)=#A54ToI@PAJSZnFoe~q6GHS1X2&6zvODqV=;}%@R`D2I| zkx%KeH=bZZ09-vZg-naDPVEX7r6jxqvb$tAFprnO)vfdHHf9@)cbEw$~M z+cGcpjxcanl2JQh_Rs9>s4zl;bE^v4Vr-nDQ-)hlGa{gqWdrT!?D}b~jfNXzdOpPY{{82j;Be^ zRO159B^)ES!MI5v!$6XLQD)YX59CZvRL|5brtjl|&1rRMK>iF`GtgvW~mSSS-(q+?ec&k>%36T4w z4{ALrJR00RSO0;l|GHe< z;NS85DpI^E6o<}oBrp!`iqS(bJDvc9#q7j+g|BLXulhI0h5vWT5s zTI~v$t#5{{=@~XQ1+g5&bAO#wEQbq5Z6DGeSPo;j>-J|Dc0dns1Cy-nVWBiO&DGv0 z(M5tZ@ck#mxjgg!xdUG2Rob!*tbOR(S2y+Nxv-m^ktS__*#BF9>;~Uy#-ExdZTXfn z(zrdnTP ze%USoAPU(^*DV8nL(GsRyX zZodt69%wY^3f8kp|7(Y&6-|XTg@48q=cLjphFL<^dA1 zwAiuFWfdqi_}6az?z;9<%Q*MT7cFyJ%7|NNEP9taWUco5Qisqw3Coyc9;ywO$?Q&c z3+?66*qR>LEzrVoJ5E z<)faz)_R(EJnxndtEa=u%Wtg>ZPxoA;B*(0-OROd?Qyfef7xz-7I36_@z=6g!F$bv z?~nVYmRC=)Yq$+E7V?&TscYt79z_qqdz)%{E1 zb%IQX{bIh_H|m>+aZB+#G>JJ2czZ7{Va@V&=i0MrpXZs$n&&4ke~e9Dcz^OTP$`{x z$w84lpxnB#T0O}J`hXz(g*pE8U<$|Tf?%qt)czoOwUw^IaRC# zwMc!_&s^#U`Bh4>L0ffz9T8eaM|XCi&AM|0yHEPX8_x^ff>AELTBt(J1|7{Qk2L(g z@^r-g80-rYHDl{-F0A^V#qRf(Rh!d09Q%-mBaPti51p6ASO(kqMhzIIWTa(zkx{~# zew@fWci0?D4($IiGVA5)Y^-WZJZt%N3!mAY;nbmi3hY_V%O3jB5qXhDnINpu#c*ZcwD9$8BT-x=F`wg9D7^6E( zF_lztrP3UNYfapmisfI=_Z0@8%Tl?EDb6_66c97c5b?I^p2v2(`JBnSJQW$qicfEw z%SznK?l@vZ3k>zAWuY$}6Kab`@czmKtm(QjM)z@Vu${-H7d?)Y^)6cEg6}_p)H+95 zZ*1JOBkO$v=HJkjKFq&$D!V%;AQfPJ>RnO+p;jDuLwIpfVVb%bYd|U>SV$o=lO8ov z0pUnk>5vVnKx)Coqpo_S0Jsgh|V3z?KU9_cv03ImV7uaOM5L{b%9*9*an#(hb;) zuQ0}3Y$>x5_1?z@>_rw%ZxEKCBm=f@ZtRc5G`2gF?hi1QTS#uS{d^uMK|fHVH;B>? z14_c2uKWtPe{THh%5~<(btbjoyAl-@-ahSCc}omq%0$+MeseG71EhFV4-v#Olu>0t*;*3-Ewi;Q zfTW#Eu8BxSnDN}?+_}LWnE?jSJEKVgJ#+TTpV+pV5BG-8QxFsp?RHOHJ#r?Xh)T6v z_sFt*7J*HWWApy7dwV$mZ`3re2>Y(>qBzs?gPBq1IN{DYsP7;$54KhMe^Yw|ppmAM z4q+Kam|GY~y`>~)9UnuFY;cvyt}@wGCi^5FV&|79#zx{h@`Qb+t|#H#C!vSA#6jR9 z&eS<QRow!Ycnd9m8;smTQ0(gn(tmVOD(urkqCJ@}ui_p%ff=8AA( z#-FZsyX_8?n|9kgJC|1|Dia(zyG1#nN=jj+or!s=dn5u$Eok780p!mj;&d)fkn-j1 zEbA~SqS)g!zih*2xyOk(Di@S7lKWq{Pd{QP!&neEzy}`XnB&+qo!q_Sn6IkO`RPKE z>hr-Q6|XAx(Svnns`|tk9ot^$mM9iubUZ)1ni|1#PoAX8lw|jMsan%?SEWw4+aF$E zmt8xqQ6uCYxTT+|*HuHlYTx#xJ#04a>?pv``*#;x`{(xc`x<)Wu=%;!{(^F|)P_N2 z+7z2~g!#2Ahr2Ki_sMki4{eN$;BcSPdE_uMSV$O(Wj&Y+U}~TCMXbbN4pOyaY~wPC zRfPk=I2PeZAt~)}ktW$#Uc@L*A52VgUtv~UV8kh=%AIho37Gj8yLWkR=0dB&vQuQE zH>*fVDmw+Wo-eEN@sT7}F(v68U6bfRxTjP;=EhO4tir)6M#g~%!`_I@%XEN31j>?B z(DW4Ub-W*NcWGEe*W;;Px+l%a?q2@RD{(=T)7FRdury(~f7`ALrgZ!DujTIR%li9Q zpb@{9gJmNOc-%j(ib%4?OlrT+F;vJq#`a_^`lMKpuP(!hUE%FXb_sLQ9qY!5enbB1ou}G|N zTNd&D7xUVWvakrvRBS}f!|UVAx+G7U2JOBU73{tqsruLN>rLzH;>*M0>+1cXeaG?7 zyWg)bi!XUaz`GyY*VO`SvARL;@~8E)*;sY)arwSnG^QEr^2_#lUtQilw=Nqew5lDb zi0tO82CMgU>K&A9B~v+D!RQ;)n;+e2W#B(RVUERcPyEPtm)@rPZC1R;~o+j0p+Pah@VhH8M z6phP)T8=E!Dh?5zT8@aI*fRoFYkYIJV$MYlHx67q~65NL=JGgtU?ESoacmP?Oi<;KME6E^3 zgmXqjaAbPQ;KQ>hgQJ_~6jD4~A=k6EU^bn0&yi4sNR?&rC(n_;sM9LN7#Agx;Z|q2 z_6}CypWF!wc}G+(#~e{9d0f5avlIqTYA|N*l7<{xteql7Nfy^;QqAuCL@9>jW}#i7 zoG`(eEg39gt8k~h_jQ@OUXHk&P>pwppOgbGVlN2SvW^*xUEFl?qU_y%bIKStljwpS z+y9E|S6nX+o7|xOUcmsV4W5IjT2H<@ID=Dd?2M}K@*Vce@PS7emr7U(kn4^w|8_Lc zZbFGHFS=m&%AS9?r%%iE%V7tn^MxjJ|I5YLBSs7hWKkm>XN17zzQ-jvSwEdyFK&0x zOaYdQ;-0v@K~<)x%}-7_Z&BwbY9{aBA7H`3Kb!sc7C7-~i5DjAa@>|FxSqd0=3bZKD`2`p z7^BRtIkafmt_Wh@O;VfIkjm{-%*twBn${T46hqkOyA4{0b7{7*4cA{9%W!kG{=;Jx zK0a*OgpEsGi?DIAYY(n38c@jmZ112c7B)6Uo2%wKHzdCyk!G?!+LEo}15xH| zWL)%^v#~@R@z{Fq)ihDUJH?bc&PXHMtkaCR%}&3XaGSe7q6v30BQ2yVADfDlK?1ul ze)oD=i^qIB#6XHOij|aO8%Q-9MR_5PVFuFCX4ZNxXz?y7C8Ig@3m>|m#oODQcir8l z+kpz9R76n9hp2?PZ9OB*G~wHW0tQyJG#{nVV~dzb7dVq z)1P)|LBMcU8imtxdq&~AwEikg^;r?XthS_AO0@i$S#-xQO*@8m<9MR+Wz20L&F^y# z`J73@#!hPko$@{Ne$A3l?vqdJ>;5UTB>XjYmV_8cC&gDELVIvrt!M|NQ_*3}Gh#)C zHs<7CzkYqm@rpP%=l~kTS(ckN+*nYCx}K0OEQnyKjG7^f1`5(NPtT0-6tAzq3VY=B zsLKtC4Ps;hNI7Iw-MRSkb5TGT#v>kYYn)-lx~JX)>ySiPMp<4=13L>BXtGqbPd-(c6?}1T?IGR))rZkrJZ+0YZFG-krbM?Q||5!O3!) z-DbP-nk}Mqvt}~0>Yk_>rV1eh=yd%Jm~O+{>}PWZCSZ@@?JVA{m3>SQDh0v7MoTe} zoSHwa{VB?@gtQh(xQer(jBbF7HOlmNvxXKk!NjC@Q>1Hsf-Q(itktWyEs|tn zw%k~PtwtGW^?9N^(ni~zeW8z}l3c+{ADky9GR9MmacQv6&oR~%e>~G@kfN2kl_~sr zMf`vTEhtF#ls_XpD-oqi*#!g_wS|pvW=@EAq%i~PH5`|Z&a^Y=^Z=T~X9wEr{XLC> z8~Iau0BziIk=vsu*#pRXMm!!m;~(@*g}X6|xl))@YpbMtsU$Y%S*{2dAw~)3?hr~) zG!FPOF^;%EL!FNN9N@;$K*;S8bR->=#UR1$Gv~rSLzZ`21KzHs{V?O-Fl!Ptv?u1q z{3{tLxg2x?25im)@Ob7OD6aD{L4zKa|I5dMtmU3ZR-l{u^IS;Dud#D=PLGsO&f`*b zI*<~-e?1ub5Mo{9MMlW9$cTDtU`>TF^#$gP6*>{g?9;*&mWRjndyhDUi%n`08gTEK z@~LhgIe4R|#??>p92yatt_OuzJ){X$6hg@iVKh8LO=5GyG@(2vuyV&r^wES+rj%wR zgH<7GVZ00P4OMW#d>_w!9_U$8T7(OP`J$#zP{p`yf({|2j>kSM$TuUv*%w$gHjXr& z$Md*|lz~Mtj=&T~?YuuU&$My+^g5kfOPcy~(DIy;=}97#3ELlJFdQW$ktmDw`aU_F z9GmJX0Z=AXA}FoSV7PGfTx5D#h{__7&A7M+jub|bUh`40Gp-)aKs&iS*4;ENsLVt* zBpehWB6F$}CnhE76hpGi=#wXj;E?xGjfN^F!shhRcaL|(5fV6@t$}tk`X2p6>!t#p zqD6v`=H?>TNb{{pHgddv?4di|Nb7kk--vmwn{dRu+RZrP7}A)&sbi%ad3LOhGf8vl zAFNNh&@9-D(hfN;gmWJ-1ThWIrSaa;cr5CBN zmU|wREN|-1v%x!aC}1;ZiqT~?b0WG)v}~SK9{2ok`bzvEX&T?1GP+PY*1AVDp(R=8G(Wdh2!(Zc~{j9LtZE%bQxh^ zFpKoq6&8q9G_q=gJ2Brq6P6Blcy&!~)iYb=g($`npm zaBlmNEjsueLQ<=e$jX)^H3niir_=mMhH-$sO^!>y{lBiQWWRqj-+$I z9te;d!cPPQNF`9WtVRK=%aJP)NPph~V~dnM`HmVANY;4JQ$gHiY^~pezVk^(%MleI z{y_3u#=apSf(!&to8RVBUFFxL)m2gwWR+9ICGKq0kmYcc>KrXN+*TNmFnZ((saM+? zO6zdE{doKG^!EB~@w(JAv|Ch@viMJhOM$-nRj=q*eaF}8&cfy3KQF-lMvZn+Uy#Zp zBN0lDb{Xw3S}oKk011Um>0g&Zr5%@^;Xm3CUM+Y8@I6HLN7D~CqBqiZp6eoeq)+m5v|ft$Yp-=T=4TUr|BIKxdBovV8tP&6WG=W(@Y^Y zUHynA+#qEu1#c~tXo;i{?GpWPW1hS`3(HXmA|&VK15A4vQA(@nW93?$LG0gb%C?%5 z4PPSBzhC{id7x^K7Wgqyt&pq)UvgH;w0z z-VYlHfXA3Ifrzczw$Ni9haMwJHAgnJml~VEN@*sBrZ!a%=sx7#Tj94vy(3O%zbdC`k1qyi^BZCNd}#ZL_iO|;^(kgI z7%P$Y5Di|h&oAWY?yA21QVlb=9nuQpD^6J(B9;C@Q7y%Cd8Es6By?e@_@Sn z{+f(s6if&d+&))7VdpO&!cVwyEJ1L&_Sh+8TEJD{&g?ml7Z^2m8F>UdN$VJ4P|@eE z>jKHEK0}i+wmSjjHzA=l9yjvsoaNIfkqU}@N^x_@4Y-jWG}BeNA2)_9C4U~`GIz6# zYB$O!NiS-~lU+Qb0=zJySV0j~;Ax2Vc0yEfE+U;>CP;S}lSI(DOs7+dy5eN(8|)8_ z*a#KquV~KXiMKveVy$^qK^Y%Fs+aqw{yZ1ru{02m!@vJs8`XOt9^_7nEL_N>+S|7X z7yZ6N-#8HpKoc?r?6;q*-+R5!+QhMiOzc*V>%9$jls|WR(X?aiz2#re_wVm7rrcdk z*yDHOtmVzzng;CE-*0QvHLGVaoucP)co1}JG#q3T9N!yevw^?=>lrq%x!wLHeQz@a zp{481(>7}J7B`yMndbk1UFue=nD=kn!oHpN#jr2^_~$JUllA=YaNpWG?2gRbhyTiQ}RUUrk!y}nc1RFYF`)m-sRNQRh`(gd^SaEeO#S$+GQW?&kmK2-!7Ch|s z-`1PM-wS$&bbESdA@$|?;ca1YyyA)7VNxn*! zhll0&>^pvVP-Y8dy4zZGzAa+ZioH^P7O`p8v}=WP{r0l@d%bzSU%ssiiREqk@?zeY zuiieV6#3#+|G8m2SQEc}JAB_Cz5_z@?Zc1dX0v($%^SIt`@Y%%@PdU96~dbSx7r>+ zjCZ|xJG|fj{Qd^NXnT0~Uw_-*zpZxn`_)6RFAv+-SG|?>1Le6WxIIDo#3^C|hmbv6 z!JHw-e)l(rP(}nnIr8G4aVIf&cv)*@3?K*9wqHF$EJw3|=X}YkGx@UK17WMT-`CH@ zUFE_4et3fJ$;rO8ea$`|@(5qMk6N?%{$fe$Km(Ak#$gYlsW}F9Tf|VHJ8JKc3Qi)D zlRIKN4(NyPwF>p}xGS6yaCS%Ss&si9?YpSDBP4RYTz)gI(bV!>9%&1>&6H*mBDF*y z0jHYP@@IKm>@eMY7aVePgJyjJvQ}B4&7YSqdhM6*+d{?u$Lh8C{)OCWHP7RNlFI>l zH*A0duD9j#G515VT>r|kK7!mWHv!!5mw&+~t%CXGw$c5%d?kp^m$DCHM9GZVQMC5q z{{HNKW6>d>`vJt^z}Mv6KkW1-i)rtR8Lk00SWcG~Aqpm*GXl_{mvh$VUFkJu9?qg^ z?~Yk+pP;4swOhaYCau%0;2Idz17O~s_w92obnrYLzmSm=Kl(~WEE2G9y|WTtg-9~D zTfM!kHE~!2_Tby^TD^VQK7+)&N=@TP*YdR9=?>=H^M3pERO*U0UHhR4%u7L;?Q5l> zIw)=Jwxyh3=B5CYfs(i0?_V?-fTWo6!B#KZQ*~qhb+uEBYNz;PWIKgoEjz`iWg5DA zFlbEXy^YC^CnI;s2Mk6ak56)$Jw4(_vLcUTdoLH+f zK?|A7RUC5;bT5~xt#?5Fo9)DGST43t@9W*4Jsx~t0h(;^G0=Cc6y z#TCaKaip|5g_Yy}xZ}SV70Wz7&;7@^JXf&@Y@nIx^*;B~Z*#|R_zY*(o`r~C)wZ#1 z*V|l521MJ#{x={E?p8}syFc1HJw~E%Y{_o*=V7&X*qUBfyIlWmnN|T^!ew|3DS9ql zV%jbNhK@e-=pC8v{sA0Wj#*Y}N;d@sg+4L7ir>n9+zF30&dAx zK31$K6IOWD!&VD*w}so0W#O%@C=3+T>W2x%8D(bFKs#k|mIu{vtsgpi#&oX< z@$h0hnx}rb(tLq+avYAp;64dU>KZwRGIh_i1I{{evVDsKTotzZmw8pyvle>}){ygy zRwMfjO)pvrVXfqF(aL0bCW}auyu9*>Uof$ymvhJ`{UonT7}?AuuNct^#mH8T?1VTo zw`n6galuTP>lmz+aV)x3a-w9bMl`~NDA%hAMT%r5#Ar!gsGFQOLAD~4cg4c1Y&Cz` z>S`uEJ^t4;~ZIpT3Z4tmayr-`E8?Ywg>Zzqp6z=|j z|L*PnuzPzsKn@^}t0LgIRyJ^^>6u4#t_Mn_z?|pgzjGNJZz~%^hH~d*vl`qHw#%sd z)zzrAdZF^vT-`{Vr9OZV3|T*fd4?E~%zSfbD{+Jw(!|}lrS9}qqYQ{&c{sl;F|yl9 zSC+U0Iu~IY!T<@(-9F=pTydvC;*fdxZkhE9vVVdRelX9Q{R-$M&1?MIG*vjf9Eog3 z>U5HDc-3(~ij+AYRxr9Z1d2D=Z&vTWw!5ERkHBY0JqA)yRX6>9!72D5tE zhFO)H_8(I_NsMXkx8!6FId;aebhEHDMip#0*tJyVIf@qZ(G1YjGrJ@<^)X5IXm;ZZ zQq!(%3Sv`_qa$@VUZu*7MQQpJLUBG&Maw20*e6`1Z){4xNS^+YH9bRl))o&wU6f1r ztqCzq!};dydDJ)x*|=OjiEn-ywsKYPMq!AN63Kk{=IE$Yn{TF+8#=tcF2RyPhs~zU z`eCXg6_vI?*LRmv_RsC>_cip$Ve@md{RN~1Xn(%*qegmdTQr&YCo71 z*GJwl%j6YRvA!M;*VpgsP3!C8%fq6`D%!f^_~+g4*O$eYJR|+xkL~Mf0k&A(P^Kz1 z8>=opF5j1nuYWDevVGR&m+kYuy1adEUGA>Fzcgf8WyPbmZYS#tR$a`WGA`O7N;RD$ zS;i%k=`|KrPKq%4M#Z;0*{rw5B3$pV%Kwk^BG_FSu3s5Vh7?5vNRZXc3nKoUesvj5 zETzCAGXt(GuSKC0r>a|H!8GT1i-@|)D#EoDTKhe%pkPS~gOB%r@xoK?ZU*J-fOa}X z_=0D|Rgtl0Aw{4+{c1Y~J3jx4jNW4yEG;fmtVkx4QZXaNsUsNFTV^n^InUY# zs{$gVfjL1q=Zq(ot{blqTzAkkW0_!3dBcc;aY+jrTM&|J zRg7eDb@EPL7BZ?hVbTgG?3~!G9bJs=dHB_2=2}ozb1f zdwLb58Jp`V(cF||W+tRX+pKI?eTgwfn}r+v)C;mTi(*>%Hzd9h6|gl!WNTdVWOTTq ziEb~w%Fb>0>G@5>4Uq6~xG$=5q+ks$`+1$>%NRhwtllrbL2XL+OiM8t=*7R9+Kc}hGdqWv**P3Qfd5^oYBE)w zB^jGqzZKMaQ-VrzF0mZBgH|fJ9Eq%3+PRsj<>7JtZaeyb){>CR2j~F#uQ`L;NXZ?H-2II=z#wbE)vD8a;htfkl> zh7r>=)--*)?2UGxyc^K2GlG!Kg=N|*-L^@ z%?*jAel8|)=SlND5=dY{0EeC4EZP=!`U+kB{2g28k4a+2UDQoSIYnlaXhzBHO$pL| zU@hk3^62rj{dlglft4^P>&EpB!WeA}Pfvin5b@2#VT+j{cr+e#kZo9mdcm$K@tBHc5n!3(}NXp8NesVY z81?HfjZMF~TL0m(=pP@p4En~Uu07wl*fr(Dw(L%lfn%bM~|f z30cg7)U4Dh8tEX>aua^e$+pkWm-A9unw}0}&4>$}7tM%-1QLxADVCd=#7LhHUhxX+ zfe@|fwtqx;R$fbvLXH`w$ww-tG*2HgQ4x+AT3km=jq8{}CDS6<14b=4(HUo#K;Yrcu?dnAO19Uqm+lbJz>t^wbcji$ey5z;OIPWwLtN8J zCTkd@=@0|NmgRtISpNvAGl|U&Q)ifDM9axzsxyQWE(W`qgG=LGeK%xz zDx!9|$SBIQ+t^MM<)~t8g#_z8i%yV&^5fZ0huWfhrl34J<5ETkSl+2Z439I^NsmU< zJYE6$i2(U1ERra#A;*E?U3eH}R5Ar6(Txk>5Yg`FlY{W%2ZYoZIU@?IAsG3oV?mN) zA0#4lbSxKBCi*2po!pmV0uPtb(fuS}7(D?TihmpIAyWC9Fd|jRI2{XCPNYpVaW|67 zj8aG*tAI$%5ek<8=_^UcJ=e8n1YCeS4wbg`DaAv$NECLHcg96gJkx$HEj}hdlZ>WxH^C_Ij%TqiA)C)JW`hH3783wczv-s_JR8O`Y1-85 z$^E#{YQ)JM2t+0vZmTm1=-wnDd6;J+_uchKGQ2DCI%8+3zzQQrNFF9Q)5?i-m$&a3 zZYi+LoN`#Y43;F^2htF;Y|J#oBgS>PF-{jq=!N?Bo8{YMsyRIHkQ3aS5R?O2>jfp6 zd*}-8T>!WjauCev49O^_%F@wB#?ug?Y*aK2Glk=NR9)nJ8snaEdI1?DCsd%XnOBAlE^*1H6NQAQu8B!@6nCggt z;mM)16kIW7zoZ0-B9^I0Xc0oYKxildn?_U-Y9~e>712GNZ0Z#!6G6QGQg4aOA*`UF z_6FKhgkx&e>W!Nm?>NJ=nL3wU>q2e4DsDII^`#>-?v~x`l}5czF=V!7dco&j>_tz$ z0{v+cy)-|LT4hMm7WWyg%FwJrgf0ahv={iM{yZ1h@ib|zmjsh@J^Rnw?emLXjMe+E z?e6D&WKc(C7?z0S2})qQus}lZ05e@)&}yyqU@oL>2t8V@nUP4&Nt7xI!$dccRa*L{ zJfi09_xq3ShAf&Nj9GhJ>WMOuizK6Wvh~`UpL*94i89`^Xj{POO#(*mnmn5m9!db0 z6uweU{g-O$zm!v-7{~G{W7MxEXs5ksV6}skE!lHld(Z6v<2TDBQ(D&`#M;wi8^1Bb z$Zf0cXZBv9e4hc zVjZ8YMfVuHlJDyNQz*151Z?j9^LT;Q@fqzz5BD0~@Y*9wA=2Wu)|a4)Who{}s%dIw zS&#;phl|QHaboIdu^ks~LY@E`NDY-p>t{@}xd+l{X&aNa>F7~a-E%4OLLUl4wLVS} zepRAY`RT_z+VXpDjU&-)KAw17nbDy@H6Ow1H;>*aNNm8clt9LBI0LySH;Dmrj_hD~ z1N|LsDlg69G^3)$_j);~r<%$yHvZ(CCVI~TUp?qQwFmtt%=)!7K$`!1^&g}sNQ1u- zb;mdg7jLPK*)76FzwgjDLbCSeuShDU?UYnU;8klk2M0lY{k{M51)!(J&z(+Gtr&YY zXE#~^EA*oh#ij=3`}_W|*LUb+zR|})?}5@<-KA*Xx4U=1Mysj#S`#inMY^rpD;jh1 z(ux_HNK4&WV!~6o9GPFR!WrIotL3XHz8OyR+t*i3ukF`8u3lCJ#$gUY)85q%h*-GY z>n9#cuFRz%%n)gA4{whpYU1wA_x0vw`wUE|L$ABl2kmFRQjj)!Tm9}90y^)0|Dk8= z(H8W}mp=m1$%B5NTz}+P=anTBEehCTlS4+nEzsR}EK>?~cW5menmDH3cliU9XMz$$ zl=<$}!%FK%MYkv?xj_dhcQ2X&ntSmT(u-XivAuaYr9e%sVi}uzVpmLW(dBQbd#l}U zyMvBjxp(i6OKslpYqz!)9wQLu<*@&8U!9xoLGBrOS&*%`;4J9Y=*UZ3?(w~0KFsTn zv6&Z-uRNAxO+K04;%2CE|Mv&Z*&vn+a%wpW5a+JcPXZby0FrkfTkrl%e`vFQu!(W- zDOd+?4Nf{A1#z>s|Ac#5w4T^&j1SuipzcoBBVe&REKet5`9q{8?y zv^t)bbIvf!1Y-(o*^wg0{c(gcpci|l-6ouU6s1!rLfz5Yn%QxXZC$n0exHaCPgqF& zuv+m)m8~d|PfRGqGlH|_NZPM3MhIxXqPO#CaOwp!7Z5{^TPBNzsd{_?%cN)JHoM~eR}b6Nqp)!xfj6=5+$72*7X+CQfh z)cQvaQOKlUvA_ZBGQ<@#XkzD%wF3yiT%~$2U@=cI$&dbyAEPV45LQ&sGcK_f+__JwW&y&41 zuIFiVZ>#{9e%US`)3`L2);l1nuxQxW3CI$BnDq;?e*$xS*o{HWH4Qptp~eHpFX^1Q zc*w^UXzXb}KPwpBD?!A20#=y_(gf!wAHDxff>{pW@YBYR&OA=Jzq)mIPV`&>%TXD0 zo^~t0oh^@QE#m&{p4QJ=_QRsclBI0rBR=fjUJj6B?&GQmZ>+70IMbWh%F{IQ)Hvs$ zelL*%Gl7WebPRrdD`y14jAERb?&Y9?H{Y?&^^1U!tV6JH)P9=||(cK-A* zI$W5b>(*N;N!g9mbpzXVwb|22H!Q`9Gt3oX&K*m*z)}d2wr6|vsr5=GIi{HzGu~$X=N=}7=dOBGwPNSiqvm`tXP}&1 z5Vf5p8H*82_gY$N37~gX%C)=w;q`UdMP`hwZ1=z|G4gEVwCtB?9R(@sms*12F#(K~ zpQLm*v%Q|*T@vI!x3AyV5Xy4c{M>ARZGbB^T44nVHpL9Iklc}d=cpcy3&xOxo&)sm$M$u#09&kX&GO~uEl5s1!E;8gl3#&REx1u zFCQ;AIFwr5s0UZwnUpqNW+I~_R@G!&NUeCpCE`ALhVt(8F`hBIWK^?dO7oqjVx|qS zxMzag`O)dVvEG7;0F_6ecB9ggCv1aplhmh_=ara4Dfxrctds>?>^d=Fc+8WRTkb;; zj`cAZz;$#BBI7Kw7R_6bOqcfgVF>q{V$3ldIJLJ;Eg{RF~UM1IkI2D#YVlH6TMK*pdy=l#Xv>KxHv6TwYOdCQcp$3d!xlhgTFl;1&_~zE}4SNgjL;Qpiu|tlvn_;nf*SpYGYCt zTuWYNTEOC#sw|*FD7NyS)g$lGaXb@c6bL=#FbVXXNT(@bfQk>y_#}pj;M!eH3Dyl8 zw-uq)a*rHLnCAKO_YYL(3yym5USkf^nn!qaj&q=6}Gv;Hm8Pd24XR-+d=?P-I<&E z^IWjam`%x=(xz+`iQI3b07xbpV=o1;WW)!nI=SUEu^??|Lm)gjE6|ne3&Ey5f56{TJ>f;Kd;g)I092Sv)UqYjWTh55Vv!KxK1Z_tIlVc!Y zLKIPP$R-54x#MgL1XL0QMcJmHXbBzsWVmW1aTyx|oiH;q*^3B-vau^6MLPIPHJ6lv&aE6LEPpI65YzuuRI z+xuUCj+D~PT+9>2+>}Bw@BUW)c+}sb9brmfW(O{Z!E;$@y=VdtglbCQ6M_H2?&-@+fX5_pyXGc1mr+yz2c8swgSb`Hd zc-wW=DMMEql2TdbktW=eQdyvICe_hMm3NroxAY)~rw@pjI#KTg4C9(hddT3;93wF> zj6g8zcKruwZ79ugUJ-*0PIElLHV=h?Af*%)QV1q_*xM}>3F2+-#`O&{pCN)-_vdH$ zcaQy#nCUZ5WB_cNtc&Gwd*>Bt6^q(ofJvtI5o`*4*=;2zfUKB%P`kKi+ApNm_G#+7`r+T>EM5q_Yc2L1a$<+j*Eook0dK8Afci~0_2;>8kkvWT zIK<4KWFlhz`XDa848~?X-cw~T2J=HN50C5jCP8%bt;rC5yx#of$r0Up-bxZ}Uh8Iw zHm`QmL^oICz^T+SLKCWNKx@4e&7g>WDXL!z+BKQ|!MVn9cG8lp9S=mJ>SjOal`n%i z14isfvK~ng$|%i5rif|E?vYR+rLkeQ0D;MeXFHoSN+Xa^`gw8~cv`FUH8SS{yofbkAhe}OH z_(G^m=9a0bmnMuxH;EV-(Fp}}$_2s}fAaP;2CPq+fO8g=Mp~KI`h80B?ZQDrF-4(6 z({ZKAEA9CUOigb|Czz8vPUxFq zFoz39iDW7f%c+q&Bswxd(Bl}cv~{jn36$?@7qaA^+yE}bLctQv^fkW@FQNL;A)Zca z13@y+wA*lzjnyQ_%}s#h9EWfrSWTFvG>0Hiu(Nd~-6nH4YixNwz^o&C|NGS?ZZh28gh+w{s z^%zSs#&dP=ix}J$<7w_4?F@R)MiARMF%c*$ENYRLl1w5w9MVZ?%d<F> zjwoG8CeIUnd4SF_RWIk1(g7g`M2p^p02a@FfW-W5LKhLcGW(6Em6SoL$0@}GNb%cm z(_Je7yg)<0n#lB5ysB^>e8Vt#1)lcgXW}Tn|%2x~;QEJG&Xk)r2u-G85?)%4}DImJ@@_qzrVt z0Y8}jA9awc?f?RSg&*7LlbMnxW~Q9J?wMBOj0y(9KrY->4qTbfpPRdzpL?Smmjf-p zV9Qy+8PBxGpd8nPgC7><_=M@eS5}J8<^M4R2#s>YU6zW+O6MnmS@TtyVdfs{Joo(?}w(Br8QSeY!Y=v zc>UC$2R&nj&cUQ0%n1KH>~@++-kMo|O9}PX%pACUcv!s^jY02v+--9;%j)5;B|M_` zK0eN*9-b*pB%{j_Xpl)CC;#7u&*14nnSMsW-O<-D@KL@~98Ty*_vkKkRMYk`IjvNypP; z7I;}d7Na%Ye)88f&$KNMu*=i0U%xDABOl5A>vE%&u|gVq{H^a^KXmWgzifZqw#%U37je{aH`${r{l@UeRcV1%jbO@y}mM9Z~<0qvwHuv z-TfTyDN{G(@RWJknwqLjbXU9Gb_XC2E_p4V{>C*Ww*;y@M~QLAo1WFxdmZtS3FS6N zm8QY}H}>6j%gLQPjyRI~_jKySTA}3`6`BeVBq&0exf*V}0k9(%bGDg$q&(42mTTR# zjOxk(79kE`*^%bS)-Rb+5h!=bsTkF2v!`KJb;RfLKx0V-rlxLnWDi>RKzdM8IjO&! z-=#6D_B$2VS`ji;l4HkppShC4ioHwj)^K(;PK3ZGV|sIBSEJiVX{;xBJ0o^;mUDz{ zFuky0I!(qaN8iqRf}V&iRI;7^(0~zPm&4Yx#QAJxsc}51JfT_ZZEo*$KI?vN_hAz>%R1O@O=dUqQS>t9JRF$9h=vc@Xdtq^|VI~luJ(`cXl^{EeKznT-x8< z6d}>}i>T@&^v;Lnj*gNxy|xz0o1ny?RK~9)?uLEEkQ#9*i$; zRDL8gE4fi)MCD3Qp^yweOwhW8~3$; zex|7-Gd)@+?)Se$O`aCZSG&JJ*mi%|y}elR>aZP%NP&4#tkSgf0kITK_$r}7^F3w7 zE!2BT@=o$4z>ai&Sz=`1k!K`ct$bYX^Yj;Kq(#M%ma1)owB#6#M|3qr|OyFTK%tY)v3n!{&DFO&{OrI&#dR9q86TMzxu9xT#d?F z>^bN~=NHLF2G=c-Y;YXq)%G(&9OWe#F0QmQhIY=9j7_P7kqlX{iPynGx)5cEnOUV; zx{y}WErr|Eg|tlS(`S6T5HoU^$LT^R)HM7mhApjMHI1QTPt`Px$(W&@9HR>vJQTK^ zG}aMBtvayB>BAB!#myt#SY43ly1m(K^!zf}$le#dWU{N+H8te+@nn;;=yfv?I4@cz z%e{@#Br;}4or5mU+nvdY`g+jz_Sjw9=@|MtC=YU{KAm%Oe}C~LpYIv6%^xFss_;xD zq;{xs5bO`Hugg>f8|4}23~IE0TRyZNx~pDrSHB?Y2s#qY*KJsfec1fmY=3P4?V-jl z%|dj?9A&_@-C?r*Xyr2f-Q;QkL;vB_JIX}Wq&W|zAM&fd?i zx=NvnMFbHhgkVJEBFm783KlIw0t;4DTNt-)5g{D8t04u4bc$0SszKGP0#%fm)h|9z zxuvK&Fi0Vaq@$`0c*c&E6|zjp3@R@Y+$ElZOCPVwHqf)AiskNtOXshsgcwp_sg>yc z$0$Y0tnXIzX_}e5mRy>sWKqsR@b%MbzoRm{ZJUT&=2}MRs!}S0all)%JtZmr$CV> zPKn5UGfg+JP?0CC%UH8f51ApocQJ}9@`P1}xX&>ZtkdMIxKslerJ7<_8EXUl*0o?+ zrn^)xL!h2irg9Vmqi-zxMpao)$~pLBxOZb-Yc9{op&zp;CCM{AW5uGvE4;?$ z#O6GEC&Dl+sQzE1Set_uY$XKaJlfRkU3a(L)^GEnfqPB~(hWz@{1Q{0uJuq%$a#UEqrWrQ#VYU~MCKSEHh?nJ#krK~ijiktO% zUF}Y5I*YYfR%wx9+Z=TUVl7@1m;sZFOH!W_VJ6OUwcIi;5r!${>L&2e3B-YqiWnlq znB>gfZehd_k&HuF;~>OvjOn~6KruL3Zp3i5Tdz6xM3b@sQ&>LVZys-4-(Z7RLjnv} zR+lxiwkBpc%S)@6X1L1ODVfLw=4MQ6u%f+?);4GuZM~?!p7yG9EJR80ry3=oL-=@=S8A>icBbI3Eg%D9V_-vT|GL*ykF?db2h} zJkY1)4af=+kZl8kq&JEt@73M@L5spp_|<)j18SXrxP-%a<{W9%bSyj|^CYk^WH;;& zW(Vi!Qb1UAMNv!~) z1n}?ZBXCT5I+CPDr{}dtPAz?&5tx6up;C-76_IkeA5H2GsrAjUKY&R<`UQ4qTArCX zLKcn9Bpv%pS|tanDgHqG8{^*y4TN*l4*9WgAU6{QhLfRCsd=3>4Ha5gU3M?qjrrI4 z!H4zO*(y8W!xcaKxTf_Rqvd%;5+%p?#KrXmY|j14Jl2M0D-EfgCm(c==tdtkL2a-1 zrJd{k*Pq>uGR(-_i?3WNOYv}zGiB1MnA~w1KxdH&5FoA?^rmZe+mmItJ-@Ipb&kKdY?yk6(>bejz;eIUS~*1=sL1h-*E(iD)=rdifZcYiAA4 z<@M9kS*PDD%qz9Txs&#ukv5cWI)p1KDN{@^6ix~p^s7p1ZkT74Qb>}dB*S6fDvpuF zDB8QqyX@Y4y)y?)uK}aJK80p4E*ey8P+59vW5;80^LT;DMrO1VJ>+VFj0EHPBBdqH zqzp+G>5mlQo>gl&*CGjW-EDZ|l8RAM~}DN>X~`p+foGt0K+ zYBMDb?(q(UIMV+)?yKD6s8E7H8Nw&_4ISM#w(S>41!GECr3EZ%Hnr$^d2G8;hXuui zSxH^%amAG`AW|SHBK@rVa%JmVMD%| zU51TRR;fuI>K#|)c&NWLDIS`u&Bk;mcsM?6<##YHb<;Z-7rWUV>WiZ|X_ac!%+R7H z`2-4~MRnTLuIq7Qg@dQc55$G)OQqJyG7~nRC{e^Qr7Svz#SAYh`@ta>^Tt7-m1o** z{ATW`L>m~oLQTbO4yegm>^a1A-_)OH!*8ZeO)-JPhY-SA%=B#EBBKN(&DI4M;Nvmt z2CIN&jO)Y5q*gzMC)-VHZBSu1hNV)Y*L9;A9bDG!?Z=xw1z(=tUQ<;W;7PA|bj|1M zd6Qpt9kMw`FMgDg9+o36pxk}21`Eg#kz_N}`l!Mzp`Ok0-HM5fn+jcVUrdZ@CgSt* zj&4nhwNW80WMYNlveveZB^+xlom!<#7AGrY6|?)a5H0&v-5n3 zbUbnA)VFMvkcO zc>Jzp(@x~4bSIlz5~&m=W0vk@t#46*;YavH@6mjNep|dQ_0HWbDwD|KKNVnyzWP;f z;jj9RuhpFe81kR(o)-G4IX}@OA{kUL{wb)mrMgQ`TN%L?xkd`B4qJRSvgTGjd z*(WFPX89JI5x90zVHit`mDlot)(JVsnOTb^Bp+bTDW!G=msZALqd1dW^h#oEy?h8@ z#^%ma42mR?g(-&OUBS2jsTFvJ^TJ}`>Q}>}0uWYiED1Ce1TZhm7>bVwaG3szBao_L z1|AB=c6cV;yVcwP*K~s!mKBXK%BZrv&&sA_EICArTmniH*~h>*sj(}#Y;J zN&+O0s3J5rdLpG{E8v&_nT6uiiQA~M@s}I(uVk>}lfV;QgXBld%^23U=gRhnYw8@c-1N z=U!lkKH}b_;vnvR#rCe$E(iXX<6oN zyV={bqxaEfy|S``=5Ky~hfE!}?C*Ta6tR5bZny703Z`azrJ&*&d-`$lJ7<|9#Bx%; zCB;?DGD++vX>pNYt!759(0X%s413Q6&oJp`snx>cs-zRf(l)E}@BjV3{5O+gzP{uk5ZPDlwxsM4xGwboe+ zfSdPPY|5-U7aB z=FpF`x7bdYx5GEjpSzn$KgZ?nvCP?IF0f$Vq6kuER3f7wnpT0kSp`-dOPO<|tHl;?=5`>Zg`3B`Frj7Vma&(GcRujfMjjin8KMq~j54I8rAjh_t> zO|U4pIZeri^x2ZkcGfG|5Mqk@eHt19M`=4*;Q!|*GT6F&Ay?nG6!6}wnK3De}yk_C795eK{8+G*|=?^iGSy}Fn6 zTNurFSFpMLwOT*_c(-KY$L+7$`iP8Gf>WE6KHma-v55@dFWYnR9fFbCf? zD=YkkEMd&jn(}5EI_uej&8+^<|87}{AZe#~lOZd&M4-Hfxdh~VVI$-AI4@lt(Id%> zl`y=oh+%bTupS-A?+});jQ&RobgU`(aeh(A%%5={QRtExos%?*C z?kMFj4?{*4$4M3aYN<;gTU;x}LMsbFf3Z*>LdmVT`C2T@sFJZ3h_=ws)gLD!_NLyj ze9K*DEXBdiglq{3Db+0_8j@NqokCKf%)z@%k3+bXPppg+938d|f@PKw<$Q5l55od! z{fKr4?2suPlH({sp1FzQgglE(hGkf@MO%hV7srlrlsWi*f|}bDWNFCVl&Kx{mr|(| zk(oH|gyi~lQ^^fY@ZX3cP;^bqG+R%!1UMT>=%*RqGO8pLtOPS?XJC$j2`{#xy<;v` zCUXiDDOL%~SjM_kyv5DC%)HC-gkpqcT}p325lj(;O;Lk<{ns47_Xu}$fyoBTc;^?XM)#t@@yS`&o2TsrLO7w^ULZ)MD&B91REIav zw^{Gfhoem4-0=T=S%1$X5$@rLAeRBDI&wjG0^5_f5icaiRCpk+(kGT?tb6zl1$nqH zyzb4UwEMm7v|7dh-M_9iANL7{Fio-9hufmo_zrn_L*sb>yz}Sk_r0S(?jAX*9O!6X zQtA8M>Hsk2;+8%hxwVXvJSOLCf?F)ykz%nQ?_aiCEzJ1kvGpSm2vUvSeO_vzcXN1k z3ZQnY-`~I({Cr;S-7aTqfSs4zIDw<>4x9U097o0hds_j0)f)p6&7O9vK6Id(uTpgA z9@eeiGZ29&o6HZlv(@+I{%7F>)cMtwKLL(dbVU33WCMqUb53VMpY{ilLl0$h3TiE) z?Wb*SQLiETdD38P>K=J2i2JfzfUllZW=>yxE;n z?m_k%ARNrp&Tr#>-}cuMh|Ueq>HEs_%1EM;TJNSjK!V{s_=iZ$Iii^&g2aabf%Iqb zAv3*sCO(yTw#dWf$L_ScTF&VM=WN9uuzbLoeB|FTquok#LA2{x)xr+1PWk;0SF_1A6SXW|PTeJI0{YFPcVsZgSjZR8_f=9v zzrO08g7`L;m4s-)E)_^nv3 zHcy;fWGJ@DeC6Tgc8IcdFTf|zc5DP4#560&LlGdCvi)KA_HuxnG9On(a_Cxr!kIGD z%Pe4@BpCT8QfN}Ic(>9FJP)n%8H8ZXBZT?h#!&%z;D>592vL+E+O6G|2Voo_|A6`- zOn~ls7Ow6Q;>?a{XbJ&Rs9uZ5-3>}$f1LERt~q-Zx2M{jyb2Xpp`sj451}Gi@ti>9 z_>e-yCk^m@8Qo(-cyqdbECa^C!+Z+EQ|SB;In1+_)nldF&FcNvcK0()tffj>?}5bH zx^ah(%xbfzCWE!b6=yv7<8GT*)d8;5l8NAyu#8BB%#0Xs%Q|v_5?WN;aYr$g!5YJR z)q1CXDPcmIk)=%)oh+l63DvDhbM-lxkI%u`xz_9G7<7Uv+>2=FgE$7!c-c-$GB721 zmY2+|MbQ@FkJubQUfJgZh`k!awZE^4l)_ovZcedi-`T5m3;JhXP zY`a^fF)I;gw=EhrWvo5{PW^+%`bT2*4>yYrjp{x&AWE%o6j$Hqw$A0Nm2$>b%Bzd- z2V%t${PR3f+2`k)X7pv!a}uc~);LKP-VMlbm`2w$0MhMY~^*!~Obw zy=i@2e0f-WUA;fF?>PQ>_xtr_@g=Vze)nVhx>|rORyXLq^R#|88>=opF5j1nuYWDe zQrOnzm+kYuy1ae<>ROv8z*lVhw#qk%87NaHld={pPjq#g=QcB4yB4KIYj_#xNCH!$K5Wg8)N1VVbijV^RFgdDq^-N%fVVdA8g42Pn^Yu})AL z+`3UPkz{qz6@m)%F8BnrgYp6`haK#o?cq6{Hz|w>5jZ1UGAab_x6?d_C-*qNFMPMF z3YJ>Lvs{v^`}X%G)~(l8QeqX%EXAJt+>bppEQ%B*nMu_gga;I*I?a(xGKRQ}Y7cai zHX4ju;4(G;{nHx2WO_ANB*P6gB^1fHU^uG9*X2L9yZi1UL!0r(dbKN*nTO>|o?UwX z>pp6K#*OQBncM0{oTzH%mm469s?lK5-dJxET8@;0ii1=5tx!z#uD7b%0@JT4Vch&j z(Ffl^W7Z^T#~n5+&5GWa-+Qg~ESTo2Lz)c_*L*vj zu>}{bASUp1j=>;Dm|JHQRoVaEB1Dhf{nNSiP9{uDvojH6nXm~+cwc6$o3^5QDoM2b z{$l63DK4B@0{3jZJeLi0yu9Od4(G=4%#KpCIPQLX14>He zLT3qu)wo~ha;{(1*0tSsYuIieEyFpL?aaW|{DXn>=2O9gSzFsH1;-x*r$@efud~3E z2JuYg262qOG4u^d{mSe=I;(PH{uS-gUmGslhVQUTKb4v7^K|tSEiRtSPxPk#JQvQh zIfq+$vjf}pHSz(PtsDnx;$7FCA=6el1l-ksnE2Ck+B=PxOyh4a}C z8g~dS1SqRiY;jA}90@I-QyWbHCu*oY%a2A~wwY!WBy0$koEC-{W||%bLm-L-$ILd( z4g{9;CgE{7S}YVa0S1zUHsq>Pr05ihHpaDfatx-04CVHB!4k`I70j$yQrtKmj@!nz^Oc|&#d<8AL*H^T@+e-5sFYOGjQ-pfF-j3+mG8rE zPwE)ql{1|vfk)pct@H?jbbUv2HllXxn_**tEcz~I*V@@MFBHm|724x>g~j@~*_rbe zZR-=0-i51OVI^jSdddTsuCBRf>)Y@5AKMLCG(Q;DqjL6qK_XY9d2w+L$rY|{``754 zPY|86nQ5+cst>yd(Xke^M;J!=$YTYs$L1W}Zr2+%;xIl**s zLq8+*11p&d04q-ZUNKmTaK?lc)?0FagmLcTVG5Qm_TR#mm^IkOE~Ka+s_Qo5ky+B6 z5P|_2`DVG>KWyJdh`sPy)u%JcN6Mbgkw#6&;u>BttUG58uNY|$1j7wDQW+8ojeyLg zwB9=S?unX1&LqaLBW%x^>=_w#y8STggX>`oQHFO!q<(#z>3v#o zt8K)VLhBI2@G6|MJrWo4k%SoGjLIZ*Ee2XpQXmosSd0z=wqTsXf8!J&$+*Z@EHW5@ z9bwKggyOc%yn~*wQdt%kHP)Ru-7l)35Xzo_Rgi{Rvb$Gi3K&19{9Oxy$N86=88kvEA&{nHmN8_}at77M zfeX6ktf7#LXX39pj6O6NVy*WzGi41voU)LTw4asx03^-h#m^IfP*K#nX zrdC73^-vKhfWuciAKS`Vz-}c`jFx887t&a|SpZfNyL+S>z0WvIbne{XR|J385&5 zcxmh$mCwgb6wt@dkauE6JJG{2M|aQ~-ODT{Za>SYVk9zoLaftQ%e{@|@i+{WJzLI) zjOC&Q6cQbm%77zG(a0GfI97;8W;8gtTUtsMk)$Q=E-pffX=wz~EJn+uaPHh8Ntgivr8@Kr4Z*P#^Dr!;=I?5OUrPYiaB_bxRQ* z4-QMc`~zp-GX9OB(o%19IEX%!N(DL@{@|RdP^>6Y8Oy9ti5ln9JOT?zNMf!Cgs`NU z$ZVri6HclLedGw5ysPGFha6nMifQ%MD3VCjUz%!Z&DCZvx+|p}AGYeG8JD_M(u|AU z8fneWZANm1ab^tT%mRLhh6M(~N*~=##aizxj8nrnGtFedm6{61iBDE>v@a8nAf@-#=P2PG0oM)6bl_$@;HFeN?s1M^KabN3wLhgcnLl< z;NCN}_@o&bdLl{v0JX_8GEBKWf_MlL8P5a~j1$6w3lhXb(wZBRvH@jE3gIrz32nYG zW+s(Vo?H+~3-3mFF4{_&WXd9l*b2Sdl2sWY31cz?GcHD%NE2Q zun&*#Ffvk}oGjk8Msd2Wwcs5E*NJo3s{#>PToOj}6h?8#)iKSfEl0Le&1j-(Cc<+? zZE4wAt1umiJ5W6|64be3HR-{|o{7K4=2V;E)5hj}(hMQnsWXJc(6cMa>IKm!(X*Mt z$yZ9)hZ4?~o`vAtVNw3#s1Npw@^_${-XOI7X8HD*su=|ya${MwMmVX8GYGpp0@Lf+REy$}$!ik1(IC=vT9Rryt`o z{unm}#0BB0S*^#5xfu^+PH_lH8T5sh{!Q@YK~xEq0WfdSdw~l93H(t$33^x=2BV{$ zZ!NrYC?h5iP~37-HN`Mei%8b}83HkDyvw{fB|5FnBZvD&r{&tz z`D4?XYLWRYcgz^K7WcIWnBa891jZ$~wP&6FA+$`sIQuPRv3e zL1drVNB1a2u)Iv6QNh%4d?ls~Q|TOCnnTKHMAvGe$%INZCmvLh7KhwXKu%Zh;i^>o z^5J27*qF$c%P?P_*7DIW^`l?PGVf_TJgp4}ATUDHi)-$=VT1d;x#t{Wb71>zLNZ(5UuvCPzqDmwHskIq)Hj1Z7GIE-B>{4X?E8ZOywI+_=Kk#MtS_$mHc{kik+C zK^ai8G|4tcvC34WIcW4SH6xD^)gwa4R+tvBf#dY%s99TN$F-a$+0-bJQ0?1+1~7_| zjEp90n@975K?Lg?NSJaUMmGE%JyaVWGxxh*I?FDj7)bMTY~ zmvIIWWT(TT1Nd!lvU)<*M|=hehM;Jj*jd1Y;!FXd(4aIjC%D=xaXO)g$p!BUoj_Vf zhUTMTS9+*=;dnU1MGs}{#?f9ACBqy+GRE&|S!(jEG;hD(e{45o(fnXoXYR{>I|>vu zKlTn_xjKAb9loy)-|Zm`cliFKS;(tsb>tzG6(}^;*zU@&_s&rIHVf zq3m%v7N5ppKK;-;MAh-6_aMxN@&0pU#>=v>4@KoC(N2kSoUZjg*Cq!uyQ&@IJp9_N z-vP2%VUZYNj5VDw_1ju=mPjB$kTPumw}rk{FmJt!JK3-eqHL?l&Aam?;|zNq&A|uz z@nyx$&>b=UGx}I*ueE1@nM~pPVgDQWdAC|ZkZ6uy-S1Zquv+f2;Q&DM>d(V!??9Vh zSG(MHe0&vHE8}?8d|T(cX|#ZMLa0lvx7`uVe%t>bY{VMDoy@Y%zu*)_%`|2Cc}H3O zFKH_Dcn{!IEdP4Gud5_`TX4@=yA8y0!o*wubsKf={l>Yl!x3D&^LQE=HLC{Krwvhp zh3lL%#T7B?RE;Sjx#fXqbIIossggvbs{nK<0#MlgWG(kRwD_}2Y)}6>vBY*&_hzB) zeX`^3Rbyvft|CaqXG+ULdRl@`*1A?{ca&JKiPzIYf?Z}MgKGpk%*|ArN5L-lKjGa# z@vfxl&<~pz6Ol>Nf2E~8YTeIt`+~Gb=j;9YA>txkKXfT@lWJc5l$cW}a1k1rf2fw) zH_q5UgaT(YI<{%Tx%XT8A(~^L($gPfi)_3lvVl;~c4uygvM*VeX!JoP&H;q{$mFXN_o(I!8KR+1VV<*+qut9aY$PQZ0yoor~DNG7ioi>Hcl^^7IA-beM};hEvwI z7lJgf*0~e)#?mHLI;kh>7>^1APWi#OA176ka7NnojIN0Kd=d4lL~)fU-n&HcI69)9 zAyI5rufMjtpLrrh<6;<=DC)i)vgz`nhuyZwAOKKz56ifDF&n;us&L+{cDwD)W}97Z zaEJ%Dg&J>bi89Y>i8qX!p(xRUzOWMPga!8H@f>U3M0F+qAM$UoD?aX zgcWgTFEdzC{prJ@a8$qoZ>&;@aZLjJtn(eqMr^W?y|& z_^<8rw>4zYdfWWmY=3QlC$$wzYU@Fh{kHIYwC!VWo6X^o-CgDOK{IH3znsJpw{wJ- zXKQbmP^-;twXV1ILIOvzdgZQuWiaoVv1&3uUX{grWz_p2%jL=})O^2fD+H3jUHc4cp0j*Ov9X?Of_@%eu7 zW%YXBe&hJp+drS57N3iRgSS7n&#ML4WA%c$P~X>&c4yVYhvn;X@#T-@p#qBY_-XsN zuO4q7TaUZ)0z8$TEQM9rix)C+CP+^!Y*KJP%;B~Mb zhA#L%!A0E{f+F=W!c{F=Corp$MZ8_GoOQH${|_$$wJl~)xEkoEQz;{Qc&@cA@|rKw zYg+{GVW3Jy|C1Uk%1}`VR){=qP@Q{aB2^ih?g-PwE=-%XV=2X}nZSzst7QN?9j{+4 zu@r$mqf_#dpWxp6Yf_wooLyeN@h0UxVj2+vm6BMb=A1TtNQvMw$~_LiwK(?i{pey1 z%s7qc`A_1tYaTJukVsMujJ8$d#;Ar`V+kca z%P7P`gf(>X7)ASZt+os80Iyw6$wSFWxhHE%EV&mQd#<>rf3 zT=Q4R;=dne3EDU7~4DBMtMTH*hM?7XO z>)!QR=T}VFXKM@C4(41EQW_CMp(3(QNb8k++e21o0bws{BQT;B&9XWq*fJ<3SSDK? zg5=(BOZceO$r@i#gpKHK!$9@4l1i9igotpAsO6}7s2uaR70jr%sNYsF`-6uWqliG6 z(^3}^Gob}ziI$3_wYz$?&o~Y1l%BT&i7QmrCi4kA|J$BqW zwrM3_l~9Q*m{(glz2COgOCe&eyOX|Pk!Xl8gi>quQ7YJWm3mDu)`&wCw`18eON<49 z%#V<%AYMPAM@h$21H(*pkH(Ouq%cyqtC=loBZtuLB?wF3J*GUygu~tt=h=Y|=_S$A zxdFQLz5FeP2rjeql4$+ZwS~l-{-{yb9GN@j^GAqOSciQ65Z6HhQ2YETra4B;JN$?X z+-UV|kL7f`X0be@_yt&W?yD8;2MFP$^wv8Fy__8TT&x%f(O#AD5IFKixO z(;Ixu^afXN_}N8^e#rC&KgLdPkb>n5^xYRoI@>vd?|y_)3&g2Xjzz7_Q^LvjYd+1e z5*XXL4k{sn8ZB6K9jJ4hpVyo9>+Sx2`{Eb*{jUTidT+C&zCWsPe#tJ(lZoG6)g#~2 zAmqXvLGK6`+(_$&zr`&U!`y~BVxzhYbF7BC3lF}{F`zZDy1@FW%+zlzq8SuQR}C!zTZ^REA@#RTY2eXBX@A=1R5S4e9Om)i%|I_ zkD22CL#NBhMLq)Sel0Y8eB=G)fp)h0nx^sqJdB;D@|r4amZ`#~qz$J4Nn_+>2yM86 zs27kbtSAxhd}+K?VVNny`jv^Qp+`TgSjmSSRPq>(_d>+@c@HQ)*1HV>SZA)$8gi zFeC^J4d-u{#XMQ8`4~L4#W(%-Bg?O)w*{@AUoXZ?UOW#C*?L^tO$}KU31y@7vKx?OLY<>>W`jTgXmBmQydQ%!QEMGhEmHSMEL5Y%rHxyjN~dhvD(nMb8D%&f-+N9p3&H> zL)JXw(@C1lC(jpReiWDs&Z#*;X$JFS)V3S6(#m^Ii&F3^IPcnkk2&U?bdF1p!ofp* zRhr<2{(ik51eER?_r~*u`&9pVHpt`hQaVT?2c>kdl51~PufMjtpLbco67lR#ifUVH zjAnPDNK?W>StHVtMks-0H*(1W?&_RNqWkMd`1kXxXqX0?>>~9svlNuHc-wL ztB&TL$~4Pg({v0O&d04Z=uuRv6pq!M9F_;t(@F653`h_{DH570fs|wG8{Hl*5E-|u zAeKn`dz{baWkVjJT?w89zg<7DcWK3pqyiH34~`CJk`s~DZ;ExoD7J~6PGHyLuer}Ulze0 zSWuH2a*h??+OSB?E5IdTZkRr_Y%?<(LQ8oCnBm{#0L-%oMY)mpT*vJ4m82zN0*tGne5#=F zcNz}WYWZ=Z+??&6hZp^)`p>h$G?OO4m`9e8K3EP&z8f5)Ti-km+F(&smCD70?OaVQ zCQXQtobg1|hI7)bp_c`E1dGmED-o;i(F^!6aw>Iw1TF>m$iR#Yqrd-oxBt2N1;a)j z4CU%8?ELdVRJpWl#S%-{FafT4#J%|4s&bc6WV2Hek8-Hu;OJIOtFj)ot45SBO<#5yhGP%<*Ln1qkseX>`{QA44hWz^bGqw*qrHD zGlT2UYr5l1HmT6*8Fs+ys5Oae6~uS@JA_5a*?V-b=>f1u2)PVI+E+v^mL_r99lnhjVYFgb!{(6&go$lgqSdM)hGLJ(U^yO=#Tcb9lhu9SC?#)AwmM^8+Z((M| z6GO0?6TKwx&L!>4>3@~X!ZsC0|7L@cI#K) zv!AQg%iZ#6{m06Y8Us1A?zg+ux9x#v1M6V~h1GIXLMQeF3c=uR|Fk`DbSM2`0sfew z-hpk4u{J}so;_^#cTd~xPq5+B_VE#1fSbqN@_zOG?dj>yyYK7GdjA7{ZMRxJ6vL_x z3-Cs@{&&Y+1zxIm6?13et4;NRmy$|aMz)(@%W@0v3{~!af@$wAm8ZUatdT;uig?~R zPEBKdOKAr^y?J{9^`@Ibo-~b{$5L}fooHP9vHwm$cx5GeW5Z`Sv)8Sb^f3~**uH~? z^F2N6%z>-Aa5k-e-gM)hoRZ2F=r9pX6P_q@CV4v?h;5p;1Nd%o&cLL6%g0a5hvWWz zY>vy~9QVjqUw*vYeSdk*Wvq&{K>DLbvE4qoJ5zt6>myOTYRhB?h2-vexmi9Qq~eD^ zP2cPLE?+dX^;dnF9iu`QUB{eCN+pvTc*jt)`$H6@P#kx?4uY)9eEDtVq?0Xpm*Lef zujM1cDB{R1jb(1(=C17E?x|EDjeu>v^t}AXUHe7zQafXTcjHu*RR3OR9Es6B`<%COpYMU%t-PR-6w@ zjqY(_;8?A`t9y2jl|bL_@4rj*oyhN;x6{N9QpK$t)sQN_?5&EoTh9GXMwy#0Edxd^ zve(R^kj$KKK>mHM2zRqtcP>)(Th}?vQZf!{$MYK&%83J1!v@@z^PfM-g2$TNYU^h} z6_@d})Y{Jp*4skn4}Fz*+rmcsR#U&yV5S;q>K|?5Mg@3UqVaT0Tcl-(#hOcr7!}+! zr>aQ&k#2~EZtG&K(lLY0x$e53o%yPN8kzYD-NzF;i^_)WudalXYTSER?+e5qH17H6 zGzH9e5J9f`wlRopVb*i+Y+>nee!FPQWWb|EiR)E12FQuxd9{1&7$TB@!s^|Cr$HXZ zSs1|};5Y4COk%BWsTNXGt|YcSP5>-Bv|!GX$XkIqp@<2j2{zORSjXerMtDO?VJRpl z5^;vJR-#s$oRwJq@pxAkATdm$Kw}9K%t%&*3!?)Dd-cz^-LDZY5Wi)-`8VuQzpQv5 zx}~D~udQ2Ez-F!5#v4@jSwpL=Y5Lh}V~Xz}N4`sAptpq37t{l*eoD!*|3PdshUP|@Xi7;~`WMuCD zaX5CTw=-8_yDF&{uB4t{*c%%ZRlU=tuog$bDJ-R--Ix+3v>h05WI0AQ@UomD z>vAqjX*!m=5L0Z+ZNqU2mtJJsR4tCf6cT=(7Gfz}7tAW4g?fZqKd*O$m>$xvE8hl% zw|PmwiE=%?)krGL1;s=VPB<{dxKKOJ%%igSe5GH4q`cM43|f|d>R_iw>DTZiGl=7# z4h(8bzfOa6F>G`_mAFY>uhQOJq`j*YH-9NE*XneBX>V-UUZNnbc0Hn(0N6k$zj8$5 z`lCa$T;YDGbv8%-PvwwtKG-fWa)i~kyHz5tw%yrcOMi%LVwA^%z-*Ct02bF1O1uOF zFD#X%h)c7QLSVschJu{C?&s&9WBa9a_$NeN0B>&Bm)rH^uKc*WR}@MIGnQj`gYAcJ zOGt+)r<$k1VCWmy8+p1L8Ib+XCa45eq#iZRN0(18PyU>#?00s4pvQKVi1Gt4#Z@7< z1&q>^a#TdYO53Vh3p`42zqIsyw<>1A2{HePu7#`coPC1?)~XT30%1eG?BG#&z^xGh zDX5Q$49pGDnxN#M7$^sdcLd%%TuDXSt9knzj{|{KZ;z`obB;Sw!&r-84#=T-|F(O1 zdIN@Q?oF8&rZ#XAWO$H+IQxQ`BD>?=nY6X>u0cHGspt&Hq=PFNlQZ;zA5 zYO`lHdv?VzGqazoGICD{A~co6@&&zF?RMK8D2(m4MJ7t%Ns})PX~rd$7!kjGbVzpT zAC@etb_-z->-Y^Oj3z)eqPAya%E;Tp3d?0#0@H^UfO0KA?z*3!WsMFg;&>!*b^A3y zxKilI5TXH*hNGg*IA_S{+qS-Yyrr0%J5J1j7X}M|=Vw==BX~II?>tA5J1$o%shKsxz4=V5&25#z;dcM_{JiX1+N@N4 zcl9etY}ZqUr0&Dva{E`GZ2i~v`P&+@#=dQSZnnQdd4RNSDQ&8F0MB-Bn+=?usB%#l zS#EiAKPJ)cJg3n`X4Ig|Wu;EaN4kt#wwglfYjllm1uqS$aH zuD!TiQ76iI7A=8Pw6Y%NmqF6Sz7YJCo1+&igH+Xv(o|U`wV*m%M>MNGe%+OfRGESj z0FRsL*IJw^yD$#;30YO3%B<#Jj`J(4KplTve7;|NS-sx3-#GsD_Rr_1#pfc^^6ii9 z^J)S1SiN9q)%W$I-C6bUVfngTeEDO!`|`B@=01MfKJKf>+s7}y&G1#FI^6!&sI$`J z$J==l;=jk7?ZK4n(`9sz4moj)`)~3hP+(xf!T>;Ty~-J6QP@Dz`&gd(l1B(cg+NAR z9dgp*Y2~G+wD3YnU%Hg+_lyuC+0b49b!%sz;`!Xo|(eu2H3pyF1mh!qtG zQ#%(#`O>r%in8ijm4}g&w4R~jQ4l@7;NnpemwpqhtRxD&m$7GwTsB^aj0nt>5^0sg zQj4!KtQkdVeP&$0tg)sQP0Km@?W%#4OJV*4-a1KfuxV-Zzye@MC@q}~ICbAi6~MGa zMY4m$qNKnsoUH^Hw3xo?u`{WpInnahcqZdCm(vIk%mjm_FTyetRH*6 zO2$Fa(p$SPp>`g$z=yhd@uVRWQ2XvYTR(MeE#Y$Jv0CkzV_Z~Ax6ux`SbM!v9BC}6 z%T!zoH@KEg<$ z&G-|mRltjz2*J-f`vF*lNi!qggz}-QEa?Y=tz>!9)K|p6;uvfds3j@vnn+%VsezH0 z0u=8WfvO%S3OThDkb{dg+5O5x{$Oox5XM<=)?y4o>-D66w!g^Z;pejEqXspEx=c{(x_ z+*Lo!GSa4cZ9wNYOGqUYvn%1%!%i~t5Gg380(dLmuo*ps0o&t57QV}|_q-?DBUMHE z)&T~0!I;DVU^9j7@%+m*{b3t=aRb~V6@yD#uMEghYfPxk_+|pxCV_p}FhG?!gErQO zu_PD+FO7$B4+9Oo<1c*>FjiP;;GHbj2f}Q%D)i|i+HLrqu(OtzucbN?Bw^TyBc3+8 zY5guncOA%b z^vToq26De`JFD&s$JC-*%UV!-I5)q%7En8L0kr@EagFPk8;;QG^?lU&{8ayWHUwhi zfczu`;)pUp$&_p0puO3>V)8u*#DR8qGt+rdi3%2QQmIuHCh|~<#4K@Mu9Fp^(Tc+G z+0KjTjUW%NZ1(;DjS3Fw1Ubg+>3MiaHn8DLw!S|7a`X*_LMp_;O0HWS^`Aw~h}G_k zAy)racaa=OX}H92xm>%`+u4(-1SE!8usVRGUL}}(3Fay>cqE3Ab0Rnr!!?8EEHY?* zyc<6^on<^iK2us2(-U$ug4VN2y(sF{4bl@J*%lP%!u~%2XBb<57&qM7E0bOY^!E7c zsQKr+gFnFCuivwLpQlj*?OE1}s9(`24;bj7c{K&H`yw}K_vaeG`=A2(@m^3ybn{H#X#u6gVcm&!@iNXTAUK8h~zUnuE zz8V6IWq<06&qRLf(_VN{0LhoYyi)bMWmc*BhbE^~^R)g;AfME+v6D^8deqG&Wj*X> zlJZOiPMQ`BOK4`0m0K#-Dj2U2Y25dti$Ea53<4E^emdb5_APZLcMW97YrdF1kRh7S zsHEjmFwKaF8$Y5+s`9!UlB9|tMzm66C#f=n$7pbps?i8YaNqr*4%hSwopFpy5>DuwRn+`lfL?7#JQh8f+z08=yf$( zwt1q3LQZw;@~xA@SZy@Gj7yq!P|C)Xj4DVf3MGV^7VJvGrp(qCP)C0p34%y+@}ZQ( zh0RrJygXxVlZ4FlP4tj7W*AW;qR`QbDDzbRP9&C^JM(Ilmk=bl z7d4W=xkiN8$)*}4p{V4daK}9h%oimT>BtS4?!u#a13Nv`)<3gcMCHfZ>CagIhQwEl zzhZTH&cZc1|YnpOLHT4i^}@8_z$J4uX*~#T!$~_jW5-kr7Q4% zT!8;{k9=eOJ2W)?bf3p!ILFI0HY*ed2DWAhgay_;C1UY3l|;f&&~XZv0`;^pl5_>eF~TU%Nn(UqR!%7K%LzSe zg&49)*lfdxViJK5oElKt`LH6guo_4l7k`FXt~HiikDR?9Y0ZQf>NLN6dsx5raVtt_ z7_Gz*+=AeN>Q&b{&COXDH3uj9kLFk>St0(U#MS$I%tdeHrFgRC zsJW9lR(kg)jpdGhExUK6^%I;wr0F2b`W`6=3#RM{;Ubn3(W!6|I892kBxRnI=BFl6 z%JKPe_5G<*TJ4=&DfY8&vK0GiH(QElvT=NTMOPQgO+ZgSzC$G-Y)*D4Uwl43C{lO>#MP zI8#QNu5ppe(Gjg2^b!kI_&z4}I~fR7p|+fMxoCGfNij=>?w1%aah9N!BMNJjOR$D( z5}a=afCLzsF&>6D6xAgJGolkqDW~AiIY%|ag#j}ygiH*ug79?ZOV?JRtBfiQRiz#P zJVy!mbWCd)xYN5EgHH6An zlGcD5RTfU6bzz6@LZh}%cTls$$q1}^Vy&U^_S2Lj%piQQifbZDhv(V)scR02xEd3! zjSME39WfMfH71-(OkKXvay1s=lD$ptGsc+UovUhrJ0J>GLms%5>g|en%op*Pg{eN( zhCUF1dGG1Zob8@Rt*cMT;j<7EwqCx%8o-o3s)IlnLZxv}l=ht+-f zhC(DKDZ5%Z^0e~>y_%d`EeY{$zA&Ey{M(cVxZk40&VSvk?=N{~RFBs>}D1ftH ze%U(ryVZ-44VSNL!0>kS%}n%Z`v}QbKi2!#C#W3UqPDAnk1AmfBc`|;AaV13z1zRu z6|&pi_WSq45{6;H-S)6{hj?KJL)vaOh9#~Z?)Fd1KOpU+Y6yR>E8i7@Ghm{=IXKwV zCZU_s(WYGe!=I%Cjy*7=C*8elOHf91s9O27b$zMXc44>v_O^a{sN^7_3%TI#+qyI;-E;(k!}JYDE)|MWMtmxSKpVO{K*)#BG311lzr9odlGFkdYo$2}4c4@Tc`J%iHVS&u=gAhqiC8;pZ>=qVVwDesv!mOGO~e zu7e}lt?pNbl$B*h6_Z?W=WDyw-%AP;{Zu6}INvBSnw3)n`|zxkO5%O*|J>X|eSd#@ zazvN%!OL>@y7p=N+n-RIVmP}UVA=>9GK`90c<-H2Gk)H^9kzsM`;L30vhvxFbyb)I zBh%2`fakS2&TdW>dmNh;48j&?Eo}54xKR9&cH+of8`$A!hP%TUQAr6BG_sIhVsQVo zHd;794jOh>e#YL2?dGxAiR$`1t@nUe&&{{>WBJzM4t{(44!u(lZ0A(kV|*(avNJ}b z|9yLMR5YLi$VKUG55oC1c1)F^x70l%`#<-0Mmv6b*p(6sLAT7wU{?0gev9c_>f{}*wln87rN7U1m`kordb#}$ZPl;c`ZamcqI+P`2Y}xOzPB&LptnHt z^woz}YxLz$J3nhMRktV!1luI$qwa|hH zEU-4>7SW#f(+Jw)WFS}BJAL@BmgxHfd7vx$@Ss-@lq{EoNs6WTzEmScxOB}|AZjLh zqh_9#i45fOL9;901^Mn@dPz0YDN#Wd;Bx_giTE_u!4Xe!^+FUT+F;&_!Y@rFd&6kyEOK)uir*aspRb2Ol zZ*TiQO97G=ncz5PhzmlPjcV;yOVHf4TmAmF+Iy^~&#PTw=V{sV0iD@r?e~PURPP3C zw0S0OpX!}Evs;3YLhVHi&J`D04l=}FFv2AwDycqEeDX|FcB`qDTq7#5W#)`6hMDmj zxEO^eMFszsnqBv-1pD-_W4l+TF~7C4k9)5{6EgX*>=Hiklp3OCXzooJd*FZ8J7X?LHH20%JE2~Dd*gr5eLIMjE$TAse|U#x0VsaEV|(G+OrF8zmM#h znKt zs%_-qcnqbkBfI2kj?*Q#%EKZ{aw7^mI|)f{p!WvsyU~h9MOYFb zTB$*q5cA7m-*>CkLCDigpl%<9bL|_1#MF(5FpKFXDfc>?)FZ-Nxn-T2x=)xeMeUr@ ze(eg346ldih=vs^t-J&xm#9~LaL$#$3i<^r_u&@vVFjama%8ZAf)ZxBP&PU6A}*BMooxXe;Fs9X z`*MgkV=wo^-Y$^o&WGJWI;ztEuhC3j)hq7=-k%xoe1AOT!nB{!1cLp)qQ*XI98iIvw5E@ zG8|I}DohDR(n*@|vaAF7sTPV!!R*#z=>C9dB^Yg0F;lm6)uOG!o3zmyejHhj!UidHIF>SLV zgb8A&)M?$&!gEUyJ5y=v*5^@+6r$kyWOUH*n1<7ei@viLp;28W!20=B0-QhsJU^Ej z8<>)+#icR|IPKq_pO;{^+*co6{%iaEZ4LPuylsANw!eT>ZjE<OQ7jCkv{U?6z8^+j?1mb5*A?173;q`oasdFV}g$V&sG@>B@CLu5${m z(%mDM&7GO+d_+6m*ch175w26@vIGGSvzBF`L!-X@qo|q&5uqoC)p&d+LEkyha}IW0 z>wcpgx%=DQ>QGz8eN->|cQd+MU^SfoiZ-NdeS442i{7wuO_x@sj{^G`- z){N5Jks{f$pOa!_{*|mt&@I;J7Y+;~;Zi9fM<@k9j#2-EvAe61bycz!AQ$_9roH{7 z0Ms0OIft{ zep-Ak>cZXr*gmfoV2{-chk_P%XVt@p%6RE8{yX)x@TxwX>^_(qvs1=C->@%*a^*JB(x)$Bz? z8EF#u*vZRAPg{IEwFogYM3JJjBFWwI$P95LCA5@KF=Z&J$>;^r+f~Pn0L-{u&8B>7 zf^z2xWv+=NiZZ8&1>E0wrM)wznl-|Vg5hZc&8Y01n3+GN;JTzj2rklk%qo-a?>S1! z4ia%oc*ra?o6^$Dxo2A`xZ%r)AceT?v{}z9g(VThD3?YzPh(Bd4GR?f9%DH#ijUii z)s?nw+gZ5G^0ZeVq2MyKWrs@3dHJ^zr_*;bV6~nTtzv<=fooW5H`RrODptR&cIz#a z&ZB(#c4&!GNyqPRTgy^uch-jz@BGQyVq;Gf9Nspe(j~nI9+HO3vHMQ<>yO>`_4NtN zvl4G!*bBxezi!U+^8OyK7vZY{G;aWD=B#M(cw zYb6J8t?f%$Y|W{W>61%t3{gK6B6UqGWq@%-@BKUc$^P5bk9>Z9? z8?uV8dKrifY7`hod#Xie#lK~x^JB9C9Jn>cUJTYQ+vmzd^|3YDf@V@jO7#L9Se7SC zd?n^T9O1w|kOUSs+e_O^cT4DC$j3waTQ7|YvSm)E2S$&^Rey6{*!WeqR?oRIe7gQN zOnc#qQzJ-?sk~4@g+j@?i^p0!{Y8x_r5ItsxZoU7u7@k7;qHRF?+1)ewN_s1cF;(g zWCo?gEDHuL$Ka)E%+^{6q|(mp$!ze^Q*yOzdw&Ci`0!etA2p%o)G~nmrmj&@pM#tT z$`3n3%pRbc!AT4-*(6w$YNO=4G;TIfwb6!f*U{SFZK@~49K1H#o+_MbVi&sthcLOP zO4pMEBc`~C7N8xDDw0E@HPmk@Sg2T`=A zpAwNlYu+{kjAhbf-Ph#z^&9UmW-a07o-yHQ2D;}3=c=-fdAM6*i7Ojos(?U$?u<$n z>jo^>OY*bGSGd}JL0?Ihdj|;10dQA!$>moR-Dxnh3mq>eK>89zLP$!D zNuv-J<(EdS<*7tq|Ne&EbSe?n63-7Oq7dQ2LhB?v%+0==C?0L&{+u!YV?_t)1gxTyo;28+pzJ%eRO1Yj3acSnJ-OT?BjzX5jM; znXua)3N{mRCU^BI$ZNis-X}Z;jT1wak)|3`jG2rsR16x=>~5IHgQkcz{s~FvC+@C| z5ysr#XLLrRQ;^`s``rn86R69JeoG5kM~o`MgbR$tyc5irxdP*Wqle+@BH;Z^j*Gx- zPhJzyD$UUvu!M*9Bd+7sMW7kSxYEFR0^~6g5~X@bW%&x^_nQW6(q#Pg-JZMft~b*%{s8 zqwRn|%_$?u_CiXRMuS47*Q21fOqt*!fH}b&AsahC%%VgUD5Jy)DI90U35_gk1ehfX z^dqQDn%EFp*r?rn)=9S6Kb{dz(A9jYjBROtYSMEZpC6aPpPZ}J-pS2nKkKIEvY&P{ zb9vUIUvO)skDlBjZ{r?tXpQ=fpdz$}vPfvni{}hQFdd;NXUOrpiKdD}(haC;c)NKj zG*RLC)&XCIHr>seGeVT>Ol;Mi-ezy@4=nqIBnH2_tW1*_`~%i*e?3P{zZAT&lPYxF zET#t*A~aVyEQASZq<`wv0gbo^Xv0FJ3L)WyTA2_$EW}VeLp+5aQO-k#3VFOYFcfLr z_oIs|EHrF5S6B#|Ks;5@bmut=J5fxj)JCLXh&qnn`LI)7cf(*OB{}ALT-b>z&N1zo zB`6sb3d}phYA6+zL;*<3iNaJmkr)($@}t!U_`v z#hxS>lC!q%-rG(vU?eATA`KS^(e=2$}&S%?ex&K;iEX>mIsTbB>mmnhiR4hxVsi$7|^T ztB24E2Ia~~r0H3diRM&s!Dx|b(+?jBO&vCq5@PC%?~|uRUx?zMyUZP;AQ6ZnE7YJ@ zs!VIZwL`M>4ylIT9Gh3W$?^(&ZL=B6Uo@cl9F@c z*I8uj!`$)%ZbNWe(oHwi3~IkwzB~-_4J$;;vX?JFU#XGP zO`>2dzjBlpIUUtyY(2(N85&he7ImS0id0vdh-wY?if8!z`7reeXifx@g_Sp;35sq^ zl@~N;l4#;2BC0TbLJ8tbDt|TZKmcfRa-+fJ5W1_Mh4PmtxfjGAYT4^^i)$UAjL$(p z!WG;HCJ+brr#Q(`Sic~^6fwedJUM+7)X(W`VC5gm#x46pxF%$3IRA13<|t=E5-|Wq zpb{&|0r zRbs&<0qU3!bo{_fQ-%`z&2oAn#7Oo?ra8Tg?g2HP7tI7-VL5(Rm?NE-Z8#^IHs?4^ zn|k{sd9RybL_w(&FSJPXY%;p2R;XvJ@c03*?HcX`4C8IP;xQ#5z!`Fpa{O$3{!Al? z?Ll$Ui{hu`an@82M*Sc=COYnYdzyJdU-{&D-Nihchcn7UHfajeOEAPHSX&8hlcG@r zXkhzaF9RvHI$1uKLOMQ}?pei~6|TK0dAPHmlbnE$3a17eOTGNMb3l zCfQ-D+#j||jJ7GHN{cyC<`i{Zi@Ph3X<;usMqd7W{juH9Me_@5^&XaHNo=ghWAn@m z&_8_XbM>XqhcETA@l-?}az5{*vPonC;ejPk_neuHusA-;@%$}`y*40`CueqYjdU9_ zoRN&-!Mhc(EXPc?94W4iYDKBDO=FvE2`AWZVeMzLrOY4JHRCH4v&x5dC3q5I)e6rs z*%`aW<6@z?0CeF+YET9@J0;-~ib>-fD<VGOF)8}s3#Udt)9B`UI8M@l$Ky1`qB0wY2$r9ETV=x*dRETf% zqKwIv-qHlT^Ci?PJax_#1UouZk%Im(!>$oc!&1%{3q2k}k{Y?219^DYFf3=bezKhJ z4&HRUn}95wS8XnWUIG6C43H{1PFJaYrp5~Q)T#MFF-?v}+ zr~1!xfi!Pp7mLv%wO9;AEy?T{; zn9et}=QMRsuW>qOrl$ZQ>Bl6U&7K3!e0DDJ&sN;xUvK2OH=8gnpbgGXS%7D9N_dX4+k9G{;FBC75Lz=G{A$sX>oth*o2al z`;$Uc+iB>-0UFU7Tf;SL0Um_cXUK4LW9ZM%wgWm=E*%Yi#C~pyI?`zc6p90nJJlXtlHO zkbdLB+U7n~$baWBZ`SvK(&BnlxekWjR<{UIZ%Yppp44{z0N7KTmRkD*K-b$}OTaP~ zou?Tq07XZet#`lo_}2FOYp;edUfzzfO(ZA%6h=`L2ttG-$+;#*bYeJNVFW175VdT+ zYG+{Cd(|tD$?6S6)Zb%niSJa(??ftczgme0jaH1R?_6pv5G80ilFlmQI;+gf5Yew* zK_9L@8=m_w|1>Vo6?7DyO9@o1ppf3y+cdUYy=&c^LUx4|v4gRZYK*MNjGM|Sjwr;P zYBxvRn<~<_EEiBY4xO9p*!4cN zTLQM(;_GkwKLK3{T;1~bzrU^aZa?M2=hd!2*I!nop{snCzIt`QgJ1A!tW6Kg5%LGl zN?d^jxcLcuSz^^yrWr-1$+N>xBB&;aRj0RvoL{W^ZDO(NsvXWjJN!^L{avf131sZ_ z+F?wOvhX=^cl>r`pn|0&%7Uf z#$smgSB>o7(3Pw5aI=9N^AsGhD}%W#dI-n7 zFoh?9!H=MTB+3H0488yi^VmCXigZNK$?eW2mpy^V-k@0w!3<_q~LcT)<6f4ly=7{9%NzuWt3725=`cYYo1eX{_Z9mV4)=Zz|hn9zg(;gz*$g;h7K)bA1thIB_qkXR?; zZ{WNgKk3S)%r8e4LEUA9x;xUQapoG1Is?PJSG$9=y<-n~+r2!!LGIxXt1^XtMYo~*~K__ zb`la<>b|Y3bI3zuv5|+}wn$n6FtHc2v8zLTm&P3VeE0<87-2!|=f^lMFY`HypEg1C zvpe7CBBS+2m9^&I9%q;hUiIlY=+hH&nYrhwm?f9#ZZnnQRz?0gV=mdN9f{NOa?|lkDhL+{7~CQ?A-~bBk>Fsd+8zgI{&gT`RC4x$>p)=5ibSRT z*AQ!EPTiO*c`bk3jHAa24lIAn6q1OYEg$`~)gVSMDUeb0fC!E>1OK*wGQ;3$)3Yb(vEU78>f=F>H@**M==hb&s zzS5PKQm`+swzWqjPm;QWyT6`|{^7hB}d9?t0tX{a^ZoaP{?ar!)56jo(;>#b) z-Iu5JH}~<=_Hkc5-afV-TT_DyReMWLA7k@e2kmHG>7rHiHq;ig(q^N=F3UhY?ZT#o ze#7W1WnY;%)YJAJkw8TtJCWRU6@j|P5q{Paf`Jt}!)ch{lIoq!Eo&}E)ssSg8E5I`ofam=I9jz80 z3cYeR`wH+B0ME$&*Q;VMbT60W3SZc{76L+r#?RWq)Bw z5EOu7k_A6V78XDAicR$?p%^3X4bL)ty8Jdps>0U8Dv9%C(<%gcYJrJ?io)fjTU`DBPTiVO4Il_o0 zXdDM(dpx$8>bKi4C=#cAE%{q%=A4VQij24`@7gBfOzu()c)`08a3Gofc*I;(N?vYA zIg?CAwXQa`pH4J1UyzF#WYb# z-DO}vIo&3~UWJ#EEXuAXbvXfWJRXz=0)iS6H!?6wv)GtZ*Ewe(sEno7Qe}am2Q1G_ z2mwwX<0ItVb)-gpgrLxxPq53MDkQ(+}74 zO7Ws0W=xa{;ogX=8(hXHKAanzk->--1J{ z->=CGW}D35UEvw6H$HA$<`vBO)LPd6K5{aH-qAXs(LZ1^rgjRy)4D zTPnJFuwL{>boq^OWk=c0YvD#-8*RrL>NPd{WSEoKaHA65rPye543IN{6S`L_-K-q5 z(_*bPGyft%q;2OKJCcw~9tisb#r9YvVd3^YJd$vNdmb~k2iHBg*?yz)1*@tBH$qB* z7bwj}LL?>XG^*iBAtNWvObTwPC?7N00I*&u zWYpQr9OR{rIYwRRqW=DRf4^TRTH+6jcxaKwn8R(}n*(`pw*A&<@j+e3d!h;bz?lhM z$A?+vndEp}qdb>rs7ZdBQyw$QD=8?Ym}wq22gHDtKwrUq?&UKM*)%AycN6$1XIOJN z2ffJ#TI`taR$}vaI<0}YZQV4|ebgqVIHWbFSpF#0G|}>zWW-fOruLWV)2t9n^T$7n zeX=$b+5wN{3mK+KER9N*XNpcT*B22qX}!(@oH#3KzhLN-Q_TmthYJLfz^ik3#wb3X zbGS5Ae}Gw^QHJGMiFvPhduJR2RfR}S!IR6@4YsP4ga}<703Y##Y5kOt^&#Rp*f)a| zLXOmSyi&X$@5s8JyQovTi zaA%m&Fd7dg*JuL8y58>Z%}Gdv*D6iJ*DR^;#Wh+c<8zQz@bu9#L1;9NtZw|;v>z!Q z5lKrrl+ip&2us2UXK^JbnnfwStAU|8Svi!V5Fj5MlhfLO;AZ;avZTHA+V7I=J{&Pu ziLZN3s&Azk=sn-ZGj>wTSajC{X5*PS!%nn(eHP1aHXgoK3>V4P!6Ox1F>2IqnFu${ z=h$5h$DMJE%gpoQTZ%+SNhp{r!q}T=9-8-f<$l z<5T_T*&v2<)CU=8)hCTKG%SRIcKiw=*8X_%C(fBt9*WM8P(&hRBiK=rt{tz|w(kQe z3S#+bItW4(q5)9C4XoHvzgrgUsDEhcbu>@wzXYmv92+~uI;=HIZmAB>RI&?N z6n}z`h9BX6DJu1*3KeHt*-+%?2O3D`?Xh$GDUJew*Nou0AtXzOnY3`K28vyiBi4o?Bs8t&V;1neBaB49y%=6@6%y7TyDxgrl}Lw5=F~|kl>-|9xSF6985DlY?^}8d1*n_o zWmGarMm#L4Ljt`}4z6%UP|9}u1fSWLA1`;`U!HASc=70IYe-i4gL9&}z|MKDd+OS| ziw|2TdjGWjb+=pn{$?iVNH|@?GUilLs+5(B^6<`ny}3W+z!Va9b0QWP#Ks)0^>*X( zF~d9VS1+%n&4O@@xLx1R$XDhfZ|=+p-&S`|hj;-&!fZ&(|8!I8 zosP8ZU*EnJO2V6mDVECxkrzzL3EyIuylAYQy*c#L8A9vR7K!<_TfY{Vk`2MMsE+1J z(yktRycPDZ3wlvBGUBenwA<&yZd>Rp4k7!sgvZc6xX>CDuNWqJu&F{Hynox7OJA&$ zv?jNFIDGI(Zmt(@k_+bsm=3&fG=AaYa;6c-|K_e_VOVw+9>S(w3-rxq-I+@DTNf|x zvIx-3d_)zow_(M6JPmaxn~K$PTU@vNp%$?3diQ&ehOaBY`X6lug9fd&A^s`$8YXO@ zZ$Z5N58iJpKrTQ{EqXliu=_-q_bc{Jc@MOqe%Dmko2@nb1^&_|ljw7J!AzI1w` zejzrt5L?XROT%bk>y3-6kNn;k+3xF%9LiFv>Qw?>4e_E#kmS{RzA?7BpL z%>%+B8~w*7?!KXUQFzd4*>)MK7R0X}6>x9~Be^4uES7hj(ne(c+HlL&?hnv{yMNog zJiP&HU`SXA=iSv_z{n7IZkwQ+1^2E&{RUN%2(!yAC+E?E!mh0I!>7%AZ|v}W>wBrn zNW~em)DglP@bK)i#BZZRCoCO0*{oiFZFfKOR!_Ll2qd!9ecJ}zMv1fuuwRlP3TbW# zpink*c`?UpbwE>y!bod7KxMVtZFeB=I)Wx%#&mFX`d|4y=8h7WXnRn@+2M?hjPqrx zS?q8^HS@|>&!T3|iXEPxPmPW^Ch(~P!)asWS*&XapMv<2pTZwKJu%TjNhPW6@N#4V zLYmj8B(~?vk+YnTBMGSmRoX5S*P0QNL}G%O65e6eo3h&MS%_>Va;sS=Lzl++vbfc` zRE;a2t9l%b&n0lH5!g`T0hkZB8X2q;hy=m9(=Txv>m*nL{TATZaK>5oVtdvO@b>8E zUeecn1}HAt+l8l}Cr)oCrG7q9S*}gPdHAKX)3aD-vv~NG#m-)pyg0TwGO#I7f?H{` zGV6VjMf2+B+&?U>3txCLyTtNXnvy82jh<)eO!wQjO~rMQRbk|&jwdmS z6!OP56mH`Hm99G$jAQQ9FR!|$3JakfwD%aPstMJS5hncK2lCi7BS(@`p+ap7S9rHQ zxR#5?6&`q0o|Rn@Tlccs-R)QRt_EAa)OuHE6>}OdCaSn`qNU>1|b~*NrxBZ{C{4`t&`Y3|SsFsv0DdnNW_hJ`r}7 z^`j0!1m=oszdbCb3lvrE?L>twT|gC%1QA_8a1k&V1$6;QbU=^s=>q*k=C}wPRt{V_ z`zkVbULGbgJEM9p`rcI+n4vCkeu->kPY8k3g$05g*sVDzElX56%>B#qzQv+%tBf4C z`?u%kW!Fp7%4c*3ywVSr@+3H~`*&E=+F@PWmbfOBIPh%u zw%Jt45v(T_GUHI+SI|T8N{D7ch(?BHPNV;XmGuv#9bFnU^KWB&G*A(VIrCMD@MOUc zq`)3loK|bBC>ganEfxeT;;(ocl`hX%#p{qJn+nZzk^K-WJVJKwV0S^?!Jia6l+wLh zSr7}1?Q-#lE=Efynvv2qJNF}#T2forZoPDH+GIs`Kn>-*Oh|RAiv)wn$uQ|T{$r;) zP0C4XbYVh-Q`a2sF*Oq|!`(PS`=h6fW@aZDs9s50!bAHJ*YN_YfuF9tMV4GS#{#;CqFoY6C7}f8M|6d0p{3C; zvSyq#v3}DESJ|3wExon2dR4!I6olz&c17>Iuhv%25?TF5Kd)L_8$U~H^_)u?T0eDB zMzF|Xq=p|@CNNS9GEm;pb^$$6dB?nRozcRZMWMy$v1y8amc|0)O^D-kW)nJ~awn3X zvHFdmub6zLI8wQ@-rbu1Shng|B}V7l4TM0DY2A+QkF!M z)MI@()tusPdgZ!mrSrh9Ra#E9A+aKHK z)dJ|LdVIg#d|y9yyQv;MEMJ$4FMli#^-`^ePus_R^>F*xJiNw>F3tkU1eQG|+0Qli z-5lYH)@$!6*-w>4l##ZTHLD~}{iRR!pJ&5y#tyNe;ac<8>u`AO@*&yFzPSVnM9#Un zeXz=~E>Ou+1aa1p+hXd#G4)tY4&v&|A#|1 zg&EZ6j#((8I@Yy*cV6?x<`5rp@CF5(7h>2s#gt1;g;bg{#{)QLq2g`}l1Q%b==HHF z6<7{+hM4x&#~dP>UEm6dJU{GS9t>wHzFPVlaEb)8a|o6%jay)LJnxG<_?c_7mn;qR zpQ@~D3iM8l;G7KVXDmQ|HC|2>;oM1`y-4yc$(qLLi^)PvV{~txiHgIv%H49siRQq2 zY0fp?J24CDd;p+8U%$BsveukS>e_7&(@OJQzznP8g7VS*y8147f0N_8aQ>r(Io1Ml z3rs#)oH48uePV!7wvS8FO8UJQ&cB+|AGXXD49b*V?}ey$0d%pw;cBNK_Q832zxT=0 zCJN6HT?A?h8-J_dIl-u;+VM5>!E?uCYHo<=F^Ur-PPoNe1JEl7wjGzCgxiikHh^2} zjn;bkLAQ1n4(#SU>;iAj<1X~(GhF4N%C(jJpn8!I9_+|HNsx4&8V8}ux-gX!{FS4x zOh-`V7mqOzbTVk%2%2ABqp=nrJ1q479y?J-2iS?3*W3AzEEQq z6^z@Sjnykj>rWMTSw%Ub9>@Md!zE^9{E7tFR%nsr6qsX%1)X!EMLs4$T#axsiJ?6M zS)qh-C;8LV;8zz2&>Gr~1egX>swrR%9Ege;)}?e}w_RiGzq*>j7ph> z5~f@ZqXzTDeS=^%=oFqlo^}+e=N-UNNqmC{SyXh+7J^7IP7E9sdy|6VV$?<(*_@gia{&8~eE=n$fA*6@}M z73tt~8>>6hs0(2Zi8nfa-bw0_WcbDQmN~uDhCD3@=HVoXo@gWa8x~)=_{vnoE<8r? zSLMiw1+-bU2WauIJCje)->(%}ir!{fk!9`~wp(`KYgoYHwM&YU`BeXTHi%>F%$F$; zM-G_LdR8GL0&(eVW(LI3eErAE=kG7iX6eR&ObdiN2$+ttGBDYSabGv zEm8(@I>6giGsY=kCOw0<>uk-0GdhbIu~Fm3h)fhnQ(|R;C?ZsfX?$MLhig0Xbvquc zl>~iIftA9E=wT`}g9%qeLk8_(P*^WGk4q#VOg$@*3=?L^XBtG5648aENKVC@fdre~ z6jC^8?b1OfD93XaB22l^j<2?F1Z^~05Q$Ync=-lzbJ+TA*o3< zGx_)@-%nl3M8r`v7J|S9GUUa!)Hgs4W*QYVEf1NCQUYhH&TU7S8#eXQ{8O+l!=H7fUZ+xlVEaM&i;{yB#_Ar)+(e8u%{D3dV zu9{z8^ODUrFWI{S9a?XEyyBV8W?vDP0&$tN>dQokOT)(oAufj|c3_ATak5#%6g-3G zM?5o%GM?rrb30>bEaniovA;)Y04X7OBu#21jxfwH>b#qV!&I&;W`S<^_l8${K?(mW z9{k~QLn?eTO29Ck2UyaF5i4S~`3;{u7N{z9Qm7&^TG?^1dP*u=lTn;ztK_ot<^^+BQaxiqD?k^vq zWHpeFY9uUzvV-@hwW6_*4`+#@ZmZFA(UhHG9AT8WIQ_5?rZ`Z+r4HUWJPsbX3K0?5 zJFo~eb2&^S!)b-?t(>t_dcsb}ZGxj<>B|Npo~5+n;sS#xWmU zePKJ}=&^!l^My^dco1ZyEx@3c>bDm#86{=(*XizvX&E)7mQ(?$5N2U`7~R4%LDHNo z>y|QtYcl50HhfTy5VL{v@~xaiCxjVFtFtYRloMuz`(btxN{gzV$+vOTxlEOUh*GX~ z91cDRfsJgF>j|6C@bdDsH2a7OjFhnf%m-u4xw4%=s&U1cQ0M1N!`GC1nh@lR1>%fI zI6qjad{SxD@~j!BO|0j%!g07$uI7h~!o3zyhaR0I3ODK^gQZZENJCPUu;s}fPBMAj z4Rn)X=HGE0WwexBh@qY`BNCAAzPEm|umg`lqhB_QY8SovEQW&u!Q&h&Cr=}JEc!-^ zR23-{mq-$)U_~r*7ea&r_J@}Hs8r!;*QvXT;$2J<@BGrEMe2YK3#uGBio`q6NCJ1T z?nZM3%CZ~HPfgX0mFwRcKx*w4BZH|(d~f*VHz;U{|;vT>ac69_UUniN>} zlr&!NJ@}&C<9h7Bo-2i z%>qBzZpe)c0+RdaCe1&R_I&I)C{9NF7EY`+R53h6L1AN!ZIu=EPxjxgV8`shjtQeiuEkGIikdi^eFZxTu*0rd@)_6Ep%>U; z$VCh6_^~wC@*iCTNU3nzcj12f{9>-^=Cvjf-MCF7rr!T_DYoI@o7dZd>J`JWZNktJx-o+5tw)kD{PAVE->)9L zFPKivitJb37g}TUBOe7{2h3fE&G$E}Kkha(6lA?}0&9ykeSL+LryKl_e?WrN4Jm&w zIMS3lvEMhed`dV{)J+M>%7>H~{m^;F%V(N87KNMb>yL6JEVmKw8W@_kF$8@LD4C5^ zB&5PLkb7*m`u%OSccq6`2Sz?Z{BMbiyxQ%yyV6<9P9=Y{I{;H&kjdSFgBXids{cv* zIAbk2WtuU>ob$GBNe2Jt|M-`G{_Vf~^FMWoyjhe3L9>Lt12}mH#h5u{r2KXHrk!}M z{`QaM_nqNOtIb2exygJF+~NDT-OdmfU=I$;H|F93r>zd+92I^!##7ruGz7I*6TQKtY<`QsV#bARf8qeEW87A4 zjm2{4`EA|@XN$mmIk18%lx!FM)@XrWP zciY+WNZr2~5)mQpPi8ts#;V7`84{E@>(LQByN|sLygo1XhL^kcaO>aq>V?DhyF%Z? zdjGO~HS#XB)W;3FZ6tv{LR{0BF& zbL|$7sAN1RSym(Axp%b^LKAsrOR`o9F@>$nTsQYm>q7BZe%tO|%LSoS+Xvbw$@nDl zV`uj29>4^JrnIICN$tI)u0mRIazCC%;fO8W4E#PZ+?BYY z+ep2i^~=ybq+O3`WuO?IBnlFVagm@PEDk7+v^9O78156B5Av;B<2oweI=`<3aLknw z+<96F;D~9vm{UstmpB|}chn_#;C^C9&T4dt_S#=1p%X|#|F0e2GA`sZ)Qor@QHnMm zH$6nDhVykr1)I72=l}G7{8z^o?&^}fOFu#gQx-^MJ<3C;ddLH#b4CZM$YhNno4t2_ zEkQ9NCt6M_u$)+lgZ4<$vC5uen*-jMV@8m&W|V?>X(FX9U?dRl4ksjIdnHKk5}w`+ z>k~}9i_(=GrRJ2=?zD$!;p55j7a)_JU!)q{i-wFTQh|cZdh^}(CB1oj0RsWe1-?I? zQSX_1EBWbN8Pws_8m(^k=Iz(>2!iuLS1h)21Dov?k&aTC+lvn9?1 zKMVhkBp$z7es@Rp?FEdVUjqW-L4pH+U(D?;cTg|umlZG~m>s_DK{oh(x3WD^tnC2K z-UL@5d>$JgAmE!nSAX7l#uFNm=gVMl-Qh&u?N)Dq!YMG4hJ^^iB=2+_5URpnHH1PgNhL2IY7|Kj??#c@fbq}WVm7)P zm28Q3P@WbyxZd!Q9U#Jh(d?}ZD}hU}``z2n-)Q@52}Hw0+nE^xVMNhpaP(0-37og- zW_|Cyt)=-&$Q3K=%-D;hxj->|;CC36uPKpR1s)!IpH8Uz{dMpq~ z78Wy$2C`KJZ#-3C;d2$V76p8VfkXE~@D;x&>YgC=AifdKzUc=kSNHeg8|R(L4G0{< z);WM8hracW9Qu|QIdmSz7?T<5UJ7mkN(a7#Vz`NEm;v)0+i^$pQOfKP3GLTRsz{H#pbBvU|RFt0fS$TKljV8fPc5XvKIdM3uBbUUT{0N=2Pu!TpT%*KQ4H z6YZ4!ND(cS!gfeX-9JZ6yFo71$SI?QaqN$w0V1C3wwf3Dg#(Or3!rty*x&Yl0=f#g z!VACoxqSG%+7(F(URJxigOvRsS#zUcC>mIiNO{>;pkMV~5BoAnhQ56=+;zj-$(d z;|Gkte<5)`vfs>8?OtWS4`USh|HgJB>d0m30+UBRIf@sUb0=EXmR^`sZl#f4m=wIr zyE5bxLl6UbX?^lZDsQkSbroxR&Fm`H3=nI)hr6Z7;1o@!(N+X!Tx#!qB-kk%e$;|E zW^JdGtHg8>64OOU0?8cugIo6!B&NYaQ0v9G^ab7gkhQE5GqMb3#|&pP5X{DQM$)ot zFiRnuvm!>xHvY2{^enP@B|{%e(VS;GmHImkvjTh8M6U7 z4({J}FHdifx7fp~O#WSKn{Hip*gb?QY51--|8^dO^KB(Crbf+HO54h0<9J~-a_^_> z1533KNVVdJdMlbAM#dReX}wBJSBa^5`O+k&ibZD0OawQD-p(&njP98s(^IN!R50 zw$B|w%B;p^pzn~mokCa5VxSkHHC-8O9*lW@el-U;?<#*!FMrSUBA>>mG6=o6Wvr0JQ9P+p4=OvWq=9nkI(gyZVtJTYT^9ViLy=^v!M{aWDCkT++zxouW zzqZfc)=-nT&CgAhuP$91=@(8Xc{@K^Nrm=C&uX=~t(Nt+UPpjV)>($?SD^7-vA7R_ z#a+W>W{1Un&@h>QKL<#bV8X+K2|oo*i(vLJx9k+AXSEP%5CHO1HU(Ins z2>rW1eJfZ8xd!zIc?U_txDw3q-`N4V z)(VPL8D%-=nj_@qLT&ao7P`APQ!m|T`s=-u{;#cb{;=%ANSSc z?c*2UUA=$YZQlSdIde;w_xIpoI?%(`gfc6Yr?d=|E8pxJa=!1yN_AH8*W|a>c zM+HJCl>||tIFpj3uN#z?((1gZ1|g(kKxE{?m%P;OLUXO9uqbFXuB4F`)m+|oaPTCw znEPJ?mUG0#8?b2ZC?;8~pWdU_?gseE98MbVFgxGP=otLmVfD@Q#l zFJ56v9C2&SDZVQr8e+XMtQkeNqy_i+y!`uich{W~n8l!oqPRPFdN6_%qmHuEyj8lW zFhb2Bocf~$E!(V&81uUPHr0_g@>SZI@5^7Bvz2lW`j9fO77!FIzdgB`KgtIIfj_`I zip(2HLcjz%OK_fv-|H(-gGQ9%`gw9?82x9xg<^)vr*9ee`)vbO7KrpTgfYJU*lk~5 zpTLl(*5v%s#U_1vt**{-q@0%b-#v?xu%S3zz5M-cYr!dYXKDSER*ZdRXtEdZlkcZ% za*vBh?s3I=t~k#JzO!dGJJH5O$jnjsTNsNks@FbBocYU}V^On2(Xk@=mC)M0~|Kf{{VU zRs}x!3O|kmczH(@0qE+Z_V;fO?khD#@`&VJ8D`RXI9hh^=6Ea%iwK9Mlz^LVLf z_uIqzHQ!6~W_N+}9(T?{T1m-r9KI6V$duN)$b6RQ@s)fXf*bF54GTMm%-+>zddHL@M=Zln zfGQz`bDc+UKv0+wMAV4R5{eTgG){AA7~NH2bO)Ifq#YxQ%^6Nx#I{2N<&+5t`6>)W z`oXo%@wg~`DJbU(VQ72_j!jvsa&lJ+%bA8S#he_ai*(nQIrvBo^KY4fq;=}3ax8RisWMeS79 zhXIzxDJnR!c~`*Qr4O{!Ol6E%x=Qt#DNd+Pa2Blq#5`p0e2`#%=70I25!Xqc|R8eyriV>ap$qnpv!5NoZZS)sWJmRea9mKbKH&7};%4ZRw1 zfu{ZRnjS{n6f+$u4k68qB1`Jn5;6VVwvCTU3Jg*E4C}Gc9WiyoqlZ`@v#i%dYvd?t zC$cn;9!-{HUB^_JE0zWXB-m()QF3vjt^Sfsp)DJ>Qo>dAfB~G?;%wS8O(E9P55bs- z<-8*sts)F#w-DK3R!JsWLN#K*kggV5YaB@<`zRLL0$_FWAXV=qEwSK=kiNjcC*Mz& z*$ptR1>C%xocUfiugaAR8xe)u1!)#7FR=1);$WNN<)xJVkYav{WUIo26e%@?B@acj zRcR)vc5559jHlg9WIi(@!vuBb?>7_f3!7j;qAdg43lv`S2<$6pUyj6gAbqggTH}vr zcq_bVee08Nj_!H79e2i0cANfz93LgDw0o{jQ}gJ3hBUNVejtx(XTRs-AN{HR^K9V5 z)JaIM^lTpV>`I;5D>*Cb)ZT^n67Mk)?8t=krJN{mDBwGSMV>SA+b62R`fotNf}-E+ zN&T$qT|9h2W4M9{&FSf+ZhLvt6bb)AmFpzC7kduD<1VQ`yX5fg#Az+&U9q`0LDSBc zG6-7z^#WN)^yP~ANa23EHX%|Y>N*3ST;0xc)vCxb=bT7IX=1+c#==7EI>;^BjE(HX zkVI(-!?8vjF`Z_FIeJ&s`(C2Vle$??~8@#yOi%K`-(HU_Za*z??ge7 zd-BQC!!U%RiGAZ%p4-RcgXZ_wbm=ormwxp~IWGIfW4@o-|352?GihqkOM!7xuo^1t zI^;Jk;K%vWXc-S}(|=)h-*1*L4~IXK&FD6|aegy;x~x{t^eU+3&h09wWe)j36T7D^ zsLh1Hpco1x8DkVvLX=Z7dSna+BdkY7V2DwG{g_U#Wlpp(MjAztw7{YVH`)*XOgEVs zm$;>z5kb)adzcv-C4!yE_!qF0j$s!XVP*SUzrZ~hf&pA$z*ExdG0p^lj>VRcal|3q zCutr1meTWI;K4OYYO=)1NGhuni^k2FLy8LR29+*qTnJOFv*sC}PSRvPdA`t?v1zv&bvO~6{c>W; zM8MqAC!CdJy4a59LF@F;IPVrpQED(j-?WE@1Z#yH$gvf#EYjkYF++@FWrs^wzPvKFD}d3x|}QtNQpvd8WA@oDvWd4In(r+okUVQCg=lPAOH_2B^o zFBV10n*BIyxVS>0!-g{w6dKfH20(@wX)T3fOfWoc&RVWQ0anmP#!*O)nZ!du!}Hv# z7_1oFnBZv$r_S~5UV?F-P%JryicBmLZTy5Xf;3P>Y4#r1nMllRQLW2JLkwA1AxI>x zgquJ(F~}+fVqruhod{4&7r-{I4Srl8W%K~aEQo*^bvMzF-vZr;QdBYyL}HB(;IwhZ z;=5Gxlo-7er}V|ltO&-geRYwCg67#1~kU%okh~(NGzEa)K0e?1NsOr3af+?6LS@wRt5Aa!Z=9)@<2e? zwszGfxWi$&s}D=p3OXp#%J$PQa`L?V`TAqKp^N4h*5~gIXLVqLoYQ&sf3p8}ekey- z0W3e>{$AT|bDwEuV zhp*p2%#l&f$~5u}Bg!NZLZoAk_fPB9=Jg6W+Hslz)Q!YZxBK3xo2O;s&i()Fy-RcB zI<_V{_pfkx)E&|3B;G*IZp0b%J$<@IHMl);C~etWmA2$9SvzajufG6aB7ub$NlBEg zQ`OmJkpw}!*5muuTAz_XQ7oUdKDuN~F(wpRNd8F0lT`ANF;qM)qF|~s-ARZeIJ_Rf z5xh5sH=bYU{&QlX%Q}QOP#`|7cCOiC?2?ZKAQOLYS09kscDG&rxnJ%)Fw)y{YkWQL z%k9H%`3M_!cb%(I9sh7|fOMH>z3J}n!7p3<_43f97Y?@IAA({%>aK3lbQi3dM^s86IV5EE^6F79ZjcD@cLuuYMhs+0M1m6JG*|R{$pzWicg_m zA;p00WH5t7&}g%@Wx{YcW;i}F5Xc#ZQw;>gk|CG=mkq?4hNEd!;jXLTya2&DM6As` z7;UCvZMa_}Ra;3AoWp7+4wJ3(5u8(#Em8z$Gc>Q8MK}FIfmGQC z-b`gQOyjx4g_b(5_x`wF1W$|WZ#RDW< zStR`l5caD^adeI1iyLL1N(Z@W6dsLYa_BolqgXFLes8wF@>B{boVkQFil%LARUV96 z`}lBA_vLoG*@B{PyD>q$z!i`Dx_j3vWcgv^j(rJK#k`L1L+4$--c2it=6vAK*JYX| zimpd|dG%A!#IB+U7DeBViW1IakYkdu1||y*?BEn>IfZCku6Hyp9OE*ODl9qIMxn6G z?T&=Pk|0cJp{zR&VlPizc3RewL+^WOx7?|RL8&VA>Fj^EU*t|JK);&ko5ozs5};SI z%-qD_a07Ne5^HjJPDH}8JSiu4`?t3Rm|Eb&cS`?z^Y(KEdCT_eU+c~9HE^YIkqP_6 zY{U2Up>H#ExBK#@6U1`80e^(_y; zEpbtMwU*{$EnUPZb|M??(uGrkwe%&aA>XEk0y#~0+zm>sj2UW^b%qTTkCY3fWU(!b zGZ$N}rsy!ud3l`U&waMs&CxF&K32Ea9L?jpbM73?gQq=~L|E%gOmU*5kdnpIJI9hm zH_fS{;Dkh*8(CqNa->zIX^YGXBsdjgGe!eb6P$a0M&|h!5uH)OV1N4R^XIxm7^oms z-;*>*h!mJjlo>l|B(KS<+kOmKi_tQor9&AJp%fBO>gtnc_Z^!B7ihAdFc@=FnGwol zJb6OsZU$vN#zKz;v{I)_znzd694jd)MQ$-*sJ$7L)D)a!p?F#*AevUP6-z^5F8rySM%a6zI9i1)p_uK33H?#5X|Jb}OZ^0Jp8y+|7=hchd zSbgzn@v*r5{?}sr{dM)zz5Kd)+0~afFP+QR%o&#e>0eQv&Ieq0V6!vb^Pp?pH2#AW3pPyM-ysH+im zoJcOYaB><(v~gZAB7s2BgIQsDWqiswMUo@r&nz@*>zhtQhhIpC93lE=V7OJrH;vHVQ*JK7YDJa2uz9?x95)!`Ct63>Q*M_3_|( zPFv%Ubym{&|mHo!O4djTrWn}z;jMHNtAbu@thYprxp)!_mQIk?m}qEsoF zR%>|XHLp{V_N0>Kh#;J`QBuAG6^d|@U1?i)hC?Kg$;)g{$g#-RVul$(Ua>r0a%vk0 zIZ2;9pVNDg3nEnF>N%Ob%d!F@2>Iw)O8~)5LM~`Y?4ceoA;rlAn=w0CLA^*^J*17bN7Cnl_HaT8OpJ z%OB!ituqQOJ`63s{)%k9rcFfW2)ARi)VvNu=l5(!WpJp*x*VHz^2;PXSZ==;KZ^gE z!+D6fm@|FL1KqB*LphMJ)_pF+3tQzlrg{@mdwZB}M41gB%68vR6d4X` zg%JrjI)4D_4fI`5krjOK)szICKh7D0#=b?il6Kp@_zEUa4YVg zgglb;rKGTO25kNWV5iH~d08G7xgqb7hdxu5wczp(@TQM9x-qhKc@{~Gk#fV`-5x~P z)>(~>O=L#Zqw}?tbp!_>yIj|gCk&pgnQ<%Dlaw!u(KZnzv)9$py=;LNOn=V2ik2Q~^ zG__x5rJW8V54RCAj54a+Fw?5(6j`IUu-*=-Ij&|ca<0K--d{#htxs$=v=nwF6q9zc zs;XZlLV~cH&N%p;@y|*6m>bU<05^AgHMwfYSeAx#GudCk#kqis7e#X#30YoxeUBJq z=}h-Lz{Q*9-*Z78|Bn-(v7Qj}xQvuFDJM1K40!Dn2<|ZO5>qMW3SMHA1YRP}`sBO@ z-?D!nm$yd{B8jqnRZ*;o6pH9U4q;8_6N2DO!xiLmZdm(mv`)(dx?D-f zYVUok_ujW^@8#N8;YNZ7NfakKK?k#OBtigVpsgNqzw2{AkhH(UmdFCd+GSSGA$s2sy_6-ouei6fhpD=4Gg4#dbQm!bfC?Z>Lp(}1M<#SAehzs^ZYjGRLq zxLh6sVp_KtS5%A%Oc{08=P)iq02a9nQ9B`E6CEr+fhK9Jm{#}H2sBPGApmJVdn_)f zWqRSIV;c@VspN-|M08c8oP)t3$UjKOntgDZ5zFl}L4e~mwf+!DDKPHWd>qwMm~&v+ zaPX~}?wjV{v%xe@0*tQ*(~QL0nJAn$<-jz-8twH#zj%Dy=v}!RBP%9OJms7;{2rH5M52sKc0OEj}xjA;GOp2u7nTvY+Ho z39f~q4)ED~A?BST{N&EdBQTDqbM?)rtTg9>)3oZw-Gb?|zzid&K8$4pGxeKm-2_69FwJchjY;R7A1lHj*la z>~ilNVkjzbVY4G+#850GQY=tjyLss=k8%`!5C zkeb2SZPs-|+HKpp)`XvLeTHO)XjL^rvP=Qilz!0WdTrkWc*Hpa!wY$Lq$O*LQc=Hd!zaO zctIGGW%|76$3*k}1sV%3hhW8V_!cDX0^}Ep`LvC@5fhe{km@4x?VQSCKHMc9 zoRIvwsnNl@V1Ig*S#h{GoeLx;i)Og;GJ5@(R?_D%1ypJk>64Q^vKSBg$WHr=$?^5+ zI4P5J7$%POJ1)Tm%D2UOh&0MZ=BIYpECi(b zjAcg6P4x{bn30ruv((Si!l4}C_r~`ZoPx)421Rq}Aa0mLxsWLrj4~I)^FyXK>e%49 zjNv}eKRlUE<2PFV2J`6*!)A>MP{Hp}_t5EYg>s`C>|U?JO1sqx0qrLuzpIMCyGP&M&;9OiSFO=Y zshl(Ff9?Jq^cLP3`Jsoqy(|=?*d|5X*_R_<_p4Q^iDF#!IXm?rTm3-5bTHsI#H_=s z|Nbsy0xeUsP^*v?egcQ!Vs*^{#q{I7q42y0Xk@=LQ8<< zVqL-jP7y3~lCIV-5AfCH`pI0}F5h3Fd4AozycitCeez|ycw9d3Utj;$mdSdx`vbo1 zX}x=R-E4k=Z~whmm0f$*YV_k~y6Qa#4R@ zv%8&5`nuVfJ9_UAR8wki12#+3OZy#*-QVj+NYN=|-`jHR9Leg}lMZKH zy$B0g+{=Rv>I%bTgs?hrCqW1gO*!333Q%^RKflEN=hPCHrc2!S&E^%Bx9@+vKRmy` zWeQx33g*mA(^Mb4HE*_&+e#Z+0-L9@;R3S8_Ovhl_0T?Jk&t?ynv_V3e2)9>c^ar|(7Jr^+|2oY2$;2wPt zJXYCKwbi0X`k|!Xyazwts08mHL6r-FYYk)lP&V-JTH@r$ChwLb-MvxY)Xj|! z)J6;(FR4e%6vxo#IbQxf_3^?Zr5;^v_|7OVj{ghBB)hh9Sg#8_io8$O$A#xX<=0qO z8>5eey6b3hKl2#gWuR4J+?>)mequMhr)P_u~W z55A|Y{ZBX#|Dx7UihF^3|8ZP{6-Lw8718@^Ctq=IeWT-sG42%ToBW?!F5~S>&+!0e z@;zL&E`sE(`rZK6l!rIKD?9tkZZNeQ6X?KCw^?V@K$;%BLx5E9^Jh z$|vK<4>g9APo^+p+|TClDW6x(>nxfVzL$lhm|?-BDP5URt>`GKmo*mWG(|Wj;$E11 zO04`h)fB03Z~u*%BKG~$Dti~LbDhnrnWgMqeTSb%!@Vkd9%XN8#9kEXh`oW*f@&S$ zDRpZvgSg#hYm1lRaM>s@X#~`^aC!@Sn)FG4oQ~ zqvd&m{5%Ktc7FLeH6^7dKOxZukbGT=uS@W)>Alt(gQzTEe8UJ9@%5|*?w{RR{W;bC z6P^C^vgT%bR;OA8bGg0w@dRC3}d1Y>t|Ip6N-@d=@f%og}TSgZ*Zctok zIcI0YJ@&``4|v4AW6*SmNR!e}@lJTum2`O}U7lamULB`1RVL~X9tzO|Yl#_BG3KLB zObx~hlnTa6h?H8FH60JeHw}5v_~m*>?Q_@_gl(pcLQy6NRf5}kgEeZe1ngRWe>B z<5e=AUt~=VDWZr8?2#ql*_?8$dPN9gsKA&zXZ68&ri>AxC6S*Xb#QaUUKahc$&wTJmb1jwRSeBv45hlbuj0xht|mwDP_Rn-IcP>HuJ@gO zs&g#g*J&T_cl)=uMc-VuGJZV(x5SJFH^0|_bCXZ)!NMQ$D?iC-M1wMLlwOPKboQqr0vk^Vd6N7~W z@r-my^|6|DXzQJ;+@weur*^o+ODvPAwt|q!C2Akh;Z&xqP)HCFNM(u$>Rt1tGR0DH z6V`L%xz$rOvrf^ei0m_Mn(98z1v@2b`Tp;RC0C|IJ^Xq5?eX^e^5e04$Kik8|NZuQ z`^_Z3z5iqLw!8&ftZ&dK!Sm|HZmhoewD?%ue*bH+{r0W-_yzJ`Bo0rbz{#YEG z@bL9WWusvkUI~&yQRzh~4U^Tm7R~c&@n6f;5MD+=u2*GtFh)O^KJEtPdJWWiLbd{O zqGC_JN=@F3&IuWnp@6O`n{qsut2%8vJ0dehH1K3_o)h1f{x<75Pt~cQI==#o`p$DAdMCf14>TSWwDa`MVO8Q-4P;BgD&bj#2X zCOC7gO|PBWdtKHNIeFQqevukZ8AEnL`{qNFO72jkOg`SEcc&Fh%Gn2#*L3QXDXj+HimcoSa-qV1lh2xT-*lXJCmqV&Uj22yGDGko*TOejxb+i3r-@ z^WxXbx}L*4-*)UNk7xTcc|x5@^||c_dfUB@?c9c<9UtSi@A%q5rEz^sw|!(4rmx=M z{tI}uC+>#xT-0k`ogY+irT<@a)S_PVyygPyCdI?8EihEj9KU(g7mo{yRlpY?HaoIB z+SkJBZ9k?xa*pfZOY%NRj3s4&Yd_*F(hnh2jHz9n<4DV^-Hx%qn5EUQp4q0-Z zKJp11vF$WUMFgcBsG^=KbdUkq3&LEd>oDOne@Etdfn3;W4D9Ak(Z+7OH#Ph5m(&9q!+$SqbLAzEuS z0+j%nyAm2F7eV11?hVr#DZ`5H>7Ca=8R-7G1KQO~2#)D89y&B|?g8jfWg37ez zips%y`lj^+y|%MrXd;>ttX|Zb1SYJ1cMv4%cQOwuN_+MTg+c@&lj9*SiPk{Ubd8(r z+s_3A29JpmAra;bGQn<&sOa3qke!^iM#4IrO^fN!Lic-Q7{pN)b#UJO;L$0!nb&u7 ze&-D0l28Vaj#Irex;xsknkFbAx{LxY!ThbOr z`TQj7;;3%Tq;b5$%xyoW)xsu+wx$CbQ^DdRV6W)_ViJ(f36(Oln<+RaN0O>EEW3}| z5;yz&?HS^45-?(EG6kj)0U#*cNrM1<<}pI2N*)9!(2116DqtKT0Pc$c*%*x0%2@sx zgPyTkos0`*n^|Ur7cn}eHW@HjYTOAJr*_L?&Yhzr5ckpdTEI>VANmo2Hwe>xaaGTb zqo`29*=W6bwM`+cGU~U zS~wwm;fm|b1=sncQ7c~(3A*Y2|7QhKCeFQig4h_tbauAOSmeT!7)t%4;6D)hp$D`C z1+2q;26zV&3R{YLR2p-MdH?qp&jlEYh@cw-g*(?mStwg5cZUV>zGmr@?u@AdW1D8v zQY%dQ550)|B_&`{>cLq8e&R97X&9rNk%@EDXw!>~_sPEh@vhICZ_n>aJl(C#lye;@;G~GM9_lhVI~7|?r_~@tROCNbn55N7M+p9 z?E=}NX)BL#1+Jgi!ehkbkhyw)>#K9|{`Q?^RL_zSlmOqF;j|)Lo0Ci)A$Z3%;C;!BK>Ll5gS{J3_COi@HLU$af#&=Xm3VAb+>%>ik9uQ^{ zD<}=lQIV0H9BpM60epBcm_ZEcP$Z`GN=Xq`2uVP9^KcD1sA+ng$VXALE0-{|qYvJ8 zC%R&)Pfav2hJLw^u67E`<}*>JoR7Qm{hS+yCPucqeB=8I=B4VTXx5=#jz`GuGHsgj z&X4ac`6j;`p9J;cD z2UP$NpI{pW&gNLa-Q>%3nDK1au-a0*(kqV*&p$tHBSF zpDmNzw28$I_<+QPGxf);m|<+419N6k+oi(}JLuT9ZQHi(bZon0+qP}nw(aDJ zIeFi&YG!I`s?I;yM|;8ZQ6vmy-)!#QA{C$B>BoWd)41ak!T9KanEw>P}zd{_B?gOaMKf#f++6h z;Nf5bstrUf>RIw#QZ!3!j zQAAq#&~aBsZo;sWA4qB5_^~kK9dofQCrOn8Bojy}v^03j$55I~LW;H0qpBG4oO6s{ zqR^?T2$?q?2PVEv4+ecvq%T^$XXm(+Sq$Qm z(=h!<6s%zApHf)Q8CjYyZbb(Z@F!k;>n%1?Db*gVnB*K4qolky7Uq5OPFt+>EP+8t zM?F#A_93SMpAiC_ccJTq7hTzeX~6MMdy=AT5L!Ish={7Uk3}-lkZ@-9F;@95T1nJR z@6C)1g*OS3J4$MtaXu7VEMV6xJOuhW2?39?pQl{fX}S~{+|+1U1LRelpl`7eBUi@Z zxA#}f5gv{s#_*`|9!2Zjr^zd&F86deJta~ZVj+rt-jYoRzZN#JeFYw_@=!kiI9#x+ zHk%A;7YKv2#}R5g$H-{-8Xw9TdXRHE1-sjp?PYSkLDmG+L^{&(LG-%};ATxft6({u zLpBx6!hYYt;Llz<;l+@rEk)ccQD5xkY(k(enj#M`)6o|UgrQs!3A_qGbomHjQV-2L zOf{q}zkp+JWHm)WN1C3vaekoiAZ+yHF%%O<*2#9gWmHU$HYS>0)jZe*3?#23L{16U zjkIw*0w~9{=N5fGSO=r2o5X@LO?4t98KOHtuC3vxSpjb*A{zu(-`bGr50QGM14_7` zNw!ii!eG(ZdB(#sHrkh;OG3U^q0h{GqR|*gVXfmfBT?f@-qEpGPMWSIk2W&8 z5Z}nkOnz@>f{F5J=^S|EC0390$s9Yc57zg23xX4#$gmm;h5pzm_KLCX<%wn zO+IndH-9tdmgIlFVoK8QP*SU%e{7ZlbXHzU#PggMK0Ij$5BRDYjeC->%2k1zo4=?j1{$am5tAK zRRvs_uZKqbiGcEbs5@|9(HK57nEoRs?>{jy5jjJ0A1|essGN904`6ohZ+PF`po(wj z6jjRaiW{CR=b1MDuGMPfoOfE0VLI`}QCi(}<*j$D7BfO~D(0K)R~D?sCsfdt4^&&J z2J*%ws=sIk3Nzj38(NvP`lJm%ec{@*_m))1EcU#N%apc0S1h}}S7^G#Jlq~sMb9@T z4&JK@{FCIoxV!l}|4Pm-RvOh10C7=xn_08$|BO~R!!A22;wz66(#+_We6SE{W@yn3 zaM`!~?0)9&3YC5vrl$q_S74IyDb~ml1WgFJ56e|KzYEcM<9q$Ym-pB0!{}#C^aSu4 z?QOiwnI@bE+5I-pO)9RIL+4kXA8HrgouKB9r^>ahqO@;tW*>HFqdw)!D{TKZPmCO$ z*WBmFD$~mbc$Wv40iq?d`)kN`ww9XoH)1kc*t$Yp;U8_u@d(6gbdSI$)m#$4ZX6mQ zxRhxNLiPA|_9RM|MRwmhu7@4oYqfYq->a&yXiV`Mg8>%?dOW#kJy%Vyo}ZA90Qc{= za}Cmsn53DkrcK+tQ0Wn00olNxrz2Ty*SSesXvCjaRd14QdElvi9e6vkBc~$ezS{EA z_c|xfGqTkmRk9&`!s-ife&_s`v8Y35@z>7GN}$Z~Um%C4OIQ4f{#o?vaZR1m?MDpO zNH9W!=2i34;vHH3h9A z0zZ<)@7ZsfMd3%AiP|e`4H9k7s$98ouYsr%#zLdX5J3FI1J#-*> z^`Zu|6$ZaY%Q}XRF}O?LCcxO?|3jqJ!sy^p9$R~?sV*|s0yEtlw{An|DrRGJEVn_v zomV&>X3)fOo6q`GsLjm&DiC})k+M@B|I6SZ{L^lZM83XXy4)XnXL@Ih-MKrvW0S-0 zuG8gsmr^1nnu#@P(NeC8DZX4Dg3FL^+_%|pJzM%~o83~-`=W}iyjR9zg3JC)Rt?Cw z!^>CaY`_2<-_~_QrYKwuoEgZwE1m+rLyc!O_FkFirPkf2x>7_;-$DrB3;?0YfQAMu za{WD@8z6c7Yh#P2rr84_3gq0|zD(wZS68YG;YY$={kHmL8}2K6Su9UIOi(fHS?&i}O@$5s^VJ>wCr@GfhyYadqAx!VFwU1+17+b%;DP9Qd^Nf5DM@MzM>(70 z_MnGdBO^A%;p3#JWlD%$t=ed2rL*SWOnSwNyWuIT%<@Pl6-~)(Y z&|H8Ka$bZ+V4i0)1jGP-Ow$s=Q|?Po^+pIj$j*emP=sclgJP2ENBi)wBW(WX^-b>m zqT+Tos`nm9^{vZ{Ax~oSN@HF5Z)TGYzYTE0y8KExplp7U4)p1{OytfuN)6VE6G-R{ z6%wv+$>f&+DCU;6QsZwc!*&Hdl8ga_l2>C$!CA?Oi%6n}fm|QaQeLZu#|GiLQ}K(M z;-w;=v;r{_@A8658Nii24Pd{q9r+Wsh}=B1RFy}DlqurCxCVuN@T#%{0z4Y#c*g

@GX4jn^u$pn|ek%QRw92E-s2^=Lzii$CLG1fedM<0400K2kQBP&m zVs0<+skshtX{%i1Hz5?S>V@i}Bp7XUhjgsELK?eddvCRri9tw^C0!NTlMG7h_AeIY z3CLUCrgd9T_sdIb#?|$0Er?$pt=HpWL)6$d z-;vN=FIj)FtgxPDbtjkpL0DI#x(KMMlv<(WZAo%gXjcSL@&nq@!wm)?f+sZ4-D>N6 z;nqlhTie08LSuov~FV6!fKHqJcu3w#>Pi|VI6PKIzFFDV? zJzd*AOeA>!ho~!u&2%w(94Z+a*?)T1i=brda(s0L)K}2`)$M*iHWjY}`n&#Zx)PVa z8^4BlwpB;B>Hcr|7rmSY+JHT!yaK36Gp;CK>5IXii1hql+ZGT~+KXjh_Ib!>@F?oW z_{!WX$&uTZf3m_6r)!-lWeTfJ<#gnIB|7b#E7#O8xqM7$JvG`Jochnz7m`*b$~%Z5 zPcrWsQQwae&HJDQ^1?+ik}BqPVO1OhRIMyk2+D_GDCWn>og-vW)Gdp~zlSK2l52b8 z<&#zCE+JVm+eykA|A}Du7t>dWYb_IUx_{P1zG;p%Rgh*KLP^Dn#MDbdU7s?gnN%re zcW#y^Yr>(`>yPH$sqG{YI@$?9A${gvHS2+rQp?N#1l>|}>hkX}< z_@1#QL`>O|OV=@(+#%AqW_7pU78nP+X%r%FR`M2myOW32VN`a!t)32Iu8t25P$FZ( z`Fyn0%yX2fAg|H7ve9B&TBbC}4gDJ$KEiIPH($Q$Kd2#M#-qHSlWbYJ+SfAeyQ;OkqV=yj=WqY>NkV=o zetp({nf~UblzV4?ffER3N)x)nsZialitt5mEl6K4PtCZS%J@zcIfRRm@gp|BD{aI< z5&W}B$wVP8sC!4{>u&r7dhwkP8IK^+3x*oLx&~qiBrT;zj7>}x;_F_q;ueCh`_tQ( z?gxGkm+W9w`{%?J59BB9HVTKNL@0?=%zFlj$@s-^#n{khzfQ7%nTUF)M41wVM0=>d zRo^k<*d%qkwo3{)kR$LcJ7^KNr-T+L?HkkCD|;DD!@ek^ zmxJ%0eTo1fh=c_KRU)1DdR*vpOdtx?h?UXMuo1+LBe&sf<-PI0g`y0ixJq8s9)4OP zL_vh^^*P~G;6rlCXQw-ag!R*>Y49g;3YKB?U|_Lk+%QRD=2a#L=@S4M`LJWfJhIz=vbDMm`27uln5RUby#qDEjI?`!F%_g`H)!$-YNlFK$a-ErL`+Bd&Pz z@_3Y&Mrd;nR*23jz7DTjv^v-a-On6zVMvbKOU0m{lxa~i8&aQ6(d+diK}KIkJ{(G$ zgpDNO;_WSldIy)m0tH&pt3HzV=1|ylV#vt?_ENoAf*^O`&+*lR3qAg1wqIqkR_Cd8JoNo8~L>< z%2?LfUui;IjvHCv&JzPj!zH#@u4Vtw2%YBP( z=>XR+I-W_&xnAs5zW_E|u*tzAb&`N%b3^DT#Ovkr1S%=GhWf+6**qVFqd^(<82r;0 z*JO{15ji^j2+&ICHD4ILCOCsgJjHA;P&nZzQ$EcFp}}E;IxMLg{zH(SFG&Mx+Pila zo(bu?$`cwmq|7EN%e_E9Z>$(Y*GL^(!|yg~h=xzJ5N*}hK|@4@Ryce5Z+&U$Y=Ut4 zTEHwqEdLmeZ4`malBfzXyMe~GQ`BCNwHnrczek)1W`8lKG4)lb83aHg8pi%2`SyoN z=nvTS|L7)1D#v)(yp4KsWC&Mgq5U%L0# z;(Nzl+(>F85_ki$vIfkpU@?XtqlUu6V$oGuM?A4aT5CQ12Y_*rcSi2?fk z-k-!^c--4xC+ovb5ls+UVquj^9D};=*p4k1_9#GpaVGFMW`ajK+KSaAExqZrph{>( z*XFsp=hxPrK?z8fbD5s+bo*)zF9g^2df4gH2o;A@^WiL2G(cnCiv8#Ho_qT9dbhrv zQeaY?Gzg1{Btabhp&F6v;U=zXXP^C%5UmXBd^Npc=lqdyrT<;)qceEJ0ik4JdItQ# zE-MF4N2>e!{ZV;Y_*V>SF=yGXmGWbH$x#h4-A?P*vm|mm_rj~Ze~P9v6*8(MiY4?d zV@;d=ZV_QHt8pD|`-eN;Nwuna1z?aiX`4Cgu!@#EE)}HuL++^R z%j^2IuJoS7vm#ixj!3lCgV!cCVR&xlFFM|QCf;Nw>pWns+2V*BatWe4YqzS?!l76| z6&Q$U^$(LHu|0U9txTElOG`u<5+MpLKK(xXY72iq@rk(7D%nAqbOyocX_Mwdro4N+ z7thF1U}mOTf{J?(@ye4pCCdKByg^YtKrK9?d+E0np7*=jMIoOypLv`QoA-(Ph}>Vj z3$F943U4`YPiN^-c`0d{D7eGlIQBk#5`H#P?nQ{>Rx+^55unkdcabW@s_9bw=6l2+ zF@*BLb`fn&T!MN>E|@fUAi+^2ODDfHF4)+VXb6`prX`+i%{NTfZ7*5t{fjh!S?PmV z_(rMdFZs&>69TfFEx-K->gy`L@Z~^?af(en*ela6|AVF)aGZ!g#D&C>>zA>Fg*9k6 zWZBN<=D{k3>g(zI)r>(~Wfk8G{m-fdSgkx)5syCu( zl}cC>66$ailxj%kT8C40+DcP@mWQ<}gKq4u90isnLYQxUNJKAd(?4Y|NlY10$x*-8 zK$YU9h%*6ZS`_zw`~m=D+)s{{8pH4Xk6)1<$T$_m5|;8^7g|-)Mp}fuco6Tef2{+h z5$@kHupXwbWZ;Q;u~y8+UOpvz)RTj1>Z;C>zhVuIj8CG8=FX7-Zpqp|>ZpaespW2{ zSL9ukC3W_Pl)|TtEKc+b{Z{yO<$#o<42)msX+IUF+KY#&M!_&>TR$O$+wQm;obcEX z3&_A%(p~UOHsw~DHCwr1fZe~rHcL*&pRkj)_Mr5iWDWh9wEnzCHhT%=ZUm0O2)BJZ zjn9>El*B3NNN;@x$QCSdjucyr9&1L*%2CVzY=tg176fBf-z;gLeeq0>1Z{T&LY~n# z&dh(+Jzva+Juhh>>v{_e5L@z^RbNUpi%oW#1{+I4$%Zu`-cMar4iBfTr0(%Y4;nnN zRVfX28;jy#e-hg|r~yjXp6Pr~El^yIde{Nx`LY@x(HZA;vQ2AW;cGdsk zMRFVowkMu|K4xeTh;Cn-IW|-cyc%y_%6ElXp5vaEc|rneWt4Z`ckq0zmk*mi`z-U) zKPUt*!i0mhAbm*1DI{PjjX-Ey4ZgE8Fw47E-a&^)gX7#_W3**kb)A&SS?qPWyQT^lLEv4Y(rFx ztQJIQY0>CW{wT@9n5ke$1!#H;ChzOVoA~zZcmoo!KX<@X9@W4gxTc~nA1SN#%J;7CnH(_HggFPs&B-bcqH@Spi92ZV$JtyUc0?IbASy|8U6DXFOn%u1QW^EhVBJ!%_c(9Gis;z%* zp!7{om5D)iwkMZYs|}xC5fZFc@AQblPO&wCA`!?AmnyyakKMf14e6FKTVjC64=|f- zC)QvaG}t8oUtS9UOf`_J>tvuiREnKW*j~hoNu>WeNwMZ{E>o; z9A9t2hKGaC4`OQ>0A^ARcSF$OaxLkdiW-hl+iJP&E-ogaD9-=Xt`GrAj6Rt*C{7+4 zJ%8G*YObdD>b*@X)k4e~gkA;pkiRbtwuZ~7eO>}d0E-xMB`(oAlJ!&PVNOu$B<0AQ zB`RF(aNHL=X^z%OeEX&K4e_!ES5|5o`c{R5w4^55-o|5tH;p|g(Zg?5GjXLSHA2dC z(D7fcknNmCO;m!l+fCctgqmN*@;~_%#t;ae2d8>Ym)p*=Mxu`E=1jGMmo!`unR=?d z)F1oO2VtDlc$ZQ(Hm>AUPh{$rjVaVki;XC#4)AI>*}x9hF7p&TR=D+@Se3?(t4DV3 z)R*!^UC(zr`g@|y8Y*>1&RWvkf4-Ce+rls3Gu3x#mOH>iet}>x24gkG;NTvKsF1Qk}Y;Fwv1dzQf00Bg_6=v9Q6(i_B77kvr`!O25lgx~H=~l}f z(59QTldEp!E3Tu-O^e@Ej;z}&uVy#@0~R9M9yNFa+5W?8!fs)4>+eRDBi#H!3mr6> ztRdg=K6hO4c()#QGFoz|Mg!abn=RG&Q$_74k-yW(7{V!~PPvR;uUwof1_9gotTC~m zj!HPh!$rgVOvXwUFprDUkh3d$8_-Xdu!i$(9y;f8#r`tO)%I?ID$(t7tkbLAZriL; z_ieStu}_J!B9C2PPkC@P{zM;-D|A{%ZXw-M&ZUlejG#MFGovseeUo%&Os-R>GM_|- zAcsykV_ZK{pWbig&?Y|=R(no~Y{CsKe&zA)?`Swdh?dpT2NaUhIPVGg?i5QkWW<57 z*bA0aV{p2QE;*W^qGlQe-jOzK$~8x{QQU|7z5j6lF(P?{%2M}crQvYCPHDs_{D<&X z2t)*dA(or0<`k;yr+lQr2TiTW=$j9cdI-6*;ighr{$Ldvg0TY`(`Gj z)kO6pTJ;!*2f2|QifN{S(u!o{NV&s0W+-pHq2^&6f&1lrx-!Jq?703RvdFYD9kBb z&RuQ?n@!QQ8JJLj0V6Uu)Rk}|CCS3LpDA#^x&k<|KbZ4`1XZqV^imFNVo{h~DXBi1 zaq$~6aJb{~-gj#*W0h+H0GUx0ff9M|OvLGc3I`D^Y@44B$?9{S(4P4n45%s@2CC?R z$NkDAHaqq&1bEUgfiojKdF~<}*cv^``Vs86vZ&T=1fk3@=Fbp0pdE(&b+}sAv?GHM11A&{QgXy8+K0=hhu{kr!#TFX7yEn6^HDL` z>Cj7~IS2iqfKGnoWw?KCW{?A>HV-*crE_k8+sWZ2;j`ps;ZMGvz+k?WoGl3+<+R9g zq?g_*nFbYu-yBo3-;4}>6IZU@P9JjcbGcA&=Xh0tl1ejWlq^75L(H9ll1@`?b`l(D zvU%zc5SvR*)!`#?4zyk}#r=zI2#os*;1_@TWKn-myMt|9%E|k^=Nt{yM|CqphHGIf^h_CQOC2)C$E^rQB0$^Q3#{c0XE0p;+#kl87G zKq9HUg1HWjGh%Vc%@7K3n-|z&Ig8V;`*IfMXK%`?y_$kw!rC;sZR-4Le8yZnXufYG znI?|Hj#^p**+gqPu#G~n3?VS^E}`gVk@^`lI1TU*7UC$5XHhuAaB?&V#%32xYj-Xe zL+?tDbka+GB6u^_98%Xr1Gl`&rW^q89XDV7)mUgP;jp1jpIiLjQ2y|#bWiCVaj*Lk zErAQ{i7c!7dp zq%xwOZ5@8s&ky@CWRc}OJNLidrbcpdFO9`M;Uk1Ulr3_kfIY3_0N^bqeE7MnN8x3 zA@Y5o$5%)qi-3xv+bUh?o${jC3VsvTcspxog1$!i zp9Z;lxX%x|tX(ee>}A03_oWf8VlKUv5v)xuU^(l_GD-11l(^2==<<{syJlc2<{1g& z)~-<}130Y$UU~=9QWUKa9{)#y%@q4(oUe~ANmim20e+Fbzvoftv)iBG z!*FusPHE1@3_(wXrK&PbsWXY!^{`DGl~*hV)puCl=O4A;Emz>QwDY;4Hq=xT{Zm_` zG=yacq9nTYQ)^1ne)kE^*v)<+<{U7jfpwC3^ny9|i%acw4eezj1|iKM&D!#PSP5w! z^x(R_t%myS{=8)L>qz>Ug|R5WVmc1UNPC#NFUhIcu|86R;a5kYWQ~!Ox>GG0jRdsT zTM(0R>beFT%>mG)K0#c)B*6$kVQJs#?xl53EXes5jwo*-z=$tk|HDV|j|Xxfhgvhj z_0^n!+9-6@v;bnp8iau`9wp1Dh8qo*K78_y20JKKprSB8GTqvEuC~2oA4o+(Rb<5g zy(@vR82v7N<}!z)!;DG`dmFQeFQRfL_ZUS0NlI@#?wJF!qVH<0;>m&(=t7Epj=AClP~q%6ni#_za`4q5SrYXo46!358P86lvVHOzy}_ql}16IN^FOnaY! zLseS%Z!7zlemB%L$n6qVYv@VfzprCyIc*K7_*}}FBsOx2r9P5Y0TO+PE<((|Xs378 zVb!;lU>8cLntZZB`zH=K4P``fn*_LPPJ4BsW2jnt@%s1?ZjP-xkQ;riyU z6oX=umR8vXQ3=pr0~G}C_5#*W>PPbj=)sMZ2#A3o!F_x<93^jz-=)ncUjC83d3UJ z{Efp2#IH?%o^H$YLS71JoJBEey=lO~DEZS=DX5Av*cEOLIFj~ZV&agc0kkC8W)wY{ zn9I#yHXy;vwf8ZB2L8Iwmig1lI4g@``lJJ@<{=~7Xj`BW{9peyK6~y-^+)&y)yFil zs((SFgl1IunCLZPgA^YiV)68??2}_K08)0&i0qXtgp6f1Mc4NJ4VF%fK+XUjD3M41 zLDj}@NEmSAu5bn;gUm{lEWxjt`A0e#OnA#tUN1?r{*yfS2FkD)zwq zr78=$Ec!zcPWrDT^mZdnTuIdSC~3-S=5WzJal{2({{|9^3m`K84D&VV?7UI|LxdqR znyL0rsbi_8H#fvva0O|odEtaL_ra|gYwlgeiFn#-``ESH(!yC}RfC(;l>uF`JRK>* z@Ubs=57~~B0KPRX=D%)QPWVEN*j{uig3s>QMC-43@Tc~>7Nslg+0-7^+J8jXQ|-!K zeBoHF$!^=SmB6>D<)`au>IYQ7?ty8?M_ZY3I7z?*N7usstH9r?CSAX!PA-$52|RS7 zAsuR}az%&gw96!r`-?xFste5Ux}QZVfkPFl9R5~x8$$>8Kb+EAi)zP8#TMS}yX(Yb zf`xB~7acsYltj0u<_)ecTZZ25yDy!p$;rdn>bH+&Fltjdl%Wfj=s54CE?bhgOZWo~ zn)CD5CY@`u>^#~CX^`3tw`;i1wd-t2S{~i|xlP?=6O_5ewM!Cs;T3H8Tl)HiDKIq* z7%Up7j}Y~Xj9pXjFi8ZoPt0ZBGTGk6f-1b_m1)z?s_x$mdo`<9kza=c+P>8|uBvR2 zjipA!jBY)e9ns{&C>L9bx=i4CKY_qVy@o;W=>n=bI)Zhmfz#5^)Js&w2q#Ym{`_#PpxYv`A{~q-oO(C zc5Jz5#vLXx5NO5t!AiId=6_JzSP7}X-ZU>i&5N79vNZM1q$|1jniyoTaUVQu;Y+*SUU&bqpm#J-F*;V0Lvp?M>>7 zfhWpTSD7@Ep7Sg_pYP9qN2Zzn>$uYCQaaw8{q=r6pPLWSW$VdMn!gi&p7I(D!xxs% z^YeUYdr&8lVEI6f_whMryXlKzi+}qp=nSHupq8*9-jIywd=y&i9k8<4wz~L*es&%8 zR-B#aC^rGXqx;T&bKA>0I6^`n`|(YO$?E<;zUkw5 zMWL`|s8W%@LfBlafYyALPZoqEl3RN z>h~qmuHfGsWuJ_aYR9baEDtcyoilG(;y@?fxtzs~0ci;jmoAS7_?TykgJ0x*$$tIZ zmBVa`(qRFArc(=r)3wjfe3Z=bwq=iYvs7ApVMT6yzeWc0Q!1iQgW-xxmZpn_w}Fk< zIy7Mhuo1&seRXPBhgp7+*FL@~Z90y}LWxmBE;ksJ6m?c0)`(t3Z0mU%hkI7CS>#pu z1mf)lD8bCqee%VMc-3|T-;P5df*4OMFGHleYuV~~Ttm?VpY4@@HgE5+wi-)&Kpsq9 z#c3p{5c1#p-JcT5o)YRd}B7eX$GhDpn`uXr?g0!92C+D<}rH>EP%a@;Vk zup#M^$Rd`#0y?M{Bz}})b`!wCl=onR_HIOFE$g|$>JvPVyLF0z?nk__XA<-&h=3Q( zXz+uJ?69ivW^gQa964!F%sR_XJE1eISW1^lZga6)pW$E0z+}5R^H7`ED@+#J9sLLw zn=o_sBf(BH(oy9oIhTl*7Rg#E#EQq6T3!#RwcM~w4LfbnT+6%+JdXf-F7GbJwXe3^ zV5LT0Xs@eUZuX$c=l`gvLeomSws~LutHl(I2y=SGyYXfT;wiIhAwAtm$J2?l0|+os zme&>!ZzYz`3k4J6wxXW40AVVA;h~UrNxs)Zwtm<}vcxO>Y6=;9gj#!cZHc7Ho~gN% z`MnlF7*?ipl|56CNlcF8*t`Hc9arK&Y>90$u)K~9dH^fhCYmcNbXR8(yTGq(b2Lj7 z;-8X+Q0N(XqS=x&`@rq5WgoroXelWv=XLxh+1+?U^C!j~_re^HZn+6EFEt6WacSeq*gZo8K2|#S^j-Y6MVNL6< z%dALD14pkkxdm{s&@@9g60zI)G!EOF|VqnDqSA-!}JNYvke08 z(=J?o01j-=z54uhf_!{F`!Wt9~;lJG5@_GMihj6eyT_}?- zopqD8%LA{@5+(D5?S$g#-L?8gXTBks589xt&ZP7ME}oHloICz{!Pd+VlV8$j*(|6}X@FY4|9Mq|vJd zNp!^hr_gQP(om10d|r^mwE`gPUswps6?xQrkcdR7qF|>59Mr+0Yw*??U2J5jblsYx zXN-fQ&`BLu#$i@3?T{V9=ssQBX9n^gMV5do{Xt(?VHmPxP?jOZK@q1@K`FE1t9p>{ zMEzuij8i#)biMJ!L4UIb`(~!nX+}(2CVDsTlJW|^<8xz!aK*U-+GGV{?d)jD{kYrq zyW4_KqSoy^fZ3)MyKkMP#9F0J<{VOc<9fx)x0-zSWGhsT^5g#oqiRa{E^5wC=dwHj z+|GO*Sl8_Ri)q*Hf*7Gnv#yuK;mVVN8H&F;|@;{*KX#{mT?Utp|W2A#!M{s!X&W-52m zk1kE*u7VX+O+#wn!;qn_jg$W-swi1Nxoiz;XV0Rf4?+t=miM1s6r@L{NYG$B8?rD_ z?SwHvHG2S8>!4~~G=fm?7aJ2aur{6&Ona)3$FhpQ9u z_s-v%mYql+yYG=>8+Vvy^_|;R4Za%P%i;3~xrmsdtLGlnjhmW^oa>{Nsfp_DPWLly zI0HPjNekN4g(SUMj8Uo{eZv2muayGX*qj3Dg3E%xOQ4!GOW8C1Ig6yzV>2j~%g)l}Qp3=A2)^*meCaUB_WszXOkxVS+i-!hFhXGVgj-q!4#}-kr5Dp_dW&2pUx0TYOk!_E6kMg>EF>_j=W~b;pc| zdaftpM*_H5_%Fj1!V!ie4OR6iL=eebhTII(rlJo1F;sQiGgHV!+7Gs2PW;I@y@i}^ z%b7h2{x=h&ZD=X(W()@EZ{8;Z6X4$ggpG7+hPD+Yd-CxLHK3qp2M59v0hgSUL$4*w zWARWb2nh^ZvWjk4^bTG5<8%?+ny+``5~(w?|MPJA0~Itv(kv(}8zzu0!pn?%U)WN@ z2)xiuQV=SAgBvGKGr6Bm*mX>CgR*+tvS}a%Em+iRE8Dk09ba7bExxeho$8>(p)HZ3 zy2m2xSz{vY%OsU?fA&%Q)9D{=@swx)^u2ke1k^>t!8HS%F)wge- zuRf|-6$@OeN2h`C_Dk^k&PjsHX%Ff20m6aCB!lxhI~wiM{ertv2n^bjUA8lu!9RBB zc!>tK#68|o-`#zPc)r*$>(cZz38)9TOf{ZrZ&4sC~zKviDPnG~aki+?b0l22c_C>NE zhw{Bq(Tx%FzP4eRaGrM3^N!;-(DunipAjYf#Zg!69TI{)HwSyj29Kx7EBeXc+I}<} z{kSg1yNu%Z2u43zV6{Zxp1sJTP~xn(Ei~)bcRpeOmER> zx@qiF3aXn!*=~|yz(TjrD9H50O^!j}2_!!N25K`o9X;>hEh&+p*Q32FGVGg} zu5u9|iGcuy?U*j9c`GPr#FT}{VH62qU9gYKpjH=@^Xo--n1ffbByA|BRkI^13(HLe zojy`d3z9z14XE|s=PK1O<=hZkL&_q^17nD^jy7^vJF-_xHLPmD7Riv+tSkeabw5o{ zfB(5KIp0Zy%)Xx$00p`coj%7n=b0LMV0}u{84d`YaM+6VKir4P&p6sm-yYA+&Uf&h zZ&dhVJLiZK9v?1F_cGV;_~W}L#~~rGq;2F=d}euuOdur!4Ao3K1FYCrasgGN1A34= znkWmVF2z346Zfl0VLMfbA{8F2yg!b?(7^QZL~yu4V9gaoNo+-R?+?~~+^6=o;zbCu z)=dW^LgJPcrj;eXsET?h&bAWX?-jFB7GAfh_v>~yO|&<0`|N!jp6~v7`AcXeF`k^_ zz|!gK)*1%s**7NQCAZa2K~l99Lf+Et6m#A_q?3fTg4#*;I$>hoeh|f*B7-y18(Cs~ z5lEpMytvxgn79*$(ps-gq1f~4yl9c`V=rPJ$bS1L_Yw>S5oo-0y^l`Wr&mDkxMfF? z>gBEy=RXna(ccZILt1KB&K<&l6D)pi)4HdSx$GqTeZ(0BUA`svb{l!d08|88LHl!fcsO1-AV2hY0 zm|=l0nX@>=H7f62MOCx`3mWUCLxflM3^X$3mUThr@%=u~k-Kd9*%(e1vZGz(M*G~| z*0q0XZ(E%l(1OcAU3dF!cxUdUQ_7ZRvcAF=WWKK5H>lsuc?kw920=|0=~LSp3j?6Q zGhn7aL`X;X+HER_U$Er`9%2z&lcf~J_%uQ?BW}f}l10;+k0I4emjnlp9~$Tl!yj~{ zUKZ6(;t9!6a)s9u2S3NDvs<=~P0ja&;U+pAonp=J^HU}8DfdQaF9Bn(>Pbn;1V;?u z9F#%CKX&HBEk=;1V5$?`s4A^~dTF>^NQo(bzsEXxGEZ6Q zQ3Kmj-p$}#V~4^QY!5s6g@<+k68EEg$o9sv3}1)bWB1K4KstrI6pv}+qq-on@8J&VPYO*HY7Vy(<{#S`3bqkz=&-pm_O+kI`1i1 zN?{34Q*hAUTKpT9qs{Dr8<){i9Vrk516_;^3r|+15_)JeD zm`Y?!F1hkd$!}#+K7vxs=(`0g45EL#@@M&^VqJ!WO9p&gHJNh-C&zGlLblr_+~6!W z|46gHSiKiDx**X>yY>OgZ=QG5{One)9oQ3%TUUBE+t&k+1Gu+l*Vo)Ph1bnBkB+Vz zYVTtm-WjCGx$)qB96@JK`z*f8UI4QxO!U+CezSkinS{TUVELhcN-GuN|J$3p%wZXv zY}CiupEeDpk5eouSL`Vb=zPOj363~Z?StU{fNfj%E2~Bl!H-mA@kVBh! zg#Ht^-3&XOObSpd5R3juwqMhQ2bGgC!=skg#%GXyA1t^bxt6I^=QSwa?N?|&)u1md z=4N`;&++uC^7MRnHkNtj{&%;TQ)(wB8!^CvEM_MpLfDfBIh>->7b#`I+>BW%KO{E( zK2JfCTRpYc2zW?>A2Uw^xLlMeI|!|>Lnj9)iKwzYE#p2poExPA*kmE7LCt;ZzZcR_ zdq6y{p>Un#q+|-xg^9K?C}9R9k+j*2-T4AsSeAe4`tb zEeH4R#gYMUVVBI`-W4&%XdgI%>)CTOF!M-cagUR>Xdu#geED0^UP&x0#-#A(*4~<>yc!Jw=fV`fAmkn|NxU0ZFdCYZ> zt*0;ba(^~1AK&ZUQ1zZKiJeRgjEqzOevX!_v7|Br+JPgAFWogASWcG@H!USj^xi{W zsds&`9f9Go5?9}5^kxvQA*{2P-rN%!pC+)XoO^V-dn~cujKI;!j$`$#ph~8;w=VYS zMyDLqMAZ1KvvVron`^!ojULeG6qWbRevT&7Q!T%Par8^>i! z0z3{}lw_nHDSTu$)dl=^zOPLl?`oMkq*@f-Ki*5k3t%??xBV(i=c$bUcy)C5xjctm zu8N0;$GMTZmEdW-qg2q5Bq|I;2DyGp4$r4n)UrG6Ei!~-IeFX>FQiPHalR9;btu1s zyMwpQMlx%%T?~5@eL6H1s zK*8O7!)@cbPvUtJ)7Sg+ItWrY5pi7?*wck(l^6BP!v6xQKvloff-DQFiYLSu{24v| zTr3Ee&-6(=J}!P1Kk?(EvS0AFfBjg!zb^l!&47o+`>Iq?-#4$X_KiRHtJkOcWn78{ zUJ#@TTs$u*4y--UwODJ>`oGJ~9<;7D`;Yhi$HT9m@1T!VTavqncfEgi%SZ6~YTbQ2 zxQ*WTKX?0|P$wS$Sm<-)74E_N;zRE`0I7D&yT8|uQ0ve8S4R%lEpI8g-aFz)6j-7f#RO!}I~&D)#aLHZw8V-8zr zPqz3mNlT*0`Dd^Ws&ni^a#Lbglez`Bwh@jokD5BEZ)-N`YPtYv2&m zOLp;OJZFvvq57UDP@ovs&%kM0Lo}sDw zsR!lvcJ<*IxcEz*d6>2}>pTJ^Ti|_@&q3Nc+8KGc5A-^HtwH??Px}q@zvt=YxM}`9 zo15aF6T2xCOJ^1v2@1N?e5_*B#;y;^X!QvaRY|It;)-LAI8s_fV&%C%ZGql~F^jJcCml-X-b($?Zk|6@+dsVz`yc#R0xpE;V~?Af zHs1RcW-4?(z;95kHoq4DxSuxULq2@Hg4A{3DfbvVzuf)zv~pLmE<6Bj5xwKw$Qi9X zE&%q%<3^v9cO}J1*=^hI#R`1J|7R(I$H|lC*^mq4hpBApi_|N@v=W)y&T$}h_e>5$m)JH#I`V$>* zS*h)8joo;73h5PxyAKlUAuz0=emLYPBFw0BQV3IN0-?fYXoYPp{l$B5FbphN<0Gb6 zP@!kq6f>2Ca4rZ5HtHY9ZnNADwQ}sh`kbQo0{8x74ftJ6Dr=0C;-2vSf9wZ-?stDz zA0`W}oDp1b!`jEp=0SnmF1A#hxre+4ovYI%CZtj>nfR3 zy!MGzcl*YvO`(yj zPFH6p)AdK6GV}!{q4i;2b#Nl}3-ANyjF_u828Ym9POs{qs}80pLzWDW7+{FoDVh!j z7#DUO&Q7#v!LjJ4`b;vwTKfqTqD?sX)r2BN3I`3h%`>K#OTdZ>7-0Hg((8Iyf&5gw z^f~E?S(@F&k;&)je4T;Xde!Ve&2C~wuVN@2Dytb9S#~gP^Dl-qJCOYWb3Zx>2?``6 z;DBr0GC!hcGV?M*2zX%|5b9(<8)eQf23RIKqrd zZsqatdpE!!*4BG&i|k0(yuAuDVCn(!JIGBqcNzUTm!3KbTuE4lI9$8^_WgAaQR$wR zWq5I;-r+*aTIOGB&4&^xFy}_Fj@KowSn{#4;E8NV}mE({2>Q9bIA$Lp*`Y zN&<_}kTKKzRpp)5A%bjqa>txskoyxDjqf%FHP<%i6;Le>KVB|fMbEKq+$#m?vq-M_ zh=R$PAh>T#mzFPTKiCdb-wx<_`s{P?}u{>s}-+>Kv=HdE8KwV#?-FV{P2 zOFefEm)q@T3wqGD8S>{^uf^?{;O*&uT+IGKQSC{POYJW_`tiMW~ zxk;Tbbub5Qqc0FMGm8!MY>lV$@rVwQWDw~y26AKG0 z31w-Oz>ZrPZ}O68(^YFbLWw=7<{Y#SQ)?Siq$nxUO0Q*9+dD$>IYBt*j3?@u@iJ_q zmhjOl8z$9z%o>vZnxO?N1aU&z({-8&O{xo)+$N!bpmtzh^Ia)22N#qu(GUJ^`!&+6 z`1$JQuP85^Vpap@M?h4Y^cukV5&q5;#oG!&7*ezFzHk$i#p@QDr=r`e@ikROl*q4M zsEj)ZqaRfKFojHpRxfnQfOyLnc1jdFU(+dV*#8i3m%uWVhe+UNV*BnUrNF}lv8yiToI9Jd5H*6;-;N#M8e58nu>^6N`Xayr)ZZwEFbJ_z3)F)>&~CI-yUzv zYB8NVI$PrJx7XWmW;fsev3XnGf-TlJR3&Ka#_Eeti;u*i%wU*5cQ zE>BQr@nW-uofGW|40~Qht&uRsl{9ctY|5GJIbi+W4IkneH&8_g$?jaMz;sGEYO1rG zAK&3ey=c}%kmLw-5g3w#fq}6)D^^ICFsD+>+c8;`KNE3;WAiaX)33@{V zPBlWxF6|dlfvmJ(Q56WR;GC}lq&|G@gc zD5B85gSGY?1xn_ydrh|LPod_j3xx4xZm`MsIP}bwifxs%@jS+<*ymfjkDPv|4G9~Y_noSuZ zOqoc-IC>x?*?Ljj6cT#o7?PJZWbZ8^*rJie;_B{_owseaHQF^GLQMu9jQE71FO`Jh*T zGkB_X9b*{kb5ZNugkt?4Vhf>shGAxNV;F`ex4H0B0ijJ3Cm1rx2%^dS!W-XTmhrTe#KZ$jj^0QvgOzqOIx5~1{ljZ@(YX}KjF+&2ATth-GIJ-k566x z0~f}pPH5#*x0H$~Vu1C@Sty$(a(i^dz$^ap9rUoqqgT)BV<1m0$z`UnmN=vs;egcU zG0}D=cP&lOgBJ0NAJwlIRnF$`bRX`_48j;g2J3>I?n3AlJHlIBJ)gGVlg9DtbZ`4H zU<3m;)#RSHEI+UwbSjgY?Kpx7MTptlgU(HrFO(3eaN!ivxJ~m77F-lXB5XOWZ#9oy zFOa~(v8q$Nwt9G|RM4WH+ME6vkdh?yNa_`%luQfD$iWzLR^xP-PO9^MLfkHTl2tZ@ ztM%Ok9`pO?2kVpx&V9r%Vp>6l&Z)||Pbk6hBG`kz*!NJ9Yd-pz$1gwsXzt{}P4u@W zJoqI+gt;Xi2=0|o6o16EU76Kdq7Yi3_;3X_NP-_)X)Dyof%HWYkH|-bR;5PA&L4CC z#K4O16x{g!O5meLn4J(8b=t5SYn`@4SMO&uUaodnvqEdQB#agg8XaX67lq);uCaRC zbrJ~~{IHf&Y!+ibv=hWkklqCSN_^pvA~+(a9i)F9?+}KwbCkh3<*i{cs6!#lTGdC!z1rtO}uIW=_RJJw} zLEvyCs>O$FRXe3w7I_wV?5WRYkVn3E=r~=?@sZs*vpIh3#SyhNs}o8pMg<*DjLU3p zocBNqhFDhay}0*)O2!Z#$c(e5-4FbS;lG(caI;4311l#13lmcJKmzoI6Jb4l076R4 z3BblkOua+}Vki+WJ2}Xd2mMj5^rlV=R_cb)AgT8(6s&RF_^XUhL!2anXp>`=$AZIC zwnNrNO9h=dRwy-H+UcRgUhtCcC*i5lF2~aXE|;}~7%|7AYvNVkl|)wK0-J()Q!!8G zPZ*mKO~+3dOCxP5I%@8#=Pys+3F?)Z*#9Uap&dxZDdEaaQdZtmL;qY6=TJ^Q>iQpi z<7uIVOB^2+42U$ZDe;izj}{JTueQDMgCU299W2DU)Q3W>i+v;ncBp~Kofqh;fhMF3 z3}NR_X>c&g1)+$b%oKB~5K>5&G*Olf4CkUkZiH|4|$4Z=sUmYQ55`?BnJ=WV45Ein-}&p;ca~HE=qq8c&ghd=3KFBHrLpVwt!sEgMr}sH$K~&ffViR9KeG03I zQ+73;c2!^uZRQ+^rYH!MR&jce=2Tk6<+}YPA_a3zfa+~^^>^1;S*=UNxm`74VkJ24&Du1e^q z1J{(_GIJ+T6{lqjmzNX2wT5E)$=n+Z%8Nhk4BBLN=me!^t_aAn5s)j6F)tjW>z^K$ z2JNQ#_gtWZIBLz6FL7aK@|eaVy5T-D~4CRvz`7Y3VaFp@BK>Z zZoPPa%H^p=9`fp~Jq;1^1Ds#4z3Q#b)idd>uBqkCgfL{0M&l{W;e-j7h^y$>Mx!Zm z8XFf&fe7`ZV4yD|g41E9aC#ht#{<@%jNnAa${-!%#JXJn8exC~a($FmFt-l0{;!%;O@qM+)(4^LBDVoMb|`xkx@nR1_jD zIBr^?H3J7mRGF+*Y0D(5CRN7rgJ5$9@*ag-9YdQ;sjj35$CUVkFc4Nwv{~>wkz^ME~a(`1i~bzz2dOccMQ#WSv4d0kS>@q~2rLkjd=J6+crSS%p6Hds;7u z81%t`mJ({lEDJ8NqFPKuN!dvC?-gHw?w=XH@Hu_$ohQExfZ|N{9LlWRH2^Mj9 zlLSPAAt`}jZ}1CeGN%JOA|!vIcRW%yAtlD~$Cy*DC65pH&@zyv<)oB|SVPQdnBlzGumlW?P=9{0N%l%`CB!hTb8N%Q#k`PNi;M$~ zxZ6}xIn#?-AlC&qIp#H!dSFLFZ>Ft0cD|LBmV$;Vz38%MgDP;PO@bX>BMhw;riw7k za_Ae&W2U8{vI?H1rg!T=eMp;0+6E>^Mafb?EvjWgLC%4x6 zmYu4!C2z^D+`E4LL{KC}Myv=%kd#E(+Ep;pCK>lww{Kkph|`RY-L|({+A@NgczL*@ za%KnEbq+BzB_)|XoM9wP#+RV+n`82DFc%xl@%rc6kIkCS>OVO4uKjERF3&e^pV=VI zgrShO;d4r0Qe@dLBn{Rn(2e%y`f$r(6`KImgdr_&v#)8e%wPVO1JXSGZS`;cK^lF> z1#W;eNkLUFf9`&NZZ67!3fd>_@2!me?p=tA^1IFf%f-_0@&ZM$b?ps#d^nqdTs8h+4a3KOzU<@5;Ldg`JaI4^>(@4Znl8DW$E$Kf&@Rd%Q2(sdV7KNi~Rr#u?&=$ zi;Sg3w74&-R38b(h)$fu{QG7L4zHY4F(cP7{Jb)!IDSkHXAIgI+n)=b9Tp0^2caCx z(!>2`1tzk#$ftP{983w`Lm?U;+m`dQZ$6k4oZri%CJf@9;NDQIn~afHk3YRi7C1icwal*Th#R zUyAF0{bOwAC89YT`!W4KyO4YEEYt#?x{wzHmTB1=eGKPzy;}H`9DtKuHdUftt-l7) zn}+W~_+pzc0Zp)TAgc#J!LB>hI$UyewfQv%3>V!!Zhz1J2*jY8J{{q8**w1W>JnD1 zo3%}wpT?ebxT;=E;G(*rZghl$eG+0@kI;=-cO(mY1-@59p`-2@sUdTNTec* zw+c-5M1_<1MYcIKtv6_#CU z4eVjwVOI~A*QHEC^mqv+jqq1V>ZFpCx7o?&`yA6oqP#X4Y3zUh z^_bGw6qa~2(eNPNA?4aE8)Bmu;dc-lsU%wJuyhs>4eO3MB5wY{hTJH;Aa_V^>?ayp z565iLaDwdL12Rq~y!s+uT%x-QuY)I_DZHkLhEeGuE*lC85w7FOhDoxJDuyE z;nW>8KB#PXesOGMZ;G}!79~(dL;whsMP2g969@urwk}`kgi*qo5RL+eguCkpR{`mr z&w*9-M4WOUpg2eD;e|Mkn*Y&RTNbOjS|2_djx#A8`}}-!WJeA`Wt(q)sEjvLBCuIx z>|B@bYR4^G9F3Arl8ki;%2gZBn|U+YR)V)w?Oqs{lZ%F(TCt>2u744MKSU2ad{AI^#_HuVu9mF z1!f3ax)reXmt>XksjtQb#KUEys zfPgetzd9W*;e&Pqxdi*j8t0{wu`5C7t4dCd$|sPqk!aKrG|oZ*^2EPx(U4H>bp?us zhxVPrYz4ep{z4GFc=j}bTloEoNs}3)8Kn>|K ze{ke_?jEwub*d%R5-ogAJrSi#1uY4rjBFo=3&2zPu(sGf>0%b@%K^^C^T{R_Wr$0IpYmu z-%D!A%#hMJUw>njaZ(q%FFW>gcq$Eme_Y?-xI5rqe@PO{~KL^I71+gJ+ z3eg^2hNr=m(auRrBaYmSXm|;4tX947)xN~UQmC72{M!`b-!4vh{b-(3ab;xOpn}t< zE<8J*T8wQtRV3{*bQROU}QyXHZus+r5QUuYYY`zONu}+V}O(_2$>wB@4qZ|HoBjl4(}H zGMJ?$T_X=ain`TLs{80U^dCkC3RpMWNr|`w*iI2&nZ!CiKqTf>4m^t-cvbMP3jS;y z%{_5tr^5=yc7z{?6%Yia-YcUklej^5B&HCyZer^I!LEq4zaeEtSXJgix;Bl{S5XNT z&Pi3e5^}=#){!=0>!ZK+DIZk_EL>a*p%itkPw|Jthf=3 zg8fIbj$Cc)z~9As=;t62-{$+A>!=%@pi3pGy3QT3s$( zrc98nPVb0ue%Wf|V45V^Dx>6qFLkLjz!#RSTJ;-Rr>#Tk!qW4nt)(u^P^e0uEqZ~q z7U7C19fe*5gRaDekcdf6F{z7F5&agHx~}q0)l5Hm=i*Bro=NP! zf&P6Jt|lv7eIDUyT9DQF2Dz(n1qoNnk^LdEgsaYSEuLt_mA8$l6rrCK)bGS8!`Mw=rwU_I>+`N1$@s z8nqHdBF1Je#$Zoj9kAJ?BsAD!=Uny&dj9^fdb4-puC%+~`YSkp`%!FcDe&x`&1+x% z58KDYIfI}_Z1LphOJJ6U$gZB>x3FVoqIAnP$~(cLUAU|KN45}eK&uCjMJ^g zY2ix?jIH2=e*`}F8vtH%_b+8f?MmLiE&R)tKBED1Nt^|+)+gKNA@_T0y00S?+z9zrin^w_GSK$&Gz0pPu~|l z&-Q!bDjCI_TaOzK>e$_i-LJHrNL#Jdx?C@tRI{r|!Z}r1I2MPBab=O zl)X)BvT%mK-{(azyXh8_s^2;6Ii*_2@Ucr-Mziyn)3ilg*bH!;`yy;=J>tYF#OGXO zsL)(9=m@{et>&9F87#GyiZH+H({p(5!yxNEKW`>dD4{VKz|n{q6LowW>TzXrw$AM; zXwQJ<9AWYLGkS29^F|h1tf*}H{n>ZoDIWAb*AWe*J{+1OjHv6>Q@pd<>^*BJ#l0_S zbjE2nyXX9GVSVX#8}>C>Z6N2H;;C1+EwB)?!h%>j{baQ?M5^15JtTR){n&2a-k!lQ zs_xG#Eo~CYnfIYBNzr#Zak>`!`}@W*&AN>x%CA4>WmG)!cwwqr^=q-J7|V7JX?r~O z7Wm4#-8RO;n(J-pT_hxD)P_vB=5SC-Z6LTZT&0poBPwCmo~KI#iWRZ*(F6$`iT!+i zg6CZs-0H*9p0_n7g?Hzj|4-)+AZqdA|y>kpVbvt+^5f*r(OAU^Yk?^VTkMn zIYDh@wDu#nbYW|s{Sa6%m4o|L76)u4i#`|{(Qg=iqwE{wrbYDk+wc)7uSWg1AX%Jh@r?^3JakA75gbyu9wOa1BvV}a$EbuN%g3q0 z{wv^DSx5F1H|8M?sSKJI_Ef|kgS*|rOgf^S#a>D=HgLnjW2Oe=T07&r-ZAooafgfq z7prRz-o}rlP9=4llLLf%ZFn1u&zM4~6!RNtlXJ z8pg#8VPY7IZaZg}A4aUP=&pu63r1Ro34uT-C5sZ26dADj4&T(o-WGWB34! zxUk3fgXmnW3-*g)*ighF$eS?4k8&SwJ%(S*TsKFp@bPNS~-< zj^ptnF>_1s)vuLK1x86n7;=#q&&Mah#fC`6C>h;lh$xEan7$jBA?-`JC-SH{u5VG( zxyCSZ%mKkD!5`)(^xHLl@dDx(KVEL3aiE3E3*PiL z`x;4NBT4+6N+U*+j05IPJaFm?=IvjeLh;2e*y{lJ3t$i_V3^la2JBVmaJR#D%>EF9 zF>b_^W3VdW5gJbSRl-k(Aw!Tx8N>yA~Q$9Qu<*VAq1#%Q!fRX$+0O-1SyQ(jREni1?5tVa7rlcT&FJJB(Jq$Ko^&s ziII^mg=DzNUNo&2)rf9(7-PCZ8o|GOC`f}4!I1(iv#D!Hh@?cFCe(NGt2u$Q*bQl< z7)-IY7E`Ly?91aCO_R*uj2iXW4J8P*coy)Z4i81X2jT1pfy*f-W{E^{8197PhpCXr z2m)#2&H@G$*4e?Y!U)3}q7Y-FEIHA%!iK>B85dGPNGzc#wcp_waE6^Fp=uF&ayn7S z`{;t%Hba6?fr0HvX56L;p@i(|jc^nC4fbqyZ9ZKN+uRB!oOl&|Iy|-swt3%`?>cla z#TZFHDihc7XG%~aQ8@n03l+1@)1@V@ey=wYH(i|Uyfw!&k+_@c=h=cW#;!5Z3dYE= z6@ymRUNHte!vUy0DdCX9e6wntBz2oiZ9stfji7Ise51Ih$uwdwDGz{Q-+f}8yT9x7 zW8JT~#>|K;!woW-%?-22XpI#mXxe#c+I4K%a;;sW5mH}|Ck0G6i~~zXC>L%8 zuWH~)fgGADiB+nW+QHX4H|q*}1po4(U=M|j95~=u?!WK1j#0U?BPjPQ%0%gjfuxd< zd;Y;AooS(^4+f>g>~;*W-?TnlFz@lU|5N&sOfAFPP3X4{!()+Es@mfsMOF1nouR6J zS|5dQeyYRAUV19$Q9C=8^RS(qs(J_}q~Nq2_*0vWy$6*I5pFJ?{UT^{t}~7y$-Vq# zl}Xx2dqPsm+-j#C7HOLaTUu-;Y>_4o1{L1??A8GIRl<{T1t{N=PSq*OADw5V34v%bQ+x;2EYtJS{%$cmM(I z3Lxkwh~%fig2j?%Agth|Sx1sqy_YVR8FR!0 z@oT2+XO+TYj3^5RLLCu{PRZ}Oj6moN}Vx28Ep--j$%4)!WDuT8k%lp1Zol8fXy!zzLXS|(ESt{z)xhI+XPygsnzIU$5AB&oySyK9~cPnc|!I8?|ic4E#MZvKa3 zIcLU9$bpex%jkUBII9BrWlexw)Z#{F%1M@XKAxoOi(+eL#dchVB=fsd+|gepoi@PO-S%q!{!a{)QPB z(&w2*L-hj;s|H)+fH2K91zE-`rL1Ew9xxQraIKIXEcDq~yZI><6@B}yS zZ+C|*OOjJ&%MP^!33Ig%uSi?Zf>7KRV(bPNnEmbF{^P&>yG!3+Ubki$H^AzD|MPXe zGeXQ=z=nBiK78G*cgx@ljj_3pno|oez;} zZa3S)Bhxn^1rA2N$>D?1-u}pB_RHnZ=EvI`1oPbDKmGuFCdJQkJGwmjHw!8KAqqv_cdeRTe9uZ_;%o>>MP)UdFqguKm-2;}R#gFCU zr@wUbC)3!SmE`OJcO8!oN8f$&V>y4e2~esJBSfaKXV&8H|NZ~|?caa_GS#Y`)vCmPpbTn^ixnH~<||Mwra&e?i4hsIFY z>WFY=X3)BRxAuhIFMiC|1xiAgF!~O0FHMkHJJg}UtiPL;j`C{ns(QVKu4<4kcdBx_4MP-BUwQ~v)Jc{ zyD;S{U)a+ff4v@7yVv=fAv4fK4jXY-pVW}T5}{$wD@z3q>qTk%EH%V%r4UmX;e+d_ zZ_%2H27Y!?=*M3#Q54EB5i~LJ3~8yqC=_NlO>*p7%7f}$h)0#Y12OHpPt?4lmFcd0 zwr6gB`QYBn4RfUgPvlWNOtzX=m`H5cMZ3P$31qHPvho)+UpZo*=C*hmd5s3= zf606*#QhIk+ch6S=EfAUAbfn{I*rFk+it`$ou?^nIp#M{$-`QscEe4HkTIn-Rj6I< z?O0l#D@)E_t$)2IOnO?VGNViuSfc`GY6`ydBiC7}dK z$jz`gswC9u7%&J3!J={3+EPw`L8g5lq~=Cna*ZG{Oe3GDxpXi=*9kDobfah%_bPdC zg6idJqmzapJPd|%P1@-!o5UY^b8GRNM6Gj7ew->yXG#z$qN)X?xTcuo+aH9~L`s*j z4YWTDkvyaJPKU!A%?j~0_yTC@{3HxMta8;yN4Ys~TH2V~ceXZGgGZUl(-3^i5PcuT zs`0JXgSf!jl#Tw+|KtDqA0F}(v+f5}vI_Tg)~|tDC#q!G*rZEG4tKq|2p1p`4Ys13 zU!)q{izdO>GFfV3O=+fH($)HLGlprXXvdML{`I{2ZUaT{;eepfS-E{t70!Fl2ji5a}aqwGiEauIrhZX-Ou-V-K;1d}^QI zyp+iDw(slvN=j-AIdAjb&%$#Cl8W}yURw-&0K$07K&0@pLMQaL_A3Jx<>&Ix`@n)7 z&ZxUAvyjme3ZX0a>3+L>2c)RRtTICbOTjIBPQhakxRYH2DH19?+&^zNMxTTna9YZR-^ zuQ?ER+C6$W$y2lTO1RGm14nmSx15S1MCIb6SC3MlOmbq&l2Jv3zzk_BX?on1Pw~4AbnB@KH;rr7^O7NW<*-VdB?L#|aSYK$B`P z8eaKTXv(tyD+ETQcrrYtmEO=Ee&V1khKSq)iZ z`v_?n4M4kItNO)HajnjyyQK2%_44i4X8SXbaU0>?>j%;%s>TEA#B#l3E*taZ;@5fQ ze#9tanlkP>%Ld)EAGRA?i~y3FtD=E|+0-`X8i(@&?tKA5e!b~^HYQ?bLb>wndUcv_ zgcuP-w+md1fd5^-ndmHXo4@eq=UQX?K6G%cPeju%#ctN0S5HM4^Tsp57qunZ(W~713-@`S6JGE#Q+^Yet!;Z4VXJ5eQ`E+e1rp^VT9pBY~SlR1?EGn>=5PvIz{#}MIR z`pmdPc`QSavUEoxsMig|^TF^Yn_uJ|3UDanV|^&Q^#3=CmLFhWDPw|aO&JsMDNiz1r_^Tn|;!uorFq*Ln<2<=|SwDaDfbsoCq86HLP4ywz!g(k;>}k?6%x_TrL-s#8Dm?0vnq6_=r0tIv=;xO)pBGymGWd|yGIysv+*%T#~? z3D?bRbEpJupIuqprLnjx=bAp}N@hQkWpQU`KR=I(6Gj;~V+27+Mn(Tq*moaBQr2ZB zh_~yf6j=}Vom8Z|O%VgBbV>t=B#bM;v{!=-$c|%AU}+%WoNJDdpY*ZTt8hm>nB9+g zL86G#Ot4tN-KXv59k4kqUf<`71sKKv=QJrEtqb!8;)E%xh2{z?=Or*c#ZR|VKEsXX zBr&7}cQ$7?3|icN{+D#w%IwQ{jEIQ?7K1?>DFJ% z`P&cs?$=U&+dZ4tz5-uH4^QAw=d|yQ>?N@9MJ<5$Eo|VM9a3e1%Uk_xlL$p{YbR{UURoU$Y$8pl++Xnqbnx0XhEO*0^lht&6)qa`grAgyZgNZq><+oqh2i?D-f@i+d`pQ z%%AV~Ea(2HhXfY7T1``=ILE>jTHy9p>wV3Fq&>@8=(64U8pxVDWW;6#?k#%P)hNT7 zQN)tk1R+bOy|n#t55(?Q+IdK8{bl}-&Gx>1gdsXr?`q2Gr**x*4~361Bh;)cbZIiq zQX)-UFO4YnHvitM!Tv&NRJ8p5?58#;9`u(iBkIU%6WZnUSoD7LOcdGsP8nbYl{ z^=?k zZBGP$-W{V@$2l%V)k|UwrIZ5APj%LJkP#Z@^SZL^Rk?Q zEtW4VHtWaLliOJN@L~QopMCx3eEaoz_1%B`ym{J{k2gebc&$n3bs6D%TVhC!gT@E`4$78W$GQFTYo!){HVG33dJU z1E6)oq1mq|f3PSD%xP+IrVuDymK@pdT%Jj#phe@XRxNkw+PBC*$sxy$ZC5+a1Za^#55u<;uR$uY#+QTiS(YH`qV3bQYdd)%`8y`I|Q@oDzu zb@tV0?)BeH`?D{9b#2VB;ij^Jf%c~+jtjm3qToS1yJ4E?1y^@_+t-M>RmWsUQFZ{V zmj!^JzEM_#_04U(asM>|(B!DO4US|wC6#|*zu=fXqAlDk7uBfd?+>dtADizmQATX7 z*v&58Wo(6PH%(kWk5D)Twx0sik2_s-T3`{uRJy82Wr7uoa)y{!S*{~+h-j%5bM3mV zJ1u46VuXyaLC%pt+cBr+3V1c^ig)%jo(hh-V}|xuu|9XXY|8&IO1RQ`OYZCQnw}@( ziFW+slx}{WfO#1bkYi4h(Yq2cKX;jQiBU%ck^*Z=(Xnm1N^4C=w&^0Rq+~*b03O8)}VXT#}lkFDg!y&^S%ePq7;yYGfCZ7IboQ<4l$q=A|2)rCZaE9YZs+wPQR(Ow&k6Ib}jZK{lh??Q)E#IhQ8m1XCr1@VInr zl?r1ka;~|ej;h+nSGnYni9TH}~ z|GwX$y9xc~SR=p~mYN z>Wwch!tJ~90LdP?!pDX=jeF*U2hHJ~!>i z#Kt)%Qc*AEdIz9_%{6C+uln<HOD*-( zPpf}KWS+yvp2*`oYD+xM!?wT!?+`5S9N;x)yF1{+c#J?j^DL~U>#G1%)2p#r1Qa-m z89#`TL^}$B51s1JN5roNhEA-*ifkCIO1G+b2QEsMI^zVo&u`yz--$vHsSzcNB0)T( zb$+NoW^H&1208hTPv$Q8!`qO~%t4=f{IrvvAJf(daA4jwX3tE<}T+ zWZ3*~fY5+7C0KC44WtK98*+|?3IA8W|gG15~>jchBUfM>lNj27wdvuT5VK^S9h;`Co$2FGFtd)N+(U^ zJX|Wy(ZDa15`Oe^P}FS=lL(G*VvJOVu~;jKX_~n<37{}qzgfn#aE}bDEwMZ`F%`_{ z*7vrJ+>C>1D7(zb5u*!>rpkhXh|MmL*KEp2iPp#q;6FAxF>XSvChn%Bz%UvLK&vhd zi^_~07W2U(V@fs#iV+z1QJTd?hqbuz8|cB=`df!PU*!ha`eS7e*{c{2Dei=jJ8QS! zDpQ{EWLCSbmXD*mS$fQhaG~AOyA!qNkXqEH%9BIHH>C55+LY#+e7K;KB_ERiV1~j+ zvyXvVb5{I|5 z_t_wN5wvfu2NN&1&yh6p@LP=Gg*+aU(_`U!1W7=65;ek}^Rr*)f$es0ZCN!IQCcW$ zS;HX+)h55sj@RFJ?FT0)I&QQ&++>RW7?v$5{EvEe27m_##i7D-jqMB6PrEsYh*`|E zku?~nhQ;5qIX)#7=tQx(rJRq(Ue>F55qIEsf)ISt*;nS`gG@IL;nDU>*K~d)DvWMy z#BfWD}qm-wqk$s~WQTF#tH|SRs4<4tDYPAkR zLQ)LfRk^DWl5|`0(MB|ANl~xn4@6rdamF__)_G1>9x2>P5>W5bpUw!;P4gH}F1Wh0w6<^QPJmuDLb@J=Y=lm^g|SgpCt3<-C_-~@PW zd`2(w?D^TOxhj8do7Q=Fv7hYf*U~RqJN?tMd|hs5t@>sk=(uOvKn%~`?#&xZP1%lx) zM~I8UwnY|eMpp8SqdkuOjZ=ZlZwf~$E;GTo)#Eq5k{4rH@QfX$Y@rvclcMPb(Ci@? zyz>a#p`pfO=29$#r5|p}Y22|?6#$u#)Kcoler8Y_C%haOw;h-&A6`@MG8gZIkIjv> z&}n>jyqZal)8yAjOQ6!p5!86EQS<{M_Q;6F$E|t2-(z+Ic$1Biqf>D)}*_IK) z6vU!nTfF(F>kFxMfI;E-T%NDVwO~kGC2XxTNnrLi)sMIxd83kCk9UB<6L}Z&3M<@Q z%l*6HdzAtaTQ+#ts9zCJw-n-#g+P#c9b9=Tr&bn06pakuM9GL7LAn?uwr>K&R*9Fu z6ml#&q2i|4Pq88hZ+LUFUNgR@>~Qc+jXlv`$lBdtD~h)B$EilLz9eqWgqR$W;v~sz z_FbOcdu3PchYe%`u?g~sgxKtVKtCQReWmvOGmen=%4Dm4)|LDV(M=2y9I=*NYZfhm z<<2kvxFQG05wEh!t5LC0TsK7*E<_TjFZ5pM2R1v zVp6XY2_BOgT_H}_jK;=%;X@Kj(TQ1jIgJ3UPlmJ}ySC8yP#TJD@YcHQ53?tKEF|`Z zTxWApy8Ir;LI~j1EDe$l=D#3f_!k6{0jx0onC-K+7%w+eoHcBLGmG&xd4>E~neiMB zr%uwjrN~4KZD`IcFr5V@S!)`-h=-3gAo;>hsm43${ugBrIR>_>64N|_ZY&GA<;+2D zO6TW8sKS48e~@=tdxpHFY%M!1^Qj<43~0_8rcgXs&n;Qb6wCg2edcKNFWyZtuX>F5 z>@UM;0jX)}1?PwHGZBNrc;Vs?whfZqG;b4M`zgMog_XYp45+=JZ-#s6*!au@E;+q^ z`j5@mTKm=f@T|C)uM7u6EW8?K9xU68(9$|N;P2(E_+#1JJZZKzFDXxH&CT0?&KkD_ zOQg#!gOA={&a9Zi@fOOmIje>4zpjy+(1_C;3BjZONtQ^#=a}`m6B@!i&KyA?W=r~aU)JD-@Y!c z4X+dV#618c*B|^$F^+T;{OS^A!=v6_HyP;2L{-MQ3gMU>wO_=GCebD3z>8N%vzOqm zx`U>?y`GpN!;N|-U;DXY9Jwd`$12k(25bN_K0Iz#s3FLdMwE&{_E#nmT!l89dd<%_ zYlL*b8`3WJbMKFiz_KMKiVbRJ-B_!WIUprNMaJLavwNe_&sZ`pRef9El0>--Wl4jH z#FX8ktxe^&(?Mrz9Oa%kysG|L8Xr45(NGa}`4Bi%Ue%d7cW|IYrlIrH#)}9<3NZwZ zTkKtkPi%C!Gd9kX;CPsC!GMm!PRd0N&aQPNm12e}5g|YgpOY6u{1c)|$aEo~<_uCC zL1gZb8eyc)25vVB1kxG5`)R4mD^W1zPsJ??qkKqPe#^6+r)4=QA}))Uan z=*zB5i06|+CLN_Eh$Tg&$xfi^xr*7{Ad8LdYLm*;aqgkRdCyba7}UGnHtlcErK|Z zHQ77#hWs8$=;x;1;l zAP@fo`$*66hhg6r)8&YhAA3I2`HU2xawO-t%J^Y5v%lC8)gWIJ6o^>PMBHh)!vK!A zE|ch31A3L4#T+l4In33ldOUBG|88OYtj&M^4< zYji&;Vt&GJ?u*sDISmDxVADgU3Mo#N??=Y|3rt?!VmK%^Ireu_*(^>?gmxUkaaC>BeO>WSODCNV_aCUq`AWhk+dLXw8HD8=g>% z%0)y^r3@$~JO-H^+>UTm2)|7z-fOaZ07ZJQid zcZ{&vifEJsB;O5AD}4-#!=4WeS4d+4&+(y!nla(nbDL#|?Z(54I=EHXCb?0gucF|S zZbQrezc5x4bu6(1w6iti3ViMBjLBV&wcMH037=)hPF(Ky`}{0Dm#@zs1$$<1kZTAT z98QxEju^eIi33m8K@_pj7tv({?TGA|%e2q1sh>_FH0FZ3uLP=V!5W9%yZKU(buT01 z`1%HPomI};vtXO~O~k-HE&GDTpa};SZkOavMEW3< zBNohDsB{Z)0_^$i*pJIUE6#PGX%s;ir^6V{MV3^}Qob`D8Mx$r#R9Lkmr&_k4m<(;&{%Ap(yRrL8FR6tGm8l;4~=M55r%6> zw}28y3@Fe+jPcLcShoN?IaD34(Z+cJR-yA%e3Af02ji$igo~Vr>EqA4`oL@%7-2^S zprukMit6?)%5Yh){$KA;!$gw(Eaby4yJjswk51gwF{+KX{#RjKePILxDug@>WtkJx zM9TZ}VwQ~Xp;MSNs7GtQJWodT@;+;NXEQe*5Q%nqz z9L>x%#S1p=E*sBaV;r1AU?;1 z%Tt9vh1=`+6jcFVl*ew)HeA09swa~=Ud|r&J3^TpAYi2fy^Wi7)&0SLM#UiO4=_wH z=^&Cx?Yq6hFh7WrCxz7o1(PsHkJHUp>nylZ?rfl`mBvoS|L19#Bf*fjI*ROfdlc=FqjElpQR2$L6eyOZ(D@qBBq99pRs=u{(AG3dV6F)_H%^aZJb zW5{ss6w5G&YgcjE21f7J2*xqBspc=o5NvX`+4f_?jDeLAw3Jqf#Tt@LN7+kG^?jj5 zG#uN!sjHOHzjtjn1?N-;L0nbRlcfd?-50WkF+G$9D#|bJB67dgcOoJo_r6VB5od@b zNe6`0d5E12^Kz3tWC5V&#ocX#;O1(yMqGr74a4EL9N_RW4bNicme%mRrQBnyV=)8H?h1oi!^#D`QqX4H-Xk41~A8mD7L zi$H3@hvY=knNW1R;*oVV$Ogy*w$b7Tsc?~6(f=Q~2D-_kYp_&Vfw>i5rcQ%s&3R_J zWa|BO_kMKubhLRnjF1{Ox$jRI0P*lxxgKA898-Ig1*&kTZ~o6e{vm+B&Ceo)RssFF za7>&?r=Muz6}Wi*(O$x*=n;F5*VxWbvA?QG^UauiiC~C9WOQ&q7hC2)>=`{exgmu3cIgB{fI=xuA@F_2gI9*ugWGmbuPo0X6jRv zXn0gh2#Ki1nPsP3DsV$O1i~}gRpX3PCgkh9%Hhi%PX~0oYDX3tGZqq)eA;GZvdFmtbSP%BDNuNQ7TNlc65)6u?=;dKCuy}>@s&lm_-GK9;+ zYt<*U@S1=X83|aU%)_;Vnf^sbJ52WVOzroUqvC>1rxbw12ZeGulWvq2ijP)e1_^rH zJD6*Rodoz8p*&|_x{G{0j^^18%g@a|1wcOa-rwnjT?P8`AnC4y*-5ypU z?h%0M6Z7-Yap39z#FG=G>~(lu>t6lfHoON?K&V9Y^dkR+>Z8BK5w{))#d^%QC zV6hhovd&%?kv9zh%y4nE1f(wtxfo3*NiyX$p6Wm$Y9sC8zGPxjfEqCcuLB0Jvh7<7s9uyLyTw`;c^tkAufX{ z;9#dFy$+G#Qli=XIENsa=aJQ}q-%(ptk;sxjDWDpDG$-Wd5N%jLm`Mf3!w?u}ux^(wb?)2QX~;R%-P@5R+KvrK~xNL_V0rojRS8QIf?FOO_;# zig0N+zUyK#wjG);u79zR243GCV)SkD`KLj{xtc8ODhv=4AWFHPa(0JvE}ylejsyg*L#P^_*Fvp~A62uYHD zXpdmY@OLsHmSV{;@FBEAh3qnxOCF7Z4bVb62d9ZD}zWchS%+Y9>T4`lTDwLbgGSOb$7WC;T6rVpy$=-so%`F(MIrw;f zdc!@P*Qq9wsbuOx{%eaA*b9Qj(+0MT{hL6?OgOx?vd{2D8o7!>Uixz7?-gO>`s9uD zR8tE0TbpLz%eI+k$}ez@J9>J>Ddrs zvI0x5#{IGkX0RmbC>uIrpemRm5^}yUW1?buTL5m;SS5xJwskI98V`d#B}8#h#)7+# zZf4DEf>Z&=T!F5=qeW)8`N-iyiQSl4_zhcF#>!&O}@ZTD(N zU+;L6pRh%(#|ge`VRoE7KCi`U*BE;98afRY)D8qv)3E?F6#fpVK*l~-cP(9 ztYLY|X^53NyHzCBY`IDtQ;MnU`MK)zO5#RTr_TrFY9^EdUZP__pu7&LYC)Jqx~``F z5#d4>lQ5F26Q}B$4AN7(^of8NttlL>JSYfJ7FK!U7LzAa@qK!6!0PwbuEgk@>!URm zzS|tc4D#Q6|1Vi)*?sM2qnFBDH+&DOUE%h0$fm~UlioXRuK&ZiOWt;m$8VqOc62bU zeBk(jHL4sKlMTCbcMtOX*YOP|xY@NL*dlf{y|vq6TKf&VpUs|Mkk@+Wc%>#sz*Z|i zN6qeGMi$bP_$Eyl2SaYQ={N^CjzphV%T>$3YY*kUU?~_jC?Ufi;g!itz9Ffp6sDS5 zxwCtFV#~l%4*!A-O1FLE;uu2QOQGdCdFx!ppnSPZ)G}gdfdWNXx#i^Am&4xM2~>=T z#0aY*C_Ta1y$i@&i*f`h=_OVVjh=Pc{tPjmdF(G$3}@1x`*$J37)?u$Vg!tbDy2;C zM&=SFCBS1;IVp^sLNK}lre*@d;46&#R+LW%LjKA|%_2N3m zZO67hmUSrlnl7{coAlM{{5fi7FYs}wqAOpK_d1HX^5OT7rV+{_BO7{#M@ z`7+US-t_Lt3Re|-HEkqs%Tfw$T9Bv|?HZ7VnT&|#ySbrtEDhlvMbd)$bq@^DJrGpI zGqs)8aC9HA$lC7cjdVW6ffZLYK`k4!Zq%hdc4QF1Q5qj%-YALPLhO)(oWL&3bt{hg z2Bpqp-upK=t*4}s0rUpO5m-vA>bkelC=$e?C?j4R97)S-3>IOAN~#OEkm>!=jSh}_ z?p*WTaKW_bHvI)k6i~^$GR@Kq72z^8$s3*?bWIv(XH(q4HM$zReNUG zZNYO2q%$NW<2d4(YkQLC5+!|hGWdY9Ll}3t(2g#Tla%5Ugs+^%c$CFlu8j{92~MFJ zS`phY$=S|@q8mVhr*uscv@mJ{_BenvxC)4^c@S)gOD^p?8)}+}9>3;qLtsLi49HFv zMA2oRpcn|=@0mvMm#G6wfm_Xjv|ngYm2sPxLKM=S!*+l@kWUO$3giiJ3W|~vujK>_ zM|lgi)k_IW(r)XyMq>0aJ{BIe`(^wN)xNV|DdnQ5j1pPze_T&15H_&{+~g%@C((L}~4*gF;R50L08SP(v-jNfrRBQ%Fif zvSg{QMe@;U0u2aj`SNU2pioTZnYKC&gg{!s1YuMKAt#%2p@R@ZXHf= zAmFY7R=WA|SMPSM4CZ9eAW(j(OV5`{M0~t~nSPZHqCVN*MGBGgB%DZ*1lzc9tTa6# zMGld43OUz(W*l&(h!@!t60PmfPmxu2F2V1 z8Izdi61ae@gkv#M@T?aA0O1m>en6wjceRtOf1xFd!?G`w*CP;9ZBsAm+a?|xYh=Sg z|M1c+2%wN=U?C+C!yF7SAqoMmyqUBTOIuuyVYVl$JRu%dii2+b4-SuikaMjroX zyLNQZOZnitFE)-n{C|e*zouIT_R6!JY(2n?5K2tAvB&RRT1r?%&ne01D4xLqSJL80 zD|WtOX00?L+3AYV)G4tGvT@-G3RaXEe6IfJ-M#3XyYQZ`voEFG9r};OtP7W%bqVxm zNy-K~p=gOMUDXQck{K%-g9xfX2Mz)FrVckzM5(_E_2;MSaKM8n+z^A&?dik?f0pb2 zB{IzTw7K3NZ{eWq9rT0X{tE6Iz=|M6H5e0H{;7%5kS58UUBd3Jl$J3?qfl-g$(LWG zAjmRM6rIOSNT5K~#i)r%6Ves9_beFgU3;f~bmct=SL_(-LCSCnDQaP=WGKUWpvUW& zKDvoIoau)me{C;4SL)vF)lXv2xZHIZ za|a*Fx$Rv9-Iv{V|C2%%KSw!{tkeL&jWIanDJ>%0b(tIzB>$p@8!|l%8yUxT33GD= zgk}y%#}9yeNPHY|z@LTDO*s*ugP#V`g{x>d%MaQMpm*8!z!{;-WObsK`=$n3s&WGa zYdKucS7m1wQz$$w%8zuTAz?FRPfCZj!%bEj8nW=R5M9VT^RCZV@(@rc6J@O{F-)~* zIoaAYMJWZnm06&thza3gWq2lDO@^@;e<1Nf&&%XE{7GuXACeEZ*1I`huK>{zGVq8U{x^qi83W3M zPkF5aLCNHD)37AdK-(8FQ%dYbDI*Dv1SdD~6)S~fk)Z2rY_%CuRI�VVmC^HJ%(s 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

88MH#C#z^WV=vSyGH?2NNvfm(J<8Y&#w(7 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

+
{{error}}
diff --git a/x-pack/plugins/ml/public/jobs/new_job/simple/recognize/create_job/create_job_controller.js b/x-pack/plugins/ml/public/jobs/new_job/simple/recognize/create_job/create_job_controller.js index a7899729d8df7..0e518e38f8eca 100644 --- a/x-pack/plugins/ml/public/jobs/new_job/simple/recognize/create_job/create_job_controller.js +++ b/x-pack/plugins/ml/public/jobs/new_job/simple/recognize/create_job/create_job_controller.js @@ -212,7 +212,8 @@ module title: o.title, saveState: SAVE_STATE.NOT_SAVED, config: o.config, - exists: false + exists: false, + errors: [], }; }); }); @@ -342,6 +343,9 @@ module obj.saveState = SAVE_STATE.SAVED; } else { obj.saveState = SAVE_STATE.FAILED; + if (kibanaObjectResult.error && kibanaObjectResult.error.message) { + obj.errors.push(kibanaObjectResult.error.message); + } } } else { obj.saveState = SAVE_STATE.FAILED;