@effect-app/infra 2.1.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,206 +0,0 @@
1
- import { Rpc, RpcRouter } from "@effect/rpc";
2
- import { Cause, Chunk, Context, Effect, FiberRef, flow, Layer, Predicate, S, Schema, Scope, Stream, Tracer } from "effect-app";
3
- import { HttpMiddleware, HttpRouter, HttpServerRequest, HttpServerResponse } from "effect-app/http";
4
- import { pretty, typedKeysOf, typedValuesOf } from "effect-app/utils";
5
- import { logError, reportError } from "../errorReporter.js";
6
- import { InfraLogger } from "../logger.js";
7
- import { makeRpc } from "./routing/DynamicMiddleware.js";
8
- const logRequestError = logError("Request");
9
- const reportRequestError = reportError("Request");
10
- /**
11
- * Plain jane JSON version
12
- * @deprecated use HttpRpcRouterNoStream.toHttpApp once support options
13
- */
14
- export const toHttpApp = (self, options) => {
15
- const handler = RpcRouter.toHandler(self, options);
16
- return Effect.withFiberRuntime((fiber) => {
17
- const context = fiber.getFiberRef(FiberRef.currentContext);
18
- const request = Context.unsafeGet(context, HttpServerRequest.HttpServerRequest);
19
- return Effect.flatMap(request.json, (_) => handler(_).pipe(Stream.provideContext(context), Stream.runCollect, Effect.map((_) => Chunk.toReadonlyArray(_)), Effect.andThen((_) => {
20
- let status = 200;
21
- for (const r of _.flat()) {
22
- if (typeof r === "number")
23
- continue;
24
- const results = Array.isArray(r) ? r : [r];
25
- if (results.some((_) => _._tag === "Failure" && _.cause._tag === "Die")) {
26
- status = 500;
27
- break;
28
- }
29
- if (results.some((_) => _._tag === "Failure" && _.cause._tag === "Fail")) {
30
- status = 422; // 418
31
- break;
32
- }
33
- }
34
- return HttpServerResponse.json(_, { status });
35
- }), Effect.orDie, Effect.tapDefect(reportError("RPCHttpApp"))));
36
- });
37
- };
38
- export const RouterSymbol = Symbol();
39
- // export interface RouteMatcher<
40
- // Filtered extends Record<string, any>,
41
- // CTXMap extends Record<string, any>,
42
- // Rsc extends Filtered
43
- // > extends RouteMatcherInt<Filtered, CTXMap, Rsc> {}
44
- export const makeRouter = (middleware, devMode) => {
45
- const rpc = makeRpc(middleware);
46
- function matchFor(rsc) {
47
- const meta = rsc.meta;
48
- const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
49
- if (Predicate.isObject(rsc[cur]) && rsc[cur]["success"]) {
50
- acc[cur] = rsc[cur];
51
- }
52
- return acc;
53
- }, {});
54
- const items = typedKeysOf(filtered).reduce((prev, cur) => {
55
- ;
56
- prev[cur] = Object.assign((fnOrEffect) => {
57
- const stack = new Error().stack?.split("\n").slice(2).join("\n");
58
- return Effect.isEffect(fnOrEffect)
59
- ? class {
60
- static stack = stack;
61
- static _tag = "d";
62
- static handler = () => fnOrEffect;
63
- }
64
- : class {
65
- static stack = stack;
66
- static _tag = "d";
67
- static handler = fnOrEffect;
68
- };
69
- }, {
70
- success: rsc[cur].success,
71
- successRaw: S.encodedSchema(rsc[cur].success),
72
- failure: rsc[cur].failure,
73
- raw: // "Raw" variations are for when you don't want to decode just to encode it again on the response
74
- // e.g for direct projection from DB
75
- // but more importantly, to skip Effectful decoders, like to resolve relationships from the database or remote client.
76
- (fnOrEffect) => {
77
- const stack = new Error().stack?.split("\n").slice(2).join("\n");
78
- return Effect.isEffect(fnOrEffect)
79
- ? class {
80
- static stack = stack;
81
- static _tag = "raw";
82
- static handler = () => fnOrEffect;
83
- }
84
- : class {
85
- static stack = stack;
86
- static _tag = "raw";
87
- static handler = (req, ctx) => fnOrEffect(req, { ...ctx, Response: rsc[cur].success });
88
- };
89
- }
90
- });
91
- return prev;
92
- }, {});
93
- const effect = (layers, make) => {
94
- const r = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)() {
95
- });
96
- const layer = r.use((router) => Effect.gen(function* () {
97
- const controllers = yield* make(items);
98
- // return make.pipe(Effect.map((c) => controllers(c, layers)))
99
- const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
100
- const handler = controllers[cur];
101
- const req = rsc[cur];
102
- acc[cur] = rpc.effect(handler._tag === "raw"
103
- ? class extends req {
104
- static success = S.encodedSchema(req.success);
105
- get [Schema.symbolSerializable]() {
106
- return this.constructor;
107
- }
108
- get [Schema.symbolWithResult]() {
109
- return {
110
- failure: req.failure,
111
- success: S.encodedSchema(req.success)
112
- };
113
- }
114
- }
115
- : req, (req) => Effect
116
- .annotateCurrentSpan("requestInput", Object.entries(req).reduce((prev, [key, value]) => {
117
- prev[key] = key === "password"
118
- ? "<redacted>"
119
- : typeof value === "string" || typeof value === "number" || typeof value === "boolean"
120
- ? typeof value === "string" && value.length > 256
121
- ? (value.substring(0, 253) + "...")
122
- : value
123
- : Array.isArray(value)
124
- ? `Array[${value.length}]`
125
- : value === null || value === undefined
126
- ? `${value}`
127
- : typeof value === "object" && value
128
- ? `Object[${Object.keys(value).length}]`
129
- : typeof value;
130
- return prev;
131
- }, {}))
132
- .pipe(
133
- // can't use andThen due to some being a function and effect
134
- Effect.zipRight(handler.handler(req)), Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void), Effect.tapDefect((cause) => Effect
135
- .all([
136
- reportRequestError(cause, {
137
- action: `${meta.moduleName}.${req._tag}`
138
- }),
139
- Rpc.currentHeaders.pipe(Effect.andThen((headers) => {
140
- return InfraLogger
141
- .logError("Finished request", cause)
142
- .pipe(Effect.annotateLogs({
143
- action: `${meta.moduleName}.${req._tag}`,
144
- req: pretty(req),
145
- headers: pretty(headers)
146
- // resHeaders: pretty(
147
- // Object
148
- // .entries(headers)
149
- // .reduce((prev, [key, value]) => {
150
- // prev[key] = value && typeof value === "string" ? snipString(value) : value
151
- // return prev
152
- // }, {} as Record<string, any>)
153
- // )
154
- }));
155
- }))
156
- ])), devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")), Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
157
- captureStackTrace: () => handler.stack
158
- })), meta.moduleName); // TODO
159
- return acc;
160
- }, {});
161
- const rpcRouter = RpcRouter.make(...Object.values(mapped));
162
- const httpApp = toHttpApp(rpcRouter, {
163
- spanPrefix: rsc
164
- .meta
165
- .moduleName + "."
166
- });
167
- const services = (yield* Effect.context()).pipe(Context.omit(Scope.Scope), Context.omit(Tracer.ParentSpan));
168
- yield* router
169
- .all("/", (httpApp
170
- .pipe(HttpMiddleware.make(Effect.provide(services)))),
171
- // TODO: not queries.
172
- { uninterruptible: true });
173
- }));
174
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
175
- const routes = layer.pipe(Layer.provideMerge(r.Live), layers ? Layer.provide(layers) : (_) => _);
176
- // Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
177
- return {
178
- moduleName: meta.moduleName,
179
- Router: r,
180
- routes
181
- };
182
- };
183
- return effect;
184
- }
185
- function matchAll(handlers, requestLayer) {
186
- const routers = typedValuesOf(handlers);
187
- const rootRouter = class extends HttpRouter.Tag("RootRouter")() {
188
- };
189
- const r = rootRouter
190
- .use((router) => Effect.gen(function* () {
191
- for (const route of routers) {
192
- yield* router.mount(("/rpc/" + route.moduleName), yield* route
193
- .Router
194
- .router
195
- .pipe(Effect.map(HttpRouter.use(flow(Effect.provide(requestLayer))))));
196
- }
197
- }))
198
- .pipe(Layer.provide(routers.map((r) => r.routes).flat()));
199
- return {
200
- layer: r,
201
- Router: rootRouter
202
- };
203
- }
204
- return { matchAll, matchFor };
205
- };
206
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGluZzMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3JvdXRpbmczLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTVDLE9BQU8sRUFDTCxLQUFLLEVBQ0wsS0FBSyxFQUNMLE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxFQUNSLElBQUksRUFDSixLQUFLLEVBQ0wsU0FBUyxFQUNULENBQUMsRUFDRCxNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEVBQ1AsTUFBTSxZQUFZLENBQUE7QUFHbkIsT0FBTyxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNuRyxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUNyRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFBO0FBQzNELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFFMUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdDQUFnQyxDQUFBO0FBRXhELE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUMzQyxNQUFNLGtCQUFrQixHQUFHLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQWVqRDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsQ0FBMEMsSUFBTyxFQUFFLE9BRTNFLEVBR0MsRUFBRTtJQUNGLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBQ2xELE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7UUFDdkMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDMUQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQTtRQUMvRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQ25CLE9BQU8sQ0FBQyxJQUFJLEVBQ1osQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNKLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ2IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFDOUIsTUFBTSxDQUFDLFVBQVUsRUFDakIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUMzQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDbkIsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFBO1lBQ2hCLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7Z0JBQ3pCLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUTtvQkFBRSxTQUFRO2dCQUNuQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQzFDLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQStCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3RHLE1BQU0sR0FBRyxHQUFHLENBQUE7b0JBQ1osTUFBSztnQkFDUCxDQUFDO2dCQUNELElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQStCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxFQUFFLENBQUM7b0JBQ3ZHLE1BQU0sR0FBRyxHQUFHLENBQUEsQ0FBQyxNQUFNO29CQUNuQixNQUFLO2dCQUNQLENBQUM7WUFDSCxDQUFDO1lBQ0QsT0FBTyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtRQUMvQyxDQUFDLENBQUMsRUFDRixNQUFNLENBQUMsS0FBSyxFQUNaLE1BQU0sQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQzVDLENBQ0osQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFBO0FBZ0VELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxNQUFNLEVBQUUsQ0FBQTtBQXFFcEMsaUNBQWlDO0FBQ2pDLDBDQUEwQztBQUMxQyx3Q0FBd0M7QUFDeEMseUJBQXlCO0FBQ3pCLHNEQUFzRDtBQUV0RCxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FDeEIsVUFBK0MsRUFDL0MsT0FBZ0IsRUFDaEIsRUFBRTtJQUNGLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUMvQixTQUFTLFFBQVEsQ0FJZixHQUErQztRQUUvQyxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFBO1FBRXJCLE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDcEQsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUN4RCxHQUFHLENBQUMsR0FBcUIsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUN2QyxDQUFDO1lBQ0QsT0FBTyxHQUFHLENBQUE7UUFDWixDQUFDLEVBQUUsRUFBYyxDQUFDLENBQUE7UUFFbEIsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FDeEMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDWixDQUFDO1lBQUMsSUFBWSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFlLEVBQUUsRUFBRTtnQkFDdEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQ2hFLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7b0JBQ2hDLENBQUMsQ0FBQzt3QkFDQSxNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTt3QkFDcEIsTUFBTSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUE7d0JBQ2pCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFBO3FCQUNsQztvQkFDRCxDQUFDLENBQUM7d0JBQ0EsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7d0JBQ3BCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFBO3dCQUNqQixNQUFNLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQTtxQkFDNUIsQ0FBQTtZQUNMLENBQUMsRUFBRTtnQkFDRCxPQUFPLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU87Z0JBQ3pCLFVBQVUsRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7Z0JBQzdDLE9BQU8sRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTztnQkFDekIsR0FBRyxFQUFFLGlHQUFpRztnQkFDcEcsb0NBQW9DO2dCQUNwQyxzSEFBc0g7Z0JBQ3RILENBQUMsVUFBZSxFQUFFLEVBQUU7b0JBQ2xCLE1BQU0sS0FBSyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO29CQUNoRSxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO3dCQUNoQyxDQUFDLENBQUM7NEJBQ0EsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7NEJBQ3BCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFBOzRCQUNuQixNQUFNLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQTt5QkFDbEM7d0JBQ0QsQ0FBQyxDQUFDOzRCQUNBLE1BQU0sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBOzRCQUNwQixNQUFNLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQTs0QkFDbkIsTUFBTSxDQUFDLE9BQU8sR0FBRyxDQUFDLEdBQVEsRUFBRSxHQUFRLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7eUJBQ2pHLENBQUE7Z0JBQ0wsQ0FBQzthQUNKLENBQUMsQ0FBQTtZQUNGLE9BQU8sSUFBSSxDQUFBO1FBQ2IsQ0FBQyxFQUNELEVBQStCLENBQ2hDLENBQUE7UUFJRCxNQUFNLE1BQU0sR0FBRyxDQVNiLE1BQWUsRUFDZixJQUF5RCxFQUN6RCxFQUFFO1lBRUYsTUFBTSxDQUFDLEdBVUgsQ0FBQyxNQUFNLE1BQU8sU0FBUSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsUUFBUSxDQUFDLEVBQVU7YUFBRyxDQUFRLENBQUE7WUFFekYsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQzdCLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO2dCQUNsQixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7Z0JBQ3RDLDhEQUE4RDtnQkFDOUQsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtvQkFDdkQsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLEdBQStCLENBQUMsQ0FBQTtvQkFDNUQsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO29CQUVwQixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FDbkIsT0FBTyxDQUFDLElBQUksS0FBSyxLQUFLO3dCQUNwQixDQUFDLENBQUMsS0FBTSxTQUFTLEdBQVc7NEJBQzFCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7NEJBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUM7Z0NBQzdCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQTs0QkFDekIsQ0FBQzs0QkFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO2dDQUMzQixPQUFPO29DQUNMLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztvQ0FDcEIsT0FBTyxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztpQ0FDdEMsQ0FBQTs0QkFDSCxDQUFDO3lCQUNLO3dCQUNSLENBQUMsQ0FBQyxHQUFHLEVBQ1AsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUNOLE1BQU07eUJBQ0gsbUJBQW1CLENBQ2xCLGNBQWMsRUFDZCxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQW9CLEVBQUUsRUFBRTt3QkFDbkUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsS0FBSyxVQUFVOzRCQUM1QixDQUFDLENBQUMsWUFBWTs0QkFDZCxDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO2dDQUN0RixDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRztvQ0FDL0MsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsS0FBSyxDQUFDO29DQUNuQyxDQUFDLENBQUMsS0FBSztnQ0FDVCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7b0NBQ3RCLENBQUMsQ0FBQyxTQUFTLEtBQUssQ0FBQyxNQUFNLEdBQUc7b0NBQzFCLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTO3dDQUN2QyxDQUFDLENBQUMsR0FBRyxLQUFLLEVBQUU7d0NBQ1osQ0FBQyxDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLOzRDQUNwQyxDQUFDLENBQUMsVUFBVSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRzs0Q0FDeEMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxDQUFBO3dCQUNoQixPQUFPLElBQUksQ0FBQTtvQkFDYixDQUFDLEVBQUUsRUFBK0MsQ0FBQyxDQUNwRDt5QkFDQSxJQUFJO29CQUNILDREQUE0RDtvQkFDNUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQVUsQ0FBUSxDQUFDLEVBQ25ELE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUM5RixNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDekIsTUFBTTt5QkFDSCxHQUFHLENBQUM7d0JBQ0gsa0JBQWtCLENBQUMsS0FBSyxFQUFFOzRCQUN4QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEVBQUU7eUJBQ3pDLENBQUM7d0JBQ0YsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFOzRCQUNqRCxPQUFPLFdBQVc7aUNBQ2YsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQztpQ0FDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7Z0NBQ3hCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtnQ0FDeEMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUM7Z0NBQ2hCLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDO2dDQUN4QixzQkFBc0I7Z0NBQ3RCLFdBQVc7Z0NBQ1gsd0JBQXdCO2dDQUN4Qix3Q0FBd0M7Z0NBQ3hDLG1GQUFtRjtnQ0FDbkYsb0JBQW9CO2dDQUNwQixvQ0FBb0M7Z0NBQ3BDLElBQUk7NkJBQ0wsQ0FBQyxDQUFDLENBQUE7d0JBQ1AsQ0FBQyxDQUFDLENBQUM7cUJBQ0osQ0FBQyxDQUNMLEVBQ0QsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxFQUNyRixNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFO3dCQUM3RCxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSztxQkFDdkMsQ0FBQyxDQUNILEVBQ0wsSUFBSSxDQUFDLFVBQVUsQ0FDaEIsQ0FBQSxDQUFDLE9BQU87b0JBQ1QsT0FBTyxHQUFHLENBQUE7Z0JBQ1osQ0FBQyxFQUFFLEVBQVMsQ0FLWCxDQUFBO2dCQUVELE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBUSxDQUcvRCxDQUFBO2dCQUNELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxTQUFTLEVBQUU7b0JBQ25DLFVBQVUsRUFBRSxHQUFHO3lCQUNaLElBQUk7eUJBQ0osVUFBVSxHQUFHLEdBQUc7aUJBQ3BCLENBQUMsQ0FBQTtnQkFDRixNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQVMsQ0FBQyxDQUFDLElBQUksQ0FDcEQsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBYyxDQUFDLEVBQ2xDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQW1CLENBQUMsQ0FDekMsQ0FBQTtnQkFDRCxLQUFLLENBQUMsQ0FBQyxNQUFNO3FCQUNWLEdBQUcsQ0FDRixHQUFHLEVBQ0gsQ0FBQyxPQUFPO3FCQUNMLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFRO2dCQUM5RCxxQkFBcUI7Z0JBQ3JCLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxDQUMxQixDQUFBO1lBQ0wsQ0FBQyxDQUFDLENBQ0gsQ0FBQTtZQUVELDRFQUE0RTtZQUM1RSxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUN2QixLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFDMUIsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQU1qRCxDQUFBO1lBRUQsMEdBQTBHO1lBRTFHLE9BQU87Z0JBQ0wsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO2dCQUMzQixNQUFNLEVBQUUsQ0FBQztnQkFDVCxNQUFNO2FBQ1AsQ0FBQTtRQUNILENBQUMsQ0FBQTtRQUVELE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQVlELFNBQVMsUUFBUSxDQUNmLFFBQVcsRUFDWCxZQUFrQztRQUVsQyxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFdkMsTUFBTSxVQUFVLEdBQUcsS0FBTSxTQUFRLFVBQVUsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBSTFEO1NBQUcsQ0FBQTtRQUVOLE1BQU0sQ0FBQyxHQUFHLFVBQVU7YUFDakIsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDZCxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztZQUNsQixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUM1QixLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNqQixDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFRLEVBQ25DLEtBQUssQ0FBQyxDQUFDLEtBQUs7cUJBQ1QsTUFBTTtxQkFDTixNQUFNO3FCQUNOLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQVEsQ0FDL0UsQ0FBQTtZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FDSDthQUNBLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQStDLENBQUMsQ0FBQyxDQUFBO1FBRXhHLE9BQU87WUFDTCxLQUFLLEVBQUUsQ0FJTjtZQUNELE1BQU0sRUFBRSxVQUtQO1NBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFBO0FBQy9CLENBQUMsQ0FBQSJ9