@fluojs/graphql 1.0.3 → 1.1.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,6 +1,7 @@
1
1
  import { DtoValidationError } from '@fluojs/validation';
2
2
  import { createGraphqlInput, resolveArgType, resolveOutputType } from '../pipeline/input-pipeline.js';
3
3
  import { GRAPHQL_OPERATION_CONTAINER, isGraphqlListTypeRef } from '../types.js';
4
+ import { ObjectFieldResolverRegistry } from './object-field-resolvers.js';
4
5
  function isAsyncIterable(value) {
5
6
  return typeof value === 'object' && value !== null && Symbol.asyncIterator in value;
6
7
  }
@@ -14,7 +15,6 @@ function scalarByName(deps, scalar) {
14
15
  return deps.GraphQLBoolean;
15
16
  case 'id':
16
17
  return deps.GraphQLID;
17
- case 'string':
18
18
  default:
19
19
  return deps.GraphQLString;
20
20
  }
@@ -35,43 +35,60 @@ function builtinScalarByGraphqlName(deps, scalarName) {
35
35
  return undefined;
36
36
  }
37
37
  }
38
- function normalizeFieldOutputType(deps, type) {
38
+ function normalizeFieldOutputType(deps, outputTypeCache, type, transformObjectFields) {
39
+ if (isListOutputType(type)) {
40
+ return new deps.GraphQLList(normalizeFieldOutputType(deps, outputTypeCache, type.ofType, transformObjectFields));
41
+ }
42
+ if (isNonNullOutputType(type)) {
43
+ return new deps.GraphQLNonNull(normalizeFieldOutputType(deps, outputTypeCache, type.ofType, transformObjectFields));
44
+ }
39
45
  const maybeScalarName = type.name;
40
46
  if (typeof maybeScalarName === 'string') {
41
- return builtinScalarByGraphqlName(deps, maybeScalarName) ?? type;
47
+ const builtinScalar = builtinScalarByGraphqlName(deps, maybeScalarName);
48
+ if (builtinScalar) {
49
+ return builtinScalar;
50
+ }
51
+ }
52
+ if (isUnionOutputType(type)) {
53
+ return normalizeUnionOutputType(deps, outputTypeCache, type, transformObjectFields);
54
+ }
55
+ if (isObjectOutputType(type)) {
56
+ return normalizeObjectOutputType(deps, outputTypeCache, type, transformObjectFields);
42
57
  }
43
58
  return type;
44
59
  }
45
- function normalizeObjectOutputType(deps, outputTypeCache, outputType) {
60
+ function normalizeObjectOutputType(deps, outputTypeCache, outputType, transformObjectFields) {
46
61
  const outputTypeName = outputType.name;
47
62
  const cached = outputTypeCache.get(outputTypeName);
48
63
  if (cached) {
49
64
  return cached;
50
65
  }
51
66
  const config = outputType.toConfig();
52
- const clonedFields = Object.fromEntries(Object.entries(config.fields).map(([fieldName, fieldConfig]) => {
53
- const field = fieldConfig;
54
- return [fieldName, {
55
- ...field,
56
- type: normalizeFieldOutputType(deps, field.type)
57
- }];
58
- }));
59
67
  const normalized = new deps.GraphQLObjectType({
60
68
  ...config,
61
- fields: clonedFields
69
+ fields: () => {
70
+ const clonedFields = Object.fromEntries(Object.entries(config.fields).map(([fieldName, fieldConfig]) => {
71
+ const field = fieldConfig;
72
+ return [fieldName, {
73
+ ...field,
74
+ type: normalizeFieldOutputType(deps, outputTypeCache, field.type, transformObjectFields)
75
+ }];
76
+ }));
77
+ return transformObjectFields(outputTypeName, clonedFields);
78
+ }
62
79
  });
63
80
  outputTypeCache.set(outputTypeName, normalized);
81
+ normalized.getFields();
64
82
  return normalized;
65
83
  }
66
- function normalizeUnionOutputType(deps, outputTypeCache, outputType) {
84
+ function normalizeUnionOutputType(deps, outputTypeCache, outputType, transformObjectFields) {
67
85
  const outputTypeName = outputType.name;
68
86
  const cached = outputTypeCache.get(outputTypeName);
69
87
  if (cached) {
70
88
  return cached;
71
89
  }
72
90
  const config = outputType.toConfig();
73
- const normalizedTypes = config.types.map(itemType => normalizeObjectOutputType(deps, outputTypeCache, itemType));
74
- const normalizedTypeByName = new Set(normalizedTypes.map(itemType => itemType.name).filter(name => typeof name === 'string'));
91
+ const normalizedTypeByName = new Set(config.types.map(itemType => itemType.name));
75
92
  const normalized = new deps.GraphQLUnionType({
76
93
  ...config,
77
94
  resolveType: async (...args) => {
@@ -88,36 +105,46 @@ function normalizeUnionOutputType(deps, outputTypeCache, outputType) {
88
105
  }
89
106
  return undefined;
90
107
  },
91
- types: normalizedTypes
108
+ types: () => config.types.map(itemType => normalizeObjectOutputType(deps, outputTypeCache, itemType, transformObjectFields))
92
109
  });
93
110
  outputTypeCache.set(outputTypeName, normalized);
111
+ normalized.getTypes();
94
112
  return normalized;
95
113
  }
96
114
  function isUnionOutputType(value) {
97
115
  return typeof value === 'object' && typeof value.getTypes === 'function';
98
116
  }
117
+ function isObjectOutputType(value) {
118
+ return value[Symbol.toStringTag] === 'GraphQLObjectType';
119
+ }
120
+ function isListOutputType(value) {
121
+ return value[Symbol.toStringTag] === 'GraphQLList';
122
+ }
123
+ function isNonNullOutputType(value) {
124
+ return value[Symbol.toStringTag] === 'GraphQLNonNull';
125
+ }
99
126
  function resolveArgGraphqlType(deps, argType) {
100
127
  if (isGraphqlListTypeRef(argType)) {
101
128
  return new deps.GraphQLList(scalarByName(deps, argType.ofType));
102
129
  }
103
130
  return scalarByName(deps, argType);
104
131
  }
105
- function resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef) {
132
+ function resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef, transformObjectFields) {
106
133
  if (typeof outputRef === 'string') {
107
134
  return scalarByName(deps, outputRef);
108
135
  }
109
136
  markAllowedCrossRealmGraphqlObjects(outputRef);
110
137
  if (isUnionOutputType(outputRef)) {
111
- return normalizeUnionOutputType(deps, outputTypeCache, outputRef);
138
+ return normalizeUnionOutputType(deps, outputTypeCache, outputRef, transformObjectFields);
112
139
  }
113
- return normalizeObjectOutputType(deps, outputTypeCache, outputRef);
140
+ return normalizeObjectOutputType(deps, outputTypeCache, outputRef, transformObjectFields);
114
141
  }
115
- function resolveRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef) {
142
+ function resolveRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef, transformObjectFields) {
116
143
  if (isGraphqlListTypeRef(outputRef)) {
117
- const listItemType = resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef.ofType);
144
+ const listItemType = resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef.ofType, transformObjectFields);
118
145
  return new deps.GraphQLList(listItemType);
119
146
  }
120
- return resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef);
147
+ return resolveNamedRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef, transformObjectFields);
121
148
  }
122
149
  function createFieldArgs(deps, handler) {
123
150
  return Object.fromEntries(handler.argFields.map(argField => [argField.argName, {
@@ -147,7 +174,7 @@ function createOperationField(descriptor, handler, args, outputType, invokeResol
147
174
  type: outputType
148
175
  };
149
176
  }
150
- function pickFieldsByType(deps, descriptors, handlerType, markAllowedCrossRealmGraphqlObjects, outputTypeCache, invokeResolver) {
177
+ function pickFieldsByType(deps, descriptors, handlerType, markAllowedCrossRealmGraphqlObjects, outputTypeCache, transformObjectFields, invokeResolver) {
151
178
  const fields = {};
152
179
  for (const descriptor of descriptors) {
153
180
  for (const handler of descriptor.handlers) {
@@ -156,7 +183,7 @@ function pickFieldsByType(deps, descriptors, handlerType, markAllowedCrossRealmG
156
183
  }
157
184
  const args = createFieldArgs(deps, handler);
158
185
  const outputRef = resolveOutputType(handler);
159
- const outputType = resolveRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef);
186
+ const outputType = resolveRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputRef, transformObjectFields);
160
187
  if (Object.hasOwn(fields, handler.fieldName)) {
161
188
  throw new Error(`GraphQL schema conflict: field "${handler.fieldName}" on ${handlerType} type is registered more than once. ` + `Found duplicate in resolver "${descriptor.targetName}". Each field name must be unique across all resolvers.`);
162
189
  }
@@ -175,20 +202,22 @@ function isGraphQLSchemaLike(value) {
175
202
  }
176
203
  return typeof value.getQueryType === 'function' && typeof value.getTypeMap === 'function';
177
204
  }
178
- function toGraphqlValidationError(deps, error) {
179
- return new deps.GraphQLError('Validation failed.', {
205
+ function toGraphqlValidationError(deps, error, markAllowedCrossRealmGraphqlObjects) {
206
+ const graphqlError = deps.createGraphQLError('Validation failed.', {
180
207
  extensions: {
181
208
  code: 'BAD_USER_INPUT',
182
209
  issues: error.issues
183
210
  }
184
211
  });
212
+ markAllowedCrossRealmGraphqlObjects(graphqlError);
213
+ return graphqlError;
185
214
  }
186
- async function createResolverInput(deps, handler, args) {
215
+ async function createResolverInput(deps, handler, args, markAllowedCrossRealmGraphqlObjects) {
187
216
  try {
188
217
  return await createGraphqlInput(handler.inputClass, args, handler.argFields);
189
218
  } catch (error) {
190
219
  if (error instanceof DtoValidationError) {
191
- throw toGraphqlValidationError(deps, error);
220
+ throw toGraphqlValidationError(deps, error, markAllowedCrossRealmGraphqlObjects);
192
221
  }
193
222
  throw error;
194
223
  }
@@ -200,21 +229,21 @@ function resolveResolverMethod(instance, descriptor, handler) {
200
229
  }
201
230
  return value;
202
231
  }
203
- function createResolverInvoker(deps, runtimeContainer) {
204
- return async (descriptor, handler, args, contextValue) => {
232
+ function createResolverInvoker(deps, runtimeContainer, markAllowedCrossRealmGraphqlObjects, objectFieldResolvers) {
233
+ return async (descriptor, handler, args, contextValue, source) => {
205
234
  if (descriptor.scope === 'singleton') {
206
235
  const instance = await runtimeContainer.resolve(descriptor.token);
207
236
  const resolverMethod = resolveResolverMethod(instance, descriptor, handler);
208
- const input = await createResolverInput(deps, handler, args);
209
- return resolverMethod.call(instance, input, contextValue);
237
+ const methodArguments = handler.type === 'field' ? objectFieldResolvers.createMethodArguments(handler, source, contextValue) : [await createResolverInput(deps, handler, args, markAllowedCrossRealmGraphqlObjects), contextValue];
238
+ return resolverMethod.call(instance, ...methodArguments);
210
239
  }
211
240
  const operationContainer = contextValue[GRAPHQL_OPERATION_CONTAINER] ?? runtimeContainer.createRequestScope();
212
241
  const disposeOperationContainer = contextValue[GRAPHQL_OPERATION_CONTAINER] === undefined;
213
242
  try {
214
243
  const instance = await operationContainer.resolve(descriptor.token);
215
244
  const resolverMethod = resolveResolverMethod(instance, descriptor, handler);
216
- const input = await createResolverInput(deps, handler, args);
217
- return await resolverMethod.call(instance, input, contextValue);
245
+ const methodArguments = handler.type === 'field' ? objectFieldResolvers.createMethodArguments(handler, source, contextValue) : [await createResolverInput(deps, handler, args, markAllowedCrossRealmGraphqlObjects), contextValue];
246
+ return await resolverMethod.call(instance, ...methodArguments);
218
247
  } finally {
219
248
  if (disposeOperationContainer) {
220
249
  await operationContainer.dispose();
@@ -282,17 +311,24 @@ export function createCodeFirstSchema(deps, runtimeContainer, resolverDescriptor
282
311
  if (resolverDescriptors.length === 0) {
283
312
  throw new Error('GraphQL module requires either schema or at least one resolver decorated with @Resolver().');
284
313
  }
285
- const invokeResolver = createResolverInvoker(deps, runtimeContainer);
314
+ const objectFieldResolvers = new ObjectFieldResolverRegistry(resolverDescriptors);
315
+ const invokeResolver = createResolverInvoker(deps, runtimeContainer, markAllowedCrossRealmGraphqlObjects, objectFieldResolvers);
286
316
  const outputTypeCache = new Map();
287
- const queryFields = pickFieldsByType(deps, resolverDescriptors, 'query', markAllowedCrossRealmGraphqlObjects, outputTypeCache, invokeResolver);
288
- const mutationFields = pickFieldsByType(deps, resolverDescriptors, 'mutation', markAllowedCrossRealmGraphqlObjects, outputTypeCache, invokeResolver);
289
- const subscriptionFields = pickFieldsByType(deps, resolverDescriptors, 'subscription', markAllowedCrossRealmGraphqlObjects, outputTypeCache, invokeResolver);
317
+ function attachObjectFieldResolvers(typeName, fields) {
318
+ return objectFieldResolvers.attach(typeName, fields, outputType => resolveRootOutputType(deps, outputTypeCache, markAllowedCrossRealmGraphqlObjects, outputType, attachObjectFieldResolvers), (descriptor, handler, source, contextValue) => invokeResolver(descriptor, handler, {}, contextValue, source));
319
+ }
320
+ const queryFields = pickFieldsByType(deps, resolverDescriptors, 'query', markAllowedCrossRealmGraphqlObjects, outputTypeCache, attachObjectFieldResolvers, invokeResolver);
321
+ const mutationFields = pickFieldsByType(deps, resolverDescriptors, 'mutation', markAllowedCrossRealmGraphqlObjects, outputTypeCache, attachObjectFieldResolvers, invokeResolver);
322
+ const subscriptionFields = pickFieldsByType(deps, resolverDescriptors, 'subscription', markAllowedCrossRealmGraphqlObjects, outputTypeCache, attachObjectFieldResolvers, invokeResolver);
323
+ objectFieldResolvers.assertAllTargetsAttached();
290
324
  const queryType = createQueryRootType(deps, queryFields);
291
325
  const mutationType = createOptionalRootType(deps, 'Mutation', mutationFields);
292
326
  const subscriptionType = createOptionalRootType(deps, 'Subscription', subscriptionFields);
293
- return new deps.GraphQLSchema({
327
+ const schema = new deps.GraphQLSchema({
294
328
  mutation: mutationType,
295
329
  query: queryType,
296
330
  subscription: subscriptionType
297
331
  });
332
+ markAllowedCrossRealmGraphqlObjects(schema);
333
+ return schema;
298
334
  }
package/dist/service.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { type HttpApplicationAdapter } from '@fluojs/http';
2
1
  import type { Container } from '@fluojs/di';
2
+ import { type HttpApplicationAdapter } from '@fluojs/http';
3
3
  import type { ApplicationLogger, CompiledModule, OnApplicationBootstrap, OnApplicationShutdown } from '@fluojs/runtime';
4
4
  import type { GraphqlModuleOptions } from './types.js';
5
5
  /**
@@ -21,11 +21,9 @@ export declare class GraphqlLifecycleService implements OnApplicationBootstrap,
21
21
  private graphQLErrorConstructor;
22
22
  private middlewareRegistered;
23
23
  private readonly operationContainers;
24
+ private readonly requestContexts;
24
25
  private readonly websocketOperationContainers;
25
- private websocketDisposable;
26
- private websocketServer;
27
- private websocketUpgradeListener;
28
- private websocketUpgradeServer;
26
+ private websocketTransport;
29
27
  private executeGraphqlOperation;
30
28
  private releaseGraphqlInstanceOfPatch;
31
29
  private subscribeGraphqlOperation;
@@ -47,10 +45,8 @@ export declare class GraphqlLifecycleService implements OnApplicationBootstrap,
47
45
  private registerWebSocketTransport;
48
46
  private unregisterWebSocketTransport;
49
47
  private isWebSocketTransportEnabled;
50
- private resolveUpgradeServer;
51
48
  private handleWebSocketSubscribe;
52
49
  private createWebSocketOperationLimitError;
53
- private rejectWebSocketUpgrade;
54
50
  private getOrCreateWebSocketOperationContainer;
55
51
  private disposeWebSocketOperationContainer;
56
52
  private disposeAllWebSocketOperationContainers;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAgD,KAAK,sBAAsB,EAAsD,MAAM,cAAc,CAAC;AAE7J,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA2BxH,OAAO,KAAK,EAEV,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAmIpB;;GAEG;AACH,qBACa,yBAAyB;IAEpC,SAAS,IAAI,SAAS;IAKtB,UAAU,IAAI,SAAS;CAGxB;AA+ID;;GAEG;AACH,qBACa,uBAAwB,YAAW,sBAAsB,EAAE,qBAAqB;IA6DzF,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAhE1B,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA6C;IAC1F,OAAO,CAAC,mBAAmB,CAAkD;IAC7E,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,wBAAwB,CAAkC;IAClE,OAAO,CAAC,sBAAsB,CAAgC;IAC9D,OAAO,CAAC,uBAAuB,CAAyD;IACxF,OAAO,CAAC,6BAA6B,CAA2B;IAChE,OAAO,CAAC,yBAAyB,CAAyD;IAC1F,OAAO,CAAC,IAAI,CAAuB;IAEnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CA4CzB;gBAGiB,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,oBAAoB;IAG1C,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;YAI9B,wBAAwB;IAYtC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAyB3B,OAAO,CAAC,0BAA0B;YAuEpB,4BAA4B;IAuC1C,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,oBAAoB;YAkBd,wBAAwB;IAwDtC,OAAO,CAAC,kCAAkC;IAwB1C,OAAO,CAAC,sBAAsB;IAoB9B,OAAO,CAAC,sCAAsC;YAchC,kCAAkC;YAqBlC,sCAAsC;IAkBpD,OAAO,CAAC,6BAA6B;YAYvB,yBAAyB;CAexC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAA0C,KAAK,sBAAsB,EAA4D,MAAM,cAAc,CAAC;AAC7J,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA0BxH,OAAO,KAAK,EAEV,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AA2EpB;;GAEG;AACH,qBACa,yBAAyB;IAEpC,SAAS,IAAI,SAAS;IAKtB,UAAU,IAAI,SAAS;CAGxB;AA4JD;;GAEG;AACH,qBACa,uBAAwB,YAAW,sBAAsB,EAAE,qBAAqB;IA0DzF,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IA7D1B,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqC;IACzE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiD;IACjF,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAA6C;IAC1F,OAAO,CAAC,kBAAkB,CAA4C;IACtE,OAAO,CAAC,uBAAuB,CAAoC;IACnE,OAAO,CAAC,6BAA6B,CAA2B;IAChE,OAAO,CAAC,yBAAyB,CAAsC;IACvE,OAAO,CAAC,IAAI,CAAuB;IAEnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CA2CzB;gBAGiB,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,oBAAoB;IAG1C,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;YAI9B,wBAAwB;IAYtC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;YAyBb,0BAA0B;YAgC1B,4BAA4B;IAgB1C,OAAO,CAAC,2BAA2B;YAIrB,wBAAwB;IAmDtC,OAAO,CAAC,kCAAkC;IAwB1C,OAAO,CAAC,sCAAsC;YAchC,kCAAkC;YAqBlC,sCAAsC;IAkBpD,OAAO,CAAC,6BAA6B;YAYvB,yBAAyB;CAexC"}