From 293188d3861355ae14df5f3945db1074185c4e93 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Wed, 3 Apr 2019 09:28:26 -0700 Subject: [PATCH] feat(context): add support for method interceptors - introduce `@intercept` for classes and/or methods - enable `invokeMethod()` to execute interceptors - add support for global interceptors - add acceptance tests to illustrate how to use interceptors - apply global interceptors for handler routes - allow proxies to be created or injected to apply interceptors - update docs for interceptors - introduce AsyncProxy type for proxy with async interceptors - allow global interceptors to be sorted by group --- docs/site/Concepts.md | 3 + docs/site/Interceptors.md | 657 ++++++++++++++++++ docs/site/imgs/interceptors.png | Bin 0 -> 204169 bytes docs/site/sidebars/lb4_sidebar.yml | 4 + .../interception-proxy.acceptance.ts | 203 ++++++ .../acceptance/interceptor.acceptance.ts | 529 ++++++++++++++ .../src/__tests__/unit/interceptor.unit.ts | 156 +++++ packages/context/src/binding.ts | 37 +- packages/context/src/index.ts | 4 +- packages/context/src/inject.ts | 17 +- packages/context/src/interception-proxy.ts | 97 +++ packages/context/src/interceptor.ts | 432 ++++++++++++ packages/context/src/keys.ts | 26 + packages/context/src/resolution-session.ts | 7 + packages/context/src/resolver.ts | 14 +- .../caching-interceptor.acceptance.ts | 98 +++ .../caching-interceptor.ts | 80 +++ .../global-caching-interceptor.acceptance.ts | 122 ++++ packages/rest/src/router/handler-route.ts | 11 +- 19 files changed, 2471 insertions(+), 26 deletions(-) create mode 100644 docs/site/Interceptors.md create mode 100644 docs/site/imgs/interceptors.png create mode 100644 packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts create mode 100644 packages/context/src/__tests__/acceptance/interceptor.acceptance.ts create mode 100644 packages/context/src/__tests__/unit/interceptor.unit.ts create mode 100644 packages/context/src/interception-proxy.ts create mode 100644 packages/context/src/interceptor.ts create mode 100644 packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.acceptance.ts create mode 100644 packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.ts create mode 100644 packages/rest/src/__tests__/acceptance/caching-interceptor/global-caching-interceptor.acceptance.ts diff --git a/docs/site/Concepts.md b/docs/site/Concepts.md index 47a4cc99ab18..f3893955682a 100644 --- a/docs/site/Concepts.md +++ b/docs/site/Concepts.md @@ -37,6 +37,9 @@ LoopBack 4 introduces some new concepts that are important to understand: Controller operates only on processed input and abstractions of backend services / databases. +- [**Interceptors**](Interceptors.md): A function that intercepts static or + instance method invocations on a class or object. + - [**Route**](Routes.md): The mapping between your API specification and an Operation. It tells LoopBack which Operation to `invoke()` when given an HTTP request. diff --git a/docs/site/Interceptors.md b/docs/site/Interceptors.md new file mode 100644 index 000000000000..21200ff4e9a6 --- /dev/null +++ b/docs/site/Interceptors.md @@ -0,0 +1,657 @@ +--- +lang: en +title: 'Interceptors' +keywords: LoopBack 4.0, LoopBack 4 +sidebar: lb4_sidebar +permalink: /doc/en/lb4/Interceptors.html +--- + +## Overview + +Interceptors are reusable functions to provide aspect-oriented logic around +method invocations. There are many use cases for interceptors, such as: + +- Add extra logic before / after method invocation, for example, logging or + measuring method invocations. +- Validate/transform arguments +- Validate/transform return values +- Catch/transform errors, for example, normalize error objects +- Override the method invocation, for example, return from cache + +The following diagram illustrates how interceptors can be applied to the +invocation of a method on the controller class. + +![Interceptors](imgs/interceptors.png) + +## Basic use + +### Interceptors on controllers + +Interceptors are supported for public controller methods (including both static +and prototype) and handler functions for REST routes. + +Controller methods decorated with `@intercept` are invoked with applied +interceptors for corresponding routes upon API requests. + +```ts +import {intercept} from '@loopback/context'; + +@intercept(log) // `log` is an interceptor function +export class OrderController { + @intercept('caching-interceptor') // `caching-interceptor` is a binding key + async listOrders(userId: string) { + // ... + } +} +``` + +**NOTE**: `log` and `'caching-interceptor'` are illustrated in +[Example interceptors](#example-interceptors). + +It's also possible to configure global interceptors that are invoked before +method level interceptors. For example, the following code registers a global +`caching-interceptor` for all methods. + +```ts +app + .bind('caching-interceptor') + .toProvider(CachingInterceptorProvider) + .apply(asInterceptor); +``` + +Global interceptors are also executed for route handler functions without a +controller class. See an example in +[Route Handler](Routes.md#using-partial-openapi-spec-fragments). + +### Create a proxy to apply interceptors + +A +[proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) +can be created from the target class or object to apply interceptors. This is +useful for the case that a controller declares dependencies of repositories or +services and would like to allow repository or service methods to be +intercepted. + +```ts +import {createProxyWithInterceptors} from '@loopback/context'; + +const proxy = createProxyWithInterceptors(controllerInstance, ctx); +const msg = await proxy.greet('John'); +``` + +There is also an `asProxyWithInterceptors` option for binding resolution or +dependency injection to return a proxy for the class to apply interceptors when +methods are invoked. + +```ts +class DummyController { + constructor( + @inject('my-controller', {asProxyWithInterceptors: true}) + public readonly myController: MyController, + ) {} +} +ctx.bind('my-controller').toClass(MyController); +ctx.bind('dummy-controller').toClass(DummyController); +const dummyController = await ctx.get('dummy-controller'); +const msg = await dummyController.myController.greet('John'); +); +``` + +Or: + +```ts +const proxy = await ctx.get('my-controller', { + asProxyWithInterceptors: true, +}); +const msg = await proxy.greet('John'); +``` + +Please note synchronous methods (which don't return `Promise`) are converted to +return `ValueOrPromise` (synchronous or asynchronous) in the proxy so that +interceptors can be applied. For example, + +```ts +class MyController { + name: string; + + greet(name: string): string { + return `Hello, ${name}`; + } + + async hello(name: string) { + return `Hello, ${name}`; + } +} +``` + +The proxy from an instance of `MyController` has the `AsyncProxy` +type: + +```ts +{ + name: string; // the same as MyController + greet(name: string): ValueOrPromise; // the return type becomes `ValueOrPromise` + hello(name: string): Promise; // the same as MyController +} +``` + +The return value of `greet` now has two possible types: + +- `string`: No async interceptor is applied +- `Promise`: At least one async interceptor is applied + +### Use `invokeMethod` to apply interceptors + +To explicitly invoke a method with interceptors, use `invokeMethod` from +`@loopback/context`. Please note `invokeMethod` is used internally by +`RestServer` for controller methods. + +```ts +import {Context, invokeMethod} from '@loopback/context'; + +const ctx: Context = new Context(); + +ctx.bind('name').to('John'); + +// Invoke a static method +let msg = await invokeMethod(MyController, 'greetStaticWithDI', ctx); + +// Invoke an instance method +const controller = new MyController(); +msg = await invokeMethod(controller, 'greetWithDI', ctx); +``` + +Please note that `invokeMethod` internally uses `invokeMethodWithInterceptors` +to support both injection of method parameters and application of interceptors. + +## Apply interceptors + +Interceptors form a cascading chain of handlers around the target method +invocation. We can apply interceptors by decorating methods/classes with +`@intercept`. Please note `@intercept` does **NOT** return a new method wrapping +the target one. Instead, it adds some metadata instead and such information is +used by `invokeMethod` or `invokeWithMethodWithInterceptors` functions to +trigger interceptors around the target method. The original method stays intact. +Invoking it directly won't apply any interceptors. + +### `@intercept` + +Syntax: `@intercept(...interceptorFunctionsOrBindingKeys)` + +The `@intercept` decorator adds interceptors to a class or its methods including +static and instance methods. Two flavors are accepted: + +- An interceptor function + + ```ts + class MyController { + @intercept(log) // Use the `log` function + greet(name: string) { + return `Hello, ${name}`; + } + } + ``` + +- A binding key that can be resolved to an interface function + + ```ts + class MyController { + @intercept('name-validator') // Use the `name-validator` binding + async helloWithNameValidation(name: string) { + return `Hello, ${name}`; + } + } + + // Bind options and provider for `NameValidator` + ctx.bind('valid-names').to(['John', 'Mary']); + ctx.bind('name-validator').toProvider(NameValidator); + ``` + +### Method level interceptors + +A **public** static or prototype method on a class can be decorated with +`@intercept` to attach interceptors to the target method. Please note +interceptors don't apply to protected or private methods. + +#### Static methods + +```ts +class MyControllerWithStaticMethods { + // Apply `log` to a static method + @intercept(log) + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + + // Apply `log` to a static method with parameter injection + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } +} +``` + +#### Prototype methods + +```ts +class MyController { + // Apply `logSync` to a sync instance method + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + + // Apply `log` to a sync instance method + @intercept(log) + greet(name: string) { + return `Hello, ${name}`; + } + + // Apply `log` as a binding key to an async instance method + @intercept('log') + async greetWithABoundInterceptor(name: string) { + return `Hello, ${name}`; + } + + // Apply `log` to an async instance method with parameter injection + @intercept(log) + async greetWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + + // Apply `log` and `logSync` to an async instance method + @intercept('log', logSync) + async greetWithTwoInterceptors(name: string) { + return `Hello, ${name}`; + } + + // No interceptors are attached + async greetWithoutInterceptors(name: string) { + return `Hello, ${name}`; + } + + // Apply `convertName` to convert `name` arg to upper case + @intercept(convertName) + async greetWithUpperCaseName(name: string) { + return `Hello, ${name}`; + } + + // Apply `name-validator` backed by a provider class + @intercept('name-validator') + async greetWithNameValidation(name: string) { + return `Hello, ${name}`; + } + + // Apply `logError` to catch errors + @intercept(logError) + async greetWithError(name: string) { + throw new Error('error: ' + name); + } +} +``` + +### Class level interceptors + +To apply interceptors to be invoked for all methods on a class, we can use +`@intercept` to decorate the class. When a method is invoked, class level +interceptors (if not explicitly listed at method level) are invoked before +method level ones. + +```ts +// Apply `log` to all methods on the class +@intercept(log) +class MyControllerWithClassLevelInterceptors { + // The class level `log` will be applied + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + + // A static method with parameter injection + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + + // We can apply `@intercept` multiple times on the same method + // This is needed if a custom decorator is created for `@intercept` + @intercept(log) + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } +} +``` + +### Global interceptors + +Global interceptors are discovered from the `InvocationContext`. They are +registered as bindings with `interceptor` tag. For example, + +```ts +import {asInterceptor} from '@loopback/context'; + +app + .bind('interceptors.MetricsInterceptor') + .toProvider(MetricsInterceptorProvider) + .apply(asInterceptor); +``` + +### Order of invocation for interceptors + +Multiple `@intercept` decorators can be applied to a class or a method. The +order of invocation is determined by how `@intercept` is specified. The list of +interceptors is created from top to bottom and from left to right. Duplicate +entries are removed from their first occurrences. + +Let's examine the list of interceptors invoked for each method on +`MyController`, which has a class level `log` decorator: + +1. A static method on the class - `greetStatic` + + ```ts + @intercept(log) + class MyController { + // No explicit `@intercept` at method level. The class level `log` will + // be applied + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + } + ``` + + Interceptors to apply: [`log`] + +2. A static method that requires parameter injection: `greetStaticWithDI` + + ```ts + @intercept(log) + class MyController { + // The method level `log` overrides the class level one + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + } + ``` + + Interceptors to apply: [`log`] + +3. A prototype method with multiple `@intercept` - `greetSync` + + ```ts + @intercept(log) + class MyController { + // We can apply `@intercept` multiple times on the same method + // This is needed if a custom decorator is created for `@intercept` + @intercept(log) // The method level `log` overrides the class level one + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + } + ``` + + Interceptors to apply: [`log`, `logSync`] + +4. A prototype method that preserves the order of an interceptor - `greet` + + ```ts + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + ``` + + Interceptors to apply: [`convertName`, `log`] + +Global interceptors are invoked before class/method level ones unless they are +explicitly overridden by `@intercept`. + +Global interceptors can be sorted as follows: + +1. Tag global interceptor binding with `ContextTags.GLOBAL_INTERCEPTOR_GROUP`. + The tag value will be treated as the `group` name of the interceptor. For + example: + + ```ts + app + .bind('globalInterceptors.authInterceptor') + .to(authInterceptor) + .apply(asGlobalInterceptor('auth')); + ``` + + If the group tag does not exist, the value is default to `''`. + +2. Control the ordered groups for global interceptors + + ```ts + app + .bind(ContextBindings.GLOBAL_INTERCEPTOR_ORDERED_GROUPS) + .to(['log', 'auth']); + ``` + +If ordered groups is not bound to +`ContextBindings.GLOBAL_INTERCEPTOR_ORDERED_GROUPS`, global interceptors will be +sorted by their group names alphabetically. Interceptors with unknown groups are +invoked before those listed in ordered groups. + +## Create your own interceptors + +Interceptors can be made available by LoopBack itself, extension modules, or +applications. They can be a function that implements `Interceptor` signature or +a binding that is resolved to an `Interceptor` function. + +### Interceptor functions + +The interceptor function is invoked to intercept a method invocation with two +parameters: + +- `context`: the [invocation context](#invocation-context) +- `next`: a function to invoke next interceptor or the target method. It returns + a value or promise depending on whether downstream interceptors and the target + method are synchronous or asynchronous. + +```ts +/** + * Interceptor function to intercept method invocations + */ +export interface Interceptor { + /** + * @param context Invocation context + * @param next A function to invoke next interceptor or the target method + * @returns A result as value or promise + */ + ( + context: InvocationContext, + next: () => ValueOrPromise, + ): ValueOrPromise; +} +``` + +An interceptor can be asynchronous (returning a promise) or synchronous +(returning a value). If one of the interceptors or the target method is +asynchronous, the invocation will be asynchronous. The following table show how +the final return type is determined. + +| Interceptor | Target method | Return type | +| ----------- | ------------- | ----------- | +| async | async | promise | +| async | sync | promise | +| sync | async | promise | +| sync | sync | value | + +To keep things simple and consistent, we recommend that interceptors function to +be asynchronous as much as possible. + +### Invocation context + +The `InvocationContext` object provides access to metadata for the given +invocation in addition to the parent `Context` that can be used to locate other +bindings. It extends `Context` with additional properties as follows: + +- `target` (`object`): Target class (for static methods) or prototype/object + (for instance methods) +- `methodName` (`string`): Method name +- `args` (`InvocationArgs`, i.e., `any[]`): An array of arguments + +```ts +/** + * InvocationContext for method invocations + */ +export class InvocationContext extends Context { + /** + * Construct a new instance + * @param parent Parent context, such as the RequestContext + * @param target Target class (for static methods) or prototype/object + * (for instance methods) + * @param methodName Method name + * @param args An array of arguments + */ + constructor( + parent: Context, + public readonly target: object, + public readonly methodName: string, + public readonly args: InvocationArgs, // any[] + ) { + super(parent); + } +} +``` + +It's possible for an interceptor to mutate items in the `args` array to pass in +transformed input to downstream interceptors and the target method. + +### Logic around `next` + +An interceptor will receive the `next` parameter, which is a function to execute +the downstream interceptors and the target method. + +The interceptor function is responsible for calling `next()` if it wants to +proceed with next interceptor or the target method invocation. A typical +interceptor implementation looks like the following: + +```ts +async function intercept( + invocationCtx: InvocationContext, + next: () => ValueOrPromise, +) { + // Pre-process the request + try { + const result = await next(); + // Post-process the response + return result; + } catch (err) { + // Handle errors + throw err; + } +} +``` + +If `next()` is not invoked, neither downstream interceptors nor the target +method be executed. It's valid to skip `next()` if it's by intention, for +example, an interceptor can fail the invocation early due to validation errors +or return a response from cache without invoking the target method. + +### Example interceptors + +Here are some example interceptor functions: + +1. An asynchronous interceptor to log method invocations: + +```ts +const log: Interceptor = async (invocationCtx, next) => { + console.log('log: before-' + invocationCtx.methodName); + // Wait until the interceptor/method chain returns + const result = await next(); + console.log('log: after-' + invocationCtx.methodName); + return result; +}; +``` + +2. An interceptor to catch and log errors: + +```ts +const logError: Interceptor = async (invocationCtx, next) => { + console.log('logError: before-' + invocationCtx.methodName); + try { + const result = await next(); + console.log('logError: after-' + invocationCtx.methodName); + return result; + } catch (err) { + console.log('logError: error-' + invocationCtx.methodName); + throw err; + } +}; +``` + +3. An interceptor to convert `name` arg to upper case: + +```ts +const convertName: Interceptor = async (invocationCtx, next) => { + console.log('convertName:before-' + invocationCtx.methodName); + invocationCtx.args[0] = (invocationCtx.args[0] as string).toUpperCase(); + const result = await next(); + console.log('convertName: after-' + invocationCtx.methodName); + return result; +}; +``` + +4. An provider class for an interceptor that performs parameter validation + +To leverage dependency injection, a provider class can be defined as the +interceptor: + +```ts +/** + * A binding provider class to produce an interceptor that validates the + * `name` argument + */ +class NameValidator implements Provider { + constructor(@inject('valid-names') private validNames: string[]) {} + + value() { + const interceptor: Interceptor = (invocationCtx, next) => + this.validateName(invocationCtx, next); + return interceptor; + } + + async validateName( + invocationCtx: InvocationContext, + next: () => ValueOrPromise, + ) { + const name = invocationCtx.args[0]; + if (!this.validNames.includes(name)) { + throw new Error( + `Name '${name}' is not on the list of '${this.validNames}`, + ); + } + return await next(); + } +} +``` + +5. A synchronous interceptor to log method invocations: + +```ts +const logSync: Interceptor = (invocationCtx, next) => { + console.log('logSync: before-' + invocationCtx.methodName); + // Calling `next()` without `await` + const result = next(); + // It's possible that the statement below is executed before downstream + // interceptors or the target method finish + console.log('logSync: after-' + invocationCtx.methodName); + return result; +}; +``` diff --git a/docs/site/imgs/interceptors.png b/docs/site/imgs/interceptors.png new file mode 100644 index 0000000000000000000000000000000000000000..72691efd5893f90f93be1a1b215f36a821e36c2d GIT binary patch literal 204169 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%0D_uR@f&Y=B=lGq6nQVp6Fv0q?g_?Z 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 z z%}$xN`AZD9%CdUjE7xc9m}B}&C105o^@7QC2=wKGgCrWTNOrd~=*Oy$uRSz`0dEOF z`kH|}Zzjt_3xL(&X5 zKZTmk(zJq~cDT=*MO-*d2+Qz{6|tBok~UCXhJ%zBhn!NT!-GXZ>aUu9j1`YhAW+J| ziZ^G4yD;=M2epER_44I4PA0@Nbq0)g+UBZ(3U%~BVkNH5^3 zJnq7(&YexFr>X_u2!pLnse4JnteLfl408YrVo}9dMyR=_{?L)wPfcg*Ox(v>x3rFt zO^fR2sH@9|My}sdHORGr4i9i>kIy?aIP@gzEG>IVg=#M--p{%YR@|6mGjv1k7BA)> z+g|JH53Zdhe-K1Z`1VM86L02z`86K)IakN~N|j=>$`guk|Cn5XWw!iVe$HhmdD4yS zK7!7trSS2OT%BPJ)hf8sF)NqVoYBridMYPw9DFZC?55L_Dd zG6OfgeTy))VXGluhFN?TJ5_JSvEE?46xC;uAoUM3w8s+_=|TU1J&-CSQ+rGz^{F#! zYrqIz(DrjWJEcl1VZ2<+Ih|Rj*v(wdA6xee0*C`PwiAgc7GsfR z8)6cq-FT6x0=HPNnhlo=tR09oAA^VK))L4pFVHZjY8)qH8I$H}J*k0(Jz7qwAg8*G z7DE7`-iNLAgd$*~l2Y8F49^U0n;vMCMy4rDn$hNPTH_K3|iAAkpER1HI z_Wbz2EP$JA$qZwBvX9nyfhbUX_vY$8>;Ys6m>A(8fOniXJK0X>&FEtub_y5jfcNm2 zIEoONmc<67VNVOYGWfAZHLAW_Mk64G9RoP+{N)+-_ev9jzi-Kk#@@O@4Y`^>w|GAv zc@|Ku)0-%-s?6rgYmPq}NSQfS9i+}>SY4MzQ1aM(acs75DIFBFpI0q*P}j<1*7d9C z!82<#r9UsHt$Zs&$bVj>Hn#hB5agYui>TN{As@|rP1Ew{I?qvTKToIwow@yIRmt6$djxPcj_^@nNvka>6~It;H# zqPBm+XVY>}JJtB|#2L$wfWWmOqfe4@XuqBr2Ee;D%td#;gK)Cq7_+z8k}a_l-;(fl zP`z~pi{Sd+uS4r4oc9aSi9Hu?kv=%`z2Uh#Q*(^-z!CgZW9K}?!+8M6NT$ETVoL~p zE-=s5BH@yNYQ98Jts&OGxF;fak076PADtV&Pjy^Q7<2qGpmp0z z4)R|md8bN2Cy4;67L+T^60=W2FF7wTl5ToXpLi?@YE@PF39qorRu-WDHNb7`bt)R- zFeZ?aQbSrL81(O_+u>Qg4K$u@4QQR3wcwyIoo#-A5;CO)vV5aj|H*Y3J^$6p0b;

Wsqe6ap{ba@=~=dp-Rh-c3U98Yp@ebKV~2IZ>k_W0WJ2`xX0=PqA8f2`(klRSMPX?FMe zH6%j;MrxkXSMc3(5tK>$%=^4HpX)qbH#V-|{PduZsKn)9O@37?azQo`2pwY}Y1zWc zxEV)+oJtnhK;Tb|^-Yi#SHXG1@T2xc-4*uCA;CY1xm|+HLY_7$7m>t8@y)(mofUcd zYl$NJ+uz}(q*omugx1aT1sf`;{+1^lID;TjOG12#%q_)rK>Dkp9m z*2K#vg`h0@jb6L8Qsph(@qBAQWFg;%!sSvegY-ZdLBfC+lMI+^QfmZxX?M?*)sUkv zFne$swatlXxVASTYf@)>C{q`;B!mOdGn8`KJZ^0M%W&Ku%f_URE0LxjyyNq#=o`m2 z(+lS9%xtv+YtCKHTIoAm#Pe3f(_-e)*pe%|ZZ~@A7KLPe@K^Q4Hvlvj7&(ROU_z0eD7T<0i+TJg1QQ*Ddj+CaT3bs{}^@ zqs5FuS`5zRBKXmS22rZrc^#c34-)2ylCqpY`jkUPGNuOoN_EBGKm9%^ZP!~R=+^O~ z@u@aClg6=u4yZ9YYf9M3Eq=CXbjBxotAQEn5kVAw<4Q8>)6zmBtgmY~?aUt$g1lHM zo=g4gy5x`%CI}O1)*Pxh->Z(wCE&4Pz4tY z*1ko4?rI8mg!`$NKJ85+UZrEsu|OVAf+|rKyrWT2`Sfh|Tf2Z9d?7_8l8}b1vOca( zkzy0M$D8Se*)~tLNoezUL<;Cvl;k_$MNOif!DE#As<6r|n0=Z@jklv@Flu@W024e5 zXix*6bH;cq+jI##pBuXoap>7sI+c^`=Km3mMI%!stda8HmTzOf-KT^WP=+D~ODG1B z%%Wy2Z0``3I0OD)L`{KLyJn_RHzo3PLpQ&ne5ott_$MYtY+<6-i>30+qP^Oldf+qw z`yI&(ocSMtZ<6>QWC{WX$-`1LgU5}6Gi9%HD{cy|;fl1RFnM@+GT~$giymi!OzhMwHxl1%Tql1$%nw{{MpkSy+6B@IRZXsNX}+ix9MOzPo!dkd{U zR^m?#6M;T<>twTZ%tw=dPf7Ae)P}5YL+xgW>^et$4c8!YvfZG3pyM@>#|!xRPcn2d zXPLgr-nek}I6x<5B3=J z_>H$YdQmqWNe!~M#UNl7a%nf zJpcJz5nLDePi5vhZhx?;DfQc(B*ugtU*%uYH{L}TOtm|Vpm#hk*!0DtbCPHw!*;OV z+<{I;ibSOq#) z760h4OPFcD$BAowS<-@*gR+<|6V={Xm*~<7FlW1bu)YCH#5K*pXh4-?+pflSa?!;RA}4z}%aNR1|bX0|Aa zmF?#hHOt+^pleNA2(unqh)62KtQ6f}MK21>0eWmw<6q0vyWj&V`nn{I0{G{pD-c=swIEX~ScPVR2!l&)}R+&i0AY8$ObM^hjfFgORK zVyGvagsQI7nQzn3A`Ew;gP2~)AmzT9g43R(AX5023jVj*!?Ewfga~c^Nt{RxlU{z$!9q=TZABJ@H&N zKK)#>7$YrYB&A`}qevk$+m2I<%~EoN0!Fj z=KIj(FPo~tLB+({Q~;*ltY;VXnX>_>wSzPYd6=hWUnQh5xc>!juktX)hit3x)?W;Z zoQIsb<#DR&LrKi?Diss>s>`W6`ID|89idWkh>kB}>Z2nwT?$9t-^6To{XVTkZ$QV* znv7mLssB0#J@bCX?t8Re5)wMjH2MJ4HDo_fN=9Q{x=U{kGMs4Nei*^0m9EyBKzW0( zAV8=V-=+#oI`(pgfHBa2FOY}Tt-4J}sbmVgX1-zj7kpN%Hvzr2AKa|WuP6D6x|W9r z??1h$6OD1<*vX(jj|&b><&j8vuQaR2vgQZ96xhmtT^IQJ1;RTxiKg1Mtg3?26f!w= z8>CcEW}h+0Pv*Y%w<`JU487wltx}z}R*OZ)uN00o(W5mr-Tdscx==tC<+k;}FH5dWj!(^HYoR+q$jlRLI|& zmD~PxmwN9fxpRt?ghB0$F(H^UUyU{&+KT3?M4zr!Ky8MLmaPR*Yi6wW22tWLdQJ?DvY^3gB9M zJUGU^+eN$*6Pp+SiDa4YrG+EQt)Au-+jNbxC@^}>HguP4sew`qDfKkoH6tH#-H$of ziOH4|bp-p8(O(cwkJissCX&y@|0L8@Ph?#ATF-4P0{<<7>)|9qCnk%x8-$rm?;PRT zrm^SpP2py}XrJtoi($4Y#h9kT?+AFD!>CkJt9eCx2vj*jUZmmBKzOX5UDtWWE$kWx zJo~hAh4)o42T4S`F((O-yEF4_DY0CTcD?7aZ7^>6tAyx@aj2#Hg%=#9xlVX=LJMnW zOh59WF(S5pr6w6zR5}{&Q+4^_c}xQzr25ioXW3HcG}<>76m{r-z@I#qJd1r7`Ep=- z=d}djb#y&pv&|+C?||h99LCCIc)Fxg6daoo%D|&<=S2x3GCF(PFOe;VWSAPeu}zk& zHxiNR4JQ|glzEajN(Vcn&L{5i2bIBfN|W2munR?<%?r^7i3>)!lxfjAG5g^~(*D9H zR#LHqsR?k}W=u_CDMl?#rNaE4Y$mk5AIyCOCl|Dm{+jwvGIkIy;F5GGqJ>mqA^k!w zKUp=hs>3-xjv?cz<(0tt@l=Jes-oRoM6!i#Q)ZjoOzo{kXR#Q4aO5f)q+dHT9Dk3R z9{yNiItt^lNqsrE!3%5GAAAqLmx$?VRI!I4p0GY2aj`C((0yYKIa~=#uXw~x2>hwV zo&_{oxzZ6#o<-T_+{k2RFE`6{QR=~9j-Xr0i2~3Fazt5@#pG}x=ISrA%RF`zV#)~4iW-n6L7%KWX$rX2y)3}Ol zzm#m#R+bLCk_Pu5@?D{S<;F|gZS{E8>{}8g_vtEUp<~hOGcg~jgfyp6 zi8g0Es>_OCyZQXR`hH*z)km&ZHW8@X1JO}TZ<3e(3~d=SZx(pG22^~~5vwanruNG8 zYxWg}x*_Va0Vgi!ckZB{Pl%F1Vy{DTZ)D;SW5r+U@p;zkm45YR2XeEuWK|`C4r+cA zQ?shd`-?H*eI3l*hXQ;37uFjQB9ZVyE4SOr$nI=rPypTwu-&dh6mlT#y7dCp*nsui zUOxW%RjXhYi~Q@)(!Hs;X{LxEQmE*EZvx!k#8ed=8_vLne04$E`7k&1ozKla?%!AH zX*uU=tj4^I%0ogj(w$k)mD`z|_X}Cz`@1vG5?+(OS+GnI2Nzt)I=CcfOo`6be9s?Q zI7}hM_~!hpAdHlPXe!b~e55$PW^d&2c-rX;0~RCb(Y${p#7|5B6UHhCLzHIzyLl*m zw4mftzJ8__`$Y8wUIy3gFVmpgQ5u8hZ#Y`BEGS@#SAGGz&yNmS)K}oiyD<<Wm}mk97wJ4d>a7H$8U@BNqo8S;1k6|v9*qX=B>%Y<_MvhTNpa*j^=I*kpjwvh zd)Hu;Ojm@g3Bd8*J}fqV45?f%XyZmup+SKZ`(ObXl&sF{VgB*8Sn`Y+(9F~im&}M1 zovx)@rWGqL=2>)8D?vRm!l{&ONX#j_^Dn!fG&ZroxBo7JQ#*Btvso0WVE^`cCVB;wi%%?u^ zrk69q+Ul?;WE|zCc~s}n0Jq>9dZ%H)W*Qic4Goru=_6b|k{z_aJ);dkv31^WF=87R+Dd{HcgF^?0_)jE>>TgD6c+R7GCm zMvv5Emb^brWeaz{*hrqy`t|U6>IQB~34X8mP#$N-jS@Lp42wYPP2k9{e(FoZ;(hpD z85G=U-R%BmQ#k)SCMCT{DGcT3@o|jhXt8QN5$Qhe&TlgiE5-{EBIl7*^~PP?SyTZa zX^Y?C7jf$$O0?PV5m=KL)U2uF_(pjSKAI`94B91wib8xqPpdgg&}a(?A>o>guQqbO z)^X=F(f~=wkDJ?=^}@aKaD7e?L823!qong&v2;G}CWIME*43)*Z+snW_;Xg`WD)e8MK_<^cO~OyN1PW`*U5lA2YQp&!F{Ky zI5jB&jKvy9^`dgssEZy_7Z#jnGi))!i*9WET6ikt_ zk^Z{F>%knlJd@bH9C_%n4b;Xk{2F3jneSG8vD3#;PU@J9@cIx)-i?fQMjl0pMZB{v zG{Ft~EIXoRH%2qNG@V>wAWr$T?#rYBnB?aryW#h{v%BV#JpKFK-oN!v;dj1+`cLV) z=o4e(I$TDQ{ug!wV=)3&BX`}5678W@xfpQP{$=bQvRz?kW{PKG|xki!eKAw~r zzxjWP>#8+Kz_U8c4y`k7zy7_0r{=vs5n}lF3HbXt$)#yCElPSqOD}*Y7S^#eZ{%+G zOYX*SCF&~J8Geey4cC=v_{g{yqr?}@KSXgV9w{qSAxOMe1iv@~{kpM7`mVfKrO85B z;GjFLiTu`ctlL{V!3X@?lWudrzULD>Ng+jtLEXe*O#E6OLhwU1nK&ucr`{Wx#-z2D z7bjv3yd$BeGP54(LBYC5e{*rZghue~l0GY^X7Xi}!wT`*1%}_^(BcLKX$zAc=)m)k z?Q;`_TI-!xFIPYC4o%>O#bivKY|4+Z;M>2#7zsKk=tNLRIA!`%?>OA1J0N8gFyM zt$-*Nrb8G6_x@?jwOLU|SBp}!#WkE~kOp>2w$hlNS-QSwmswgZ8eYFL7j>o-u(r$**~zhC8XM`%1kN z2t)rdk(M@mG>2PB?UKz-e`JGX&)s9jpDK_~3S~4~v+ztmBQTwy1$XJ~rmt|0IgRSL zKL7|`V^saWJeQ2;en*RapGu%PlfW8?I7tRK7H~RRVvUu|K+P_t^kc=NLu}Stv%SxL zHQHMj=@%)lZ_u1hhrrCo*OTH-+Uc;?H)vdAx04Q(7Et|4vKRC6H2@s=LO$~BMt|Q4 z(RJQ~-t+-^yJ1pRgToE@=Sb*{!5@*PFdA+3>CF>R4`yg-w(5Y^!<)+AOrts6dAtvrh|@B60|bAi z5S+n3r~1&5vzZQEgCD!*{c@k=W!o|OSG z?v%HhT=4J-+5X({oiuVxvU9SR4>C(A0J9&Sm(p8c{B(IqctjLG?5J>#{*?&=T)lkb zc=a(w<8MYE-r8YUQxhEGl##j?^yArA_!s~7w@ZihPi`+>7d3cvtE>hxmAj~>F;PwpKcjZmJ!N49D42$>o#_664G(z zDWK|AM94jSshn#rLv0Z-5-{t+=bwl&iPE-%Bi5&Xa&gux(TRx84H*Iw!@GFnNCHde zBZ(D97bepNXh@nUF$5Yji=&5;ip_uReMg!!M+q2~Lg?eGQ%!n0Emx+FhzgAeKoWuV zajh%#cD2cX5b9g+tY6+UdpmrAdp475=N%8Ss+=n^gpWimc39|mX)LvJlVc+|ol6sM zZLE6W(f#PV&ifIWQ6MT)@6n*03-HLA18PGMQ1b)ok+S>gA5j{}_#37&^XL?8Zqumh zVqGQw_JsFz9W0!j&Z+wduRm8eTl>X^GQ)EyS2eFHeU$n0N~x<2xz!#5e8`x=(&0$y zFHJRL@ys}e=IlYOyi0?Cy!P23hc-QK6Ta3vc!m!`pCQwt&+aS3^ea2Q*BY4VVNQ<% z=02!=ELpG(v&6_Is{8hm&(<{QTmO%82zz`yz#%Ya}yNeCp1kitb0Je|SH9 ziE)xtlIQpNT3w@4p`P3+SY$r0{WJLC677Du3ZW^2IRbR6Sfb<@l>nbXj}8oWI2sfl zZ)yzpAO>uM%wKnrlA)6|%wNbzR|s>RyAXE`nvjoHEJ_6M?&|3-bhm*JOtGpEIKMgF$<iWx7imFthmD|y-ReCbMp6?XYrLCELV5YH2A z>@vSq;Iss+-?EbR zIPmm~6S`9q;Pm9jKC^LE&AOX?azO@3a4a|74&*mwx`a*gXFgdq86mC)d*6JvyM1uF zT24X$i;)O%Z-c*%jH4x+`Pd~IzH+oRPLM9Gsi~vD=U#_W=@*84?e6f68yQ;!o*M>) z@dP8E@s-6hh^3o7&6h!^{_q?WMKBnWL1__?IbWSBMXy!M*P+_wqPNn*>gi>&Gld~J@PCBQV&Js21ckDt-Cmh zY*=!V*1dMK)_c^zS`f#Oss(SVyGv+FKXn``z6ar8lksSp?bTecnB2H8pN!QM{GMR! zNv{19gB;}EmFm9c;TNu%pR|)$jSe%5IeK1IRQq|-Xh-w8?-4uUPP2|6DgNxv^wO8P zr5~#pszxMG@JXFuDcP$E)|NJ*5nZ}qlbAl~V|inuRxFf%Trooah~qd zJLThPb$2@jcc#8I0%H}ZJM{t|&h&e*ppt}L;uUtV`QVFb@?L%|jZG%*xM%7nxd;<#u4iqOyHh+3yGu6XixLEi zns~HX6Xap}Gu!3oo;4N~1!T+rXKmCSxmXj8rd2{rUdEGvU$+S#LU&dU2Q(|WnA-31 zt8Lmdd0$?CqS7xYcj2oCY3*B9j?Q`#j+KgAoG5fA*0;->c(Zu&ZUPQ+H}ml zEnMOiiu45G+K#;`Ps|NY#Fh;DVSs z=(EGtf2$9=68GdSr%p{IFG1PW#d6GxGkRZQ0?sP?#pE%yOJ+@{R?Y0=$Y=uC>aT;{ zQn5gd+IZKjpBZuX?dgBDs*7lrJY!ic#SpoHqEh=x{`>!T|9aQyHT?grL2x%9`SERv z-}{^CtH-1w93K^kou@0mwZKkA-KrS2vN0T6_e#FHfv2qZsCYk(`cc6%x<2;u^2+`m zcE&JYwE>G}t;#Vv9XdS;sF1=-{Ja-~_*_h#0XLubqPm9$-{ei)WFPU{4D^RBUa)lg zfu7dOc|=?@VW0QTCmpgm z{8s5lh#Dq@0@hW#EZrGZqU81rc{C?eI3^Q6#JtiQO^pRFZXEmFjur~q8i^?_o{z@? zbS{VXnM&i_4n|PFR8_87&$YgE zbb;(Qo2S+>U3fHq@CMr^Y$@Asp=Z*y{11Kq6KEX6+gyo2f_IKG<@;zN5|oI6X-Tao zu#Gk$#ab$1wh>)=E0Ll5_RFTGCeDyHFu6(@zND%RFMDx1)truNTT8>KjjstOgVl9= zQFhD2J~%_`cTy|aG&1?CfNwTd6@PXW5jzPHvB{1UUzo(GJ<@E8AxW=h2#vFv4_Hli3oq;{PLBZsh488W#@?yAuG9xF5 zlu5Oshv4u_Q-W4F#s^O3ea#~>oL}C2<(VvA9_sP(-2#ne4(q#h%wl^yt&Qsb22Cc5 z7iiG{72uYhq<*H38E8DysSzeH^{&Rg?D$g{n23~g6fg#N!Z0h!y^yhEHAKZ zKGghs3E;PvIbPtFd~HI#T}XvPS|1%q58k|{i8))CWh$^HbF%C7^s((;pJq^0D@_V+ z_)w6Wl|`43yykzFB22hjXdJpNxP_VvO1V=3SZ6J52O|XyEmmy?irjtci!xCwRcu}E zTl@NAf_dDVi1j19$-*ALlyZ$IlSY~gckIi;$3o6gDYyK2ehavPg+qnf*j_>ND6$f( zvdEt+<0K#QqFX>@J)EmraJJh&4eVP`bV0~5;1kxZwl;J{(~Dd(6)}3Q04`*e=8Jjl&_?7{?}0Dub+tIJPpex+4kv{#KSUr zz-?;r0E13-B@?er$^~MW14fgwB|h!;GfBpvKujEQ;kA9)IY8z5Lxh0!!D%va%DQN* zkq`k{gG%+hKg@>~CW0Dgh)rT zADQ%6%av0lBwoJ2x&)S-*Z13JMJ8EbEB$gwWrXj>qU9h1nVq^?a-O9W zv9ZA=+wJ)rg{;>y6LrdK`j{Uz<8w#kndpvYJ5fuhonwotfOxl# zCafrsWdbIlBb<+a*sNnyNey>0^Ufg*PSQqKI{PA-f4XM+FrvJsnXJAkq?NY5a}jc_ zudz&?KZXA38rg>FPA5i(k*^pX6m9nY5Wp$T@|A#+Ql*TPs;N_*29UmF8JMO$nyf;? z$4a>EnBF8*g#y>crtab<72>C+hzR`-UICV|tGIO}i}z9cBijl{t`nA^GV)O0Rv^GE=y_*`qE)s|jyJLViM5#!aR z$b`=6Fsm(IhXq)-IF!XWjU@zIJ$97DPn?VII`|G)QDc~na@RPR z(tYM>IYJz%4XhlGWjmrn9uzOo=;-h+)AUa;B(iM+haaBHI2$45Bz|npzO=awntq%o z_ePL7MRY0}>v_`jh-|WCjqwK^@Kq1ATzs7pC;MIDRW4CgQn?w?v~z1`a@J$6N}YEm zXQFHv{V{gvO7l|~{BpsZr!pqf^TD&=X8p@v+Rp3H^FG|%w))s^A+`;r9YUeCb2Slm zgiLHZLhkm{5sCBXiXd*MRpjoZX-d!>lhaf`Nz2(VQNKIY>os4M45hn73rhL#4@KYd zO-Oet@8u3aUofq{&`oIfRYsihdYcq`$0 z1`7WFQfMBss}`Fo%&F*`!hkn-SR@UH{F40uTgXG|NBjc2DpbLUe0(RAo85&)c)aHm z*OQ~C=n9>Ng~ttLTs>Av9Z?rM4j&9!NQ98U45v~*9RIgPrn2@lhTaWQIf2AF zI$BHpTbN?$@n(VFn-HT|0!(!zO{3v;{H-S?0SeN56ao?7t$HKxt4(~!Oc}B6I|?rX z1$0n5#@kIyb>a^*F$_K%da!8}#m`LtAF95xp{=%SHWYVjaVtezio3hJ6fN$q1&RbK zQrsPiL($?C3GVLh?gW=4hx>ls=bZQafPBc_*R}SnS+i!A8DE+BOmYHi_s>NQG13bC zg$FDRU!XJi#hm0UhA`ylZWUNJR_;!z1;>SOuE8u)=7o!OE%Q^9dWmnApr=XO%f-hW zD=Rnl2+WBnN?UFqh0BqffomKV&zGh=UsO)zmu-_$nh+;;Q3q)M}CDSDoxm3d^uu2x+9tsj1pUW z!$$=l6svI&o82mUe_PcFyc5Kk)EeFf2sTA`FC}KM4zLR9I7um-jBY2wrdCP+yJl4 z8uN*Dp|bML2_-_8B8@FdOvgt<<$zEfRu(s_$G)`L^=w#x5mHVZLlItZdv|e}A)Ovv z>+4)Rpg8oXuaT(Hudg0poUj zu*P1wT_V*EFH-=@&y3!}iRT>FK!L3kqN5q^w+0v~%d@}PM{Skc96$yboBT)zh9m=m zzSC{CSuf6JZ3Z)poY?xKJkKR%bSxs8&NDoh`O%0ojr9F`ws5JTxe==Nj?3)QL2hyDw98`s87_^#U=2CCuP7#F zkR?K}Icus$;EUpZ4<~(z>usZtyjV&n+psvBWXhcs0Y`zYo^OiE{9{|h|EJL~-$wgo zW(so2_8Je8USXo-c_s_{TN1|-2nK%h#-sVCj9(7f_u1js!7g7+cKP(hlep^3Bqh~6 zoFpUDTEnCzuf);1I_#F&eA*xHo(Gpj8tnLrJo|Tc3Srqgd4i*)sr|^re6D?AANHOx zNt1wC9y(3VM!zv$PR(?i+>pn+ViLz2P8NS{w-WHd&?TTh20CKm?26Qj*s7lQz}O-v zgURiI347jK3Yt}vVpRfH!oe1?%MEDNqG1Wwa2p~&x?nxtuRtWy^X2;C;tIsO0Wy64 zbbd!~fh1>NPDu-$-Jt#3rLmvWc6p{d!^Sk{ z+iDnJ`Infl2wz%^UNh;w`Y>-1NL3k|~;3mo)i9tM*!2X|u|M4vu2O3U5W@=c>; z)LCHvF{)vDW-l;@hI;9uM>pB>mQ*_asPLWWe ztQx*veT0TWFO#@yH1Uuv@NnEa<(sh!$Hwg>bO@K+GFvx5nF+$&PUh- zPG>PXxt_9b4 z+qYiTd@$-|hfrp)Zql)>C^}DZOeQEZes{gUB_@?eDx$N;<&)$%>~n%Vp3iw{)lB{#&}2}gBhFmj8^d7=&6S*Lgxet@lm&V3 ziE;P44Modcpn*yPkAEiB0%3_kt8hd@7!dXr33eMDnk(_o?RigfkgZGhA0Th|EJ6C~ zQ|P12pIcB`KVG7sPQGn-lywBZ9^?Zg0whGT>}TNVLd9`HT(A`uYgzN~eiGToc+q_< zh&zw`R5lv=qB*_Ffysr!kr!{BdZjqw<;Xf|9Z9T{OuEb|bUbzcaM1vQzX$R4SPnk4 zY>bfaT+C4X53JwV_JKX*a`+@GTQS{4>U&gAMvyBY*d~u41Zeuw(m88^Op%~Jt1-gF z(*q<*zITnCNXVJ(;H2ewYcqOyWrDdOTZVEcQT^TxO;}u%Z)mpasj<2I3VY2~K4y1< z^2zPd%ApZ)=wn?Jqkq-~bE^!01osI(IS1J~{I=S@7z9%r`>3CBzK{#HGyC&81@5>{ zwCChA?keA6fq?Pad&YcC2Gd=E!a72TvQ0*?dYm5*5=y5e{LGZ!vqN*!5d$VK=@1VD zn3v5tT|gOx*v^w`W_H+)u%M@(f)`e>G1VHc%CRx9Y99(*iZ`N9 zr1%B=b~z2N;ZTsZ-toZ&nBot15CE>Zd?Zus2Xr&_CD)}WwpMAiB$cH}{u2MX9ioe` zl3gh%mJKuaje9fFQ0}?Ir0W}UeZ!t5cy#l=ABaMyq99R7Pla7a6F_G!7jLB_gW}x9 z9q&2M_UfY(#Gj=qS4g|QV$q48qyIoZ{6N0F%`k-{<5ofc0VseLi=6hulIiemQ%jT?RS|0d-eIqat9S9P z3Sd1MMd)x6ahUEV5F?TuTia$Z3k)>oOkPs^dw5$86U&Wx{e~~M`1*)4;rXc%AG{CZcHL(L4fNlH2zMoZxuNV!v(KaFlblLI> zP<^z%`e}9>&+q0>rH@Ni%+o(gdCpeyAs{Rj@I`qE040JeX8>}(I@E@8D)UNQCL}Pu zTq$;ujY?ryaRTlEsOdb_RNdIPsDcS8G8=FTnB{^{J0EzCwmZT@qf?-}|4oZ^=f(d3 z%+KrhvEK%%U#3aIx?|hTt6eDNaYny9+5JymQ|K)JtT02~ozEPu;`9 z69;^(wuZ+%n57X97=IefU9onFRWhYy$yOhrvVU@PH_iKPDPHzy#RWh`FzqJavsQH} z`yJy0lYO}UNSSS+qZ(LQf#6FS0x1+xl|fma>zH;*VXY?a^w5+wG_RAX7c+<0x|}*B7N0K z#N!(FAdcwp%^XUSfPPMf`RW=3$?JSNv>d*ro(y@OlC3i1e0Z>nS}#0NK9_I+26I9) zVCpt`C^8^_T7uifKTY++!1%A`%vGPolu1BLtIe_7^&lSOko+0F61gG9s14g?a%@ zaM@Qr?74Kl-i5%R13;Jyy5p7k2f}Xk%ifqFvaoF2&#A8KF@5`)8tl$UW?3)IRN)Mm z0z$YM5oI!}JWO0{aC8qPb{cc9iD-YJz3DBp46}W22rvK`kXb5(@KU|tLZnUAon0Iq zNirFQxMk8&3D7mo;2_iEXeNp~!s(6T=eMpi!l0-naU`-;NUcH$aEq*~E7u23w1-6E zBvw}ceLgKJ9u7r))0Q7WhBwtT)H+cPBK{a zhx0Ct{TGLygBl}Bi`+>paLXaIq5@OteMQ0NhG`(WCiTZ7_rjJp_ORj<%giIMBOs_k zKe}&IIcrJpi!cSRq$3feOmVqZsz~-xMoLN{m%m{zKIcH;M*^)0H@^m5rJ?SqI&;od z^{+jnG(|Gdw+8zFgL3t%V5$W*v6ckpz2&BF4&D!fgAJ0XOHCpYbd`F#X;S>w>&QN^ zx12CY*yF1}!!3!W!tT3cMIPv$F7!{kt6?VGNgjT512q;97nivQ7rF0@0yWsuSY=4UOFB6g32l9 zUs350_JBunki9l;KX-D)^Qd$IX*lsu1J2-A)TK*t{)|vi{%pPc44$iXLeqp2Hnd7I zAF<+Gm;vHW4n{_RAaZLU`Ek};aoF6EldQC*bl|jzDg?U(vf(|gJEf#_^&eBlmM; zcJD#5#6bC8db#vMc5Ag7$&i!FoO^{5>5^gMYR>_b6z|m-V0<@l#c^#%MY0VTg!m~z z;F;nho+$-xEIb9WAeI*ygEba_v2z!FW7(!Z2g$?``l`FIMJ~TI%)Efe6|tOr>pqo(BIyr3TD*GC<{F7 z0g^$CB)B6Kw$$vx^M4T}sHf%-n=Mv0^s;31an6k<=RfeureZzkN&s=oxb=4HbB)j4 zq6XjXAO;XgxJc7=*24gs=q{E{qV3DtY@HSp)qd0a`e|_FVZKm$cBL+UjrE+{7rYDe zNi>(=F?ilSIakI}>8wj~AoG{6I{{u8?S#v|4RC;3XkC+N9j-(9XRye-J-g6mBW4b7 zoKc?#b3hF9oi7%CVf7g5cMMxP@tFdqfpBH&J@QE9^84`B^MKUR%5%bErUHWNq54{* zFOT)US~8Ej-_mBI1+`VrHURs}Mll7@Cj79L4pz8mvMTR}W3YH`N3$xD zk4lNeI2#tJ7KNn`TF!j9j-b!+LNQIZ0xE7Pf{$2;m2tRTBt2M_99~o|9FA zucZ^KUJwHD7-a*l5>dCu_vj_QTJ<;_o_KkXV~aHVV-7KU1kiIL&Jj~t1~Xb9=L9(M z;IsF5ksH+Jr(PxL?F|mH0uOHZD%z!Y6`KgF@y5L@#kdLt^&m0=$F~kopHdwr8$qk} za!tREC`+NI^smB$YFjqZoWJgpD7?+|ezAoYDv4vQ+~ORr<;)x{u*o)QbZ@J{F!c`| zK{EqEkc&S5Y5*A%Vhms~Ed8aAlwfEydB)7Z@6X15rwt~D#WVgaJG;hgnsuqJH**O5E1L#% ziZSQS(9&Ic-aCVaT3xX%b#qY0_FnmlRbe+vPFlRNa)m;40&sSB-mD`$yuIw;^1jUK&s-CaV0r1V;xSSW&moJ-4s2I#lsC!Ty3q+6b`-vMn~@*6 z-0%h8El)C)MWk|w?Ly8&b%jnM44P$k(JL%wmnL%4Fjvx!<#Gl-Q&rPKu=q-}S<2fr0=4?D#mFcH(_bOu7xsQSK z??JC}^^cu9#V~L1{W53)7U}*H`O}WJ!!}jUy;7l%Ft=hyP7OljmLGuhXL9J+qajzwMuT1^^g8<^T;HjQ5Y1q znuc3wdQf5Jd2$&%`$z=T2FO*U5usmWYfv$;{tRRpVasm1NxHnQ6KzBom3jd5SEj3Y z(kfo%{@Oo5PVX5FQVI2F))kZNw~1SoJwJi6v^-|6yn&>gUp@WT3!qxw*TR~3`_tDO zZOW(fOSPsE4q#iMDDy(YfcQTL`{4HJQa=r?^j06WFJZ2XG-$eKxT%|8xix$Y_D^Y-zzM3foMx>2QQ^qIcep6h1J? zp=tJlhYjK3!aVR7&JL$33D`)z3)>^w?3~No-7QXjLVhw-91pD}eHHdLQ+jyu8eb=0 zk<`=T+{y;rAp*oR5q{{klhWDzT1#Dlz_}Iuy$BehilC*Zl6DM;GkI)2=RzQTp}QQI z%iH{=^kz@y(LBP8`7QbYT(omlK01~8Lv*5)|KU+$?PN%WE=d4YJ^gDk%fYY8hqG^f zqt`v{_*U6uZTk`Lh$*htbQgCzmHw8fesZ~Y!rv?Zab2j8jU;cibN&^)kf8;LQ@7|J zP6lt^Y*>7imd;DrQsrPtxw=qA_vF2zBdAi;efw#l%HzatD9S*4xN4R&9V;=P1$Nb1 z@#C>f))}?$$}lqIr;o)Y@1_e?K5rab&NYi;YtK?yn((AOx$xd|2aKSg>?k|(~$;4DsTu8E-V7}5q z4sTk@pOd&4gi`_WrLWQ^lpsnl5{IrclZN;n{Cbj%f zhYcnYfyp4El$GgKtNZOeUhzYvNMIk%Ao%Q)Z@Yq#aR}fNh4B7^CjNPwGmPO@b4AVuPfjH1eVlAy%jo*(ye zND@E{ImqwTjT??#Jrc)1N&%Q*d@m7>5R?WQ>hW{3q2|p$%zXNzXGi8R>&)*crP`I)*c=Iw^_h|K@jRU`el{zp(U$i`BSh}Lu^H_!|7E2-_VM$JuZ zF{G)|FNh#+XZ5dxoyFIueE(1A(C3&YKTny;QZw~S48kzcHH2bBSPo! z%#7q1nPQ=oC!^hH5n|o_0R@EJ^vE} zneqhAos-R%-6mT=8hUT?GY4qS()%AWJL&a6|Mwur#A9E% zy!Uf-A-S*Hv%K?dBKOtsHt_|*0{CqKNB(oABmF6!7>yleb#QtEtbRrjId~d7>}hys zh!$O}M#b+EPZ_!R9slZGDnBabb*i0Agf2BF@pCD9xeHo7BgA=GH1jQB@)WC;%Bk&- zfUJKc)H2E`Nw^ivGZhwfrNmQ0!uU5n?8$@CCF7lbz2ovfbDFL)Kqp>@INBIB!B^ZT zC6B-aL_3VGH3Ixc*rN-zN6-tEUZFpMC7}k#UH4Ou;^PO44Bw_3Qr%q3aj}{kCmUe) zY_*QjFck~G21o9V4e(EWxkr$2Z03D*lo5~EG0j|(zDhe6&Pf3=B;hhjE9K;smysj;$bWF9^OG3gZxoOV@{{C=ZeEHadD*rz`ZPCQ-0_ zOI=zy7=~nDyvC836eB7=`9nRyYsW@=z48uwZTs!N)@HSiwH+DkJS*aVoa~Q8f;y<& zzKv_I6C%JWUs_UjfIXz>2IM->uG`G7s3iCWTe~W%U@!svUI;(A@yEK#Stf0T{fcZ_ zV6kFq#0cFW3u*BW2cUtcE5u@xR6dqdab>3Xw{WPi{(GgU(1MNDaXweQo|!_qTg&Ns zTQ|88#l**xgW>$!>plHJsOMla>oV{QH&>yWx@NxKlC3&pafSWRdL<;5QYnrl3GR8K z9VAHQ33~zLsEWzpVKmVZZ`qIq$9I2*5m;mnC(|3*^nacFdob`!%Rw*k#M3URY&WZ= zY%{5~Vm3VgHofN1ikR&daVasetX|164smw;ixB&|%z2+Tj*KZkw&okiuhayR2ze4!%cN0Fq5sg?5)9lC}1+7F66&SyQv%v<;ZPDDVUG*g_4Sc#bb_)tF9#1>@ z5Mgv~eUWIi5P8|w3(uE%AGqyh65kg{`HY=#uB6YKiQZ^04YfQwTeXW@$)(tTJdS-0 zqGmR*#`jr3+3duQJJB7}Lok0^B?~vS-EYslq(irx5i32s5=o$=a&i10)(A+0%qxth z1nfR)Ln#)0Jawxg*$jCulNpDGXbo@USSeIV@({zrlC! zF64Zf#^Id})a`?2xcvZv%qgizZSO4 z#qA*hADa2ivD^C$l^vWh0q^~xQIkbm;-Bb@)Eq(CP@rphoA9&JcS^3;LQq*T#vZkt zye|lX9}+1IwAmFkjsdpp8HtpIwynb)UiaCUk`{?MRbd(LY~?2A47Sv_%NV1 zjnlIP+#B`&I8!iIqliTieoqFG$4oVu_Lm$1m@Y92g+LVcCCJ8u32iI%wpp9v@p$9a z5BlJGI!rO97y@hg&d-o`>twH3(YAO%+wy&uDAUXD7^{7p~4a6!Z436h|IJ-u%MZo_`uz(SKV2gj_|@;E)uR%ml4o(!ao z?u%HnD@C=eWpYsPe+LT~(H?+Ys}xrsT7AC_$+jGZK$TOu-&KD76XWjSo?-B9_?_$1 zbv7-ngCE6Xs;H6opL>)RGH>01S+3!QB#sRC1?c@%eZ1>fnjI}>03+(;Y3*K%ZHpZ# z$610Cx4!aS1p3wcZViYbr|yTHB|FO@RF*6qJoKT4c7l`=k;oEV@_s%i4=AI$4Oiz|Usa)@#UNP_W_vTbk zuLhv+x96*z5kS+4E=4iT%H%+jdzkd49O|iAG_Mv7V=fx+>3l_Z@`O@PYb-04YVia5 zyUOcA!sj!F5%MUDj6Cl~BWf9)G3ZnuYMLIqz=-ANXsvpm2i9p0cn#HBF}@SaMUjk1 z!#$yY|4jf7rI-jJl+1Bbvefozs_@lm3~GWib~O;e@>7&rDO4OJj%;B6wY#2y9FssD zUd^cJ3x50rMh|lZn_k4jU?dd+7dBV5SxARSM|m%&m+m${OWb10gd`JhDaHUcPbcbf z{FWeaQg%qRL3i@4rWlpt1YTjlt=~@$wD^Ae>zmhsvZH zQot_(+8Dfpn*hunU~7`;q#P#yF!Dl-y0f$PF|%%sf8goJqSau)>v%+g60}QfqgCu3 zc)2mW0S<4ogyWOpfBU%d#6do@nCmfCWmyzx1bhbg7P9$x@$*$n&U zDb{zKbHXICiUIPr=V9{yi3Nv+are8U2#9kj@9rifP##&|#k-1ZaHi4_@B%d`DLA zZFyimB3|F~PCvyqmxI&S)#w5?SaZj-#kL4L8x#i-0rDvg9@B$@Z8p2QJnHg6a2mS3eHCgnPNwk%v1#|6J>SX*4IE}uX_L|PS z;r0bek@6Uu{m2zjEiP8M7N*ih@&3HqXnI006yjZSyhqlO5AU?pD&w!$Ec)eQafl}8 z`rmTZDUt&(e3}4W3*UN+wQ}lp3Ex@3{VRRnMPC@7w6Sd(qs-+l+ZG_@XwuDRV^WR% z=yLz=Q7uvxLLB(m&2ov{$tHe;zZ+5I{6lh%h(;~>@2^oki7(W(&0TLxy`Zd}kg6(!8h?I6-KMvK|^Cvz{!*)k*THXdEi_v2y z@arYG!qe`Hv~N`yvYqD{)Jxw%J_3;(%0N}H9xhE+F%WhcWG zE@?kF6z=cdn=z@}7ta~sVHQxrtSYB?bAo=7#^-ckz`X0cZ@EgPa#bzo0#;jJwWPe0 zg{(AFZi$_Azwh_<*DFm2{Q87Md^a=(23t%%n7dq6`zMEjtI;XM=x;{$va3|Dvp2>c zKFa;A~; z?^Q$Lmhbhd9I@wFDF^ayX(!pp{)fc^)$RMnws{is+|%)>ps(r6Vg{3 zT_zZ~95>)(Q_{(lA8%A>aaauc1e-&v`ZCl?KGKgI=9v|#AANlCbv(K5y>Ed#!TjL1 zyHT=%?AB0B<}-6Q7z}IGUx!{REx}jr<0a5Ed9Yny=G2Gg9Bdf0jG5(e#Klm1^} z;-%oboE49cB<*pRMpZOr>+vfqmwnuj%5e`gX zOAYz5(vmT4r*{;3lqiX$M6h(ON2*aC1En<`EA&$MJvjI-CCF`Wl^9=9x#HRrW!B5v zY_Sggk=D88p)K9FR(&^xn|d$cy1pBiyken_G4BzlmkiEOlf`CG5F@8~t&To?R!r!q zvE*@=S;trRjl<~qwV$g6I{tM=ihp`@7kzVp`^9hT{9^;w? zCdtqWJkrP)KtKpg34&p%7%HMH2tCtrv!hURMfTfe_TsY{i80Cz@9i5<5R8?mNwYyd@|kf2%c zEH);d;x%jZ&O7}vWwQPTXo#9?T=1b*Z*{`Kjy5>$)tKF&CpLW!0 zbD^(Gq5j(no2fPfDQ@t{tE1eaXtd@Ajc9PjR2IL%QbgxvLS}T=(yoejh2!;>ZaLlz zvcbQs7iDf_^0bKZYz^r6$exz{Sz+|DU-HapmzwPgFuYEv)9d|zPygB6i`9-vBtmX} z@E>n-ouY>re`J-Dt4*gRx<2I7@l-W2&RBZT(nbLG%nq)$PZ3rLHX11c(S3#86Q;WK_JcRBR}W+pOs?NgCb*3t|=51ZUug;f5{G z5;6zYkTl98TrC#txJpRJ$>=5~d@;Qbt#^jkoLAPM7~cA>!>BN_r?2JNOsO7!^&V9S zfULJ)TTDl_GAL!p->@edFN0s7KnkVfgRb6euXesOOc=)YXgZ}`i!R7gdIwvs@SJS? zGze*@2>Qk(qQ^-&S39Q7q@}B5J-ur+yl(;SZI;=qpS2SWMV^Hrn>6EgnxPNX?0Ri!IGOx_{ z=Wn>g`ayu;@m1_3?MBGN8k>>flTAn)-|p9UC=;k$zdqyVVfe;R@|mXpb+0ve1fA5w zY$%`*@Um0&FwUEhUn(+~eVM`?hWmh0PE-iH#SA5Qeb>|cq2=B-YdXTB$T4EM)^y`z z(ZXL}j+VQ6((DIn9)GWB-bb971xSbc2$BE&|6yM<1gfa zwhDXy2h)DaVQLb9W${MVm@M>SX!V0#W7Yi4?rHHFX@g*e(W?*I|IiOInSBAGuLJYC zuSKOt-*5g4b^hCa=(C{%jnNdNO`}JO0Ak%?DqSr>eo`HRTDxj#3vU(f`KfpQMy{@j79!8*dd?F*c94#<^u8;c6}nCx zv^8TJ_A*wt2oO`O`s$t8X#jdu?BIrTr-5UBn-OphT!~!WP~By>QnBOx@Qd}t z^M*;L=~TwBIOK6Xn7hTZI9Et{1QfgL-@T80>o&2G*C5Gk8$uce4Sv<*VNI{0JMU$G`RsZm^TFbE;Ng0~C$zVE%oX$FH>6-B4W&ic#ox%Dy>GZ7&d$+!a`-j@n{i<+ z?xZEh05YM_f^_TH*fG;5^=x$W>`gEd8GPdbX#xsBqw@?{POjMB$SN37> z^qyaTD28(95rAdu`z8nh?aI8^97|JtlI_jmv;0>Em(Ni8KP6DcDa9I@APnJ1u(S1D8(C{wu4MF*_iA?n!3a3}wbZycA$lte{C z3JxmjhtSzO8V;S znXDp;$;)@1CYg~nRUA*T>AFW?R_hQu*a=7DFuI7)nK@QnAur({pLP!TiPv=RT_Eon zY>QDvK5SrRxC8`bI7&Za7S6n7L7ne;3_w`#{|e;-pwCa-fO<=LiKE;em|)rtU*E5= zf7?v}af=kP`M%-<9t-_OW@m{f*lcnlSInN_SZzZW;S9_Tkn;6q*xR*BLFne9V2Lv9 z45kGroKi!O<1Lw7gE_QX!3unU!>#Xc_@FNh9x?V^VSxTei>dw}>>i)`4QO0qMcn31 z;?DmM7P_GIXW3{c7P^{r(TX`pFc(Iw|m=V+LQ0;q6BtFF1Dgis$~}U|-}! zSM?00Qwoaro`Up~ag}8nwC|L1T(kd|b@;dCiIKwc4dL?`ZlbRKb|r^yJ?oN?i{X5_ z`uCx{hs31g7dpD3Z>M1j z-N2gaZvYQwCp0L+jTKXTKb-fkaZQUY78w0){dApgLVzwK4-pa%&&>c+7h&#+QdWt} z#@kI3BY<1QazL^F%a8q@v=z90%#i8DC#J-zuXtFt7vVk*BcyggN2Q;=2h8Ky zgnaQL|IRY(rCJF*?213=-p}yIZvnoxyps+%I!?j38UY?W?aml1hjK@IMk`_&=#2l|wmeNVSV=(7y{%U=zuw^PTCT9{7nCQp?}94re~{S0=?PCQLq+i}))#hQnjZ z5lpV(+e3)8&1%t%HOQd$kV+fzd55jgNAP3*A8S~kfy9H;aFt@*V|cl-CJ~hMj5f&Y z&_gqu#zS+v^xgTqw1Mhx7X~A8K!k(8k1qWL(y!dX6};g%<*R$ALergs{P82 z?*;c;4-*W3^pqt)uT4?vmWa&|f^MS#tq~L`eDCJ{9->7irz+3L^?Oya)&}X_4SFqP zBDmNPHi4`#$Ksf9osrEFYxs~v)1MqN=youMMqut843l`p{B-yN zSF+;+3z)K7uG1%v_DR3so!`;$H>r+>)DF&c^yJS$N5oI1A_!FF zDV0?gwtCT)!9hD4g|{3QbveJ!yh)r{VRgbH`p}*E57_MfaS%w~JZ&grMJV zzFvTgGZ}xjrsY#@PyPSJ0Endsf9OfKe;M0^+foCkXhfHWSdjiXQ_h>D9!ZAfYA6^0 zSl|uNL9=(!?gh>YzRYDsnCY$%jzGvk?7 z3gw&UUbJU;r}LC1dU2n&Eeb(PRy72ju3*1g4d%`HI?#;y@%!(5WD~7F$P3i~Ez@R+ zc)QSHtwJ$cm8w2w-fF- z5Fm_*|4s*?Q0%j)l0&1Hhdhd^Y6Je3lXAxga$9n0Y>|yW3r ztGU}xQp&`12D(VQA_SOq-ZBjnn#|UM#W<2klMv82vJVluP&!I`qgh>422fVNh0*2X zGEHZGi^FuvxEXm9C-WDrkk4kxG;JgBkR!%2f-*yA^h+G-k-^P7>o*?XaeE)HjnYm9 zwh-vMD?cmN7=5Jul9F7OSr3JZK3k^O^D`J(L$>UG79iAn@(O#OOf&}=C3j%IzHCuk zeIVi(F%qbVlrXPIW^V*2F^OV=JMQ={HQ`;=g$4;qH@d zJ{?&t|2#6?w44T-LJ6~lD`a~`uyjd{8AWM;paGB4`$W4*l zMiWbt&)l7wVPnbgl~+->`t|e2rqP{QA1O^11NOx z@08&GQj`ohSgOxw{An+3ekp_A$-ca1*atUo@AQ!a?3qQ|8GUNpo#`%-KRk?a$2;{$ zX!f4IB-Qe+eXA z`7$yQtrN(Bb(M+%oeh#oY+qc^^LLJ71f2@POt(9^eKE)GCQDu4*%13JR)Qn#iwV)}u5y!+epOdGiJfgVrK(SpJS%ALts&s3S8IgBkut#f#W@u9y>H zah;gn0D|d&KcRBQ1;)CPL;UWitot%)YfvPbIU@kRG>Z5To$!9JhpFdk<9*&%c>V#M zZGOQHC?&O%3CiJQ=;fyR_$kfectR54KU!tFx z=tmu*hQw1YcCZtGNs0ur*kh8@3cG&0s0zj3l<0ePi2yoBD(uaTK+B6IlA9%R>5LbC zk*gTol)u_tj1-Y0@pXm50-=7pNTSmBmdcd+-A3FAc0D_=%Z zyXgWFxNjQJ23b5|^yIf5+bMDkk^cDn&}0>c%3_Q1q$=CPt<)*(Whm}QeRRPEkO_GH z73N`+{bicUetDCZtR!gop!0WXN|niWnWDYmpmTSwycwy7KrG3Z|IoF?eAlOT5-!#L{1zX7 z?^c*l&Lgd&FtZNsxG*Qu8cQ+6;OGGnCX@P=8PYx2z`XlJx2u=zD)k|)ZavXX5`FH| zzq1IbZn)fxmykO`Zh^cVb8GQd>}S_wFMq0yOm`$4_l|z*%P?NL3^r2Rb5tVJm04S& zjF1drWE-L|+&{ZrfZdgr5OJOO$4+Y#E|Pg2{F<-aWWa)8Zce_!)504`cFizeFR z67Zj~UiSMrU?|R$7UiNfau>ZNOY))mj8mLUS1fNBk*wM7qfF{Yto0HzU+6$RMH63o z@8Z(4^NR7^W{glbCmZX}o*U(2aZ3u;s4!P>@%Z~>o-zO0BS^#57<6RXC_y0g@bcnF zmD3Ms;O65AeGT+XLU*_=+$t!WT1xOJ#~}LrMowRUz-R?V&xG&81aGm<@46HFpNYbL zs0buaUj!6{vMEQd3${SRxsQy-W>f^uXv|6ehL8B)*fWCM!lAJbM64?VLB4*S@G4>4xT~?vCDf;*6uZEk`?n4+oWc}2gu%} zbY-d4-eckS782xLkrSgzgE3KvwrZl58@~=Dm>qinhG!iYd+UYf!O=O_>}@nuZAWLf zP6s4Xahb77$AGaM0~dx1e((-}<7)@VRJdVvZ;(eQUTGZjSd!uEhh=(yD12j1`1 zwmAM-#_qF1CO5%t2J_1fjqE(e$sS`=1=cDqh2p%F2p*Xntz3oKI2@Dpns}XG$&8Ha z$cI#-o253Y`I1Gs5sjpl{<@J-_LnitVWqZ*(PP@uW_AR-ng`-}$M`P!eCka}oLT^W z=5oHHSveZ_Te&5hxghinBhrf(g^jF0v6+DSlsqs8$Y(zsvFyRpZBn4nQz$G+N{t_z zib>wlr~ZG_NdNPFYUZtZT^?7|X;W2pTGiCktbAX0(I(T+qDRH3&!d3#4S3wCY0*^t zxlqzRiy6J7S~0#_yV_-Mb4{8WIYqPz#2jcq%9Z?o7<xfzYH07y;>!h%^xql`18nh;%~l5a|j+=q(iKB?%>v1W5bh-se1z=e*Cp zuJ7Oa0m)kTJ?EHXj5%{JQXz*B@ewxd zl#2h`9eGqlZxCEh>Wzkb`qgfYcAIX2 zbnr#d+uuLKg^oOae%M?4>!Me8qO8TevCWyQ=$rDNy~4BL%j&_FAl60K>Isz$$!opS zczp_l(9iJgeW5mOwRxQK=|lL{@T;nA&?A={@3MUVDxRI4fAM|xVx4SV-20mwby+!! zI6ppOh>eDZp_S&x2MmeU7cq)j=Ix(8==mXN2mJ*bU;$31tj0r;Ex&4;(V_+){n0HM zo=swZeTY=feMh6z1wlb_ki+FsXjboSIT_;82WMKfIHda5bgF5!AIV!o3#(ie@V7F!@Quw4}gVW?F zVeLfFVREX+Ch!TQ5u3dhxnA%Y&qbh+Gsh7fU%0^(QL=_HXi6#`3Sh{tpzw$#Xc9)L z+9Vb;Qk?*dLxC{q3vdgZEE3q9nxd%;`|jd@EGs7=A)P}~!L%$G;NG%8X)KKb-k9ia z`nK{&A6aD*LPUW;cl%&+uAO~9-UAw;kb2e^wX-2b9?hL(f9SH*W`!(pUzhZj7J^Oz zJw2z3*elai9z99zW{vY20?!7u8g!C&H&RmVCfT!T@?_16ow)(L?S!}q3g4Lf5`=cO z9_g`oB; zSKbJC08box+k~J^YHG)ehV~?GVx|?VeDmgV-%9T%Aq75@)!*UI55(E^yd0=uoCxM+ z6d8z~^rn(N6G)cSr97bk3Oo^V=52kI4FNEN@_&bzFe4#r49B!gP;w|g6W{XVN10TQ z9OHO(gyG_mqfB=~7a{v0mQ6or^eG7TG-YMqr5r&IIAH%;P0dIi%y4UN1L&9vKaF^sqUd9Y%!^=DS9+QmV|7#57FFKEY;q^HRsb z^$;5yl4pU+$Pwj|KI#J@ zHr%_VYEcx_IM7@Jpyl@RlGtNDr9k~H1Ckz`KOpPRQp-5C28%USAf6vr&(Mlve0Jhy zO_UG}=Vped4oJ~gdpzE=(QpSk)W8(_=+6VVw4meCZVY4w4J5|PttwTIo6;bNgEoJ# zb-*4NSt&sU-Bd=WVnOpG0@y7ODQE;GNAt}UsHDHC7>c;sSjP-UDt#hQT+%|KU*=MF zLHm}#1+w3^+zFd9bUASDSuT4OZ9}Z3zghQz+A1Tqi61FY0hnx;My6dut=x8=GUci% zD@kSXL(?c_P%I6Xo1AFk6y$-}Vj|5R%_**+cr5zXq}Jm(kgU(|+URqyfANMSD1v`j z@!nj;yI;?yEuX_2v;2s#()aD7A|x3Pf3CU9}j5APtD=MHSV+kBP@AQWu^t^T3NG`7mQvSJ+K&~iO5?S&wdi9 zLC@FhCV1rZ_Z-T0!=!^lCWnFEsn*L5ZS;kxZpI4DVh$?ev=UHuV{8^>-t{~0`K>M} z-Gt_0AV%nTjS)nhR0)Uz{{iv9!k1*zeugE4WN`*{R2pN&#TqOmS-(7zMn zcW(GI9g`=NR2)~KSp?A}#L_yl)4BPmi8uk`jI$603wKB8L#Acwll?2$Ln|Hh=Bl10 z3XnUIPn#R+_zTic@6om!ht+>Ph6@;3PczXo;1Yv9u$bw}`Q2);&Gq^V^Qs||qhcVD zZHb5@`OHrPXs#;KrA8A9x*iSbnZaP0uaWIJ198a#Ij0bM%LmohrLCd-CrH%=nij}X zKn*h^rEi0k*6BWU8>~O`+1T<4*CRoR!{Mg^hGEysrD3`u$=#+cqPxK>T22aQGN9JW z)e5fAYH9te0g{9W|8)Du65$fG!zr^hgo|tg?3MrwOMshuhJ|4FWS1>Kil95>KHs(1 z#|3R^A4=HE{8T8)HMV2EHQ2K#6rY*@o$i`do5|YC?-G1#KG$Q9Lm|t*p2ZUro@?lm z58{G8%Ar~6#piF}T!UyUQ{)@Q)LQ`)!;TTi&L* zL8zY~-vPPGt19Qoy@x^-fb6q^P1I#+Qx(K>)bXjp6c@`vS{!ArTiLx>DZ#P^Ta3jn z>eC>%f3&|UJs`uBH+O5$rj3)q@LH|rcucYxrH11erN_$v=Y=QRUxLmvPjuNNwTE4; zX(^>B*wkz@yrfpp<{eb*7(qVYj_)IU=gcN!*vZZa$pgq1a<0NVSohl}+Tx1J*z^4X z&c@~T+DToZhSBGDJl8)^@bi#<69^kglBU(D+zG9v3`ardcua*fO|oRnM+33#NU{r) zV^3oPq?)q)byuxp{N`MJ#lD}1Aq^iHRqBC;hy+;|8Cz=7V3-IV-JdrVKJV|`C(uZy zC3{l4m`%&A^?7+`wn^TQYMS$={}+Ms)ti)}RjGY_*GD+#$9z;J$B@L+?Hy!2Cb;gq}WbA}>%IqlC@M{&xs#F_4oY zGM$HJ*s@PR36+V?KVki4tI26z(Ez#MER(*Dj^AHm#7})3?bN+@Th400L2C>^hv>mWsPGkEg{q!x#J&LUD(@f0(`3P zYCIy4lI0FGO(f#-2JAFKAr`a>0YVINXn4JK1F_7zD%WrurU()IfQQUtc_)%-`wBt$ zEYKS&wIU4YKyoLZBOziS4&yVP9^r3-7uv$y^8y+>ZWa{lQ&$ie=sjMqjIbV-qa~`6 zHEuNsUlQ)(RqPzrv1#>7Ey~XZ&*f}VsgQ;&htW^aAQZ9c*Hpsq_I}lynifP1ANAee z)C`xN`Q~K<*#zhv#GN6}{4z-F(mia>pDPBD06Qb>Q^Q1Xk~GfuN&&7BuJVHoKdfyx|K)*+=IMh+y1fS zmS~zIMb^4{S|zxLgpKc}_)Tva35A4b;J;R4>01hyZgDKfR*aVVext7?`~*pZf)3g3 zyV>FdK@f3PQKOfhDi@9rZdK4+XL^UgE0SuY_e1-L2TV(HEGL3NuzWEsy$jDubWAeVp9psM(*CcC*lI80f%#}(`ye&<1=*DLq)-B+^iCeCZ<0@ zm?m;VW%DI98Co@~|Sz##Oe`>_EBhh_Z9{e2~OG?J(O2 zL&<}k>(-%CJB>cJ)+)2ap$OzwiJK2(PA}P4JJHy|vu79Y1*f%@CSyo2MM@>1I0WX# zx_b33@tdAE@1!E^U^aM3ToJBF+5k*C)C8r+ByU*AaHvpbYEbo!sI8We23||;PPU%P zpo>%0?*X26)0&tFid?r4#YOn)Su!PBV}!O!Jv_mFw5g<-x?O7?$BI`B6rbc`gIEG{ z>=*4rQYd>(v~n}bo{1;r`;LA^$*0v_dPGlk!{pF5%@%x%-A6pg@-NBpj=4MMA;WhG zorsMuN%wzC4!W-Sm&Cc7{%z53Vi3Bs*6fb%%k$aK@Css&`o?7pZxNk09ZoR@-qgey$1FnJ{-kXIu$w#632e|XP@rSS;iMH6T z1UF9)J^C*d=2KU?$H&1Xw?_k=V77hD$f^~p;ED%|_Yzxaj@C0=!?Hb0RJon&+I+gxrWfKEaYYT4bop@oeLZS5|G3c*whiNH*n{6m|e&D_Y~4E1c#?>Ba5~ zHGKzC@w}5hwbop#QKz`cv<>u3^L9-4R2qZ?cXNd-8}ZH-&vx|?@(43PdTg_^O<^H> zvap(Vl|u%2FRhXkrS^~wu!iIDo0RV-7h-8PG+Qwn8mf9i_PGL78ZL#UV;_B5Vhl^1 zS5|tonLL9wHjcv9ZrN-B6XE1T9qf0wfGefcsdiVt20LD_zx9S{HiYD?4nAx+gf#YX zH<91Sx44m#CUz0~?uvBA=#L;AThNO-u<=IA5r*K+1JLbB%A&=~mZiB_>Y@zgMzwQ9 z-6Q?3tGcjfG>bwnjmG%|q3Ki2e3IASocVX`-hQXLB`=S;Tl)H&Kc{&J+5d@$wd$59o5~nEXsZj`@N}pcy!i~oDenp?VLpl&}1x?e5 z8s#0}ezmrQ2=Tuf124vu7aJ+xA43Cc(CG@decHlno(LSgiISP>TM1}}`X1Of&dZFt zjqU3|sFhhi!akb4>#Nnx1$IZW<*FSyW^!hYhW zW3_DBrnTTJuuQOo)v1xHXOWjoz<|6MHBsF9*g5-U>pK^`Zt0Pt^dhY1Y?3Km;gsSU zyiQ3Ae$X`Sj^>GY!PlzDv(zzszZQ(s-*H zEZZ;kodRF>xQ{m>G6#z!&g@k$A6jMd5wtH@k{aL?C#+-8^XlX%B}}y&sJW-#(zjgN zy870pYX}t5>ST$+MBnuI(PN42N~~qLqI{b1-)8|7$-y97>y1--m1n2MZr0SWK5zK0 z*S!Aoy+3tlg&qsMkJ8=ZGHT%-waaY2i#UF4p(VV^d#i2&?T$ggntnpdmQ`w2o0Kss zM2zD2_#fGlm?J=yqjat^z&Y{rI%;1OZ9Q*(q_Cs3nDr+{x#5RVMd)5DQMSHqxZ-WAH= zS#Zq@!sW*Ht#zEGY%O5Uw|s7Q<6I6dHeRrSlX$D8nIbfM4sFD;G}>EQB|!6Dt;RvN z?tyCkgz!g6Gjk9JeQJ-0#4N}>oMi4KOB99k}Q ztfgG(`VVX#)BV+rRP2Y=kOZl)h*Xtlw5zmX!%Kc-z{J}*yg-w8Y3$>q{RShei&t0l zdL7)mVc+7Q#9&1)qVl3fwkbs&0e#)w zn2cyWB6XFx1rGKgpl`mf?IQC&@#s}oN)Rw|&8}+Ex`aEl>M-ha!mcD{mqxFvz|W0_ zD|uFdGn>33)#L*szDpUPUl+9S1Xj%B3*PqlJ=1%d3{<+iVxe{+frt5%E>dxf;E0CT zW`H2|6eWaBNK7O*3SSMG>EXww^2jgmcH<@9)7_;Ly|UG;TMf5*Mk`O=L@LfA5#>{e zS@ljJq)%e3PQ&A>dZg(n^+}7RU41c*%75_( z55R)nXAq)&)%)pkIeSX}!vbb%UkHPim9+L6K0(!@{~Kh74|xb#BABT8XaUMD(^cOe z*2|)*ZB%r;+JzB!Q|f97By5U+DcQnPp3L{k6>5 zq~S6-@9SD~)-EHxay_4jSv`Y$S(p*43nO=A!P34ef==nz;@2V0 z(#ms(rf{#K>vvE^?134&TN(FgK@5vXK_lMDL6QLa(Jq2^c8*NsutIes0-C)sUwA2T z0(HGvHNl-;q^+AY)NY&}qNMjDFt1wH*P57YN;vCB>I27-Jf+^i6(LY{ zy}plkdUVvNu~3W7ek)aOYO0eT1$}tGoiAXMeKTzkcZz)P-8P4TdO;XR>=Vim1JA;us@1^}XcYb~q z@Yyw@8wQM$IHK`=!1uPyp2X?s=+2g}ta8ZI@%qej-IOc1-k29PqpOto(OQMEjbXwz z*O$S|nbA*}!9&zT9R6Ik&7)t3^&Hz|D<()eJ}!k@R!#aaLN|czu=+`!RNIe(gT1qR zP0v^#P@G(bs`73OB^!_13Q_qXq((>?vSm9;A4Tjx=r?c~+IdEUlUmW3a?FUNU`U+7^guq^?O8X>)5ZrF|_rFo0zFEk>Mzlv0mocoe^Q4 z;+1{7#U_?kmN-s=ELwyc6zGT4birakb>HWVaEZ?+E0%SzbPL~o&W7v& zpCijXAng;Q(r8cf4s66m0E=7Z2uOCS6lvSfiCmd~BkbJ2m(jMJX%Fn(Ub-mB^iC{v zv^y>jKUirUG_I%tFNcscTR)3QmdOGt)=t&kWKy+FXBufUy4I<}9Kj;J5h|*_ z=@wz0GA}H0;n`s^&*f~jsnbE{y3R+mnA-ISeagVmYfo=rO+fT$4fy@2Xg`0R7)GU% zk5Cd)VU(qA;#`8W1>Y{ZnecPSSiVGwI3u>cwe(1GP+QD)`a7_Hstbu}qmq z1$7c<4C&njUREQ+=f~qh_J^r!kavK0hzt_dHOS7SB1YAm+3DRMT|rgb83rJtTaX~6 zuh`?H2Q8k|gYES2RfO<9s-c{9cSE99uM-Z2^{eH{R6n##_)P&#Rs10kKF((d2M0Y^ ztEAM-%s&l;hc8BX+(#Ojev*%)C!l6%CPD{dDhjOj~<5gPuFK6GVtIZN} zi`ZV$jvte}#mh?xc9`;9m%c;#QL1|Vv?$c%D+iH9Rt27NP5NFL5KSDnFCBC&5p-)X zUki0qUPgp!BTGN{Rhxcc04&36i{~o$3&WvC%j^2%;#K*Kd5O|A2rwDV+k?Jl^t_xM zG9^Tb+lktdr{)fZZow8JOeP~Cd?u0S>G%1+^wj@iX#1*%qmbgEIoj1lve(^__NEBSUO2U0A&bicWDJFt1MS(S9M z3Fz$KtS5=aU)!i&d=|$~PpGcASK-PKp@wf_eVRa->k$&xnwLL5zQjHDwwl433nv_> zhD5*4tijI;6yGL_j7@a4ztNjC)0}#( zgpKLzFr%q7Q{!2_t*m+BL9_3Z6J7v%fb4THT^h(0a8)bcO0(zxq>mw)Z=jfD3kR|< ziGIyDPxJZ`^SawIq$tm_qA0yT2h;Vk{72D2((JU)cA7JbpcnqJswRQb+2a2G z2GL~+4cGNPs+S&azDB@IIvVEy;N-Ps;JC8C*I|tc& z?MTKh5s`0_T~6365EXbPS{eTIk$%@@<=Zf)n3bQ=Hn(8gIa??a@?iJFo&4eu6+=R< z4()k&$YPQ2+=dBVM&Cz4P$%3H+Q#*+ly$Edc??e1ds>Q-_k#@Kxp(rz9GhEyrP)*` z7MV^aL~~(O*+q1I!|VW-A@b!tEVqQ82TEwlf{2zLzu| zCy}2JZzeoHXP@1p$F7!GB*$WXVI(lz@G&szf5Cviog@ad<_WpTVajm+=AX%69{;Un z*Xlm*N15eTb9c*{+OLM8_1c+dt5!ii>9ZmIO+Jo`{!ttgABSKJFi>0Te5t>_@2`LFm89eMbUhJ0#H{bnM zRN_pGGxwO9{TLtDf7u|}494BaK~V~J`Q9M&tMlC#NsHN6Q%`l#o0gld`AHWKt|>87 z&WD(}J(Rr{ec`~2MWsic!$Sl5hLc}}^I3^9rX5Dmqz&)4{SI~*j}Mj94JseH|7K9z z)8W*g%A=j3CPhiE<*G$X@cys6gy#~tpQ$$-1r+W~OE5U`-~)FL$BK{^2Jno>LDP&3 z7q3AXo(am_8WY$%ATtRRrZEq8%eS;-PTns9?bsKQre5Qv*)OOR1b=xi{9&Ga!)omn zoL{2TEPljmS8ALo;r!K)WoIsF=v)_rGs~(i z%Wv)g)fw8Ull)Gpwf6m$7e6YZEZ{1Bwf^fv?}ON$GyPV}qYS}Q{YLY0DGeG-+V~Zy z3=1_LF1>G6q&wBHfohw*axwGAnhIRUBW;s&V%0wLzGBIVywrZVW5Y%UZtNP8P1Ggn ze4pdXlrJFxVDU}{Kk;rk()y0r#RSd06maYtK zy@z(ag+U_~x>BpFX}jbr`bz#Tx{WbO7ddKfVmc_5$ugDq;Ny|wXfvTNK$_eA=CAn^ z(a3h?-)b}e-K&>p3&N?Z=VRo)3OF}6!rYq~sh#H)TaJ2`RlGf?tlpyiCFUs~)#z9% z!Qq%0-s%fCOD~8s`0?Jy?fCd+uney8yZPID4+wp!@gBQRw8-APSCsA54&Ko-ef*7ziDL@qn%uO z`LREtmyx5+1OJS4XyH5o*rMGJ!aZ+9EsHfxwosA*D0^PEEupnq0jK_|)y+ycw$YYU zN5Ht1R={RnP>%P^t2&=CXa<+$kLMKv=e9*j{R++~$KIsCX11rzn=?STnGrn0Bx3qB zJ&5%fgjvSUqbxmUb&9Xk%!_m_Zt3~Go*cY<@t%QJwvEC^c%aPL&!^zYIIGWQ@l&{K zdvCIO*2X(eT#{L7cnvn6e@L0;(UGkzkYRhS9KxR_Z|!!Z7PF&>1%VWPNfTOz^81zH zDXoeYjF@+pB~=SFpySDnlU%%l_SM5G+yO6R$3!l$l1?LXG|UGn?Dy+*Nc1l#l5_`h-gS$G;ge-oe__gza?akja;8#e~HX1)>n z{;7WwhL_jIg)w9$o>1GE8ANVq zGPO)h7K}Q6i8`}-K-*fd39^8W18V2Iy4&7|hn3gDN$>ESGl2*14$>#009a5l2|(vo z&co*+6cJN9I;H-v^!+x)G)l+I80{4XTErH41=W;>89B_<-hFla}SQm^mlf6Fa9NmXAli&7Bm=f^MA0v zG@vfBfzM*{6#T33-PSvXBY4;U?7Ybg_90fpzsQq|J4yM_(XwC}oXnfm(HaTsHEvNC z5gfBtO5oKF>hU5yy|0zF@aZUe2S<{sggbva@?^KH!0XKg7ds(p6{7I)ukAPDgHZ5> zu4)&Hx#he5^fsl_1d8BE z3NVo8@sLQH3VY0x^<4-0Q~a($NYQK54FOYY`XjuTquYxA3(ePFzXDrBxy)7Sb6rbP z25{=B(?d33ZrEXIboGt+miW7=s+Iy9DwQjd4_Z^czsvbpo+A{IMpweWKg6BsD6`*Z zZb@U>SV5zWP45HM=n&4MK~~o;?CD1^2)r80QTCnRh;vzsQaQd6Hg0?FWk8 z!&J@ro}K#BVYL+w4LUr;NI64+dd{aaMw-Sj1!<_ZNpJVT^nmO0_+A~E3L{y>bU)%C zDJvNBQZ#fK2)9w$tzw+E3Zl>JC?b)ym}CetP#N??m;F2PUn}#iOHcK(h5!Egy=iZ- zYOB2Zx7`<6hrI8DCf6BnhIAq#6KoneCl)jfd-&Dt-wLgph!>Qt%trFPH*U-B$ZH7& zTMLYXuKOf;n1ZI>-jkh#Sn&XQ&O49-Ku*e=t;4*t?(K|>J(4qYct}YRa-GvOr-Tu(} z;6h`=UWxX$a}AvM9cRZx*0fMY;&t3KoW;`7kr$q2XQ3LK_tv2PbV-7y^K$x8HU`~{ zO&kKfC6hwQ>5i+`G&8`$kKQ{wDRC$`kp5Df&RN-=;|?Gjq7d@eB?E`KEqKprw+h)6 zq7pek*HE|4f;txAKsysUU`o0=u>QFt{HnjYldV^Ft?GSeZu$o8olN*9lJQU#zd_|T z^#(;dV`_rLW-tFX+kWS`|9uAGlViCj13&GXvAmvV&UfHE5u&)ZS~YsmfZ(m3^Mb2; z7+v_eOC62x+1-lh1`bEukKivMb#@1@yO4T>5VrEuo?*QVa*9uD#U?9>U|%b_F~ahh z0unwiIw-04ON$wv{JUcP7QvM}afoM~CZcNZ{+m)y966?A27hnUh92LteDt~EsK^T~ zG0wW?W?-Hkw!?A>`Y&XNd-I9`!0aCq5%apEB9x;)_;l+%8~HL0cFOpTb=Py3?ISm? zp4MTyu&vH{#**dU22Jo2M|MSZqFDCW)dZJ24s9<{PB9+tvoA~VmckJ?V$qL_`E^LS zDW8*uhs)_p+>(-a(K;}-4bec=B<0Zcs)ip~!p6a&{=vlyIt>Y@{}-N)gc@EhBWbE| zh|E+rKoYdSr0j@hrcP6?h&4ooP2xsF7DE&#qW(sscXvZMa7)bQO#Ym>msdMl0;M|I zZ`^lz77+lH=bTr!#(caZuCG3RP%MZ(%hpl<*gYW+YM-RHHTe^~R|uP|sjR^lx%rNV z_)U!K(JCk_LpG7bY=(~VDj_1qyFE~4GP#+fKr#?)A@EIwJj&q$>3>CE?Hr+G<6WvD zoWF0!Y}q7{gQ@6ptiZoJ-hYAQ#iP2})`4?xPdBCZ-c3{;LpNsx22Jz+osqxJaD9-E zZi}v&wlsJR?YLQ@m0v(gVhu`dO5_kfTK4Gf+#)cFlX6~$sYl)5a^`Fr3oMU5TBODt z2F_?odPyBPU~IfoXKnFLVD}&gTPshwjtx?9@Ic&3N9KUmb&W@N9RSSV5Zsfl5R>0Q^pQB7`PO+*;PWTossr|18$%w8Tp8to^|OAW5641Bn!eJst_{LETKBlGhTr;}cy}#8&3xEYEe(`-l5DI#9(lxh%m!J_ z?4xI&{#bWh6XydDF51pHGiB_Rm3(uIFkExhIUg{?K!|6gBkdldT!0R>_icyIK`Ld6 zNcaCAhVlnl8IWUGniOl*pR%@j7INv(k)uORb=RAZ&A^hznQhy9LIv?ncI0lv(EiKP z(i>#|KvvfqcS1N4P3ETJo3wDL&oJGT!_#X4K5@UHQg+<7IGZ+1yLIOV)&2Y;$k@?Q zXg$s5v%-Jyi~nfm&ZuUt*a6&Rk|HjOCw_BmdVK4hL3+7HlD>Pl!jBNgH+mjdNCS5x z9y6OHeJVAXcueGahvW8o*%MxH_g8@<<#>^GPW(0V3`$i=(8yvP@0H(*DW=8X0WFUf zePj{&^%~X5vUHP+z3smnn}0;2wR+}CmTG&YzMxOJky0RLoMi_YciutBvkf6? z{bp{et^eZCUoJZT*1lzvPT>?iA0M1o{NtPdyj;6{jE?~Na^ub#(4-`le4J#>KtC>W zEK_Zf$5vQ0vN+!$JIRf)VIc2C?4jG?^$4j%zh7|L0k7|XOw^OgJb77yw;X`D8v~wq ztTSJ5j5svsE};xo3C&~3e8!~={a@#XUv0`kkN$0Ec0DIMkk6oWL1ckIYm+MVH-m3g z9ZvpPj{mr~nft0h2>MvO5a6J0Lqy3F_9*HDG zu!gOA$dN(ckOy*|2e!*33e{}4`Xr9a_jG#Ntcuxu_G}4nAK=}~5qv@cuxJ7^etwNbL z*Ch?9&e-e!v^2U{%J&#)TKXQ zjDBgXe=&qh`0?oxtFGOEKxVMl?(p?!{}pH$Co}&U`zmhlJ>~XDHgWiz|4pT1Mz%j! zKfJipWNPPO@H&$<1`1!sWp}ima!z&pEmMCBJoZJ97y@#B@mGJ8syPMmu8ipq4)w=n zsLaJ{YnL+_T9V{uL<~sfz)bi9@wjjEWm&i*FMae2wh!ZLGsirJ{II<`1`?wCS1>Ls z?Cc5vAP_$A#jy0gX6@kWWZD1poN9;X0LRY+Dgu2HL*9jnT1-~j{dQpg&kA}@?3nV{ zOHY}0i1xQ(Fq6LweS#^X4VM-ZFs~~PZ`->#B8MXnX%5FpB-+ns1_`Wy&(^I_Rl_fL zwzR?9ew*G7WIM9S#JYbh_ZBB5^XZ*fB1sd9Gs%0>Yc#4+&iKb;{>P>J6vNl1TvuZ4 zA?1?DlGe00Too2w+-QEz9(uoBZAnVZ)kmp4?5!>^r=-6YrnA*P?^WHF;FaLZ{k+PQ z>FtEj3d6s9Y-aG}{vg_|XI$>1-KK|qCdo|Kp9r{J{ihUjV>&e!Xq|?R^Es*vbSXY# z?p>}A4CAD56Ab6o6PK1vzY4NTr*_|jH3460(fv1Nv3(Ji+iJH*@WHzA3bERW*x)u=L?8dqu4*pg;r>rMsKazi zq__T6p73?qX1wr1?uS|oRD>|@hAi(*25v$jVPjrd&v&(quv|#mqorh~OXd1paP5QU zQ?loy77|4BdFa2VX7#XswYSyIHSSg`8>bO);hFAj<_IvWojx$C!R9w?<$*P5TqnAO zVi~cE_P0-W%?$?89uef2iu9PmO}M%R|ACP;yix`A<;7cv$H*~I0?;yNwS$NKqW$Nn zBzBCD3Z4Olz0x>^pstmedS~gm&Yd7lHqG)~=M!L50`)2%y=m-1KmH-eZcOY7R9LlV zSSPUSm8+vjfMN*>%#x^}ELmQ*Ot>Oku+^K?@7(qmsw23WWA3%eUw64i_YyVY&&3ks z7vV59KUySFi;xZ^V0=+In(B=CWHt}0(B~cz7w5a z8M?$Rfj2m>TXTGCS)+r)Dpob*J(XAeewjGAK>rUr`{J{KB!JfyHR=8wxX+%7i6o{<3`= z#p$HhwEON#TS%d5^y}r@xet)27ax(1nt;R>V8!+Tq4!00*mH;~`fLNGHHCq$h*&S7 z($XJS6;;e6T29%NW&P!vKi?Kxk_j7XLr)h3k>qF#^wd zXqzwF!>ca`OV$MgSu}ZnJg84BX;G7T#OzemxB7X;is?-0u-1L|2>;~E4lM7m&^Nhx zHik}2K?j4#!SZ1uiGWUIsWcDJCJumKkk?Tl=zB>$ndU?`DFbELCgB?k~gCG z{(;@8X7V$+ugr4HN3SlteTr!1U^K!Qy%}`cvA+7;(kIFqf~uZ69lZ%-^RIV3-EKbI z12x7KXJ!XCtb_Qzv+9c`o<;*7X0@9l;=!lccz)%t_@FA(^ihf%~ zu~QNB(&PUf#~Giqb~vEA-Y#Ol{#G?#9`K(A=pW&H&g2;V2WuDiIC3~=PTnd%4-LLC zZ=q9 zsZFEAX}I!LQp4Akx7kf6t2Z+lesbK%sUm;R{`I#yQF>Rmz#eg6yn9@-r%2tR>;kiub!r;r2L0kQ>lPTvg^!~T~v)0gP;P`Xvi zo+N7F-hX@he+ZY%Af`vYp$1TYZ3%{z%BYEzz<4G6zpJFh>{V9{7~J zW77hXr5(n!&tFr6Jb_#~slCs?rzCMova-LZxFz)~$OPK5T>fo)5=7R%n=wImM4F`%6pJJBj~|)9$l?_%x<)YJkd-6H_!UDXxW2Aj zsT&&G129J%#@`XQGtj!EDzelEyEX2lH+kdz`Uso~*7j%J`1UHi^Lz5;OwqiX#;$Jz z0zRtb-gU|!#qN* z@j)o#e~(%HQN}`LE@l4EV}3O>yL2gEc(7#eu($fC(bY$BYQ!n;Gi?+ahDsg1B-&&7 zgMD9)1-*7+AD@~Y>()MwMDFi+wV4uLszToe^c|w&UgS&u^mq^eJp21j{%&TP{(tR# zXIN8N*ES*wgeo9ShF$_HMHE3w=qN1|6;uQwqcU`*_ZpOLp^9`VijW|RB9PDoBp{v8 zBvk1wlmH>{9dMj+d?wHL|Gl1n=Sn*}Yp=b^z3#Qn%5J}3=h-UJlLoKV%*CCe$%rLW zkw)L0srDJ2lK_qG2iH*pBFl>K@+5b#WYZ@FnaA?UH@uf;_9idD?@87xdNTm2-PV~2 zSe$14#ega+p;XYZ>#OHz_+tGdBJWw1tWyG!xNYh%bGO_dfgPCdtixGQ&K@8TnC@DM z1Z0{2^%J==GFk($nC}>-aH-$)TDxQ;Zn_WNd}iAAwCWJ|=nR!6OqLki=N8Db33fx_ zkFZxQ!%p{zqzlq#_e!|QAmp1z?ac*w1ICg>p|3{ zf?+HVlq+yOG)X^hjU?-jkIsHED>vC@|ElyMIZRR2`l*<-V`&QSt5TATtlL!3`lhC< z;j2V}i#moT-?WbDc2`kMUQK@5#fz7vsuQHLWjk%AZeW2Cl41MAMoTIv2BwZoQaOi< zC6EN;#lLS5T)qJa!BUr=oq6F-ADgqen)203uyOtP@Ktgj@jlrYc=bnMP#eHuqZ}i}NGHK{LVNmA2QoyRwu09QF*`^$w!& zz}NXY*?dowX(RF5*Q|*6=*NTyCW}dv0B0MYoPEHH;|y%vAcd-OBCJ)&>=96AN~>mn zdY33P!5vn9=L*Q9_$xdp-<2V0eA{9zRY6>%Q2a$sEP{9bM1UVU6ITcC^(#{Irb?Ux zY0IDYb`G0PX343qqw$^!F)X(F5U^2YgiiAD0_#?G6SBg7GJQL{Dau!tTI^VP!+P)y z++>XL$B^pz8CQ~msqNDbVoNohrchj0X}bev`1JfcYLr|`w_RDbbM8&#eD?ByNq{%< z5@$Ttx)=h68Dk3_2)t`=Oit4@SlaLLkMEv?^1WgM2g7DF6L^Lf z^HrJ?reszNR1Fkc`V_uyTZ}zz%uvDuMZww|Rm1kJ4PngGs}K7V-di|1@2t$(7}PFL zoK!lb2a`~e-?{EcO;=;Q)y$mNDXA{JmbSdPqQoV+7QErk6k{Y}y4`+Md@=)z?=ZB}zut;0CkdIuZ*~ zM|P(#3-AW(9gbn<=5P?8RRLdS?Ve6pPR?g&tvA)SGiFIpEw20X5Zh!p)+AZ!f9`mUg^ zfV+l@TLUJ#-ff>OPO4&K`#WNK|BTR9CR^5X@--fyGd4fAVJ5c_HEZHE#gChbl+Tq) z)T>=riuGAQ?v?s8tx3G$;u~8jO-q6{;z!w2sK3rh!Rt=Bw2}_Nnb#}(9-yhL4}821 zBnYf?gO7tVQ1Kh7^y_?D_{qFl<^PW1vIeJ3&GWE!=6X#r`fxROofjC`^h`Ucr5@q4 zPa|`0=49;~n5|R~k%%r3=PBUpLKU~pO;XE@>|yNPiUA<$8FM3Q{GJTOZfw>vdoJnH zLn&h1z=MsM1Lpep%5F!+eI*vkQ7@xLQF1C1RBc%5=}`jB;(jNY`Fj2;>9Izfjrk| z6Dmm&t~-roj0loEr0W;o2rW($YfF;L?La(g2MkiW@yzitDBuzET!#<6*I!Q z(X+<5`!Q0LBtHn2cc1zha;Q5Rs#dA9P@#a|+5Y zKW`_}!H= z;KuVf)dJ76WHXe$dKx94-E_&tOUW+B+N!AZpenRphf!sjqVugss`98%ULM}Gb}WN% zl>8KLIO!yZW7S$KUgIh+jxk4_d z!<8+I!?YtFNYZ_L)Hju#S!}lX;mkwQ4iS=U$Y(k4XlP_+c;BeTk_5Np+8=t zg+B)`7th~!pGni3Hu2J}oRh&TSEewJaz=|Dl4^xmcl+gR184cZyR$VzzBob~tEWnV zpMMO7{l9O%#z+wS8C5GXE3`Q#E-cWF=6FgpU=n}jlGA!My!G1LiuTgHq)lT&&1t-mNldssM1TOjNuojLelAcL1GdehP?WFD%8zFEyhd&?D`1nSkKH=^se)}`qE)CyJ3GS!GX zIoU|fAQBD9uHIBkT*^4Y`mH~A?_R>^iU1`bmKndqH~5zo{HJZ4W}#&D5gS+`qQLbk z5x$2P*UchjMJS6D!3Z^=IqbwU0rg3>f=fiTz4Tj#k)d4Nl6VfR?GuQp59{`*fPnGs zS37vlebgb61Z1si{^-_kS_>`Q#Fqba3CWQieMR$;PLzXLo0#H<)0pypXdDspCfA)t zb`stvpb+9PHf#Vqy@)MU&R07velGaO4Beu14= zUu%G&3HMu77w(!X;=(LV!+8?&Ga0=e8snPg^lCFIK_c|c<1dTdk0#{w2%T4(d0<;!#i8qD{!Ec;?KMG{F)x#t2-YJIh5tV8ja2&?t0f0Hx2+jrmt#Zd~Y$- z-a}A2{c|(^#+JTnj7VXhJI0Y(AYry<#Zur=C$F0|Y*ZqzM0ZYn_25X^RX@^%4GTA~dH&=hmtq(=u8U*Tt6d(9;x zjr&ELw1ZtKABmaj=UpYR48&f9GY%ai)EfLaum7z40 zK33ou={>_$;QH*XnXa>%!9cjP4ox@<(|SH_K(2`qP#Kk&Uv;F3hUK$y45}v_Fh{pD z;ts1sQc*YXk&;7zf|f|m>aKTdy3`!_p3#ynmAWxM89;=BGJ$3D{oP7znS+x8+u(h9 z%>vO}!Jn3Ts5D{>7SKOz<OUs4WqjiT1 zuJWBy0?7t~9_8|0J6X?!Zh~ia=7|Pi{P%I{r0fd-W+v8f-G7r4vzfXekoh1_S#ZIl!-aIt3LEyX*$+vXc_vBUS!rX0F^pN{qYIb z;Sv(8@pu+w(EY6>`R&H%>k(lrbjKszjIG{&HMyFf+Q;O6;Os{(%^!riT40-f z;MLe`kLTn1p^YTCjR#WbjTsKV8c~7+du=-JHD14Mx;RzB zQMdEeYvwBv0|6PW@pr9?bx`S~U4mXem0C ztOEvs5o`PQ*uBox1!5A(tI1bdONBPjga8_CAh`Ku=Gi=Lpy71Jz-tX|h{#bSSQv*l-Y)m5>EoInnC=a4Y zk$g9byxvcL?fU() z8zYo5O_^D>U`!&A1n1jncgzoi$S#bSs#0*)FS z$6rpu^sk8SduKgZ+HO*a)9aJh4^aLwmro2@!TgTL7n*@g`^>FZ2{ zjz~z{D$g5Qe(~OFD%)B-yk{uYNKjzIH0=15O~t5XmE$p^nncsV%)NvK{u@Wfq32`K zRu^VVH-Pbz%1ZKXo4f+rij^UMcKZD7o_}nZ+lk;LzMbpDX;VY`4uK?j`>l^5;`E6j z!Y2G05z-5}y-$|W;|$pITl*~Lba^auk(cSe`GnteMnWO}?@2^Hi1b9-3-=?`B4cn4 zGoNYOkgF%@bw54=7c7BfB%EvX>$WDC%{@z`Max9E*`My@UMv{Tjag&snsAPcT9`s+ zJl7lkvkAF*CG$ihj=;NPNPK@6h47kkP&z?X83yG{we z)l@&CqsPY%BvO`vxzYu)PaFrZBHaq!47zKWby{k=l6I!!FK4o}Y#i$ZGn8mWP9@S3 z#Vh}$3w3|K4aQd1tLbmQvkLn zvS-{|gz5$IAW-NGjRzQMU9IDY09*W4j>r|K4X=J zpJk22)gNu6P)WR2<+16t4<$0_A_EKo!Vm?cukiLcNp;4E5aVYmV}kP>exp`2?FY;` zXmlJmx7@oG0-vXMENS<2zB9{M=I||=uxwSbu15|;DVy&A!})w-S^yp`-kEn!v_V<# zd8ejZ9G$lT6PI1@5>D2w;EVX%0u=EK{L?mkS8G(;-?8R-^26u zpkt!nBp~6bcom&qoaT=jd%s&FPCUkv*wUrqg!9>Aa{Ly5?US$dIF9+2+c-ia{oidp z5LjLs=}eU>VMP%nh+kXtE2gX>FHc?wVc9&Bn=EEUTf}glhq2S2O1an;Xmw-e-10BH zAK!^F^3A=Q6^kW#fgho8__@iK)3;uni~_(?P4xks3)pgrCw)3_CZ=Vxv?Lb&z@ZB5 zzx_d~Px8h>q5+V;Y4Q(+Nj%jd7froCHqB@5XeGanUeG}MqrZNfHJo#GMw?8~)ieZy z9j1fm{L6=}Tj5po=Oo(D7E#i5k&$0B3;jp0m_LNGFv?ci&M2GHIoBQX)H#J|X@6mf zN;+uqH~Bq(uiP3~Q%5ZN2Ehromj*^tU}u@=lCqs4ZC2NElg~;QT=N5(QLZb5n=zbkRXBD{POYsU^>?}s)5)EhUZJ z!V_|t`uNqi=BCn`sI^nwDQogAj;~AD1!3Q$u(GG%>a-927mL8b$d=9N&QV21r8kpGE`gj@C3i=iB>8a%>w@AVzy+Q2Q zcx;(729IIRQ4U?0r6mPcA^s(qQ>gyE&v4JZ|t0y)U3(qgpHRq0bluT7^?Uy-QXat~L|Q zQYt*sgh47NWNEqUW5I5JVBpn0#{$k)(YVWr?V7UbLA4KR$Y{1N`&j`n9i8`W&-naE z8dJ$(cHZBKOK#TKs1TpS`)%yPHRQY|^RzA{#%$;hj$xPJv_Mk1M@`JsU_Um)CP~uD zf+kq~%zUfJJ*axdlU@#d<-zln7vgSM`vQEm5APnwrW9*9q8 z{9ZPHCJ9PyX!$m2uf#s}{|5Q8@f_{Bvru9!l`8j#4}H0x(jyAW z(ZeY&RAk&b^Ynen_rp~!#pY#w#n(M@Zx*5zi{BSIqX&vntK0yJW`fawIShX!5(Ky99J}f}tzUYlkX~kBF(Nrj`wCL2AbuhO4An}od$-GcTqGK(EdzeU zYF9d|q9J2J)X7HCp`^Mj4OQe=@yVmCE>W?cvDEX87BEcV^~+M5p$Quj4L@@+pV)me z2NAICG?XCYkMrrbJ?6gZ%`*~IDlvPDl?0Cp;;!$)Fmb8OcgOh?Fl8M#d%Wz;lFE%9 zbo12>oO9vPtNpKf{Cm$&2OcK%LZ)&4gLVu9c6(O1>dYm?n?oEF)He$223@WcwY^^q zm==et5zO6SZ~R+P8|}G|J0Q<2wKJlUXR^S-GNxXluP7i^#Y-ZHhEez9rjNR>N1XQ7 z^0D;vqfgzPY5Wtv9oPBFJxjm-ah-8H`O0ch9>P4n&cdf3Qm*!)i zt<&~)b*(uf3>MR@TN|iS+Z8|W&+=#WSIjL>F-Sp{JF47!Ww3&td3v`m`m?Mf9mycY z(KWwyeTOxwBf3>cBuI7hBJF);G6&+PEM88Ka(jiEJb?Xo$`2rxz%euFP$E}r`{`FT zDS{t){0EBjAHF46QZPuhPb;A{hfEFOXSW^vNbY~XNXFp)-<9L$-a^03AqonL5aezV zZLOd@Nmw^X_h+;GeeCu53d^$tpET3 literal 0 HcmV?d00001 diff --git a/docs/site/sidebars/lb4_sidebar.yml b/docs/site/sidebars/lb4_sidebar.yml index fd0e43f8ad8d..a41a1e79bd06 100644 --- a/docs/site/sidebars/lb4_sidebar.yml +++ b/docs/site/sidebars/lb4_sidebar.yml @@ -148,6 +148,10 @@ children: - title: 'Components' url: Components.html output: 'web, pdf' + + - title: 'Interceptors' + url: Interceptors.html + output: 'web, pdf' - title: 'DataSources' url: DataSources.html diff --git a/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts b/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts new file mode 100644 index 000000000000..e774f8bb99c5 --- /dev/null +++ b/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts @@ -0,0 +1,203 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/context +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {expect} from '@loopback/testlab'; +import { + AsyncProxy, + Context, + createProxyWithInterceptors, + inject, + intercept, + Interceptor, + ValueOrPromise, +} from '../..'; + +describe('Interception proxy', () => { + let ctx: Context; + + beforeEach(givenContextAndEvents); + + it('invokes async interceptors on an async method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + const proxy = createProxyWithInterceptors(new MyController(), ctx); + const msg = await proxy.greet('John'); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + ]); + }); + + it('creates a proxy that converts sync method to be async', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + greet(name: string) { + return `Hello, ${name}`; + } + } + const proxy = createProxyWithInterceptors(new MyController(), ctx); + const msg = await proxy.greet('John'); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + ]); + + // Make sure `greet` always return Promise now + expect(proxy.greet('Jane')).to.be.instanceOf(Promise); + }); + + it('creates async methods for the proxy', () => { + class MyController { + name: string; + + greet(name: string): string { + return `Hello, ${name}`; + } + + async hello(name: string) { + return `Hello, ${name}`; + } + } + + interface ExpectedAsyncProxyForMyController { + name: string; + greet(name: string): ValueOrPromise; // the return type becomes `Promise` + hello(name: string): Promise; // the same as MyController + } + + const proxy = createProxyWithInterceptors(new MyController(), ctx); + + // Enforce compile time check to ensure the AsyncProxy typing works for TS + // tslint:disable-next-line:no-unused + const check: ExpectedAsyncProxyForMyController = proxy; + }); + + it('invokes interceptors on a static method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // The class level `log` will be applied + static greetStatic(name: string) { + return `Hello, ${name}`; + } + } + ctx.bind('name').to('John'); + const proxy = createProxyWithInterceptors(MyController, ctx); + const msg = await proxy.greetStatic('John'); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetStatic', + 'log: after-greetStatic', + ]); + }); + + it('supports asProxyWithInterceptors resolution option', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + ctx.bind('my-controller').toClass(MyController); + const proxy = await ctx.get('my-controller', { + asProxyWithInterceptors: true, + }); + const msg = await proxy!.greet('John'); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + ]); + }); + + it('reports error when asProxyWithInterceptors is set for non-Class binding', async () => { + ctx.bind('my-value').toDynamicValue(() => 'my-value'); + await expect( + ctx.get('my-value', { + asProxyWithInterceptors: true, + }), + ).to.be.rejectedWith( + `Binding 'my-value' (DynamicValue) does not support 'asProxyWithInterceptors'`, + ); + }); + + it('supports asProxyWithInterceptors resolution option for @inject', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + + class DummyController { + constructor( + @inject('my-controller', {asProxyWithInterceptors: true}) + public readonly myController: AsyncProxy, + ) {} + } + ctx.bind('my-controller').toClass(MyController); + ctx.bind('dummy-controller').toClass(DummyController); + const dummyController = await ctx.get('dummy-controller'); + const msg = await dummyController.myController.greet('John'); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + ]); + }); + + let events: string[]; + + const log: Interceptor = async (invocationCtx, next) => { + events.push('log: before-' + invocationCtx.methodName); + const result = await next(); + events.push('log: after-' + invocationCtx.methodName); + return result; + }; + + // An interceptor to convert the 1st arg to upper case + const convertName: Interceptor = async (invocationCtx, next) => { + events.push('convertName: before-' + invocationCtx.methodName); + invocationCtx.args[0] = (invocationCtx.args[0] as string).toUpperCase(); + const result = await next(); + events.push('convertName: after-' + invocationCtx.methodName); + return result; + }; + + function givenContextAndEvents() { + ctx = new Context(); + events = []; + } +}); diff --git a/packages/context/src/__tests__/acceptance/interceptor.acceptance.ts b/packages/context/src/__tests__/acceptance/interceptor.acceptance.ts new file mode 100644 index 000000000000..44e152fc979f --- /dev/null +++ b/packages/context/src/__tests__/acceptance/interceptor.acceptance.ts @@ -0,0 +1,529 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/context +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {expect} from '@loopback/testlab'; +import { + asGlobalInterceptor, + Context, + inject, + intercept, + Interceptor, + InvocationContext, + invokeMethod, + invokeMethodWithInterceptors, + Provider, + ValueOrPromise, +} from '../..'; + +describe('Interceptor', () => { + let ctx: Context; + + beforeEach(givenContextAndEvents); + + it('invokes sync interceptors on a sync method', () => { + class MyController { + // Apply `logSync` to a sync instance method + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + + const msg = invokeMethodWithInterceptors(ctx, controller, 'greetSync', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'logSync: before-greetSync', + 'logSync: after-greetSync', + ]); + }); + + it('invokes async interceptors on a sync method', async () => { + class MyController { + // Apply `log` to a sync instance method + @intercept(log) + greet(name: string) { + return `Hello, ${name}`; + } + } + + const controller = new MyController(); + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql(['log: before-greet', 'log: after-greet']); + }); + + it('supports interceptor bindings', async () => { + class MyController { + // Apply `log` as a binding key to an async instance method + @intercept('log') + async greet(name: string) { + const hello = await Promise.resolve(`Hello, ${name}`); + return hello; + } + } + + const controller = new MyController(); + ctx.bind('log').to(log); + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql(['log: before-greet', 'log: after-greet']); + }); + + it('supports interceptor bindings from a provider', async () => { + class MyController { + // Apply `name-validator` backed by a provider class + @intercept('name-validator') + async greet(name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + ctx.bind('valid-names').to(['John', 'Mary']); + ctx.bind('name-validator').toProvider(NameValidator); + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + await expect( + invokeMethodWithInterceptors(ctx, controller, 'greet', ['Smith']), + ).to.be.rejectedWith(/Name 'Smith' is not on the list/); + }); + + it('invokes a method with two interceptors', async () => { + class MyController { + // Apply `log` and `logSync` to an async instance method + @intercept('log', logSync) + async greet(name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + + ctx.bind('log').to(log); + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greet', + 'logSync: before-greet', + 'logSync: after-greet', + 'log: after-greet', + ]); + }); + + it('invokes a method without interceptors', async () => { + class MyController { + // No interceptors + async greet(name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([]); + }); + + it('allows interceptors to modify args', async () => { + class MyController { + // Apply `convertName` to convert `name` arg to upper case + @intercept(convertName) + async greet(name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + const msg = await invokeMethodWithInterceptors(ctx, controller, 'greet', [ + 'John', + ]); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'convertName: after-greet', + ]); + }); + + it('allows interceptors to catch errors', async () => { + class MyController { + // Apply `logError` to catch errors + @intercept(logError) + async greet(name: string) { + throw new Error('error: ' + name); + } + } + const controller = new MyController(); + await expect( + invokeMethodWithInterceptors(ctx, controller, 'greet', ['John']), + ).to.be.rejectedWith('error: John'); + expect(events).to.eql(['logError: before-greet', 'logError: error-greet']); + }); + + it('invokes static interceptors', async () => { + class MyController { + // Apply `log` to a static method + @intercept(log) + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + } + + const msg = await invokeMethodWithInterceptors( + ctx, + MyController, + 'greetStatic', + ['John'], + ); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetStatic', + 'log: after-greetStatic', + ]); + }); + + it('does not allow @intercept on properties', () => { + expect(() => { + // tslint:disable-next-line:no-unused + class MyControllerWithProps { + @intercept(log) + private status: string; + } + }).to.throw(/@intercept cannot be used on a property/); + }); + + context('method dependency injection', () => { + it('invokes interceptors on a static method', async () => { + class MyController { + // Apply `log` to a static method with parameter injection + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + } + ctx.bind('name').to('John'); + const msg = await invokeMethod(MyController, 'greetStaticWithDI', ctx); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetStaticWithDI', + 'log: after-greetStaticWithDI', + ]); + }); + + it('invokes interceptors on an instance method', async () => { + class MyController { + // Apply `log` to an async instance method with parameter injection + @intercept(log) + async greetWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + } + const controller = new MyController(); + + ctx.bind('name').to('John'); + const msg = await invokeMethod(controller, 'greetWithDI', ctx); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetWithDI', + 'log: after-greetWithDI', + ]); + }); + }); + + context('class level interceptors', () => { + it('invokes sync and async interceptors', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // We can apply `@intercept` multiple times on the same method + // This is needed if a custom decorator is created for `@intercept` + @intercept(log) + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + } + + const msg = await invokeMethodWithInterceptors( + ctx, + new MyController(), + 'greetSync', + ['John'], + ); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetSync', + 'logSync: before-greetSync', + 'logSync: after-greetSync', + 'log: after-greetSync', + ]); + }); + + it('invokes async interceptors on an async method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + const msg = await invokeMethodWithInterceptors( + ctx, + new MyController(), + 'greet', + ['John'], + ); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + ]); + }); + + it('invokes interceptors on a static method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // The class level `log` will be applied + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + } + const msg = await invokeMethodWithInterceptors( + ctx, + MyController, + 'greetStatic', + ['John'], + ); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetStatic', + 'log: after-greetStatic', + ]); + }); + + it('invokes interceptors on a static method with DI', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + } + ctx.bind('name').to('John'); + const msg = await invokeMethod(MyController, 'greetStaticWithDI', ctx); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'log: before-greetStaticWithDI', + 'log: after-greetStaticWithDI', + ]); + }); + }); + + context('global interceptors', () => { + beforeEach(givenGlobalInterceptor); + + it('invokes sync and async interceptors', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // We can apply `@intercept` multiple times on the same method + // This is needed if a custom decorator is created for `@intercept` + @intercept(log) + @intercept(logSync) + greetSync(name: string) { + return `Hello, ${name}`; + } + } + const msg = await invokeMethodWithInterceptors( + ctx, + new MyController(), + 'greetSync', + ['John'], + ); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'globalLog: before-greetSync', + 'log: before-greetSync', + 'logSync: before-greetSync', + 'logSync: after-greetSync', + 'log: after-greetSync', + 'globalLog: after-greetSync', + ]); + }); + + it('invokes async interceptors on an async method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // Apply multiple interceptors. The order of `log` will be preserved as it + // explicitly listed at method level + @intercept(convertName, log) + async greet(name: string) { + return `Hello, ${name}`; + } + } + const msg = await invokeMethodWithInterceptors( + ctx, + new MyController(), + 'greet', + ['John'], + ); + expect(msg).to.equal('Hello, JOHN'); + expect(events).to.eql([ + 'globalLog: before-greet', + 'convertName: before-greet', + 'log: before-greet', + 'log: after-greet', + 'convertName: after-greet', + 'globalLog: after-greet', + ]); + }); + + it('invokes interceptors on a static method', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + // The class level `log` will be applied + static async greetStatic(name: string) { + return `Hello, ${name}`; + } + } + const msg = await invokeMethodWithInterceptors( + ctx, + MyController, + 'greetStatic', + ['John'], + ); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'globalLog: before-greetStatic', + 'log: before-greetStatic', + 'log: after-greetStatic', + 'globalLog: after-greetStatic', + ]); + }); + + it('invokes interceptors on a static method with DI', async () => { + // Apply `log` to all methods on the class + @intercept(log) + class MyController { + @intercept(log) + static async greetStaticWithDI(@inject('name') name: string) { + return `Hello, ${name}`; + } + } + ctx.bind('name').to('John'); + const msg = await invokeMethod(MyController, 'greetStaticWithDI', ctx); + expect(msg).to.equal('Hello, John'); + expect(events).to.eql([ + 'globalLog: before-greetStaticWithDI', + 'log: before-greetStaticWithDI', + 'log: after-greetStaticWithDI', + 'globalLog: after-greetStaticWithDI', + ]); + }); + + function givenGlobalInterceptor() { + const globalLog: Interceptor = async (invocationCtx, next) => { + events.push('globalLog: before-' + invocationCtx.methodName); + const result = await next(); + events.push('globalLog: after-' + invocationCtx.methodName); + return result; + }; + ctx + .bind('globalLog') + .to(globalLog) + .apply(asGlobalInterceptor()); + } + }); + + let events: string[]; + + const logSync: Interceptor = (invocationCtx, next) => { + events.push('logSync: before-' + invocationCtx.methodName); + // Calling `next()` without `await` + const result = next(); + // It's possible that the statement below is executed before downstream + // interceptors or the target method finish + events.push('logSync: after-' + invocationCtx.methodName); + return result; + }; + + const log: Interceptor = async (invocationCtx, next) => { + events.push('log: before-' + invocationCtx.methodName); + const result = await next(); + events.push('log: after-' + invocationCtx.methodName); + return result; + }; + + const logError: Interceptor = async (invocationCtx, next) => { + events.push('logError: before-' + invocationCtx.methodName); + try { + const result = await next(); + events.push('logError: after-' + invocationCtx.methodName); + return result; + } catch (err) { + events.push('logError: error-' + invocationCtx.methodName); + throw err; + } + }; + + // An interceptor to convert the 1st arg to upper case + const convertName: Interceptor = async (invocationCtx, next) => { + events.push('convertName: before-' + invocationCtx.methodName); + invocationCtx.args[0] = (invocationCtx.args[0] as string).toUpperCase(); + const result = await next(); + events.push('convertName: after-' + invocationCtx.methodName); + return result; + }; + + /** + * A binding provider class to produce an interceptor that validates the + * `name` argument + */ + class NameValidator implements Provider { + constructor(@inject('valid-names') private validNames: string[]) {} + + value() { + const interceptor: Interceptor = (invocationCtx, next) => + this.validateName(invocationCtx, next); + return interceptor; + } + + async validateName( + invocationCtx: InvocationContext, + next: () => ValueOrPromise, + ) { + const name = invocationCtx.args[0]; + if (!this.validNames.includes(name)) { + throw new Error( + `Name '${name}' is not on the list of '${this.validNames}`, + ); + } + return await next(); + } + } + + function givenContextAndEvents() { + ctx = new Context(); + events = []; + } +}); diff --git a/packages/context/src/__tests__/unit/interceptor.unit.ts b/packages/context/src/__tests__/unit/interceptor.unit.ts new file mode 100644 index 000000000000..a8420b337c6e --- /dev/null +++ b/packages/context/src/__tests__/unit/interceptor.unit.ts @@ -0,0 +1,156 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/context +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {expect} from '@loopback/testlab'; +import { + asGlobalInterceptor, + Context, + ContextBindings, + Interceptor, + InterceptorOrKey, + InvocationContext, + mergeInterceptors, +} from '../..'; + +describe('mergeInterceptors', () => { + it('removes duplicate entries from the spec', () => { + assertMergeAsExpected(['log'], ['cache', 'log'], ['cache', 'log']); + assertMergeAsExpected(['log'], ['log', 'cache'], ['log', 'cache']); + }); + + it('allows empty array for interceptors', () => { + assertMergeAsExpected([], ['cache', 'log'], ['cache', 'log']); + assertMergeAsExpected(['cache', 'log'], [], ['cache', 'log']); + }); + + it('joins two arrays for interceptors', () => { + assertMergeAsExpected(['cache'], ['log'], ['cache', 'log']); + }); + + function assertMergeAsExpected( + interceptorsFromSpec: InterceptorOrKey[], + existingInterceptors: InterceptorOrKey[], + expectedResult: InterceptorOrKey[], + ) { + expect( + mergeInterceptors(interceptorsFromSpec, existingInterceptors), + ).to.eql(expectedResult); + } +}); + +describe('globalInterceptors', () => { + let ctx: Context; + + const logInterceptor: Interceptor = async (context, next) => { + await next(); + }; + const authInterceptor: Interceptor = async (context, next) => { + await next(); + }; + + beforeEach(givenContext); + + it('sorts by group', () => { + ctx + .bind(ContextBindings.GLOBAL_INTERCEPTOR_ORDERED_GROUPS) + .to(['log', 'auth']); + + ctx + .bind('globalInterceptors.authInterceptor') + .to(authInterceptor) + .apply(asGlobalInterceptor('auth')); + + ctx + .bind('globalInterceptors.logInterceptor') + .to(logInterceptor) + .apply(asGlobalInterceptor('log')); + + const invocationCtx = givenInvocationContext(); + + const keys = invocationCtx.getGlobalInterceptorBindingKeys(); + expect(keys).to.eql([ + 'globalInterceptors.logInterceptor', + 'globalInterceptors.authInterceptor', + ]); + }); + + it('sorts by group - unknown group comes before known ones', () => { + ctx + .bind(ContextBindings.GLOBAL_INTERCEPTOR_ORDERED_GROUPS) + .to(['log', 'auth']); + + ctx + .bind('globalInterceptors.authInterceptor') + .to(authInterceptor) + .apply(asGlobalInterceptor('auth')); + + ctx + .bind('globalInterceptors.logInterceptor') + .to(logInterceptor) + .apply(asGlobalInterceptor('unknown')); + + const invocationCtx = givenInvocationContext(); + + const keys = invocationCtx.getGlobalInterceptorBindingKeys(); + expect(keys).to.eql([ + 'globalInterceptors.logInterceptor', + 'globalInterceptors.authInterceptor', + ]); + }); + + it('sorts by group alphabetically without ordered group', () => { + ctx + .bind('globalInterceptors.authInterceptor') + .to(authInterceptor) + .apply(asGlobalInterceptor('auth')); + + ctx + .bind('globalInterceptors.logInterceptor') + .to(logInterceptor) + .apply(asGlobalInterceptor('log')); + + const invocationCtx = givenInvocationContext(); + + const keys = invocationCtx.getGlobalInterceptorBindingKeys(); + expect(keys).to.eql([ + 'globalInterceptors.authInterceptor', + 'globalInterceptors.logInterceptor', + ]); + }); + + it('sorts by binding order without group tags', () => { + ctx + .bind('globalInterceptors.authInterceptor') + .to(authInterceptor) + .apply(asGlobalInterceptor()); + + ctx + .bind('globalInterceptors.logInterceptor') + .to(logInterceptor) + .apply(asGlobalInterceptor()); + + const invocationCtx = givenInvocationContext(); + + const keys = invocationCtx.getGlobalInterceptorBindingKeys(); + expect(keys).to.eql([ + 'globalInterceptors.authInterceptor', + 'globalInterceptors.logInterceptor', + ]); + }); + + class MyController { + greet(name: string) { + return `Hello, ${name}`; + } + } + + function givenContext() { + ctx = new Context(); + } + + function givenInvocationContext() { + return new InvocationContext(ctx, new MyController(), 'greet', ['John']); + } +}); diff --git a/packages/context/src/binding.ts b/packages/context/src/binding.ts index b7077d5c84c1..f1066e93150f 100644 --- a/packages/context/src/binding.ts +++ b/packages/context/src/binding.ts @@ -6,6 +6,7 @@ import * as debugFactory from 'debug'; import {BindingAddress, BindingKey} from './binding-key'; import {Context} from './context'; +import {createProxyWithInterceptors} from './interception-proxy'; import {Provider} from './provider'; import { asResolutionOptions, @@ -384,7 +385,16 @@ export class Binding { private _setValueGetter(getValue: ValueGetter) { // Clear the cache this._clearCache(); - this._getValue = getValue; + this._getValue = (ctx: Context, options: ResolutionOptions) => { + if (options.asProxyWithInterceptors && this._type !== BindingType.CLASS) { + throw new Error( + `Binding '${this.key}' (${ + this._type + }) does not support 'asProxyWithInterceptors'`, + ); + } + return getValue(ctx, options); + }; } /** @@ -504,9 +514,11 @@ export class Binding { debug('Bind %s to class %s', this.key, ctor.name); } this._type = BindingType.CLASS; - this._setValueGetter((ctx, options) => - instantiateClass(ctor, ctx, options.session), - ); + this._setValueGetter((ctx, options) => { + const instOrPromise = instantiateClass(ctor, ctx, options.session); + if (!options.asProxyWithInterceptors) return instOrPromise; + return createInterceptionProxyFromInstance(instOrPromise, ctx); + }); this._valueConstructor = ctor; return this; } @@ -522,8 +534,7 @@ export class Binding { debug('Bind %s to alias %s', this.key, keyWithPath); } this._type = BindingType.ALIAS; - this._setValueGetter((ctx, optionsOrSession) => { - const options = asResolutionOptions(optionsOrSession); + this._setValueGetter((ctx, options) => { return ctx.getValueOrPromise(keyWithPath, options); }); return this; @@ -582,3 +593,17 @@ export class Binding { return new Binding(key.toString()); } } + +function createInterceptionProxyFromInstance( + instOrPromise: ValueOrPromise, + context: Context, +) { + return transformValueOrPromise(instOrPromise, inst => { + if (typeof inst !== 'object') return inst; + return (createProxyWithInterceptors( + // Cast inst from `T` to `object` + (inst as unknown) as object, + context, + ) as unknown) as T; + }); +} diff --git a/packages/context/src/index.ts b/packages/context/src/index.ts index 106924e0b991..70eb7613aab3 100644 --- a/packages/context/src/index.ts +++ b/packages/context/src/index.ts @@ -6,13 +6,15 @@ export * from '@loopback/metadata'; export * from './binding'; export * from './binding-decorator'; +export * from './binding-filter'; export * from './binding-inspector'; export * from './binding-key'; -export * from './binding-filter'; export * from './context'; export * from './context-observer'; export * from './context-view'; export * from './inject'; +export * from './interception-proxy'; +export * from './interceptor'; export * from './keys'; export * from './provider'; export * from './resolution-session'; diff --git a/packages/context/src/inject.ts b/packages/context/src/inject.ts index 43ce0e800e43..10c540549048 100644 --- a/packages/context/src/inject.ts +++ b/packages/context/src/inject.ts @@ -22,7 +22,7 @@ import { import {BindingAddress} from './binding-key'; import {BindingCreationPolicy, Context} from './context'; import {ContextView, createViewGetter} from './context-view'; -import {ResolutionSession} from './resolution-session'; +import {ResolutionOptions, ResolutionSession} from './resolution-session'; import {BoundValue, ValueOrPromise} from './value-promise'; const PARAMETERS_KEY = MetadataAccessor.create( @@ -46,16 +46,12 @@ export interface ResolverFunction { /** * An object to provide metadata for `@inject` */ -export interface InjectionMetadata { +export interface InjectionMetadata extends ResolutionOptions { /** * Name of the decorator function, such as `@inject` or `@inject.setter`. * It's usually set by the decorator implementation. */ decorator?: string; - /** - * Control if the dependency is optional, default to false - */ - optional?: boolean; /** * Other attributes */ @@ -411,11 +407,12 @@ function resolveAsGetter( const bindingSelector = injection.bindingSelector as BindingAddress; // We need to clone the session for the getter as it will be resolved later const forkedSession = ResolutionSession.fork(session); + const options: ResolutionOptions = { + session: forkedSession, + ...injection.metadata, + }; return function getter() { - return ctx.get(bindingSelector, { - session: forkedSession, - optional: injection.metadata.optional, - }); + return ctx.get(bindingSelector, options); }; } diff --git a/packages/context/src/interception-proxy.ts b/packages/context/src/interception-proxy.ts new file mode 100644 index 000000000000..72dfabf1f53b --- /dev/null +++ b/packages/context/src/interception-proxy.ts @@ -0,0 +1,97 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/context +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {Context} from './context'; +import {InvocationArgs, invokeMethodWithInterceptors} from './interceptor'; +import {ValueOrPromise} from './value-promise'; + +/** + * Create the Promise type for `T`. If `T` extends `Promise`, the type is `T`, + * otherwise the type is `ValueOrPromise`. + */ +export type AsValueOrPromise = T extends Promise + ? T + : ValueOrPromise; + +/** + * The intercepted variant of a function to return `ValueOrPromise`. + * If `T` is not a function, the type is `T`. + */ +export type AsInterceptedFunction = T extends ( + ...args: InvocationArgs +) => // tslint:disable-next-line:no-unused (possible tslint bug to treat `R` as unused) +infer R + ? (...args: InvocationArgs) => AsValueOrPromise + : T; + +/** + * The proxy type for `T`. The return type for any method of `T` with original + * return type `R` becomes `ValueOrPromise` if `R` does not extend `Promise`. + * Property types stay untouched. For example: + * + * ```ts + * class MyController { + * name: string; + * + * greet(name: string): string { + * return `Hello, ${name}`; + * } + * + * async hello(name: string) { + * return `Hello, ${name}`; + * } + * } + * ``` + * + * `AsyncProxy` will be: + * ```ts + * { + * name: string; // the same as MyController + * greet(name: string): ValueOrPromise; // the return type becomes `ValueOrPromise` + * hello(name: string): Promise; // the same as MyController + * } + * ``` + */ +export type AsyncProxy = {[P in keyof T]: AsInterceptedFunction}; + +/** + * A proxy handler that applies interceptors + * + * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy + */ +export class InterceptionHandler implements ProxyHandler { + constructor(private context = new Context()) {} + + get(target: T, propertyName: PropertyKey, receiver: unknown) { + // tslint:disable-next-line:no-any + const targetObj = target as any; + if (typeof propertyName !== 'string') return targetObj[propertyName]; + const propertyOrMethod = targetObj[propertyName]; + if (typeof propertyOrMethod === 'function') { + return (...args: InvocationArgs) => { + return invokeMethodWithInterceptors( + this.context, + target, + propertyName, + args, + ); + }; + } else { + return propertyOrMethod; + } + } +} + +/** + * Create a proxy that applies interceptors for method invocations + * @param target Target class or object + * @param context Context object + */ +export function createProxyWithInterceptors( + target: T, + context?: Context, +): AsyncProxy { + return new Proxy(target, new InterceptionHandler(context)) as AsyncProxy; +} diff --git a/packages/context/src/interceptor.ts b/packages/context/src/interceptor.ts new file mode 100644 index 000000000000..9e242ae58c48 --- /dev/null +++ b/packages/context/src/interceptor.ts @@ -0,0 +1,432 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/context +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + ClassDecoratorFactory, + DecoratorFactory, + MetadataAccessor, + MetadataInspector, + MetadataMap, + MethodDecoratorFactory, +} from '@loopback/metadata'; +import * as assert from 'assert'; +import * as debugFactory from 'debug'; +import {Binding, BindingTemplate} from './binding'; +import {filterByTag} from './binding-filter'; +import {BindingAddress} from './binding-key'; +import {Context} from './context'; +import {ContextBindings, ContextTags} from './keys'; +import {transformValueOrPromise, ValueOrPromise} from './value-promise'; +const debug = debugFactory('loopback:context:interceptor'); +const getTargetName = DecoratorFactory.getTargetName; + +/** + * Array of arguments for a method invocation + */ +// tslint:disable-next-line:no-any +export type InvocationArgs = any[]; + +/** + * Return value for a method invocation + */ +// tslint:disable-next-line:no-any +export type InvocationResult = any; + +/** + * A type for class or its prototype + */ +// tslint:disable-next-line:no-any +type ClassOrPrototype = any; + +/** + * InvocationContext represents the context to invoke interceptors for a method. + * The context can be used to access metadata about the invocation as well as + * other dependencies. + */ +export class InvocationContext extends Context { + /** + * Construct a new instance of `InvocationContext` + * @param parent Parent context, such as the RequestContext + * @param target Target class (for static methods) or prototype/object + * (for instance methods) + * @param methodName Method name + * @param args An array of arguments + */ + constructor( + parent: Context, + public readonly target: object, + public readonly methodName: string, + public readonly args: InvocationArgs, + ) { + super(parent); + } + + /** + * Discover all binding keys for global interceptors (tagged by + * ContextTags.GLOBAL_INTERCEPTOR) + */ + getGlobalInterceptorBindingKeys(): string[] { + const bindings: Readonly>[] = this.find( + filterByTag(ContextTags.GLOBAL_INTERCEPTOR), + ); + this.sortGlobalInterceptorBindings(bindings); + return bindings.map(b => b.key); + } + + /** + * Sort global interceptor bindings by `globalInterceptorGroup` tags + * @param bindings An array of global interceptor bindings + */ + private sortGlobalInterceptorBindings( + bindings: Readonly>[], + ) { + // Get predefined ordered groups for global interceptors + const orderedGroups = + this.getSync(ContextBindings.GLOBAL_INTERCEPTOR_ORDERED_GROUPS, { + optional: true, + }) || []; + bindings.sort((a, b) => { + const g1: string = a.tagMap[ContextTags.GLOBAL_INTERCEPTOR_GROUP] || ''; + const g2: string = b.tagMap[ContextTags.GLOBAL_INTERCEPTOR_GROUP] || ''; + const i1 = orderedGroups.indexOf(g1); + const i2 = orderedGroups.indexOf(g2); + if (i1 !== -1 || i2 !== -1) { + // Honor the group order + return i1 - i2; + } else { + // Neither group is in the pre-defined order + // Use alphabetical order instead so that `1-group` is invoked before + // `2-group` + return g1 < g2 ? -1 : g1 > g2 ? 1 : 0; + } + }); + } + + /** + * Load all interceptors for the given invocation context. It adds + * interceptors from possibly three sources: + * 1. method level `@intercept` + * 2. class level `@intercept` + * 3. global interceptors discovered in the context + */ + loadInterceptors() { + let interceptors = + MetadataInspector.getMethodMetadata( + INTERCEPT_METHOD_KEY, + this.target, + this.methodName, + ) || []; + const targetClass = + typeof this.target === 'function' ? this.target : this.target.constructor; + const classInterceptors = + MetadataInspector.getClassMetadata(INTERCEPT_CLASS_KEY, targetClass) || + []; + // Inserting class level interceptors before method level ones + interceptors = mergeInterceptors(classInterceptors, interceptors); + const globalInterceptors = this.getGlobalInterceptorBindingKeys(); + // Inserting global interceptors + interceptors = mergeInterceptors(globalInterceptors, interceptors); + return interceptors; + } + + /** + * Assert the method exists on the target. An error will be thrown if otherwise. + * @param context Invocation context + */ + assertMethodExists() { + const targetWithMethods = this.target as Record; + if (typeof targetWithMethods[this.methodName] !== 'function') { + const targetName = getTargetName(this.target, this.methodName); + assert(false, `Method ${targetName} not found`); + } + return targetWithMethods; + } + + /** + * Invoke the target method with the given context + * @param context Invocation context + */ + invokeTargetMethod() { + const targetWithMethods = this.assertMethodExists(); + /* istanbul ignore if */ + if (debug.enabled) { + debug( + 'Invoking method %s', + getTargetName(this.target, this.methodName), + this.args, + ); + } + // Invoke the target method + const result = targetWithMethods[this.methodName](...this.args); + /* istanbul ignore if */ + if (debug.enabled) { + debug( + 'Method invoked: %s', + getTargetName(this.target, this.methodName), + result, + ); + } + return result; + } +} + +/** + * The `BindingTemplate` function to configure a binding as a global interceptor + * by tagging it with `ContextTags.INTERCEPTOR` + * @param binding Binding object + */ +export function asGlobalInterceptor( + group?: string, +): BindingTemplate { + return binding => { + binding.tag(ContextTags.GLOBAL_INTERCEPTOR); + if (group) binding.tag({[ContextTags.GLOBAL_INTERCEPTOR_GROUP]: group}); + }; +} + +/** + * Interceptor function to intercept method invocations + */ +export interface Interceptor { + /** + * @param context Invocation context + * @param next A function to invoke next interceptor or the target method + * @returns A result as value or promise + */ + ( + context: InvocationContext, + next: () => ValueOrPromise, + ): ValueOrPromise; +} + +/** + * Interceptor function or binding key that can be used as parameters for + * `@intercept()` + */ +export type InterceptorOrKey = BindingAddress | Interceptor; + +/** + * Metadata key for method-level interceptors + */ +export const INTERCEPT_METHOD_KEY = MetadataAccessor.create< + InterceptorOrKey[], + MethodDecorator +>('intercept:method'); + +/** + * Adding interceptors from the spec to the front of existing ones. Duplicate + * entries are eliminated from the spec side. + * + * For example: + * + * - [log] + [cache, log] => [cache, log] + * - [log] + [log, cache] => [log, cache] + * - [] + [cache, log] => [cache, log] + * - [cache, log] + [] => [cache, log] + * - [log] + [cache] => [log, cache] + * + * @param interceptorsFromSpec Interceptors from `@intercept` + * @param existingInterceptors Interceptors already applied for the method + */ +export function mergeInterceptors( + interceptorsFromSpec: InterceptorOrKey[], + existingInterceptors: InterceptorOrKey[], +) { + const interceptorsToApply = new Set(interceptorsFromSpec); + const appliedInterceptors = new Set(existingInterceptors); + // Remove interceptors that already exist + for (const i of interceptorsToApply) { + if (appliedInterceptors.has(i)) { + interceptorsToApply.delete(i); + } + } + // Add existing interceptors after ones from the spec + for (const i of appliedInterceptors) { + interceptorsToApply.add(i); + } + return Array.from(interceptorsToApply); +} + +/** + * Metadata key for method-level interceptors + */ +export const INTERCEPT_CLASS_KEY = MetadataAccessor.create< + InterceptorOrKey[], + ClassDecorator +>('intercept:class'); + +/** + * A factory to define `@intercept` for classes. It allows `@intercept` to be + * used multiple times on the same class. + */ +class InterceptClassDecoratorFactory extends ClassDecoratorFactory< + InterceptorOrKey[] +> { + protected mergeWithOwn(ownMetadata: InterceptorOrKey[], target: Object) { + ownMetadata = ownMetadata || []; + return mergeInterceptors(this.spec, ownMetadata); + } +} + +/** + * A factory to define `@intercept` for methods. It allows `@intercept` to be + * used multiple times on the same method. + */ +class InterceptMethodDecoratorFactory extends MethodDecoratorFactory< + InterceptorOrKey[] +> { + protected mergeWithOwn( + ownMetadata: MetadataMap, + target: Object, + methodName: string, + methodDescriptor: TypedPropertyDescriptor, + ) { + ownMetadata = ownMetadata || {}; + const interceptors = ownMetadata[methodName] || []; + + // Adding interceptors to the list + ownMetadata[methodName] = mergeInterceptors(this.spec, interceptors); + + return ownMetadata; + } +} + +/** + * Decorator function `@intercept` for classes/methods to apply interceptors. It + * can be applied on a class and its public methods. Multiple occurrences of + * `@intercept` are allowed on the same target class or method. The decorator + * takes a list of `interceptor` functions or binding keys. For example: + * + * ```ts + * @intercept(log, metrics) + * class MyController { + * @intercept('caching-interceptor') + * @intercept('name-validation-interceptor') + * greet(name: string) { + * return `Hello, ${name}`; + * } + * } + * ``` + * + * @param interceptorOrKeys One or more interceptors or binding keys that are + * resolved to be interceptors + */ +export function intercept(...interceptorOrKeys: InterceptorOrKey[]) { + return function interceptDecoratorForClassOrMethod( + target: ClassOrPrototype, + method?: string, + // Use `any` to for `TypedPropertyDescriptor` + // See https://github.com/strongloop/loopback-next/pull/2704 + // tslint:disable-next-line:no-any + methodDescriptor?: TypedPropertyDescriptor, + ) { + if (method && methodDescriptor) { + // Method + return InterceptMethodDecoratorFactory.createDecorator( + INTERCEPT_METHOD_KEY, + interceptorOrKeys, + )(target, method, methodDescriptor!); + } + if (typeof target === 'function' && !method && !methodDescriptor) { + // Class + return InterceptClassDecoratorFactory.createDecorator( + INTERCEPT_CLASS_KEY, + interceptorOrKeys, + )(target); + } + // Not on a class or method + throw new Error( + '@intercept cannot be used on a property: ' + + DecoratorFactory.getTargetName(target, method, methodDescriptor), + ); + }; +} + +/** + * Invoke a method with the given context + * @param context Context object + * @param target Target class (for static methods) or object (for instance methods) + * @param methodName Method name + * @param args An array of argument values + */ +export function invokeMethodWithInterceptors( + context: Context, + target: object, + methodName: string, + args: InvocationArgs, +): ValueOrPromise { + const invocationCtx = new InvocationContext( + context, + target, + methodName, + args, + ); + + invocationCtx.assertMethodExists(); + try { + const interceptors = invocationCtx.loadInterceptors(); + return invokeInterceptors(invocationCtx, interceptors); + } finally { + invocationCtx.close(); + } +} + +/** + * Invoke the interceptor chain + * @param context Context object + * @param interceptors An array of interceptors + */ +function invokeInterceptors( + context: InvocationContext, + interceptors: InterceptorOrKey[], +): ValueOrPromise { + let index = 0; + return next(); + + /** + * Invoke downstream interceptors or the target method + */ + function next(): ValueOrPromise { + // No more interceptors + if (index === interceptors.length) { + return context.invokeTargetMethod(); + } + return invokeNextInterceptor(); + } + + /** + * Invoke downstream interceptors + */ + function invokeNextInterceptor(): ValueOrPromise { + const interceptor = interceptors[index++]; + const interceptorFn = loadInterceptor(interceptor); + return transformValueOrPromise(interceptorFn, fn => { + /* istanbul ignore if */ + if (debug.enabled) { + debug( + 'Invoking interceptor %d (%s) on %s', + index - 1, + fn.name, + getTargetName(context.target, context.methodName), + context.args, + ); + } + return fn(context, next); + }); + } + + /** + * Return the interceptor function or resolve the interceptor function as a + * binding from the context + * @param interceptor Interceptor function or binding key + */ + function loadInterceptor(interceptor: InterceptorOrKey) { + if (typeof interceptor === 'function') return interceptor; + debug('Resolving interceptor binding %s', interceptor); + return context.getValueOrPromise(interceptor) as ValueOrPromise< + Interceptor + >; + } +} diff --git a/packages/context/src/keys.ts b/packages/context/src/keys.ts index 2ab2e3a6fc25..b8c653a0399c 100644 --- a/packages/context/src/keys.ts +++ b/packages/context/src/keys.ts @@ -3,6 +3,11 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT +import {BindingKey} from './binding-key'; + +/** + * Namespace for context tags + */ export namespace ContextTags { export const CLASS = 'class'; export const PROVIDER = 'provider'; @@ -23,4 +28,25 @@ export namespace ContextTags { * Binding key for the artifact */ export const KEY = 'key'; + + /** + * Binding tag for global interceptors + */ + export const GLOBAL_INTERCEPTOR = 'globalInterceptor'; + /** + * Binding tag for group name of global interceptors + */ + export const GLOBAL_INTERCEPTOR_GROUP = 'globalInterceptorGroup'; +} + +/** + * Namespace for context bindings + */ +export namespace ContextBindings { + /** + * Binding key for ordered groups of global interceptors + */ + export const GLOBAL_INTERCEPTOR_ORDERED_GROUPS = BindingKey.create( + 'globalInterceptor.orderedGroups', + ); } diff --git a/packages/context/src/resolution-session.ts b/packages/context/src/resolution-session.ts index adfeeab6d919..5d591684c6d0 100644 --- a/packages/context/src/resolution-session.ts +++ b/packages/context/src/resolution-session.ts @@ -338,6 +338,13 @@ export interface ResolutionOptions { * will return `undefined` instead of throwing an error. */ optional?: boolean; + + /** + * A boolean flag to control if a proxy should be created to apply + * interceptors for the resolved value. It's only honored for bindings backed + * by a class. + */ + asProxyWithInterceptors?: boolean; } /** diff --git a/packages/context/src/resolver.ts b/packages/context/src/resolver.ts index c4430f41e6a8..fc1c620da3d9 100644 --- a/packages/context/src/resolver.ts +++ b/packages/context/src/resolver.ts @@ -15,7 +15,8 @@ import { describeInjectedProperties, Injection, } from './inject'; -import {ResolutionSession} from './resolution-session'; +import {invokeMethodWithInterceptors} from './interceptor'; +import {ResolutionOptions, ResolutionSession} from './resolution-session'; import { BoundValue, Constructor, @@ -148,12 +149,11 @@ function resolve( 'The binding selector must be an address (string or BindingKey)', ); const key = injection.bindingSelector as BindingAddress; - return ctx.getValueOrPromise(key, { + const options: ResolutionOptions = { session: s, - // If the `optional` flag is set for the injection, the resolution - // will return `undefined` instead of throwing an error - optional: injection.metadata.optional, - }); + ...injection.metadata, + }; + return ctx.getValueOrPromise(key, options); } }, injection, @@ -288,7 +288,7 @@ export function invokeMethod( if (debug.enabled) { debug('Injected arguments for %s:', methodName, args); } - return targetWithMethods[method](...args); + return invokeMethodWithInterceptors(ctx, targetWithMethods, method, args); }); } diff --git a/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.acceptance.ts b/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.acceptance.ts new file mode 100644 index 000000000000..9477ed0755aa --- /dev/null +++ b/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.acceptance.ts @@ -0,0 +1,98 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/rest +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {intercept} from '@loopback/context'; +import {get, param} from '@loopback/openapi-v3'; +import { + Client, + createRestAppClient, + expect, + givenHttpServerConfig, +} from '@loopback/testlab'; +import {RestApplication} from '../../..'; +import { + cache, + CachingInterceptorProvider, + clearCache, + status, +} from './caching-interceptor'; + +describe('caching interceptor', () => { + let client: Client; + let app: RestApplication; + + beforeEach(clearCache); + + context('as a binding key', () => { + class ControllerWithInterceptorBinding { + @intercept('caching-interceptor') + @get('/toUpperCase/{text}') + toUpperCase(@param.path.string('text') text: string) { + return text.toUpperCase(); + } + } + + before(givenAClient); + after(async () => { + await app.stop(); + }); + + it('invokes the controller method if not cached', async () => { + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + expect(status.returnFromCache).to.be.false(); + }); + + it('returns from cache without invoking the controller method', async () => { + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + for (let i = 0; i <= 5; i++) { + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + expect(status.returnFromCache).to.be.true(); + } + }); + + async function givenAClient() { + app = new RestApplication({rest: givenHttpServerConfig()}); + app.bind('caching-interceptor').toProvider(CachingInterceptorProvider); + app.controller(ControllerWithInterceptorBinding); + await app.start(); + client = createRestAppClient(app); + } + }); + + context('as an interceptor function', () => { + class ControllerWithInterceptorFunction { + @intercept(cache) + @get('/toLowerCase/{text}') + toLowerCase(@param.path.string('text') text: string) { + return text.toLowerCase(); + } + } + + before(givenAClient); + after(async () => { + await app.stop(); + }); + + it('invokes the controller method if not cached', async () => { + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + expect(status.returnFromCache).to.be.false(); + }); + + it('returns from cache without invoking the controller method', async () => { + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + for (let i = 0; i <= 5; i++) { + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + expect(status.returnFromCache).to.be.true(); + } + }); + + async function givenAClient() { + app = new RestApplication({rest: givenHttpServerConfig()}); + app.controller(ControllerWithInterceptorFunction); + await app.start(); + client = createRestAppClient(app); + } + }); +}); diff --git a/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.ts b/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.ts new file mode 100644 index 000000000000..641df275e98c --- /dev/null +++ b/packages/rest/src/__tests__/acceptance/caching-interceptor/caching-interceptor.ts @@ -0,0 +1,80 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/rest +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + inject, + Interceptor, + InvocationContext, + Provider, + ValueOrPromise, +} from '@loopback/context'; +import {Request, RestBindings} from '../../..'; + +/** + * Execution status + */ +export const status = { + returnFromCache: false, +}; + +/** + * In-memory cache + */ +export const cachedResults = new Map(); + +/** + * Reset the cache + */ +export function clearCache() { + status.returnFromCache = false; + cachedResults.clear(); +} + +/** + * A provider class for caching interceptor that leverages dependency + * injection + */ +export class CachingInterceptorProvider implements Provider { + constructor( + @inject(RestBindings.Http.REQUEST, {optional: true}) + private request: Request | undefined, + ) {} + value() { + return ( + invocationCtx: InvocationContext, + next: () => ValueOrPromise, + ) => cache(invocationCtx, next); + } +} + +/** + * An interceptor function that caches results. It uses `invocationContext` + * to locate the http request + * + * @param invocationCtx + * @param next + */ +export async function cache( + invocationCtx: InvocationContext, + next: () => ValueOrPromise, +) { + status.returnFromCache = false; + const req = await invocationCtx.get(RestBindings.Http.REQUEST, { + optional: true, + }); + if (!req || req.method.toLowerCase() !== 'get') { + // The method is not invoked by an http request, no caching + return await next(); + } + const url = req.url; + const cachedValue = cachedResults.get(url); + if (cachedValue) { + status.returnFromCache = true; + return cachedValue as T; + } + const result = await next(); + cachedResults.set(url, result); + return result; +} diff --git a/packages/rest/src/__tests__/acceptance/caching-interceptor/global-caching-interceptor.acceptance.ts b/packages/rest/src/__tests__/acceptance/caching-interceptor/global-caching-interceptor.acceptance.ts new file mode 100644 index 000000000000..23fca210ee61 --- /dev/null +++ b/packages/rest/src/__tests__/acceptance/caching-interceptor/global-caching-interceptor.acceptance.ts @@ -0,0 +1,122 @@ +// Copyright IBM Corp. 2019. All Rights Reserved. +// Node module: @loopback/rest +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import {asGlobalInterceptor} from '@loopback/context'; +import {anOperationSpec} from '@loopback/openapi-spec-builder'; +import {get, param} from '@loopback/openapi-v3'; +import { + Client, + createRestAppClient, + expect, + givenHttpServerConfig, +} from '@loopback/testlab'; +import {RestApplication} from '../../..'; +import { + cachedResults, + CachingInterceptorProvider, + clearCache, + status, +} from './caching-interceptor'; + +describe('global caching interceptor', () => { + let client: Client; + let app: RestApplication; + + before(givenAClient); + after(async () => { + await app.stop(); + }); + + context('caching invocation for controller methods', () => { + it('invokes the controller method if not cached', async () => { + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + expect(status.returnFromCache).to.be.false(); + }); + + it('returns from cache without invoking the controller method', async () => { + for (let i = 0; i <= 5; i++) { + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + expect(status.returnFromCache).to.be.true(); + } + }); + + it('invokes the controller method after cache is cleared', async () => { + clearCache(); + await client.get('/toUpperCase/Hello').expect(200, 'HELLO'); + expect(status.returnFromCache).to.be.false(); + }); + }); + + context('caching invocation for route handler functions', () => { + it('invokes the handler function if not cached', async () => { + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + expect(status.returnFromCache).to.be.false(); + }); + + it('returns from cache without invoking the handler function', async () => { + for (let i = 0; i <= 5; i++) { + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + expect(status.returnFromCache).to.be.true(); + } + }); + + it('invokes the handler function after cache is cleared', async () => { + cachedResults.clear(); + await client.get('/toLowerCase/Hello').expect(200, 'hello'); + expect(status.returnFromCache).to.be.false(); + }); + }); + + /** + * OpenAPI operation spec for `toLowerCase(text: string)` + */ + const toLowerCaseOperationSpec = anOperationSpec() + .withOperationName('toLowerCase') + .withParameter({ + name: 'text', + in: 'path', + schema: { + type: 'string', + }, + }) + .withStringResponse() + .build(); + + /** + * A plain function to convert `text` to lower case + * @param text + */ + function toLowerCase(text: string) { + return text.toLowerCase(); + } + + async function givenAClient() { + clearCache(); + app = new RestApplication({rest: givenHttpServerConfig()}); + app + .bind('caching-interceptor') + .toProvider(CachingInterceptorProvider) + .apply(asGlobalInterceptor()); + app.controller(StringCaseController); + app.route( + 'get', + '/toLowerCase/{text}', + toLowerCaseOperationSpec, + toLowerCase, + ); + await app.start(); + client = createRestAppClient(app); + } + + /** + * A controller using interceptors for caching + */ + class StringCaseController { + @get('/toUpperCase/{text}') + toUpperCase(@param.path.string('text') text: string) { + return text.toUpperCase(); + } + } +}); diff --git a/packages/rest/src/router/handler-route.ts b/packages/rest/src/router/handler-route.ts index 999f443fd632..5d972fa16823 100644 --- a/packages/rest/src/router/handler-route.ts +++ b/packages/rest/src/router/handler-route.ts @@ -3,7 +3,7 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -import {Context} from '@loopback/context'; +import {Context, invokeMethodWithInterceptors} from '@loopback/context'; import {OperationObject} from '@loopback/openapi-v3-types'; import {OperationArgs, OperationRetval} from '../types'; import {BaseRoute} from './base-route'; @@ -30,6 +30,13 @@ export class Route extends BaseRoute { requestContext: Context, args: OperationArgs, ): Promise { - return await this._handler(...args); + // Use `invokeMethodWithInterceptors` to invoke the handler function so + // that global interceptors are applied + return await invokeMethodWithInterceptors( + requestContext, + this, + '_handler', + args, + ); } }