@adaas/a-concept 0.0.62 → 0.0.64

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.
Files changed (35) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +4 -3
  3. package/dist/index.js.map +1 -1
  4. package/dist/src/global/A-Channel/A-Channel.class.d.ts +1 -3
  5. package/dist/src/global/A-Channel/A-Channel.class.js +40 -22
  6. package/dist/src/global/A-Channel/A-Channel.class.js.map +1 -1
  7. package/dist/src/global/A-Command/A-Command.class.d.ts +9 -7
  8. package/dist/src/global/A-Command/A-Command.class.js +21 -4
  9. package/dist/src/global/A-Command/A-Command.class.js.map +1 -1
  10. package/dist/src/global/A-Command/A-Command.constants.d.ts +6 -1
  11. package/dist/src/global/A-Command/A-Command.constants.js +5 -0
  12. package/dist/src/global/A-Command/A-Command.constants.js.map +1 -1
  13. package/dist/src/global/A-Command/A-Command.types.d.ts +2 -2
  14. package/dist/src/global/A-Command/A-Command.types.js.map +1 -1
  15. package/dist/src/global/A-Concept/A_Concept.class.d.ts +1 -1
  16. package/dist/src/global/A-Entity/A-Entity.class.js +2 -2
  17. package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
  18. package/dist/src/global/A-Scope/A-Scope.class.d.ts +417 -56
  19. package/dist/src/global/A-Scope/A-Scope.class.js +542 -250
  20. package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
  21. package/dist/src/global/A-Scope/A-Scope.constants.d.ts +2 -0
  22. package/dist/src/global/A-Scope/A-Scope.constants.js +11 -0
  23. package/dist/src/global/A-Scope/A-Scope.constants.js.map +1 -0
  24. package/dist/src/global/A-Scope/A-Scope.types.d.ts +11 -9
  25. package/dist/src/global/A-Stage/A-Stage.class.d.ts +2 -2
  26. package/index.ts +1 -0
  27. package/package.json +2 -2
  28. package/src/global/A-Channel/A-Channel.class.ts +81 -15
  29. package/src/global/A-Command/A-Command.class.ts +29 -11
  30. package/src/global/A-Command/A-Command.constants.ts +8 -1
  31. package/src/global/A-Command/A-Command.types.ts +5 -3
  32. package/src/global/A-Entity/A-Entity.class.ts +5 -4
  33. package/src/global/A-Scope/A-Scope.class.ts +834 -425
  34. package/src/global/A-Scope/A-Scope.constants.ts +9 -0
  35. package/src/global/A-Scope/A-Scope.types.ts +23 -18
@@ -1,60 +1,195 @@
1
- import { A_TYPES__ScopeConfig, A_TYPES__ScopeConstructor } from "./A-Scope.types";
1
+ import { A_TYPES__AllowedCommandsConstructor, A_TYPES__AllowedComponentsConstructor, A_TYPES__AllowedEntitiesConstructor, A_TYPES__AllowedFragmentsConstructor, A_TYPES__AllowedScopesConstructor, A_TYPES__ScopeConfig, A_TYPES__ScopeConstructor } from './A-Scope.types';
2
+ import { A_TYPES__A_InjectDecorator_EntityInjectionInstructions } from "../../decorators/A-Inject/A-Inject.decorator.types";
2
3
  import { A_Fragment } from "../A-Fragment/A-Fragment.class";
3
4
  import { A_Component } from "../A-Component/A-Component.class";
4
5
  import { A_Entity } from "../A-Entity/A-Entity.class";
5
- import { A_TYPES__A_InjectDecorator_EntityInjectionInstructions, A_TYPES__A_InjectDecorator_Injectable } from "../../decorators/A-Inject/A-Inject.decorator.types";
6
6
  import { A_Command } from "../A-Command/A-Command.class";
7
- /**
8
- *
9
- *
10
- * A_Scope refers to the visibility and accessibility of :
11
- * - variables,
12
- * - Components,
13
- * - Context Fragments
14
- * - and objects in different parts of your code.
15
- * Scope determines where a particular piece of data (like a variable or function)
16
- * can be accessed, modified, or referenced, and it plays a crucial role in avoiding naming collisions and ensuring data integrity.
17
- *
18
- *
19
- */
20
- export declare class A_Scope {
7
+ export declare class A_Scope<_ComponentType extends A_TYPES__AllowedComponentsConstructor[] = A_TYPES__AllowedComponentsConstructor[], _CommandType extends A_TYPES__AllowedCommandsConstructor[] = A_TYPES__AllowedCommandsConstructor[], _EntityType extends A_Entity[] = A_Entity[], _FragmentType extends A_Fragment[] = A_Fragment[]> {
8
+ /**
9
+ * Scope Name uses for identification and logging purposes
10
+ */
21
11
  readonly name: string;
22
- private _components;
23
- private _fragments;
24
- private _commands;
25
- private _entities;
26
- private _parent?;
27
- protected params: A_TYPES__ScopeConstructor;
28
- constructor(params: Partial<A_TYPES__ScopeConstructor>, config?: Partial<A_TYPES__ScopeConfig>);
29
- private initComponents;
30
- private initEntities;
31
- private initFragments;
32
- get components(): (new (...args: any[]) => A_Component)[];
33
- get commands(): (new (...args: any[]) => A_Command)[];
34
- get fragments(): A_Fragment[];
35
- parent(setValue: A_Scope): void;
36
- parent(): A_Scope;
37
- isInheritedFrom(scope: A_Scope): boolean;
38
- inherit(parent: A_Scope): A_Scope;
39
12
  /**
40
- * Helper method to check circular inheritance
41
- * Should return a full sequence of inheritance for logging purposes
13
+ * Parent scope reference, used for inheritance of components, fragments, entities and commands
14
+ */
15
+ protected _parent?: A_Scope;
16
+ /**
17
+ * A set of allowed components, A set of constructors that are allowed in the scope
42
18
  *
43
- * @param scope
19
+ */
20
+ protected _allowedComponents: Set<_ComponentType[number]>;
21
+ /**
22
+ * A set of allowed entities, A set of constructors that are allowed in the scope
23
+ */
24
+ protected _allowedEntities: Set<A_TYPES__AllowedEntitiesConstructor<_EntityType[number]>>;
25
+ /**
26
+ * A set of allowed fragments, A set of constructors that are allowed in the scope
27
+ */
28
+ protected _allowedFragments: Set<A_TYPES__AllowedFragmentsConstructor<_FragmentType[number]>>;
29
+ /**
30
+ * A set of allowed commands, A set of constructors that are allowed in the scope
31
+ */
32
+ protected _allowedCommands: Set<_CommandType[number]>;
33
+ /**
34
+ * Internal storage for the components, fragments, entities and commands
35
+ */
36
+ protected _components: Map<_ComponentType[number], InstanceType<_ComponentType[number]>>;
37
+ /**
38
+ * Storage for the fragments, should be weak as fragments are singletons per scope
39
+ */
40
+ protected _fragments: Map<A_TYPES__AllowedFragmentsConstructor<_FragmentType[number]>, _FragmentType[number]>;
41
+ /**
42
+ * Storage for the entities, should be strong as entities are unique per aseid
43
+ */
44
+ protected _entities: Map<string, _EntityType[number]>;
45
+ /**
46
+ * Storage for the commands, should be strong as commands are unique per code
47
+ */
48
+ protected _commands: Map<string, InstanceType<_CommandType[number]>>;
49
+ /**
50
+ * Returns a list of Constructors for A-Components that are available in the scope
51
+ */
52
+ get allowedComponents(): Set<_ComponentType[number]>;
53
+ /**
54
+ * Returns a list of Constructors for A-Commands that are available in the scope
55
+ */
56
+ get allowedCommands(): Set<_CommandType[number]>;
57
+ /**
58
+ * Returns a list of Constructors for A-Fragments that are available in the scope
59
+ */
60
+ get allowedFragments(): Set<A_TYPES__AllowedFragmentsConstructor<_FragmentType[number]>>;
61
+ /**
62
+ * Returns a list of Constructors for A-Entities that are available in the scope
63
+ */
64
+ get allowedEntities(): Set<A_TYPES__AllowedEntitiesConstructor<_EntityType[number]>>;
65
+ /**
66
+ * Returns an Array of entities registered in the scope
67
+ *
68
+ * [!] One entity per aseid
69
+ */
70
+ get entities(): Array<_EntityType[number]>;
71
+ /**
72
+ * Returns an Array of fragments registered in the scope
73
+ *
74
+ * [!] One fragment per scope
75
+ */
76
+ get fragments(): Array<_FragmentType[number]>;
77
+ /**
78
+ * Returns an Array of components registered in the scope
79
+ *
80
+ * [!] One component instance per scope
81
+ */
82
+ get components(): Array<InstanceType<_ComponentType[number]>>;
83
+ /**
84
+ * Returns an Array of commands registered in the scope
85
+ *
86
+ * [!] One command per command aseid
87
+ * [!!] There may be any number of instances of the same command code, but with different aseids.
88
+ */
89
+ get commands(): Array<InstanceType<_CommandType[number]>>;
90
+ /**
91
+ * A_Scope refers to the visibility and accessibility of :
92
+ * - variables,
93
+ * - Components,
94
+ * - Context Fragments
95
+ * - Commands
96
+ * - Entities
97
+ * - and objects in different parts of your code.
98
+ * Scope determines where a particular piece of data (like a variable or function)
99
+ * can be accessed, modified, or referenced, and it plays a crucial role in avoiding naming collisions and ensuring data integrity.
100
+ *
101
+ * [!] The scope behavior is similar to tree structure where each scope can have a parent scope and inherit its components, fragments, entities and commands
102
+ *
103
+ * @param params
104
+ * @param config
105
+ */
106
+ constructor(params: Partial<A_TYPES__ScopeConstructor<_ComponentType, _CommandType, _EntityType, _FragmentType>>, config?: Partial<A_TYPES__ScopeConfig>);
107
+ /**
108
+ * This method is used to initialize the components in the scope
109
+ * To save memory components are initialized only when they are requested
110
+ *
111
+ * This method only registers the component in the scope in case they are not registered yet
112
+ *
113
+ * @param _components
114
+ */
115
+ protected initComponents(_components?: _ComponentType): void;
116
+ /**
117
+ * This method is used to initialize the entities in the scope
118
+ *
119
+ * This method only registers the entities in the scope in case they are not registered yet
120
+ *
121
+ * @param _entities
122
+ */
123
+ protected initEntities(_entities?: _EntityType): void;
124
+ /**
125
+ * This method is used to initialize the fragments in the scope
126
+ *
127
+ * This method only registers the fragments in the scope in case they are not registered yet
128
+ *
129
+ * @param _fragments
130
+ */
131
+ protected initFragments(_fragments?: _FragmentType): void;
132
+ /**
133
+ * This method is used to initialize the commands in the scope
134
+ *
135
+ * This method only registers the commands in the scope in case they are not registered yet
136
+ *
137
+ * @param _commands
138
+ */
139
+ protected initCommands(_commands?: _CommandType): void;
140
+ /**
141
+ * This method is used to get or set the parent scope
142
+ *
143
+ * [!] Note that setting the parent scope will override the existing parent scope
144
+ *
145
+ * @param setValue
44
146
  * @returns
45
147
  */
46
- checkCircularInheritance(scope: A_Scope): Array<string> | false;
47
- printInheritanceChain(): void;
148
+ parent(setValue?: A_Scope): A_Scope | undefined;
149
+ /**
150
+ * This method is used to inherit from a parent scope
151
+ *
152
+ * [!] This method checks for circular inheritance and throws an error if detected
153
+ *
154
+ * @param parent
155
+ * @returns
156
+ */
157
+ inherit(parent: A_Scope): A_Scope;
48
158
  /**
49
159
  * This method is used to check if the component is available in the scope
50
160
  *
161
+ * [!] Note that this method checks for the component in the current scope and all parent scopes
162
+ *
51
163
  * @param component
52
164
  * @returns
53
165
  */
54
- has<T extends A_Component>(component: new (...args: any[]) => T): boolean;
55
- has<T extends A_Entity>(entity: new (...args: any[]) => T): boolean;
56
- has<T extends A_Fragment>(fragment: new (...args: any[]) => T): boolean;
57
- has(constructor: string): boolean;
166
+ has<T extends A_Component>(
167
+ /**
168
+ * Provide a component constructor to check if it's available in the scope
169
+ */
170
+ component: A_TYPES__AllowedComponentsConstructor<T>): boolean;
171
+ has<T extends A_Entity>(
172
+ /**
173
+ * Provide an entity constructor to check if it's available in the scope
174
+ *
175
+ * [!] Note that entities are unique per aseid, so this method checks if there's at least one entity of the provided type in the scope
176
+ */
177
+ entity: A_TYPES__AllowedEntitiesConstructor<T>): boolean;
178
+ has<T extends A_Fragment>(
179
+ /**
180
+ * Provide a fragment constructor to check if it's available in the scope
181
+ */
182
+ fragment: A_TYPES__AllowedFragmentsConstructor<T>): boolean;
183
+ has<T extends A_Fragment>(
184
+ /**
185
+ * Provide a command constructor to check if it's available in the scope
186
+ */
187
+ command: A_TYPES__AllowedCommandsConstructor<T>): boolean;
188
+ has(
189
+ /**
190
+ * Provide a string to check if a component, entity or fragment with the provided name is available in the scope
191
+ */
192
+ constructor: string): boolean;
58
193
  /**
59
194
  * Merges two scopes into a new one
60
195
  *
@@ -77,24 +212,126 @@ export declare class A_Scope {
77
212
  * @param name
78
213
  * @returns
79
214
  */
80
- resolveConstructor<T extends A_Component | A_Entity>(name: string): new (...args: any[]) => T;
215
+ resolveConstructor<T extends A_Command>(
216
+ /**
217
+ * Provide the command name or code to retrieve its constructor
218
+ */
219
+ name: string): A_TYPES__AllowedCommandsConstructor<T>;
220
+ resolveConstructor<T extends A_Entity>(
221
+ /**
222
+ * Provide the entity name or static entity property to retrieve its constructor
223
+ */
224
+ name: string): A_TYPES__AllowedEntitiesConstructor<T>;
225
+ resolveConstructor<T extends A_Component>(
226
+ /**
227
+ * Provide the component name in PascalCase to retrieve its constructor
228
+ */
229
+ name: string): A_TYPES__AllowedComponentsConstructor<T>;
230
+ resolveConstructor<T extends A_Fragment>(
231
+ /**
232
+ * Provide the fragment name in PascalCase to retrieve its constructor
233
+ */
234
+ name: string): A_TYPES__AllowedFragmentsConstructor<T>;
81
235
  /**
82
- * This method is used to get the component by class
236
+ * This method allows to resolve/inject a component, fragment or entity from the scope
237
+ * Depending on the provided parameters it can resolve:
238
+ * - A single component/fragment/entity by its constructor or name
239
+ * - An array of components/fragments/entities by providing an array of constructors
240
+ * - An entity or an array of entities by providing the entity constructor and query instructions
83
241
  *
84
242
  * @param component
85
243
  * @returns
86
244
  */
87
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(string: string): InstanceType<T>;
88
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(component: T): InstanceType<T>;
89
- resolve<T extends A_Entity>(entity: {
90
- new (...args: any[]): T;
91
- }, instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>): T | Array<T>;
92
- resolve<T extends A_TYPES__A_InjectDecorator_Injectable>(component: Array<T>): Array<InstanceType<T>>;
245
+ resolve<T extends A_Component>(
246
+ /**
247
+ * Provide a component constructor to resolve its instance from the scope
248
+ */
249
+ component: A_TYPES__AllowedComponentsConstructor<T>): T;
250
+ resolve<T extends A_TYPES__AllowedComponentsConstructor[]>(
251
+ /**
252
+ * Provide an array of component constructors to resolve their instances from the scope
253
+ */
254
+ components: [...T]): Array<InstanceType<T[number]>>;
255
+ resolve<T extends A_Fragment>(
256
+ /**
257
+ * Provide a fragment constructor to resolve its instance from the scope
258
+ */
259
+ fragment: A_TYPES__AllowedFragmentsConstructor<T>): T;
260
+ resolve<T extends A_TYPES__AllowedFragmentsConstructor[]>(
261
+ /**
262
+ * Provide an array of fragment constructors to resolve their instances from the scope
263
+ */
264
+ fragments: [...T]): Array<InstanceType<T[number]>>;
265
+ resolve<T extends A_Command>(
266
+ /**
267
+ * Provide a command constructor to resolve its instance from the scope
268
+ */
269
+ command: A_TYPES__AllowedCommandsConstructor<T>): T;
270
+ resolve<T extends A_TYPES__AllowedCommandsConstructor[]>(
271
+ /**
272
+ * Provide an array of command constructors to resolve their instances from the scope
273
+ */
274
+ commands: [...T]): Array<InstanceType<T[number]>>;
275
+ resolve<T extends A_Entity>(
276
+ /**
277
+ * Provide an entity constructor to resolve its instance or an array of instances from the scope
278
+ */
279
+ entity: A_TYPES__AllowedEntitiesConstructor<T>): T | undefined;
280
+ resolve<T extends A_Scope>(
281
+ /**
282
+ * Uses only in case of resolving a single entity
283
+ *
284
+ * Provide an entity constructor to resolve its instance from the scope
285
+ */
286
+ scope: new (...args: any[]) => T): T;
287
+ resolve<T extends A_Entity>(
288
+ /**
289
+ * Provide an entity constructor to resolve its instance or an array of instances from the scope
290
+ */
291
+ entity: A_TYPES__AllowedEntitiesConstructor<T>,
292
+ /**
293
+ * Provide optional instructions to find a specific entity or a set of entities
294
+ */
295
+ instructions: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>): Array<T>;
93
296
  private resolveByName;
297
+ /**
298
+ * This method is used internally to resolve a single component, fragment or entity from the scope
299
+ *
300
+ * @param component
301
+ * @param instructions
302
+ * @returns
303
+ */
94
304
  private resolveOnce;
305
+ /**
306
+ * This method is used internally to resolve a single entity from the scope based on the provided instructions
307
+ *
308
+ * [!] Note that this method can return either a single entity or an array of entities depending on the instructions provided
309
+ *
310
+ * @param entity
311
+ * @param instructions
312
+ * @returns
313
+ */
95
314
  private resolveEntity;
315
+ /**
316
+ * This method is used internally to resolve a single fragment from the scope
317
+ *
318
+ * @param fragment
319
+ * @returns
320
+ */
96
321
  private resolveFragment;
322
+ /**
323
+ * This method is used internally to resolve a single scope from the current scope
324
+ *
325
+ * @param scope
326
+ * @returns
327
+ */
97
328
  private resolveScope;
329
+ /**
330
+ * This method is used internally to resolve a single component from the scope
331
+ *
332
+ * @param component
333
+ * @returns
334
+ */
98
335
  private resolveComponent;
99
336
  /**
100
337
  * Should be similar to resolveEntity but for commands
@@ -107,11 +344,135 @@ export declare class A_Scope {
107
344
  *
108
345
  * @param fragment
109
346
  */
110
- register<T extends A_Component>(component: new (...args: any[]) => T): void;
111
- register<T extends A_Entity>(entity: new (...args: any[]) => T): void;
112
- register<T extends A_Command>(command: new (...args: any[]) => T): void;
113
- register(entity: A_Entity): void;
114
- register(component: A_Component): void;
115
- register(fragment: A_Fragment): void;
347
+ register<T extends A_Component>(
348
+ /**
349
+ * Provide a component constructor to register it in the scope
350
+ */
351
+ component: A_TYPES__AllowedComponentsConstructor<T>): void;
352
+ register<T extends A_Entity>(
353
+ /**
354
+ * Provide an entity constructor to register it in the scope
355
+ */
356
+ entity: A_TYPES__AllowedEntitiesConstructor<T>): void;
357
+ register<T extends A_Command>(
358
+ /**
359
+ * Provide a command constructor to register it in the scope
360
+ */
361
+ command: A_TYPES__AllowedCommandsConstructor<T>): void;
362
+ register<T extends A_Fragment>(
363
+ /**
364
+ * Provide a command instance to register it in the scope
365
+ */
366
+ fragment: A_TYPES__AllowedFragmentsConstructor<T>): void;
367
+ register(
368
+ /**
369
+ * Provide an entity instance to register it in the scope
370
+ */
371
+ entity: A_Entity): void;
372
+ register(
373
+ /**
374
+ * Provide a command instance to register it in the scope
375
+ */
376
+ component: A_Component): void;
377
+ register(
378
+ /**
379
+ * Provide a command instance to register it in the scope
380
+ */
381
+ command: A_Command): void;
382
+ register(
383
+ /**
384
+ * Provide a fragment instance to register it in the scope
385
+ */
386
+ fragment: A_Fragment): void;
387
+ /**
388
+ * This method is useful when you want to serialize the scope to JSON
389
+ *
390
+ * [!] Note this is not a deep serialization, only the fragments are serialized
391
+ * [!] Fragments are a storage for information which is relevant to the scope
392
+ *
393
+ * @returns
394
+ */
116
395
  toJSON(): Record<string, any>;
396
+ /**
397
+ * Type guard to check if the constructor is of type A_Component
398
+ *
399
+ * @param ctor
400
+ * @returns
401
+ */
402
+ protected isComponentConstructor(ctor: unknown): ctor is A_TYPES__AllowedComponentsConstructor;
403
+ /**
404
+ * Type guard to check if the constructor is of type A_Command
405
+ *
406
+ * @param ctor
407
+ * @returns
408
+ */
409
+ protected isCommandConstructor(ctor: unknown): ctor is A_TYPES__AllowedCommandsConstructor;
410
+ /**
411
+ * Type guard to check if the constructor is of type A_Fragment
412
+ *
413
+ * @param ctor
414
+ * @returns
415
+ */
416
+ protected isFragmentConstructor(ctor: any): ctor is A_TYPES__AllowedFragmentsConstructor;
417
+ /**
418
+ * Type guard to check if the constructor is of type A_Entity
419
+ *
420
+ * @param ctor
421
+ * @returns
422
+ */
423
+ protected isEntityConstructor(ctor: unknown): ctor is A_TYPES__AllowedEntitiesConstructor;
424
+ /**
425
+ * Type guard to check if the constructor is of type A_Scope
426
+ *
427
+ * @param ctor
428
+ * @returns
429
+ */
430
+ protected isScopeConstructor(ctor: unknown): ctor is A_TYPES__AllowedScopesConstructor;
431
+ /**
432
+ * Type guard to check if the constructor is of type A_Component and is allowed in the scope
433
+ *
434
+ * @param ctor
435
+ * @returns
436
+ */
437
+ protected isAllowedComponent(ctor: unknown): ctor is _ComponentType[number];
438
+ /**
439
+ * Type guard to check if the constructor is of type A_Command and is allowed in the scope
440
+ *
441
+ * @param ctor
442
+ * @returns
443
+ */
444
+ protected isAllowedCommand(ctor: unknown): ctor is _CommandType[number];
445
+ /**
446
+ * Type guard to check if the constructor is of type A_Entity and is allowed in the scope
447
+ *
448
+ * @param ctor
449
+ * @returns
450
+ */
451
+ protected isAllowedEntity(ctor: unknown): ctor is A_TYPES__AllowedEntitiesConstructor<_EntityType[number]>;
452
+ /**
453
+ * Type guard to check if the constructor is of type A_Fragment and is allowed in the scope
454
+ *
455
+ * @param ctor
456
+ * @returns
457
+ */
458
+ protected isAllowedFragment(ctor: unknown): ctor is A_TYPES__AllowedFragmentsConstructor<_FragmentType[number]>;
459
+ /**
460
+ * This method is used to check if the scope is inherited from another scope
461
+ *
462
+ * @param scope
463
+ * @returns
464
+ */
465
+ isInheritedFrom(scope: A_Scope): boolean;
466
+ /**
467
+ * Helper method to check circular inheritance
468
+ * Should return a full sequence of inheritance for logging purposes
469
+ *
470
+ * @param scope
471
+ * @returns
472
+ */
473
+ checkCircularInheritance(scope: A_Scope): Array<string> | false;
474
+ /**
475
+ * Helper method to print the inheritance chain of the scope
476
+ */
477
+ printInheritanceChain(): void;
117
478
  }