@futdevpro/nts-dynamo 1.9.30 → 1.9.32

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 (57) hide show
  1. package/build/_models/control-models/app-params.control-model.d.ts +4 -0
  2. package/build/_models/control-models/app-params.control-model.d.ts.map +1 -1
  3. package/build/_models/control-models/app-params.control-model.js +5 -0
  4. package/build/_models/control-models/app-params.control-model.js.map +1 -1
  5. package/build/_models/interfaces/global-settings.interface.d.ts +4 -0
  6. package/build/_models/interfaces/global-settings.interface.d.ts.map +1 -1
  7. package/build/_modules/socket/_services/socket-server.service.d.ts +1 -1
  8. package/build/_modules/socket/_services/socket-server.service.d.ts.map +1 -1
  9. package/build/_modules/socket/_services/socket-server.service.js.map +1 -1
  10. package/build/_modules/usage/usage.data-service.d.ts +0 -1
  11. package/build/_modules/usage/usage.data-service.d.ts.map +1 -1
  12. package/build/_modules/usage/usage.data-service.js +0 -12
  13. package/build/_modules/usage/usage.data-service.js.map +1 -1
  14. package/build/_services/base/data.service.d.ts +6 -5
  15. package/build/_services/base/data.service.d.ts.map +1 -1
  16. package/build/_services/base/data.service.js +27 -14
  17. package/build/_services/base/data.service.js.map +1 -1
  18. package/build/_services/base/db.service.d.ts +1 -2
  19. package/build/_services/base/db.service.d.ts.map +1 -1
  20. package/build/_services/base/db.service.js +42 -31
  21. package/build/_services/base/db.service.js.map +1 -1
  22. package/build/_services/base/singleton.service-base.d.ts +9 -0
  23. package/build/_services/base/singleton.service-base.d.ts.map +1 -0
  24. package/build/_services/base/singleton.service-base.js +21 -0
  25. package/build/_services/base/singleton.service-base.js.map +1 -0
  26. package/build/_services/base/singleton.service.d.ts +5 -4
  27. package/build/_services/base/singleton.service.d.ts.map +1 -1
  28. package/build/_services/base/singleton.service.js +16 -11
  29. package/build/_services/base/singleton.service.js.map +1 -1
  30. package/build/_services/core/auth.service.d.ts.map +1 -1
  31. package/build/_services/core/auth.service.js +1 -1
  32. package/build/_services/core/auth.service.js.map +1 -1
  33. package/build/_services/core/email.service.d.ts +3 -1
  34. package/build/_services/core/email.service.d.ts.map +1 -1
  35. package/build/_services/core/email.service.js +15 -2
  36. package/build/_services/core/email.service.js.map +1 -1
  37. package/build/_services/core/service-collection.service.d.ts +2 -2
  38. package/build/_services/core/service-collection.service.d.ts.map +1 -1
  39. package/build/_services/core/service-collection.service.js +2 -2
  40. package/build/_services/core/service-collection.service.js.map +1 -1
  41. package/build/_services/server/app.server.d.ts +1 -1
  42. package/build/_services/server/app.server.d.ts.map +1 -1
  43. package/build/_services/server/app.server.js +6 -3
  44. package/build/_services/server/app.server.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/_models/control-models/app-params.control-model.ts +5 -0
  47. package/src/_models/interfaces/global-settings.interface.ts +5 -0
  48. package/src/_modules/socket/_services/socket-server.service.ts +1 -1
  49. package/src/_modules/usage/usage.data-service.ts +0 -16
  50. package/src/_services/base/data.service.ts +38 -18
  51. package/src/_services/base/db.service.ts +15 -15
  52. package/src/_services/base/singleton.service-base.ts +25 -0
  53. package/src/_services/base/singleton.service.ts +24 -14
  54. package/src/_services/core/auth.service.ts +2 -2
  55. package/src/_services/core/email.service.ts +22 -3
  56. package/src/_services/core/service-collection.service.ts +3 -2
  57. package/src/_services/server/app.server.ts +8 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futdevpro/nts-dynamo",
3
- "version": "01.09.30",
3
+ "version": "01.09.32",
4
4
  "description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
5
5
  "scripts": {
6
6
  "prep": "npm i rimraf nodemon -g",
@@ -31,6 +31,10 @@ export class DyNTS_App_Params {
31
31
  * name of the system, by default, its: this.name.replace(' ', '-')
32
32
  */
33
33
  systemName?: string;
34
+ /**
35
+ * short code name of the system
36
+ */
37
+ systemShortCodeName?: string;
34
38
 
35
39
  constructor(
36
40
  set: DyNTS_App_Params
@@ -41,5 +45,6 @@ export class DyNTS_App_Params {
41
45
  this.dbName = set.dbName;
42
46
  this.dbUri = set.dbUri ?? `mongodb://localhost:27017/${this.dbName}`;
43
47
  this.systemName = set.systemName ?? this.name.replace(' ', '-');
48
+ this.systemShortCodeName = set.systemShortCodeName ?? this.systemName.replace(/[^A-Z]/g, '');
44
49
  }
45
50
  }
@@ -25,6 +25,11 @@ export interface DyNTS_Global_Settings {
25
25
  */
26
26
  defaultSocketSecurity: DyNTS_SocketSecurity;
27
27
 
28
+ /**
29
+ * this is the name of the system, this will be used for the logs and errors
30
+ */
31
+ systemShortCodeName?: string;
32
+
28
33
  /**
29
34
  * this setting will set which logs will be shown
30
35
  */
@@ -59,7 +59,7 @@ export abstract class DyNTS_SocketServerService<
59
59
  get logSetup(): boolean { return DyNTS_global_settings.log_settings.setup; }
60
60
  get highDetailedLogs(): boolean { return DyNTS_global_settings.log_settings.highDetailedLogs; }
61
61
 
62
- defaultErrorUserMsg =
62
+ override readonly defaultErrorUserMsg =
63
63
  `We encountered an unhandled Socket Server Error, ` +
64
64
  `\nplease contact the responsible development team.`;
65
65
 
@@ -153,20 +153,4 @@ export class DyNTS_Usage_DataService extends DyNTS_DataService<DyFM_UsageSession
153
153
  });
154
154
  }
155
155
  }
156
-
157
- // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
158
- private getDefaultErrorSettings(
159
- fnName: string,
160
- error: Error | DyFM_Error
161
- )/* : DyFM_ErrorSettings */ {
162
- return {
163
- status: (error as DyFM_Error)?.___status ?? 417,
164
- message: (error as Error)?.message ?? `${fnName} was UNSUCCESSFUL (NTS; ${this.serviceName})`,
165
- addECToUserMsg: true,
166
- userMessage: this.defaultErrorUserMsg,
167
- issuer: this.issuer,
168
- issuerService: this.serviceName,
169
- error: error,
170
- };
171
- }
172
156
  }
@@ -8,8 +8,9 @@ import { DyNTS_DBUpdate } from '../../_models/types/db-update.type';
8
8
 
9
9
  import { DyNTS_DBService } from './db.service';
10
10
  import { DyNTS_GlobalService } from '../core/global.service';
11
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
11
12
 
12
- // TODO: 2 type of archiving service system (within list, or separate db elements)
13
+ // TODO: 2 type of archiving service system: within list, or separate db elements
13
14
 
14
15
  /**
15
16
  * Basic Data Service that is connected to the relevant DBServices
@@ -47,10 +48,10 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
47
48
 
48
49
  dataParams: DyFM_DataModel_Params;
49
50
 
50
- defaultErrorUserMsg: string =
51
+ readonly defaultErrorUserMsg: string =
51
52
  `We encountered an unhandled Data Service Error, ` +
52
53
  `\nplease contact the responsible development team.`;
53
- defaultValidationErrorUserMsg: string =
54
+ readonly defaultValidationErrorUserMsg: string =
54
55
  `We encountered an unhandled Validation Error, ` +
55
56
  `\nplease contact the responsible development team.`;
56
57
 
@@ -194,13 +195,13 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
194
195
  return [];
195
196
  }
196
197
 
197
- const datas: T[] = await this.dataDBService.find({ _id: { $in: ids } });
198
+ const dataList: T[] = await this.dataDBService.find({ _id: { $in: ids } });
198
199
 
199
200
  if (!dontSetToService) {
200
- this.dataList = datas;
201
+ this.dataList = dataList;
201
202
  }
202
203
 
203
- return datas;
204
+ return dataList;
204
205
  } catch (error) {
205
206
  throw new DyFM_Error({
206
207
  ...this._getDefaultErrorSettings('getDataByIds', error),
@@ -278,14 +279,17 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
278
279
  }
279
280
  }
280
281
 
281
- async getDatasByDependencyIds(dependencyIds: string[], dontSetToService?: boolean): Promise<T[]> {
282
+ async getDataListByDependencyIds(
283
+ dependencyIds: string[],
284
+ dontSetToService?: boolean
285
+ ): Promise<T[]> {
282
286
  try {
283
287
  if (!this.depKey) {
284
288
  throw new DyFM_Error({
285
289
  ...this._getDefaultErrorSettings(
286
- 'getDatasByDependencyIds',
290
+ 'getDataListByDependencyIds',
287
291
  new Error(
288
- `getDatasByDependencyIds failed, dependencyKey is missing from service! ` +
292
+ `getDataListByDependencyIds failed, dependencyKey is missing from service! ` +
289
293
  `(${this.dataParams.dataName})`
290
294
  )
291
295
  ),
@@ -297,9 +301,9 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
297
301
  if (!dependencyIds) {
298
302
  throw new DyFM_Error({
299
303
  ...this._getDefaultErrorSettings(
300
- 'getDatasByDependencyIds',
304
+ 'getDataListByDependencyIds',
301
305
  new Error(
302
- `getDatasByDependencyIds failed, dependencyIds is missing! ` +
306
+ `getDataListByDependencyIds failed, dependencyIds is missing! ` +
303
307
  `(${this.dataParams.dataName})`
304
308
  )
305
309
  ),
@@ -312,19 +316,19 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
312
316
  return [];
313
317
  }
314
318
 
315
- const datas: T[] = await this.dataDBService.getDatasByDependencyIds(dependencyIds);
319
+ const dataList: T[] = await this.dataDBService.getDataListByDependencyIds(dependencyIds);
316
320
 
317
321
  if (!dontSetToService) {
318
- this.dataList = datas;
322
+ this.dataList = dataList;
319
323
  }
320
324
 
321
- return datas;
325
+ return dataList;
322
326
  } catch (error) {
323
327
  if ([ 'NTS-DS0-GDS1', 'NTS-DS0-GDS2' ].includes(error?.errorCode)) {
324
328
  throw error;
325
329
  } else {
326
330
  throw new DyFM_Error({
327
- ...this._getDefaultErrorSettings('getDatasByDependencyIds', error),
331
+ ...this._getDefaultErrorSettings('getDataListByDependencyIds', error),
328
332
 
329
333
  errorCode: 'NTS-DS0-GDS0',
330
334
  });
@@ -486,11 +490,11 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
486
490
  * //
487
491
  * @returns {T[]} dataList: T[]
488
492
  */
489
- async findDatas(filterBy: DyNTS_DBFilter<T>, dontSetToService?: boolean): Promise<T[]> {
493
+ async findDataList(filterBy: DyNTS_DBFilter<T>, dontSetToService?: boolean): Promise<T[]> {
490
494
  try {
491
495
  const dataListExists: T[] = await this.dataDBService.find(filterBy).catch((error): T[] => {
492
496
  if (error?.errorCode === 'NTS-DBS-F1') {
493
- DyFM_Log.warn(`findDatas ${this.dataParams.dataName} didn't found any.`);
497
+ DyFM_Log.warn(`findDataList ${this.dataParams.dataName} didn't found any.`);
494
498
 
495
499
  return [];
496
500
  } else {
@@ -505,7 +509,7 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
505
509
  return dataListExists;
506
510
  } catch (error) {
507
511
  throw new DyFM_Error({
508
- ...this._getDefaultErrorSettings('findDatas', error),
512
+ ...this._getDefaultErrorSettings('findDataList', error),
509
513
 
510
514
  errorCode: 'NTS-DS0-FDS0',
511
515
  });
@@ -944,4 +948,20 @@ export class DyNTS_DataService<T extends DyFM_Metadata> {
944
948
  error: error,
945
949
  };
946
950
  }
951
+
952
+ protected getDefaultErrorSettings(
953
+ fnName: string,
954
+ error: DyFM_AnyError
955
+ ): DyFM_Error_Settings {
956
+ return {
957
+ status: (error as DyFM_Error)?.___status ?? 500,
958
+ message: (error as Error)?.message ??
959
+ `${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
960
+ addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
961
+ userMessage: (error as DyFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
962
+ issuer: this.issuer,
963
+ issuerService: this.constructor?.name,
964
+ error: error,
965
+ };
966
+ }
947
967
  }
@@ -288,14 +288,21 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
288
288
  return dataList;
289
289
  }
290
290
 
291
- async getDatasByDependencyIds(dependencyIds: string[]): Promise<T[]> {
291
+ /**
292
+ * get multiple data objects by a list of DependencyIDs,
293
+ * !!!: throws error if not found (errorCode on not found: NTS-DBS-GLDS2)
294
+ *
295
+ * @param ids ids
296
+ * @returns dataList
297
+ */
298
+ async getDataListByDependencyIds(dependencyIds: string[]): Promise<T[]> {
292
299
  if (!this.depDataName) {
293
300
  throw new DyFM_Error({
294
301
  ...this._getDefaultErrorSettings(
295
- 'getDatasByDependencyIds',
302
+ 'getDataListByDependencyIds',
296
303
  new Error(
297
- `dependencyDataIdKey not setted up for this db-service (${this.dataParams.dbName}) ` +
298
- `(NTS DB)`
304
+ `getDataListByDependencyIds not setted up for this db-service ` +
305
+ `(${this.dataParams.dbName}) (NTS DB)`
299
306
  )
300
307
  ),
301
308
 
@@ -309,7 +316,7 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
309
316
  .then((res): T[] => res as T[] ?? [])
310
317
  .catch((error): void => {
311
318
  throw new DyFM_Error({
312
- ...this._getDefaultErrorSettings('getDatasByDependencyIds', error),
319
+ ...this._getDefaultErrorSettings('getDataListByDependencyIds', error),
313
320
 
314
321
  errorCode: 'NTS-DBS-GLDS1',
315
322
  additionalContent: { dependencyIds },
@@ -318,20 +325,13 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
318
325
  });
319
326
 
320
327
  dataList.forEach((data: T): void => {
321
- data = this.stringifyDataId(data, 'getDatasByDependencyIds');
328
+ data = this.stringifyDataId(data, 'getDataListByDependencyIds');
322
329
  });
323
330
 
324
331
  return dataList;
325
332
  }
326
333
 
327
- /**
328
- * get multiple data objects by a list of DependencyIDs,
329
- * !!!: throws error if not found (errorCode on not found: NTS-DBS-GLDS2)
330
- *
331
- * @param ids ids
332
- * @returns dataList
333
- */
334
- async getDataListByDependencyIds(ids: string[]): Promise<T[]> {
334
+ /* async getDataListByDependencyIds(ids: string[]): Promise<T[]> {
335
335
  if (!this.depDataName) {
336
336
  throw new DyFM_Error({
337
337
  ...this._getDefaultErrorSettings(
@@ -366,7 +366,7 @@ export class DyNTS_DBService<T extends DyFM_Metadata> {
366
366
  });
367
367
 
368
368
  return dataList;
369
- }
369
+ } */
370
370
 
371
371
  /**
372
372
  * returns all data from database,
@@ -0,0 +1,25 @@
1
+ import { DyFM_AnyError, DyFM_Error_Settings, DyFM_Error } from '@futdevpro/fsm-dynamo';
2
+
3
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
4
+
5
+ /**
6
+ *
7
+ */
8
+ export class DyNTS_SingletonServiceBase {
9
+
10
+ /// --- --- --- SINGLETON --- --- --- \\\
11
+ protected static instance;
12
+
13
+ static getSingletonInstance() {
14
+ if (!this.instance) {
15
+ this.instance = new this();
16
+ }
17
+
18
+ return this.instance;
19
+ }
20
+ /// --- --- --- SINGLETON --- --- --- ///
21
+
22
+ // SINGLETON services are using private constructor
23
+ protected constructor() {}
24
+
25
+ }
@@ -1,21 +1,31 @@
1
+ import { DyFM_AnyError, DyFM_Error_Settings, DyFM_Error } from '@futdevpro/fsm-dynamo';
2
+
3
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
4
+ import { DyNTS_SingletonServiceBase } from './singleton.service-base';
1
5
 
2
6
  /**
3
7
  *
4
8
  */
5
- export class DyNTS_SingletonService {
6
-
7
- /// --- --- --- SINGLETON --- --- --- \\\
8
- protected static instance;
9
+ export class DyNTS_SingletonService extends DyNTS_SingletonServiceBase {
9
10
 
10
- static getSingletonInstance() {
11
- if (!this.instance) {
12
- this.instance = new this();
13
- }
14
-
15
- return this.instance;
16
- }
17
- /// --- --- --- SINGLETON --- --- --- ///
11
+ readonly defaultErrorUserMsg: string =
12
+ `We encountered an unhandled Control Service Error, ` +
13
+ `\nplease contact the responsible development team.`;
18
14
 
19
- // SINGLETON services are using private constructor
20
- protected constructor() {}
15
+ protected getDefaultErrorSettings(
16
+ fnName: string,
17
+ error: DyFM_AnyError,
18
+ issuer: string
19
+ ): DyFM_Error_Settings {
20
+ return {
21
+ status: (error as DyFM_Error)?.___status ?? 500,
22
+ message: (error as Error)?.message ??
23
+ `${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
24
+ addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
25
+ userMessage: (error as DyFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
26
+ issuer: issuer,
27
+ issuerService: this.constructor?.name,
28
+ error: error,
29
+ };
30
+ }
21
31
  }
@@ -22,8 +22,8 @@ export abstract class DyNTS_AuthService extends DyNTS_SingletonService {
22
22
 
23
23
  readonly serviceName: string = 'AuthService';
24
24
 
25
- readonly defaultErrorUserMsg =
26
- `We encountered an unhandled BackEnd Auth Error, ` +
25
+ override readonly defaultErrorUserMsg =
26
+ `We encountered an unhandled Auth Error, ` +
27
27
  `\nplease contact the responsible development team.`;
28
28
 
29
29
  /**
@@ -8,6 +8,8 @@ import { Options as MailOptions, Attachment } from 'nodemailer/lib/mailer';
8
8
  import {
9
9
  DyFM_AnyError, DyFM_Array, DyFM_Error, DyFM_Error_Settings, DyFM_Log
10
10
  } from '@futdevpro/fsm-dynamo';
11
+ import { DyNTS_SingletonService } from '../base/singleton.service';
12
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
11
13
 
12
14
  export interface DyNTS_EmailService_Settings {
13
15
  host: string,
@@ -58,7 +60,7 @@ export interface DyNTS_SendEmail_Settings<T = { [propertyKey: string]: string; }
58
60
  /**
59
61
  *
60
62
  */
61
- export class DyNTS_EmailService {
63
+ export class DyNTS_EmailService /* extends DyNTS_SingletonService */ {
62
64
  serviceName: string;
63
65
 
64
66
  private nmTransporter: NodeMailer.Transporter;
@@ -75,8 +77,8 @@ export class DyNTS_EmailService {
75
77
 
76
78
  private readonly styleLimitWarning: number = 16;
77
79
 
78
- defaultErrorUserMsg =
79
- `We encountered an uncought Email Service Error, ` +
80
+ readonly defaultErrorUserMsg =
81
+ `We encountered an uncaught Email Service Error, ` +
80
82
  `\nplease contact the responsible development team.`;
81
83
 
82
84
  constructor (
@@ -677,4 +679,21 @@ export class DyNTS_EmailService {
677
679
  error: error,
678
680
  };
679
681
  }
682
+
683
+ protected getDefaultErrorSettings(
684
+ fnName: string,
685
+ error: DyFM_AnyError,
686
+ issuer: string
687
+ ): DyFM_Error_Settings {
688
+ return {
689
+ status: (error as DyFM_Error)?.___status ?? 500,
690
+ message: (error as Error)?.message ??
691
+ `${fnName} was UNSUCCESSFUL (${DyNTS_global_settings.systemShortCodeName})`,
692
+ addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
693
+ userMessage: (error as DyFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
694
+ issuer: issuer,
695
+ issuerService: this.constructor?.name,
696
+ error: error,
697
+ };
698
+ }
680
699
  }
@@ -1,5 +1,6 @@
1
- import { DyNTS_SingletonService } from '../base/singleton.service';
2
1
 
3
- export class DyNTS_Service_Collection<T> extends DyNTS_SingletonService {
2
+ import { DyNTS_SingletonServiceBase } from '../base/singleton.service-base';
3
+
4
+ export class DyNTS_Service_Collection<T> extends DyNTS_SingletonServiceBase {
4
5
  [service: string]: T;
5
6
  }
@@ -249,8 +249,8 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
249
249
 
250
250
  private _routingModules: DyNTS_RoutingModule[] = [];
251
251
 
252
- defaultErrorUserMsg =
253
- `We encountered a Server Error, ` +
252
+ override readonly defaultErrorUserMsg =
253
+ `We encountered an unhandled Server Error, ` +
254
254
  `\nplease contact the responsible development team.` +
255
255
  `\n(Internal Server error)`;
256
256
 
@@ -327,6 +327,10 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
327
327
  if (!this._params) {
328
328
  throw new Error('getAppParams() must return a DyNTS_AppParams object!');
329
329
  }
330
+
331
+ if (!DyNTS_global_settings.systemShortCodeName) {
332
+ DyNTS_global_settings.systemShortCodeName = this.params.systemShortCodeName;
333
+ }
330
334
 
331
335
  process.stdout.write(
332
336
  String.fromCharCode(27) + ']0;' +
@@ -1180,11 +1184,11 @@ export abstract class DyNTS_App extends DyNTS_SingletonService {
1180
1184
  return {
1181
1185
  status: (error as DyFM_Error)?.___status ?? 500,
1182
1186
  message: (error as Error)?.message ?? `${fnName} was UNSUCCESSFUL (NTS)`,
1183
- addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
1184
1187
  userMessage: (error as DyFM_Error)?.__userMessage ?? this.defaultErrorUserMsg,
1188
+ addECToUserMsg: !(error as DyFM_Error)?.__userMessage,
1185
1189
  issuerService: `${this?.constructor?.name}-DyNTS_App`,
1186
- error: error,
1187
1190
  level: DyFM_ErrorLevel.fatal,
1191
+ error: error,
1188
1192
  };
1189
1193
  }
1190
1194