@fluojs/testing 1.0.0-beta.2 → 1.0.0-beta.4
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.
- package/README.ko.md +68 -17
- package/README.md +66 -15
- package/dist/app.d.ts +2 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +1 -1
- package/dist/babel-decorators-plugin.d.ts +2 -2
- package/dist/babel-decorators-plugin.d.ts.map +1 -1
- package/dist/babel-decorators-plugin.js +26 -12
- package/dist/conformance/fetch-style-websocket-conformance.d.ts +12 -0
- package/dist/conformance/fetch-style-websocket-conformance.d.ts.map +1 -1
- package/dist/conformance/fetch-style-websocket-conformance.js +14 -0
- package/dist/conformance/platform-conformance.d.ts +21 -0
- package/dist/conformance/platform-conformance.d.ts.map +1 -1
- package/dist/conformance/platform-conformance.js +27 -0
- package/dist/mock.d.ts +17 -0
- package/dist/mock.d.ts.map +1 -1
- package/dist/mock.js +19 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +106 -11
- package/dist/portability/http-adapter-portability.d.ts +9 -0
- package/dist/portability/http-adapter-portability.d.ts.map +1 -1
- package/dist/portability/http-adapter-portability.js +135 -79
- package/dist/portability/web-runtime-adapter-portability.d.ts +13 -0
- package/dist/portability/web-runtime-adapter-portability.d.ts.map +1 -1
- package/dist/portability/web-runtime-adapter-portability.js +100 -40
- package/dist/types.d.ts +7 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -9
package/dist/mock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/E,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../src/mock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC/E,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAM,EACvC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,aAAa,CAAC,CAAC,CAAC,CAsBlB;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAkBnG;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,GAAE,OAAO,CAAC,CAAC,CAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAExF"}
|
package/dist/mock.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Defines the mocked methods type.
|
|
5
|
+
*/
|
|
6
|
+
|
|
2
7
|
/**
|
|
3
8
|
* Creates a proxy mock object with optional strict missing-property checks.
|
|
9
|
+
*
|
|
10
|
+
* @param partial The partial.
|
|
11
|
+
* @param options The options.
|
|
12
|
+
* @returns The create mock result.
|
|
4
13
|
*/
|
|
5
14
|
export function createMock(partial = {}, options = {}) {
|
|
6
15
|
const autoMocks = new Map();
|
|
@@ -24,6 +33,9 @@ export function createMock(partial = {}, options = {}) {
|
|
|
24
33
|
|
|
25
34
|
/**
|
|
26
35
|
* Casts a function to a strongly typed Vitest mock.
|
|
36
|
+
*
|
|
37
|
+
* @param fn The fn.
|
|
38
|
+
* @returns The as mock result.
|
|
27
39
|
*/
|
|
28
40
|
export function asMock(fn) {
|
|
29
41
|
return vi.mocked(fn);
|
|
@@ -31,6 +43,9 @@ export function asMock(fn) {
|
|
|
31
43
|
|
|
32
44
|
/**
|
|
33
45
|
* Creates a deep mock by replacing prototype methods with `vi.fn()` spies.
|
|
46
|
+
*
|
|
47
|
+
* @param type The type.
|
|
48
|
+
* @returns The create deep mock result.
|
|
34
49
|
*/
|
|
35
50
|
export function createDeepMock(type) {
|
|
36
51
|
const spies = {};
|
|
@@ -51,6 +66,10 @@ export function createDeepMock(type) {
|
|
|
51
66
|
|
|
52
67
|
/**
|
|
53
68
|
* Creates a `useValue` provider for overriding a token in tests.
|
|
69
|
+
*
|
|
70
|
+
* @param token The token.
|
|
71
|
+
* @param partial The partial.
|
|
72
|
+
* @returns The mock token result.
|
|
54
73
|
*/
|
|
55
74
|
export function mockToken(token, partial = {}) {
|
|
56
75
|
return {
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EAId,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAqC,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMrF,OAAO,KAAK,EAA2B,oBAAoB,EAAE,oBAAoB,EAAoB,MAAM,YAAY,CAAC;AAExH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,QAAQ,EAAE,CAQzE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,CAQ5E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE,CAQzE;AAkkBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,oBAAoB,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,IAAI;;CAEhB,CAAC"}
|
package/dist/module.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getModuleMetadata } from '@fluojs/core
|
|
1
|
+
import { getModuleMetadata } from '@fluojs/core';
|
|
2
2
|
import { isForwardRef, isOptionalToken } from '@fluojs/di';
|
|
3
3
|
import { bootstrapModule, defineModule } from '@fluojs/runtime';
|
|
4
4
|
import { createDispatcher, createHandlerMapping } from '@fluojs/http';
|
|
@@ -97,7 +97,7 @@ function isContainerIntrospection(value) {
|
|
|
97
97
|
const candidate = value;
|
|
98
98
|
const parentValid = candidate.parent === undefined || isContainerIntrospection(candidate.parent);
|
|
99
99
|
const requestScopeValid = candidate.requestScopeEnabled === undefined || typeof candidate.requestScopeEnabled === 'boolean';
|
|
100
|
-
return candidate.registrations instanceof Map && candidate.multiRegistrations instanceof Map && parentValid && requestScopeValid;
|
|
100
|
+
return candidate.registrations instanceof Map && candidate.multiRegistrations instanceof Map && candidate.singletonCache instanceof Map && parentValid && requestScopeValid;
|
|
101
101
|
}
|
|
102
102
|
function toContainerIntrospection(container) {
|
|
103
103
|
if (!isContainerIntrospection(container)) {
|
|
@@ -108,6 +108,9 @@ function toContainerIntrospection(container) {
|
|
|
108
108
|
function isPromiseLike(value) {
|
|
109
109
|
return (typeof value === 'object' || typeof value === 'function') && value !== null && typeof value.then === 'function';
|
|
110
110
|
}
|
|
111
|
+
function rootContainerIntrospection(target) {
|
|
112
|
+
return target.parent ? rootContainerIntrospection(target.parent) : target;
|
|
113
|
+
}
|
|
111
114
|
function collectMultiProviders(target, token) {
|
|
112
115
|
const fromParent = target.parent ? collectMultiProviders(target.parent, token) : [];
|
|
113
116
|
const local = target.multiRegistrations.get(token) ?? [];
|
|
@@ -123,6 +126,70 @@ function lookupProvider(target, token) {
|
|
|
123
126
|
function hasToken(state, token) {
|
|
124
127
|
return lookupProvider(state.introspection, token) !== undefined || collectMultiProviders(state.introspection, token).length > 0;
|
|
125
128
|
}
|
|
129
|
+
function dependencyToken(entry) {
|
|
130
|
+
if (isOptionalToken(entry)) {
|
|
131
|
+
return entry.token;
|
|
132
|
+
}
|
|
133
|
+
if (isForwardRef(entry)) {
|
|
134
|
+
return entry.forwardRef();
|
|
135
|
+
}
|
|
136
|
+
return entry;
|
|
137
|
+
}
|
|
138
|
+
function trackFactoryResolutionKind(provider, factoryResolutionKinds) {
|
|
139
|
+
if (provider.type !== 'factory' || !provider.useFactory) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const originalFactory = provider.useFactory;
|
|
143
|
+
provider.useFactory = (...deps) => {
|
|
144
|
+
const value = originalFactory(...deps);
|
|
145
|
+
factoryResolutionKinds.set(provider, isPromiseLike(value) ? 'async' : 'sync');
|
|
146
|
+
return value;
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function installFactoryResolutionTracking(target, factoryResolutionKinds) {
|
|
150
|
+
if (target.parent) {
|
|
151
|
+
installFactoryResolutionTracking(target.parent, factoryResolutionKinds);
|
|
152
|
+
}
|
|
153
|
+
for (const provider of target.registrations.values()) {
|
|
154
|
+
trackFactoryResolutionKind(provider, factoryResolutionKinds);
|
|
155
|
+
}
|
|
156
|
+
for (const providers of target.multiRegistrations.values()) {
|
|
157
|
+
for (const provider of providers) {
|
|
158
|
+
trackFactoryResolutionKind(provider, factoryResolutionKinds);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function providerGraphIsSyncResolvable(state, token, visited = new Set()) {
|
|
163
|
+
if (visited.has(token)) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
visited.add(token);
|
|
167
|
+
try {
|
|
168
|
+
const provider = lookupProvider(state.introspection, token);
|
|
169
|
+
const multiProviders = collectMultiProviders(state.introspection, token);
|
|
170
|
+
const providers = provider ? [provider, ...multiProviders] : multiProviders;
|
|
171
|
+
return providers.every(candidate => {
|
|
172
|
+
if (candidate.type === 'factory') {
|
|
173
|
+
return state.factoryResolutionKinds.get(candidate) === 'sync';
|
|
174
|
+
}
|
|
175
|
+
if (candidate.type === 'existing') {
|
|
176
|
+
return candidate.useExisting !== undefined && providerGraphIsSyncResolvable(state, candidate.useExisting, visited);
|
|
177
|
+
}
|
|
178
|
+
return candidate.inject.every(entry => {
|
|
179
|
+
if (isOptionalToken(entry) && !hasToken(state, entry.token)) {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
return providerGraphIsSyncResolvable(state, dependencyToken(entry), visited);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
} finally {
|
|
186
|
+
visited.delete(token);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function canPromoteCachedSingleton(state, token) {
|
|
190
|
+
const provider = lookupProvider(state.introspection, token);
|
|
191
|
+
return provider !== undefined && provider.scope !== 'request' && providerGraphIsSyncResolvable(state, token);
|
|
192
|
+
}
|
|
126
193
|
function resolveSyncDependency(entry, state) {
|
|
127
194
|
if (isOptionalToken(entry)) {
|
|
128
195
|
if (!hasToken(state, entry.token)) {
|
|
@@ -181,11 +248,15 @@ function resolveSyncProvider(provider, state) {
|
|
|
181
248
|
if (provider.scope === 'transient') {
|
|
182
249
|
return instantiateSyncProvider(provider, state);
|
|
183
250
|
}
|
|
251
|
+
if (state.syncSingletonValues.has(provider.provide)) {
|
|
252
|
+
return state.syncSingletonValues.get(provider.provide);
|
|
253
|
+
}
|
|
184
254
|
if (state.singletonCache.has(provider.provide)) {
|
|
185
|
-
|
|
255
|
+
throw new Error(`Token ${String(provider.provide)} was already resolved asynchronously. Use resolve() instead of get() for this provider.`);
|
|
186
256
|
}
|
|
187
257
|
const instance = instantiateSyncProvider(provider, state);
|
|
188
|
-
state.
|
|
258
|
+
state.syncSingletonValues.set(provider.provide, instance);
|
|
259
|
+
state.singletonCache.set(provider.provide, Promise.resolve(instance));
|
|
189
260
|
return instance;
|
|
190
261
|
}
|
|
191
262
|
function resolveSyncToken(token, state) {
|
|
@@ -208,12 +279,27 @@ function resolveSyncToken(token, state) {
|
|
|
208
279
|
}
|
|
209
280
|
}
|
|
210
281
|
function createSyncResolver(container) {
|
|
282
|
+
const introspection = toContainerIntrospection(container);
|
|
283
|
+
const factoryResolutionKinds = new WeakMap();
|
|
284
|
+
installFactoryResolutionTracking(introspection, factoryResolutionKinds);
|
|
211
285
|
const state = {
|
|
212
|
-
|
|
286
|
+
factoryResolutionKinds,
|
|
287
|
+
introspection,
|
|
213
288
|
resolutionChain: new Set(),
|
|
214
|
-
singletonCache:
|
|
289
|
+
singletonCache: rootContainerIntrospection(introspection).singletonCache,
|
|
290
|
+
syncSingletonValues: new Map()
|
|
291
|
+
};
|
|
292
|
+
return {
|
|
293
|
+
get: token => resolveSyncToken(token, state),
|
|
294
|
+
syncFromContainer: async () => {
|
|
295
|
+
for (const [token, promise] of state.singletonCache) {
|
|
296
|
+
if (!canPromoteCachedSingleton(state, token)) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
state.syncSingletonValues.set(token, await promise);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
215
302
|
};
|
|
216
|
-
return token => resolveSyncToken(token, state);
|
|
217
303
|
}
|
|
218
304
|
class DefaultOverrideProviderBuilder {
|
|
219
305
|
constructor(builder, token) {
|
|
@@ -327,12 +413,16 @@ class DefaultTestingModuleBuilder {
|
|
|
327
413
|
}
|
|
328
414
|
createTestingModuleRef(bootstrapped) {
|
|
329
415
|
const dispatcher = createTestingDispatcher(bootstrapped);
|
|
330
|
-
const
|
|
416
|
+
const syncResolver = createSyncResolver(bootstrapped.container);
|
|
331
417
|
return {
|
|
332
418
|
...bootstrapped,
|
|
333
419
|
has: token => bootstrapped.container.has(token),
|
|
334
|
-
get: token =>
|
|
335
|
-
resolve: token =>
|
|
420
|
+
get: token => syncResolver.get(token),
|
|
421
|
+
resolve: async token => {
|
|
422
|
+
const value = await bootstrapped.container.resolve(token);
|
|
423
|
+
await syncResolver.syncFromContainer();
|
|
424
|
+
return value;
|
|
425
|
+
},
|
|
336
426
|
resolveAll: async tokens => {
|
|
337
427
|
const results = [];
|
|
338
428
|
const errors = [];
|
|
@@ -353,9 +443,14 @@ class DefaultTestingModuleBuilder {
|
|
|
353
443
|
}) => ` - ${String(token)}: ${error instanceof Error ? error.message : String(error)}`).join('\n');
|
|
354
444
|
throw new Error(`Failed to resolve ${errors.length} of ${tokens.length} tokens:\n${summary}`);
|
|
355
445
|
}
|
|
446
|
+
await syncResolver.syncFromContainer();
|
|
356
447
|
return results;
|
|
357
448
|
},
|
|
358
|
-
dispatch: request =>
|
|
449
|
+
dispatch: async request => {
|
|
450
|
+
const response = await makeRequest(dispatcher, request);
|
|
451
|
+
await syncResolver.syncFromContainer();
|
|
452
|
+
return response;
|
|
453
|
+
}
|
|
359
454
|
};
|
|
360
455
|
}
|
|
361
456
|
_applyModuleReplacements(module) {
|
|
@@ -25,6 +25,14 @@ export interface HttpAdapterPortabilityHarnessOptions<TBootstrapOptions extends
|
|
|
25
25
|
* @returns A promise that resolves to the application instance.
|
|
26
26
|
*/
|
|
27
27
|
bootstrap: (rootModule: ModuleType, options: TBootstrapOptions) => Promise<TApp>;
|
|
28
|
+
/**
|
|
29
|
+
* Optional adapter-specific content type used by the exact-byte raw-body portability assertion.
|
|
30
|
+
*/
|
|
31
|
+
exactRawBodyByteContentType?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Optional adapter-specific preparation used before the exact-byte raw-body portability assertion.
|
|
34
|
+
*/
|
|
35
|
+
prepareExactRawBodyByteTest?: (app: TApp) => void | Promise<void>;
|
|
28
36
|
/**
|
|
29
37
|
* The name of the adapter being tested.
|
|
30
38
|
*/
|
|
@@ -60,6 +68,7 @@ export declare class HttpAdapterPortabilityHarness<TBootstrapOptions extends obj
|
|
|
60
68
|
*/
|
|
61
69
|
assertPreservesMalformedCookieValues(): Promise<void>;
|
|
62
70
|
assertPreservesRawBodyForJsonAndText(): Promise<void>;
|
|
71
|
+
assertPreservesExactRawBodyBytesForByteSensitivePayloads(): Promise<void>;
|
|
63
72
|
assertExcludesRawBodyForMultipart(): Promise<void>;
|
|
64
73
|
assertDefaultsMultipartTotalLimitToMaxBodySize(): Promise<void>;
|
|
65
74
|
assertSupportsSseStreaming(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-adapter-portability.d.ts","sourceRoot":"","sources":["../../src/portability/http-adapter-portability.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http-adapter-portability.d.ts","sourceRoot":"","sources":["../../src/portability/http-adapter-portability.ts"],"names":[],"mappings":"AAIA,OAAO,EAAwC,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3G,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,gBAAgB;QACxB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,UAAU,CAAC;KACtB;CACF;AAED,KAAK,OAAO,GAAG;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,oCAAoC,CACnD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAE9B;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;OAEG;IACH,2BAA2B,CAAC,EAAE,MAAM,CAAC;IAErC;;OAEG;IACH,2BAA2B,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;OAMG;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAiFD;;;;;;;GAOG;AACH,qBAAa,6BAA6B,CACxC,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAOlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC;;;;OAIG;gBAC0B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC;IAEhH;;;OAGG;IACG,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDrD,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IAsErD,wDAAwD,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CzE,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDlD,8CAA8C,IAAI,OAAO,CAAC,IAAI,CAAC;IAsD/D,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDjD;;;OAGG;IACG,mCAAmC,IAAI,OAAO,CAAC,IAAI,CAAC;IA0DpD,wCAAwC,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDzD,4BAA4B,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDjF,8CAA8C,IAAI,OAAO,CAAC,IAAI,CAAC;CA4CtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CACjD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO,EAE9B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,GAClF,6BAA6B,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,CAErE"}
|